mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
refactor: re-org RequestError files
This commit is contained in:
parent
0356010ee3
commit
a7ab69ecd5
10 changed files with 79 additions and 56 deletions
|
@ -1,51 +0,0 @@
|
|||
import pick from 'lodash.pick';
|
||||
|
||||
export enum GuardErrorCode {
|
||||
InvalidInput = 'guard.invalid_input',
|
||||
}
|
||||
|
||||
export enum OidcErrorCode {
|
||||
Aborted = 'oidc.aborted',
|
||||
}
|
||||
|
||||
export enum RegisterErrorCode {
|
||||
UsernameExists = 'register.username_exists',
|
||||
}
|
||||
|
||||
export type RequestErrorCode = GuardErrorCode | OidcErrorCode | RegisterErrorCode;
|
||||
|
||||
const requestErrorMessage: Record<RequestErrorCode, string> = {
|
||||
[GuardErrorCode.InvalidInput]: 'The request input is invalid.',
|
||||
[OidcErrorCode.Aborted]: 'The end-user aborted interaction.',
|
||||
[RegisterErrorCode.UsernameExists]: 'The username already exists.',
|
||||
};
|
||||
|
||||
export type RequestErrorMetadata = {
|
||||
code: RequestErrorCode;
|
||||
status?: number;
|
||||
};
|
||||
|
||||
export type RequestErrorBody = { message: string; data: unknown; code: string };
|
||||
|
||||
export default class RequestError extends Error {
|
||||
code: RequestErrorCode;
|
||||
status: number;
|
||||
expose: boolean;
|
||||
data: unknown;
|
||||
|
||||
constructor(input: RequestErrorMetadata | RequestErrorCode, data?: unknown) {
|
||||
const { code, status = 400 } = typeof input === 'string' ? { code: input } : input;
|
||||
const message = requestErrorMessage[code];
|
||||
|
||||
super(message);
|
||||
|
||||
this.expose = true;
|
||||
this.code = code;
|
||||
this.status = status;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
get body(): RequestErrorBody {
|
||||
return pick(this, 'message', 'code', 'data');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export enum GuardErrorCode {
|
||||
InvalidInput = 'guard.invalid_input',
|
||||
}
|
||||
|
||||
export const guardErrorMessage: Record<GuardErrorCode, string> = {
|
||||
[GuardErrorCode.InvalidInput]: 'The request input is invalid.',
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
export enum OidcErrorCode {
|
||||
Aborted = 'oidc.aborted',
|
||||
}
|
||||
|
||||
export const oidcErrorMessage: Record<OidcErrorCode, string> = {
|
||||
[OidcErrorCode.Aborted]: 'The end-user aborted interaction.',
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
export enum RegisterErrorCode {
|
||||
UsernameExists = 'register.username_exists',
|
||||
}
|
||||
|
||||
export const registerErrorMessage: Record<RegisterErrorCode, string> = {
|
||||
[RegisterErrorCode.UsernameExists]: 'The username already exists.',
|
||||
};
|
29
packages/core/src/errors/RequestError/index.ts
Normal file
29
packages/core/src/errors/RequestError/index.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import pick from 'lodash.pick';
|
||||
import { requestErrorMessage } from './message';
|
||||
import { RequestErrorBody, RequestErrorCode, RequestErrorMetadata } from './types';
|
||||
|
||||
export * from './types';
|
||||
export * from './message';
|
||||
|
||||
export default class RequestError extends Error {
|
||||
code: RequestErrorCode;
|
||||
status: number;
|
||||
expose: boolean;
|
||||
data: unknown;
|
||||
|
||||
constructor(input: RequestErrorMetadata | RequestErrorCode, data?: unknown) {
|
||||
const { code, status = 400 } = typeof input === 'string' ? { code: input } : input;
|
||||
const message = requestErrorMessage[code];
|
||||
|
||||
super(message);
|
||||
|
||||
this.expose = true;
|
||||
this.code = code;
|
||||
this.status = status;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
get body(): RequestErrorBody {
|
||||
return pick(this, 'message', 'code', 'data');
|
||||
}
|
||||
}
|
10
packages/core/src/errors/RequestError/message.ts
Normal file
10
packages/core/src/errors/RequestError/message.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { RequestErrorCode } from './types';
|
||||
import { guardErrorMessage } from './collection/guard-errors';
|
||||
import { oidcErrorMessage } from './collection/oidc-errors';
|
||||
import { registerErrorMessage } from './collection/register-errors';
|
||||
|
||||
export const requestErrorMessage: Record<RequestErrorCode, string> = {
|
||||
...guardErrorMessage,
|
||||
...oidcErrorMessage,
|
||||
...registerErrorMessage,
|
||||
};
|
14
packages/core/src/errors/RequestError/types.ts
Normal file
14
packages/core/src/errors/RequestError/types.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { GuardErrorCode } from './collection/guard-errors';
|
||||
import { OidcErrorCode } from './collection/oidc-errors';
|
||||
import { RegisterErrorCode } from './collection/register-errors';
|
||||
|
||||
export { GuardErrorCode, OidcErrorCode, RegisterErrorCode };
|
||||
|
||||
export type RequestErrorCode = GuardErrorCode | OidcErrorCode | RegisterErrorCode;
|
||||
|
||||
export type RequestErrorMetadata = {
|
||||
code: RequestErrorCode;
|
||||
status?: number;
|
||||
};
|
||||
|
||||
export type RequestErrorBody = { message: string; data: unknown; code: string };
|
|
@ -39,12 +39,12 @@ export default function koaGuard<
|
|||
ResponseBodyT
|
||||
> = async (ctx, next) => {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
// eslint-disab Le-next-line @typescript-eslint/consistent-type-assertions
|
||||
ctx.guard = {
|
||||
query: query?.parse(ctx.request.query),
|
||||
body: body?.parse(ctx.request.body),
|
||||
params: params?.parse(ctx.params),
|
||||
} as Guarded<GuardQueryT, GuardBodyT, GuardParametersT>; // Have to do this since it's too complicated for TS
|
||||
} as Guarded<GuardQueryT, GuardBodyT, GuardParametersT>; // Have to do t His since it's too complicated for TS
|
||||
} catch (error: unknown) {
|
||||
throw new RequestError(GuardErrorCode.InvalidInput, error);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ const userId = customAlphabet(alphabet, 12);
|
|||
const generateUserId = async (maxRetries = 500) => {
|
||||
for (let i = 0; i < maxRetries; ++i) {
|
||||
const id = userId();
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
// eslint-disab Le-next-line no-await-in-loop
|
||||
if (!(await hasUserWithId(id))) {
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ export default function createSignInRoutes(provider: Provider) {
|
|||
conditional(grantId && (await provider.Grant.find(grantId))) ??
|
||||
new provider.Grant({ accountId, clientId: String(params.client_id) });
|
||||
|
||||
// V2: fulfill missing claims / resources
|
||||
// V2: fulfill Missing claims / resources
|
||||
const PromptDetailsBody = object({
|
||||
missingOIDCScope: string().array().optional(),
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ export default function createSignInRoutes(provider: Provider) {
|
|||
|
||||
const finalGrantId = await grant.save();
|
||||
|
||||
// V2: configure consent
|
||||
// V2: configur E consent
|
||||
const redirectTo = await provider.interactionResult(
|
||||
ctx.req,
|
||||
ctx.res,
|
||||
|
|
Loading…
Reference in a new issue