UNPKG

@accounter/server

Version:
107 lines (93 loc) 3.01 kB
import { GraphQLError } from 'graphql'; export const ALLOWED_ROLES = new Set([ 'business_owner', 'accountant', 'employee', 'scraper', 'gmail_listener', ]); type Auth0ErrorLike = Error & { status?: number; statusCode?: number; code?: number | string; retryAfter?: number; retry_after?: number; headers?: Record<string, string | number | undefined>; originalError?: { status?: number; statusCode?: number; code?: number | string; retryAfter?: number; retry_after?: number; headers?: Record<string, string | number | undefined>; }; }; function extractStatus(error: Auth0ErrorLike): number | undefined { return ( error.statusCode ?? error.status ?? (typeof error.code === 'number' ? error.code : undefined) ?? error.originalError?.statusCode ?? error.originalError?.status ?? (typeof error.originalError?.code === 'number' ? error.originalError.code : undefined) ); } function extractRetryAfter(error: Auth0ErrorLike): number | undefined { const retryFromHeaders = error.headers?.['retry-after'] ?? error.headers?.['Retry-After'] ?? error.originalError?.headers?.['retry-after'] ?? error.originalError?.headers?.['Retry-After']; const numericHeader = typeof retryFromHeaders === 'number' ? retryFromHeaders : retryFromHeaders ? Number.parseInt(String(retryFromHeaders), 10) : undefined; return error.retryAfter ?? error.retry_after ?? error.originalError?.retryAfter ?? numericHeader; } export function mapAuth0Error(error: unknown): GraphQLError { const auth0Error = error as Auth0ErrorLike; const status = extractStatus(auth0Error); const message = (auth0Error?.message ?? 'Auth0 error').toLowerCase(); if (status === 429 || /rate limit|too many requests|429/.test(message)) { return new GraphQLError('Auth0 rate limit exceeded. Please retry shortly.', { extensions: { code: 'RATE_LIMITED', retryAfter: extractRetryAfter(auth0Error), }, }); } if (status === 409 || /already exists|user exists|already in use/.test(message)) { return new GraphQLError('User already exists in Auth0', { extensions: { code: 'USER_ALREADY_EXISTS', }, }); } console.error('Unexpected Auth0 error:', { message: auth0Error?.message, status, stack: auth0Error?.stack, }); return new GraphQLError('Failed to create user in identity provider.', { extensions: { code: 'AUTH0_ERROR', }, }); } export function invalidTokenError(): GraphQLError { return new GraphQLError('Invalid invitation token', { extensions: { code: 'TOKEN_INVALID' }, }); } export function expiredTokenError(): GraphQLError { return new GraphQLError('Invitation token expired', { extensions: { code: 'TOKEN_EXPIRED' }, }); } export function alreadyAcceptedError(): GraphQLError { return new GraphQLError('Invitation already accepted', { extensions: { code: 'TOKEN_ALREADY_USED' }, }); }