diff --git a/packages/core/src/errors/RequestError.ts b/packages/core/src/errors/RequestError.ts deleted file mode 100644 index c904ccd4e..000000000 --- a/packages/core/src/errors/RequestError.ts +++ /dev/null @@ -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 = { - [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'); - } -} diff --git a/packages/core/src/errors/RequestError/collection/guard-errors.ts b/packages/core/src/errors/RequestError/collection/guard-errors.ts new file mode 100644 index 000000000..e14bc7e6f --- /dev/null +++ b/packages/core/src/errors/RequestError/collection/guard-errors.ts @@ -0,0 +1,7 @@ +export enum GuardErrorCode { + InvalidInput = 'guard.invalid_input', +} + +export const guardErrorMessage: Record = { + [GuardErrorCode.InvalidInput]: 'The request input is invalid.', +}; diff --git a/packages/core/src/errors/RequestError/collection/oidc-errors.ts b/packages/core/src/errors/RequestError/collection/oidc-errors.ts new file mode 100644 index 000000000..b16857e60 --- /dev/null +++ b/packages/core/src/errors/RequestError/collection/oidc-errors.ts @@ -0,0 +1,7 @@ +export enum OidcErrorCode { + Aborted = 'oidc.aborted', +} + +export const oidcErrorMessage: Record = { + [OidcErrorCode.Aborted]: 'The end-user aborted interaction.', +}; diff --git a/packages/core/src/errors/RequestError/collection/register-errors.ts b/packages/core/src/errors/RequestError/collection/register-errors.ts new file mode 100644 index 000000000..b4ec640ba --- /dev/null +++ b/packages/core/src/errors/RequestError/collection/register-errors.ts @@ -0,0 +1,7 @@ +export enum RegisterErrorCode { + UsernameExists = 'register.username_exists', +} + +export const registerErrorMessage: Record = { + [RegisterErrorCode.UsernameExists]: 'The username already exists.', +}; diff --git a/packages/core/src/errors/RequestError/index.ts b/packages/core/src/errors/RequestError/index.ts new file mode 100644 index 000000000..ee43fa0b3 --- /dev/null +++ b/packages/core/src/errors/RequestError/index.ts @@ -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'); + } +} diff --git a/packages/core/src/errors/RequestError/message.ts b/packages/core/src/errors/RequestError/message.ts new file mode 100644 index 000000000..541119002 --- /dev/null +++ b/packages/core/src/errors/RequestError/message.ts @@ -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 = { + ...guardErrorMessage, + ...oidcErrorMessage, + ...registerErrorMessage, +}; diff --git a/packages/core/src/errors/RequestError/types.ts b/packages/core/src/errors/RequestError/types.ts new file mode 100644 index 000000000..0cd591740 --- /dev/null +++ b/packages/core/src/errors/RequestError/types.ts @@ -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 }; diff --git a/packages/core/src/middleware/koa-guard.ts b/packages/core/src/middleware/koa-guard.ts index d226253a7..540454291 100644 --- a/packages/core/src/middleware/koa-guard.ts +++ b/packages/core/src/middleware/koa-guard.ts @@ -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; // Have to do this since it's too complicated for TS + } as Guarded; // Have to do t His since it's too complicated for TS } catch (error: unknown) { throw new RequestError(GuardErrorCode.InvalidInput, error); } diff --git a/packages/core/src/routes/register.ts b/packages/core/src/routes/register.ts index e7497d629..0924321ab 100644 --- a/packages/core/src/routes/register.ts +++ b/packages/core/src/routes/register.ts @@ -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; } diff --git a/packages/core/src/routes/sign-in.ts b/packages/core/src/routes/sign-in.ts index a81acf206..47110801c 100644 --- a/packages/core/src/routes/sign-in.ts +++ b/packages/core/src/routes/sign-in.ts @@ -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,