Some checks failed
CI / Unit & Component Tests (push) Successful in 2m7s
CI / Backend Unit Tests (push) Successful in 2m3s
CI / E2E Tests (push) Failing after 14m54s
CI / Unit & Component Tests (pull_request) Successful in 2m4s
CI / E2E Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
- /forgot-password: email form → sends POST /api/auth/forgot-password → success banner - /reset-password: password form reads token from URL → sends POST /api/auth/reset-password - Login page: add "Passwort vergessen?" link - hooks.server.ts: add /forgot-password and /reset-password to PUBLIC_PATHS; skip auth injection for public auth API endpoints - errors.ts: add INVALID_RESET_TOKEN error code - i18n: add all new message keys in de/en/es - playwright.config.ts: use E2E_BASE_URL for webServer check URL (allows reusing docker dev server at port 5173 locally) - ci.yml: pass E2E_BACKEND_URL=http://localhost:8080 to E2E test step - e2e/password-reset.spec.ts: 5 tests (4 pass locally, full flow requires e2e profile in CI) - Regenerated OpenAPI types including new /api/auth/* endpoints Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import * as m from '$lib/paraglide/messages.js';
|
|
|
|
/**
|
|
* Mirror of the backend ErrorCode enum.
|
|
* Keep in sync with backend/src/main/java/org/raddatz/familienarchiv/exception/ErrorCode.java
|
|
*/
|
|
export type ErrorCode =
|
|
| 'DOCUMENT_NOT_FOUND'
|
|
| 'DOCUMENT_NO_FILE'
|
|
| 'FILE_NOT_FOUND'
|
|
| 'FILE_UPLOAD_FAILED'
|
|
| 'USER_NOT_FOUND'
|
|
| 'EMAIL_ALREADY_IN_USE'
|
|
| 'WRONG_CURRENT_PASSWORD'
|
|
| 'IMPORT_ALREADY_RUNNING'
|
|
| 'INVALID_RESET_TOKEN'
|
|
| 'UNAUTHORIZED'
|
|
| 'FORBIDDEN'
|
|
| 'VALIDATION_ERROR'
|
|
| 'INTERNAL_ERROR';
|
|
|
|
export interface BackendError {
|
|
code: ErrorCode;
|
|
message: string; // English developer message — not shown to users
|
|
}
|
|
|
|
/**
|
|
* Attempts to parse a backend ErrorResponse from a failed fetch response.
|
|
* Returns null if the body is not valid JSON or does not contain a code field.
|
|
*/
|
|
export async function parseBackendError(res: Response): Promise<BackendError | null> {
|
|
try {
|
|
const body = await res.json();
|
|
if (body && typeof body.code === 'string') {
|
|
return body as BackendError;
|
|
}
|
|
} catch {
|
|
// Body was not JSON
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** Returns a localised message for the given error code via Paraglide. Falls back to INTERNAL_ERROR. */
|
|
export function getErrorMessage(code: ErrorCode | string | undefined): string {
|
|
switch (code) {
|
|
case 'DOCUMENT_NOT_FOUND':
|
|
return m.error_document_not_found();
|
|
case 'DOCUMENT_NO_FILE':
|
|
return m.error_document_no_file();
|
|
case 'FILE_NOT_FOUND':
|
|
return m.error_file_not_found();
|
|
case 'FILE_UPLOAD_FAILED':
|
|
return m.error_file_upload_failed();
|
|
case 'USER_NOT_FOUND':
|
|
return m.error_user_not_found();
|
|
case 'EMAIL_ALREADY_IN_USE':
|
|
return m.error_email_already_in_use();
|
|
case 'WRONG_CURRENT_PASSWORD':
|
|
return m.error_wrong_current_password();
|
|
case 'IMPORT_ALREADY_RUNNING':
|
|
return m.error_import_already_running();
|
|
case 'INVALID_RESET_TOKEN':
|
|
return m.error_invalid_reset_token();
|
|
case 'UNAUTHORIZED':
|
|
return m.error_unauthorized();
|
|
case 'FORBIDDEN':
|
|
return m.error_forbidden();
|
|
case 'VALIDATION_ERROR':
|
|
return m.error_validation_error();
|
|
default:
|
|
return m.error_internal_error();
|
|
}
|
|
}
|