diff --git a/src/app/core/auth/models/auth-error.model.ts b/src/app/core/auth/models/auth-error.model.ts index f2e6b03..74a7ce0 100644 --- a/src/app/core/auth/models/auth-error.model.ts +++ b/src/app/core/auth/models/auth-error.model.ts @@ -17,6 +17,24 @@ export interface AuthError { status?: number; } +/** + * Maps the backend error envelope's `error.code` (see + * BACKEND-API-REFERENCE.md ยง5) to the client's AuthErrorCode screens. + * Only codes with a dedicated screen are mapped; anything else falls back + * to the HTTP-status-derived code via authErrorCodeFromStatus. + */ +const BACKEND_ERROR_CODE_MAP: Record = { + TOKEN_EXPIRED: 'session-expired', + INVALID_SIGNATURE: 'invalid-signature', + UNAUTHENTICATED: 'unauthorized', + FORBIDDEN: 'forbidden', + SERVICE_UNAVAILABLE: 'backend-unavailable', +}; + +export function authErrorCodeFromBackendCode(code: unknown): AuthErrorCode | undefined { + return typeof code === 'string' ? BACKEND_ERROR_CODE_MAP[code] : undefined; +} + /** Maps a backend HTTP status to the AuthErrorCode screen it should route to. */ export function authErrorCodeFromStatus(status: number): AuthErrorCode { switch (status) { diff --git a/src/app/core/auth/services/auth.service.ts b/src/app/core/auth/services/auth.service.ts index 55fd221..ef5547f 100644 --- a/src/app/core/auth/services/auth.service.ts +++ b/src/app/core/auth/services/auth.service.ts @@ -3,7 +3,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { catchError, switchMap, tap, throwError } from 'rxjs'; import { Observable } from 'rxjs'; import { AuthTokenPair } from '../models/auth-api.model'; -import { AuthError, authErrorCodeFromStatus } from '../models/auth-error.model'; +import { AuthError, authErrorCodeFromBackendCode, authErrorCodeFromStatus } from '../models/auth-error.model'; import { AuthApiService } from './auth-api.service'; import { Ed25519KeypairService } from './ed25519-keypair.service'; import { SessionService } from './session.service'; @@ -109,7 +109,9 @@ export class AuthService { private toAuthErrorShape(error: unknown, fallbackCode: AuthError['code']): AuthError { if (error instanceof HttpErrorResponse) { - return { code: authErrorCodeFromStatus(error.status), message: error.message, status: error.status }; + const bodyCode = (error.error as { error?: { code?: unknown } } | null)?.error?.code; + const code = authErrorCodeFromBackendCode(bodyCode) ?? authErrorCodeFromStatus(error.status); + return { code, message: error.message, status: error.status }; } if (error instanceof Error) { return { code: fallbackCode, message: error.message };