Files
familienarchiv/frontend/src/routes/login/+page.server.ts
Marcel daea748a20
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m37s
CI / OCR Service Tests (push) Successful in 32s
CI / OCR Service Tests (pull_request) Successful in 30s
CI / Backend Unit Tests (push) Failing after 2m47s
CI / Unit & Component Tests (pull_request) Failing after 2m29s
CI / Backend Unit Tests (pull_request) Failing after 2m46s
feat(frontend): invite-based registration UI
- Add /register route with invite code prefill, password show/hide
- Add /login?registered=1 success banner
- Add /admin/invites page: list, create, revoke, copy link
- Add Einladungen nav section to admin sidebar (ADMIN_USER perm)
- Add invite error codes to errors.ts
- Add 48 i18n keys across de/en/es
- Update hooks.server.ts to allow public access to invite/register API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 01:01:19 +02:00

55 lines
1.7 KiB
TypeScript

import { fail, redirect, type Actions } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import { getErrorMessage } from '$lib/errors';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = ({ url }) => {
return { registered: url.searchParams.get('registered') === '1' };
};
export const actions = {
login: async ({ request, cookies, fetch }) => {
const data = await request.formData();
const email = data.get('email') as string;
const password = data.get('password') as string;
if (!email || !password) {
return fail(400, { error: getErrorMessage('MISSING_CREDENTIALS') });
}
const credentials = btoa(`${email}:${password}`);
const authHeader = `Basic ${credentials}`;
// Raw fetch is intentional here: we need to pass an explicit Authorization
// header built from the form data, not the cookie-based auth used elsewhere.
try {
const baseUrl = env.API_INTERNAL_URL || 'http://localhost:8080';
const response = await fetch(`${baseUrl}/api/users/me`, {
method: 'GET',
headers: { Authorization: authHeader }
});
if (response.status === 401 || response.status === 403) {
return fail(401, { error: getErrorMessage('UNAUTHORIZED') });
}
if (!response.ok) {
return fail(500, { error: getErrorMessage('INTERNAL_ERROR') });
}
cookies.set('auth_token', authHeader, {
path: '/',
httpOnly: true,
sameSite: 'strict',
secure: false, // set to true when HTTPS is available
maxAge: 60 * 60 * 24
});
} catch (e) {
console.error(e);
return fail(500, { error: getErrorMessage('INTERNAL_ERROR') });
}
return redirect(303, '/');
}
} satisfies Actions;