Files
sendewerk/src/routes/einladung/+page.server.ts
T
2026-10-21 17:25:28 +02:00

58 lines
1.7 KiB
TypeScript

import { fail, redirect } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types';
import {
acceptInvitation,
createSession,
deleteLinkToken,
getInvitation,
INVITATION_COOKIE,
readLinkToken,
storeLinkToken,
validDisplayName,
validPassword
} from '#lib/server/auth.js';
export const load: PageServerLoad = ({ url, cookies }) => {
const queryToken = url.searchParams.get('token');
if (queryToken) {
if (queryToken.length <= 100) storeLinkToken(cookies, INVITATION_COOKIE, queryToken);
else deleteLinkToken(cookies, INVITATION_COOKIE);
redirect(303, '/einladung');
}
const token = readLinkToken(cookies, INVITATION_COOKIE);
const invitation = getInvitation(token);
const valid = Boolean(
invitation &&
!invitation.accepted_at_utc &&
!invitation.revoked_at_utc &&
invitation.expires_at_utc > new Date().toISOString()
);
return { valid, email: valid ? invitation?.email : null };
};
export const actions = {
default: async ({ request, cookies }) => {
const data = await request.formData();
const token = readLinkToken(cookies, INVITATION_COOKIE);
const displayName = String(data.get('displayName') || '').trim();
const password = String(data.get('password') || '');
if (!validDisplayName(displayName) || !validPassword(password)) {
return fail(400, {
displayName,
error: 'Bitte Namen und ein Passwort mit mindestens 12 Zeichen prüfen.'
});
}
try {
const user = await acceptInvitation({ token, displayName, password });
deleteLinkToken(cookies, INVITATION_COOKIE);
createSession(user.id, cookies);
} catch {
return fail(400, {
displayName,
error: 'Die Einladung ist ungültig, abgelaufen oder bereits verwendet.'
});
}
redirect(303, '/fundus');
}
} satisfies Actions;