import { database } from '@/db'; import { account } from '@/db/schema'; import { createServerFn } from '@tanstack/react-start'; import { createInsertSchema } from 'drizzle-zod'; import { z } from 'zod/v4'; import { useAppSession } from '../utils/session'; import { eq } from 'drizzle-orm'; import { password } from 'bun'; import { handleServerFnValidation, unauthorizedError, validationError, } from '../utils/http'; import { m } from '@/paraglide/messages'; export const ChangePasswordSchema = createInsertSchema(account) .pick({ password: true, }) .extend({ newPassword: z.string(), newPasswordConfirm: z.string(), }) .refine((value) => value.newPassword === value.password, { message: "Passwords don't match", path: ['newPassword'], }); export const changePassword = createServerFn({ method: 'POST', response: 'data', }) .validator((payload: z.infer) => handleServerFnValidation(ChangePasswordSchema, payload), ) .handler(async ({ data }) => { const appSession = await useAppSession(); if (!appSession.data.sessionToken) { throw unauthorizedError(); } const session = await database.query.session.findFirst({ where: { id: { eq: appSession.data.sessionToken, }, }, with: { user: true, }, }); if (!session || !session.user) { throw unauthorizedError(); } if (!(await password.verify(data.password, session.user.password))) { throw validationError({ password: [m['validation.invalid-credentials']()], }); } await database .update(account) .set({ password: await password.hash(data.newPassword, 'argon2id'), }) .where(eq(account.id, session.user.id)); return { message: m['change-password.mutation.success'](), }; }); export const ChangeEmailSchema = createInsertSchema(account).pick({ email: true, password: true, }); export const changeEmail = createServerFn({ method: 'POST', response: 'data', }) .validator((payload: z.infer) => handleServerFnValidation(ChangeEmailSchema, payload), ) .handler(async ({ data }) => { const appSession = await useAppSession(); if (!appSession.data.sessionToken) { throw unauthorizedError(); } const session = await database.query.session.findFirst({ where: { id: { eq: appSession.data.sessionToken, }, }, with: { user: true, }, }); if (!session || !session.user) { throw unauthorizedError(); } if (!(await password.verify(data.password, session.user.password))) { throw validationError({ password: [m['validation.invalid-credentials']()], }); } await database .update(account) .set({ email: data.email, }) .where(eq(account.id, session.user.id)); return { message: m['change-email.mutation.success'](), }; });