monitor/core/routes/authentication/changePassword.ts
2025-04-16 22:30:27 +07:00

70 lines
2.4 KiB
TypeScript

const modulename = 'WebServer:AuthChangePassword';
import { AuthedCtx } from '@modules/WebServer/ctxTypes';
import consoleFactory from '@lib/console';
import consts from '@shared/consts';
import { GenericApiResp } from '@shared/genericApiTypes';
import { z } from 'zod';
const console = consoleFactory(modulename);
//Helper functions
const bodySchema = z.object({
oldPassword: z.string().optional(),
newPassword: z.string(),
});
export type ApiChangePasswordReqSchema = z.infer<typeof bodySchema>;
/**
* Route to change your own password
*/
export default async function AuthChangePassword(ctx: AuthedCtx) {
//Sanity check
const schemaRes = bodySchema.safeParse(ctx.request.body);
if (!schemaRes.success) {
return ctx.send<GenericApiResp>({
error: `Invalid request body: ${schemaRes.error.message}`,
});
}
const { newPassword, oldPassword } = schemaRes.data;
//Validate new password
if (newPassword.trim() !== newPassword) {
return ctx.send<GenericApiResp>({
error: 'Your password either starts or ends with a space, which was likely an accident. Please remove it and try again.',
});
}
if (newPassword.length < consts.adminPasswordMinLength || newPassword.length > consts.adminPasswordMaxLength) {
return ctx.send<GenericApiResp>({ error: 'Invalid new password length.' });
}
//Get vault admin
const vaultAdmin = txCore.adminStore.getAdminByName(ctx.admin.name);
if (!vaultAdmin) throw new Error('Wait, what? Where is that admin?');
if (!ctx.admin.isTempPassword) {
if (!oldPassword || !VerifyPasswordHash(oldPassword, vaultAdmin.password_hash)) {
return ctx.send<GenericApiResp>({ error: 'Wrong current password.' });
}
}
//Edit admin and give output
try {
const newHash = await txCore.adminStore.editAdmin(ctx.admin.name, newPassword);
//Update session hash if logged in via password
const currSess = ctx.sessTools.get();
if (currSess?.auth?.type === 'password') {
ctx.sessTools.set({
auth: {
...currSess.auth,
password_hash: newHash,
}
});
}
ctx.admin.logAction('Changing own password.');
return ctx.send<GenericApiResp>({ success: true });
} catch (error) {
return ctx.send<GenericApiResp>({ error: (error as Error).message });
}
};