import type { Actions, PageServerLoad } from './$types'; import { fail, redirect } from '@sveltejs/kit'; import { db } from '$lib/server/db'; import { users } from '$lib/server/schema'; import { eq } from 'drizzle-orm'; import { hashPassword } from '$lib/server/auth-utils'; import { sendRegistrationNotification } from '$lib/server/email'; import { registrationLimiter } from '$lib/server/rate-limit'; export const load: PageServerLoad = async ({ locals }) => { if (locals.user) { throw redirect(303, locals.user.role === 'foster' ? '/foster' : '/admin'); } }; export const actions: Actions = { default: async ({ request, getClientAddress, locals }) => { const ip = request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? getClientAddress(); if (!registrationLimiter.check(ip)) { return fail(429, { error: 'Too many registration attempts. Please try again later.' }); } const data = await request.formData(); const name = data.get('name')?.toString().trim(); const email = data.get('email')?.toString().trim().toLowerCase(); const password = data.get('password')?.toString(); const confirmPassword = data.get('confirmPassword')?.toString(); const reason = data.get('reason')?.toString().trim(); if (!name || !email || !password || !confirmPassword || !reason) { return fail(400, { error: 'All fields are required', name, email, reason }); } const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { return fail(400, { error: 'Please enter a valid email address', name, email, reason }); } if (password.length < 8) { return fail(400, { error: 'Password must be at least 8 characters', name, email, reason }); } if (password !== confirmPassword) { return fail(400, { error: 'Passwords do not match', name, email, reason }); } const [existing] = await db.select({ id: users.id }).from(users).where(eq(users.email, email)).limit(1); if (existing) { return fail(400, { error: 'An account with this email already exists', name, email, reason }); } const passwordHash = await hashPassword(password); await db.insert(users).values({ name, email, passwordHash, role: 'viewer', active: false, mustChangePassword: false }); const orgConfig = locals.orgConfig; if (orgConfig.orgInfo.email) { try { await sendRegistrationNotification( orgConfig.orgInfo.name, orgConfig.orgInfo.email, name, email, reason ); } catch { // Email failure shouldn't block registration } } return { success: true }; } };