feat: Password update functionality

This commit is contained in:
April Hall 2025-02-15 21:24:37 -05:00
parent b0fc2f7c18
commit 885ff0fcd3
Signed by: arithefirst
GPG Key ID: 4508A15C4DB91C5B
2 changed files with 37 additions and 13 deletions

View File

@ -32,16 +32,21 @@ export const loginSchema = z.object({
password: z.string().nonempty('Password must not be empty.'), password: z.string().nonempty('Password must not be empty.'),
}); });
export const changePasswordSchema = z.object({ export const changePasswordSchema = z
currentPassword: z.string().nonempty('Password must not be empty.'), .object({
newPassword: z currentPassword: z.string().nonempty('Password must not be empty.'),
.string() newPassword: z
.min(8, 'New password must be at least 8 characters.') .string()
.regex(/(?=.*[A-Z])/gm, 'New password must contain at uppercase letter.') .min(8, 'New password must be at least 8 characters.')
.regex(/(?=.*[a-z])/gm, 'New password must contain at lowercase letter.') .regex(/(?=.*[A-Z])/gm, 'New password must contain at uppercase letter.')
.regex(/(?=.*\d)/gm, 'New password must contain at least one number.') .regex(/(?=.*[a-z])/gm, 'New password must contain at lowercase letter.')
.regex(/(?=.*\W)/gm, 'New password must contain at least one special character'), .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({ export const changeUsernameSchema = z.object({
username: z username: z

View File

@ -1,9 +1,10 @@
import { redirect } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit';
import type { Actions } 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 { zod } from 'sveltekit-superforms/adapters';
import { auth } from '$lib/server/db/auth'; import { auth } from '$lib/server/db/auth';
import { changeUsernameSchema, changePasswordSchema } from '$lib/types/schema.js'; import { changeUsernameSchema, changePasswordSchema } from '$lib/types/schema.js';
import type { APIError } from 'better-auth/api';
export async function load({ request }) { export async function load({ request }) {
const session = await auth.api.getSession({ const session = await auth.api.getSession({
@ -24,8 +25,26 @@ export const actions = {
updatePassword: async ({ request }) => { updatePassword: async ({ request }) => {
const newpassForm = await superValidate(request, zod(changePasswordSchema)); const newpassForm = await superValidate(request, zod(changePasswordSchema));
if (!newpassForm.valid) { try {
return fail(400, { newpassForm }); 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.'); return message(newpassForm, 'Password updated.');