import { fail, redirect } from '@sveltejs/kit'; import { createSession, createUser, findUser } from '$lib/server/auth'; import { createCaptcha, verifyCaptcha } from '$lib/server/captcha'; import type { Actions, PageServerLoad } from './$types'; export const load: PageServerLoad = () => { return { captcha: createCaptcha() }; }; export const actions: Actions = { default: async ({ request, cookies }) => { const form = await request.formData(); const username = String(form.get('username') ?? '').trim(); const password = String(form.get('password') ?? ''); // honeypot: real browsers leave this hidden field empty if (String(form.get('website') ?? '') !== '') { return fail(400, { username, error: 'Signup rejected.' }); } if (!verifyCaptcha(String(form.get('token') ?? ''), String(form.get('captcha') ?? ''))) { return fail(400, { username, error: 'The characters did not match - try the new image.' }); } if (!/^[a-zA-Z0-9_.-]{3,30}$/.test(username)) { return fail(400, { username, error: 'Username must be 3-30 characters (letters, digits, _ . -).' }); } if (password.length < 8) { return fail(400, { username, error: 'Password must be at least 8 characters.' }); } if (findUser(username)) { return fail(400, { username, error: 'That username is taken.' }); } const user = createUser(username, password); cookies.set('session', createSession(user.id), { path: '/', httpOnly: true, sameSite: 'lax', maxAge: 30 * 86400 }); redirect(303, '/'); } };