0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-17 22:04:19 -05:00

Merge pull request #1927 from logto-io/sijie-log-4160-protected-access

feat(core,phrases): add check protected access function
This commit is contained in:
wangsijie 2022-09-14 18:13:39 +08:00 committed by GitHub
commit 0567fc6347
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 48 additions and 1 deletions

View file

@ -1,8 +1,11 @@
import { conditional } from '@silverhand/essentials';
import dayjs from 'dayjs';
import { Context } from 'koa';
import { InteractionResults, Provider } from 'oidc-provider';
import RequestError from '@/errors/RequestError';
import { findUserById, updateUserById } from '@/queries/user';
import { maskUserInfo } from '@/utils/format';
export const assignInteractionResults = async (
ctx: Context,
@ -42,6 +45,34 @@ export const assignInteractionResults = async (
ctx.body = { redirectTo, ts };
};
export const checkProtectedAccess = async (
ctx: Context,
provider: Provider,
lifetime = 10 * 60
) => {
const { result } = await provider.interactionDetails(ctx.req, ctx.res);
if (!result?.login?.accountId) {
throw new RequestError('auth.unauthorized');
}
if (!result.login.ts || result.login.ts < dayjs().unix() - lifetime) {
const user = await findUserById(result.login.accountId);
throw new RequestError('auth.require_re_authentication', {
username: conditional(
user.username && maskUserInfo({ type: 'username', value: user.username })
),
phone: conditional(
user.primaryPhone && maskUserInfo({ type: 'phone', value: user.primaryPhone })
),
email: conditional(
user.primaryEmail && maskUserInfo({ type: 'email', value: user.primaryEmail })
),
});
}
};
export const saveUserFirstConsentedAppId = async (userId: string, applicationId: string) => {
const { applicationId: firstConsentedAppId } = await findUserById(userId);

View file

@ -1,4 +1,10 @@
export const maskUserInfo = ({ type, value }: { type: 'email' | 'phone'; value: string }) => {
export const maskUserInfo = ({
type,
value,
}: {
type: 'email' | 'phone' | 'username';
value: string;
}) => {
if (!value) {
return value;
}
@ -7,6 +13,10 @@ export const maskUserInfo = ({ type, value }: { type: 'email' | 'phone'; value:
return `****${value.slice(-4)}`;
}
if (type === 'username') {
return `****${value.slice(-2)}`;
}
const [name = '', domain = ''] = value.split('@');
const preview = name.length > 4 ? `${name.slice(0, 4)}` : '';

View file

@ -7,6 +7,7 @@ const errors = {
expected_role_not_found:
'Expected role not found. Please check your user roles and permissions.',
jwt_sub_missing: 'Missing `sub` in JWT.',
require_re_authentication: 'Re-authentication is required to perform a protected action.',
},
guard: {
invalid_input: 'The request {{type}} is invalid.',

View file

@ -8,6 +8,7 @@ const errors = {
expected_role_not_found:
'Expected role not found. Please check your user roles and permissions.',
jwt_sub_missing: '`sub` manquant dans JWT.',
require_re_authentication: 'Re-authentication is required to perform a protected action.', // UNTRANSLATED
},
guard: {
invalid_input: "La requête {{type}} n'est pas valide.",

View file

@ -7,6 +7,7 @@ const errors = {
expected_role_not_found:
'Expected role not found. Please check your user roles and permissions.',
jwt_sub_missing: 'JWT에서 `sub`를 찾을 수 없어요.',
require_re_authentication: 'Re-authentication is required to perform a protected action.', // UNTRANSLATED
},
guard: {
invalid_input: '{{type}} 요청 타입은 유효하지 않아요.',

View file

@ -6,6 +6,7 @@ const errors = {
forbidden: 'Proibido. Verifique os seus cargos e permissões.',
expected_role_not_found: 'Role esperado não encontrado. Verifique os seus cargos e permissões.',
jwt_sub_missing: 'Campo `sub` está ausente no JWT.',
require_re_authentication: 'Re-authentication is required to perform a protected action.', // UNTRANSLATED
},
guard: {
invalid_input: 'O pedido {{type}} é inválido.',

View file

@ -7,6 +7,7 @@ const errors = {
expected_role_not_found:
'Expected role not found. Please check your user roles and permissions.',
jwt_sub_missing: 'JWTde `sub` eksik.',
require_re_authentication: 'Re-authentication is required to perform a protected action.', // UNTRANSLATED
},
guard: {
invalid_input: 'İstek {{type}} geçersiz.',

View file

@ -6,6 +6,7 @@ const errors = {
forbidden: '禁止访问。请检查用户 role 与权限。',
expected_role_not_found: '未找到期望的 role。请检查用户 role 与权限。',
jwt_sub_missing: 'JWT 缺失 `sub`',
require_re_authentication: '需要重新认证以进行受保护操作。',
},
guard: {
invalid_input: '请求中 {{type}} 无效',