50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import { fail, redirect } from '@sveltejs/kit';
|
|
import type { Actions, PageServerLoad } from './$types';
|
|
import {
|
|
authenticate,
|
|
createSession,
|
|
hasUsers,
|
|
reserveLoginAttempt,
|
|
validEmail
|
|
} from '#lib/server/auth.js';
|
|
|
|
function safeReturnTo(value: string | null): string {
|
|
if (!value || value.length > 4000) return '/fundus';
|
|
try {
|
|
const target = new URL(value, 'http://sendewerk.local');
|
|
if (target.origin === 'http://sendewerk.local' && target.pathname === '/oauth/authorize') {
|
|
return `${target.pathname}${target.search}`;
|
|
}
|
|
} catch {
|
|
// Fall back to the normal authenticated landing page.
|
|
}
|
|
return '/fundus';
|
|
}
|
|
|
|
export const load: PageServerLoad = ({ locals, url }) => {
|
|
if (!hasUsers()) redirect(303, '/setup');
|
|
if (locals.user) redirect(303, safeReturnTo(url.searchParams.get('returnTo')));
|
|
};
|
|
|
|
export const actions = {
|
|
default: async ({ request, cookies, getClientAddress, url }) => {
|
|
const data = await request.formData();
|
|
const email = String(data.get('email') || '').trim();
|
|
const password = String(data.get('password') || '');
|
|
const address = getClientAddress();
|
|
if (!validEmail(email) || !password || Buffer.byteLength(password, 'utf8') > 256) {
|
|
return fail(400, { email, error: 'E-Mail oder Passwort ist nicht korrekt.' });
|
|
}
|
|
if (!reserveLoginAttempt(email, address)) {
|
|
return fail(429, {
|
|
email,
|
|
error: 'Zu viele Anmeldeversuche. Bitte in 15 Minuten erneut versuchen.'
|
|
});
|
|
}
|
|
const user = await authenticate(email, password);
|
|
if (!user) return fail(400, { email, error: 'E-Mail oder Passwort ist nicht korrekt.' });
|
|
createSession(user.id, cookies);
|
|
redirect(303, safeReturnTo(url.searchParams.get('returnTo')));
|
|
}
|
|
} satisfies Actions;
|