82 lines
3.6 KiB
TypeScript
82 lines
3.6 KiB
TypeScript
export type RegistrationErrorReason =
|
|
| "invite_not_found"
|
|
| "invite_expired"
|
|
| "invite_disabled"
|
|
| "invite_exhausted"
|
|
| "stage_limit_reached"
|
|
| "email_already_registered"
|
|
| "challenge_invalid"
|
|
| "challenge_expired"
|
|
| "privacy_consent_required"
|
|
| "privacy_notice_version_invalid"
|
|
| "profile_invalid"
|
|
| "idempotency_conflict"
|
|
| "registration_login_required"
|
|
| "login_registration_required"
|
|
| "account_suspended"
|
|
| "login_admin_required"
|
|
| "admin_not_allowed"
|
|
| "resend_too_soon"
|
|
| "too_many_attempts"
|
|
| "csrf_invalid"
|
|
| "deletion_confirmation_invalid"
|
|
| "session_invalid";
|
|
|
|
export type RegistrationErrorCode =
|
|
| "REGISTRATION_REJECTED"
|
|
| "REGISTRATION_REQUEST_INVALID"
|
|
| "IDEMPOTENCY_KEY_CONFLICT"
|
|
| "AUTH_ENTRY_REJECTED"
|
|
| "AUTH_RATE_LIMITED"
|
|
| "AUTH_CSRF_INVALID"
|
|
| "AUTH_SESSION_INVALID";
|
|
|
|
export class RegistrationError extends Error {
|
|
readonly code: RegistrationErrorCode;
|
|
readonly httpStatus: 400 | 401 | 403 | 409 | 429;
|
|
readonly reason: RegistrationErrorReason;
|
|
|
|
constructor(code: RegistrationErrorCode, reason: RegistrationErrorReason) {
|
|
super(code);
|
|
this.code = code;
|
|
this.httpStatus = code === "REGISTRATION_REQUEST_INVALID"
|
|
? 400
|
|
: code === "AUTH_SESSION_INVALID"
|
|
? 401
|
|
: code === "AUTH_CSRF_INVALID"
|
|
? 403
|
|
: code === "AUTH_RATE_LIMITED"
|
|
? 429
|
|
: 409;
|
|
this.reason = reason;
|
|
}
|
|
}
|
|
|
|
export function registrationFieldError(reason: RegistrationErrorReason) {
|
|
const entries: Record<RegistrationErrorReason, { field: string; message_key: string }> = {
|
|
challenge_expired: { field: "verification_code", message_key: "auth.challenge.expired" },
|
|
challenge_invalid: { field: "verification_code", message_key: "auth.challenge.invalid" },
|
|
email_already_registered: { field: "email", message_key: "auth.email.already_registered" },
|
|
idempotency_conflict: { field: "idempotency_key", message_key: "request.idempotency_conflict" },
|
|
invite_disabled: { field: "invite_code", message_key: "auth.invite.disabled" },
|
|
invite_exhausted: { field: "invite_code", message_key: "auth.invite.exhausted" },
|
|
invite_expired: { field: "invite_code", message_key: "auth.invite.expired" },
|
|
invite_not_found: { field: "invite_code", message_key: "auth.invite.not_found" },
|
|
privacy_consent_required: { field: "privacy_consent_accepted", message_key: "auth.privacy.consent_required" },
|
|
privacy_notice_version_invalid: { field: "privacy_notice_version", message_key: "auth.privacy.notice_version_invalid" },
|
|
profile_invalid: { field: "profile", message_key: "auth.profile.invalid" },
|
|
stage_limit_reached: { field: "invite_code", message_key: "auth.registration.stage_limit_reached" },
|
|
registration_login_required: { field: "email", message_key: "auth.registration.login_required" },
|
|
login_registration_required: { field: "email", message_key: "auth.login.registration_required" },
|
|
account_suspended: { field: "email", message_key: "auth.account.suspended" },
|
|
login_admin_required: { field: "email", message_key: "auth.login.admin_required" },
|
|
admin_not_allowed: { field: "email", message_key: "admin.auth.not_allowed" },
|
|
resend_too_soon: { field: "verification_code", message_key: "auth.challenge.resend_too_soon" },
|
|
too_many_attempts: { field: "verification_code", message_key: "auth.challenge.too_many_attempts" },
|
|
csrf_invalid: { field: "csrf_token", message_key: "auth.csrf.invalid" },
|
|
deletion_confirmation_invalid: { field: "confirmation", message_key: "account.deletion.confirmation_invalid" },
|
|
session_invalid: { field: "session", message_key: "auth.session.invalid" },
|
|
};
|
|
return entries[reason];
|
|
}
|