diff --git a/src/lib/types/schema.ts b/src/lib/types/schema.ts index 34de724..434fe94 100644 --- a/src/lib/types/schema.ts +++ b/src/lib/types/schema.ts @@ -32,16 +32,21 @@ export const loginSchema = z.object({ password: z.string().nonempty('Password must not be empty.'), }); -export const changePasswordSchema = z.object({ - currentPassword: z.string().nonempty('Password must not be empty.'), - newPassword: z - .string() - .min(8, 'New password must be at least 8 characters.') - .regex(/(?=.*[A-Z])/gm, 'New password must contain at uppercase letter.') - .regex(/(?=.*[a-z])/gm, 'New password must contain at lowercase letter.') - .regex(/(?=.*\d)/gm, 'New password must contain at least one number.') - .regex(/(?=.*\W)/gm, 'New password must contain at least one special character'), -}); +export const changePasswordSchema = z + .object({ + currentPassword: z.string().nonempty('Password must not be empty.'), + newPassword: z + .string() + .min(8, 'New password must be at least 8 characters.') + .regex(/(?=.*[A-Z])/gm, 'New password must contain at uppercase letter.') + .regex(/(?=.*[a-z])/gm, 'New password must contain at lowercase letter.') + .regex(/(?=.*\d)/gm, 'New password must contain at least one number.') + .regex(/(?=.*\W)/gm, 'New password must contain at least one special character'), + }) + .refine((schema) => schema.currentPassword !== schema.newPassword, { + message: 'New password cannot be the same as old password.', + path: ['newPassword'], + }); export const changeUsernameSchema = z.object({ username: z diff --git a/src/routes/(main)/account/+page.server.ts b/src/routes/(main)/account/+page.server.ts index cdcb215..575c534 100644 --- a/src/routes/(main)/account/+page.server.ts +++ b/src/routes/(main)/account/+page.server.ts @@ -1,9 +1,10 @@ import { redirect } from '@sveltejs/kit'; import type { Actions } from '@sveltejs/kit'; -import { fail, message, superValidate } from 'sveltekit-superforms'; +import { fail, message, setError, superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { auth } from '$lib/server/db/auth'; import { changeUsernameSchema, changePasswordSchema } from '$lib/types/schema.js'; +import type { APIError } from 'better-auth/api'; export async function load({ request }) { const session = await auth.api.getSession({ @@ -24,8 +25,26 @@ export const actions = { updatePassword: async ({ request }) => { const newpassForm = await superValidate(request, zod(changePasswordSchema)); - if (!newpassForm.valid) { - return fail(400, { newpassForm }); + try { + if (!newpassForm.valid) { + return fail(400, { newpassForm }); + } + + await auth.api.changePassword({ + headers: request.headers, + body: { + newPassword: newpassForm.data.newPassword, + currentPassword: newpassForm.data.currentPassword, + revokeOtherSessions: false, + }, + }); + } catch (e) { + const errorMessage = (e as APIError).body.message as string; + if ((e as APIError).body.code === 'INVALID_PASSWORD') { + return setError(newpassForm, 'currentPassword', errorMessage.charAt(0).toUpperCase() + errorMessage.slice(1)); + } else { + return setError(newpassForm, 'newPassword', errorMessage.charAt(0).toUpperCase() + errorMessage.slice(1)); + } } return message(newpassForm, 'Password updated.');