import { fail, redirect } from '@sveltejs/kit'; import type { Actions } from './$types'; import type { PageServerLoad } from './$types'; import { auth } from '$lib/server/auth'; import { db } from '$lib/server/db'; import { user } from '$lib/server/db/schema'; import { APIError } from 'better-auth/api'; import { sql } from 'drizzle-orm'; export const load: PageServerLoad = async (event) => { if (event.locals.user) { return redirect(302, '/'); } return {}; }; export const actions: Actions = { signInEmail: async (event) => { const formData = await event.request.formData(); const identifier = formData.get('identifier')?.toString().trim() ?? formData.get('email')?.toString().trim() ?? ''; const password = formData.get('password')?.toString() ?? ''; if (!identifier) { return fail(400, { message: 'Email ou nom d\'utilisateur requis' }); } let email = identifier; if (!identifier.includes('@')) { const [foundUser] = await db .select({ email: user.email }) .from(user) .where(sql`lower(${user.username}) = ${identifier.toLowerCase()}`) .limit(1); if (!foundUser) { return fail(400, { message: 'Identifiants invalides' }); } email = foundUser.email; } try { await auth.api.signInEmail({ body: { email, password, callbackURL: '/auth/verification-success' } }); } catch (error) { if (error instanceof APIError) { return fail(400, { message: error.message || 'Signin failed' }); } return fail(500, { message: 'Unexpected error' }); } return redirect(302, '/'); }, signUpEmail: async (event) => { const formData = await event.request.formData(); const email = formData.get('email')?.toString() ?? ''; const password = formData.get('password')?.toString() ?? ''; const confirmPassword = formData.get('confirmPassword')?.toString() ?? ''; const name = formData.get('name')?.toString() ?? ''; const username = formData.get('username')?.toString().trim() ?? ''; if (!username) { return fail(400, { message: 'Nom d\'utilisateur requis' }); } if (!/^[a-zA-Z0-9._-]{3,30}$/.test(username)) { return fail(400, { message: "Le nom d'utilisateur doit contenir 3 à 30 caractères (lettres, chiffres, ., _, -)" }); } const [existingUsername] = await db .select({ id: user.id }) .from(user) .where(sql`lower(${user.username}) = ${username.toLowerCase()}`) .limit(1); if (existingUsername) { return fail(400, { message: "Ce nom d'utilisateur est déjà pris" }); } if (password !== confirmPassword) { return fail(400, { message: 'Les mots de passe ne correspondent pas' }); } try { await auth.api.signUpEmail({ body: { email, password, name, username, callbackURL: '/auth/verification-success' } }); } catch (error) { if (error instanceof APIError) { return fail(400, { message: error.message || 'Registration failed' }); } return fail(500, { message: 'Unexpected error' }); } return redirect(302, '/'); }, logout: async (event) => { await auth.api.signOut({ headers: event.request.headers }); return redirect(302, '/'); } };