diff --git a/src/lib/api/auth.remote.ts b/src/lib/api/auth.remote.ts new file mode 100644 index 0000000..0e3200a --- /dev/null +++ b/src/lib/api/auth.remote.ts @@ -0,0 +1,50 @@ +import { invalid, redirect } from '@sveltejs/kit'; +import { form, getRequestEvent, query } from '$app/server'; +import { auth } from '$lib/server/auth'; +import { signupSchema, loginSchema } from '$lib/server/schemas/auth'; + +export const signup = form(signupSchema, async (user, issue) => { + try { + await auth.api.signUpEmail({ body: user }); + } catch (error: any) { + console.error(error) + // Use invalid to mark fields as invalid + if (error?.body?.code === 'USER_ALREADY_EXISTS') { + invalid(issue.email('An account with this email already exists')); + } + // Generic error for the whole form + invalid(error?.body?.message || error?.message || 'Signup failed'); + } + + redirect(307, `/`); +}); + +export const login = form(loginSchema, async (user, issue) => { + try { + const { request } = getRequestEvent(); + await auth.api.signInEmail({ body: user, headers: request.headers }); + } catch (error: any) { + // Handle invalid credentials + if (error?.body?.code === 'INVALID_EMAIL_OR_PASSWORD') { + invalid('Invalid email or password'); + } + // Generic error + invalid('Login failed'); + } + + redirect(303, '/'); +}); + +export const logout = form(async () => { + const { request } = getRequestEvent(); + await auth.api.signOut({ headers: request.headers }); + redirect(303, '/login'); +}); + +export const getUser = query(async () => { + const { locals } = getRequestEvent(); + if (!locals.user) { + redirect(307, '/login'); + } + return locals.user; +}); diff --git a/src/lib/server/schemas/auth.ts b/src/lib/server/schemas/auth.ts new file mode 100644 index 0000000..b495412 --- /dev/null +++ b/src/lib/server/schemas/auth.ts @@ -0,0 +1,12 @@ +import * as v from 'valibot'; + +export const signupSchema = v.object({ + name: v.pipe(v.string(), v.minLength(4)), + email: v.pipe(v.string(), v.email()), + password: v.pipe(v.string(), v.minLength(8)) +}); + +export const loginSchema = v.object({ + email: v.pipe(v.string(), v.email()), + password: v.pipe(v.string(), v.minLength(1, 'Must provide a password')) +});