You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

50 lines
1.4 KiB

import { z } from "zod";
import { fail, ok, requireSession } from "@/lib/api";
import { writeAudit } from "@/services/audit";
import {
CustomerAccountError,
changeOwnPassword,
} from "@/services/auth/customers";
const BodySchema = z.object({
current_password: z.string().min(1).max(128),
new_password: z.string().min(6).max(128),
});
export async function PUT(req: Request) {
const guard = await requireSession();
if (guard.response) return guard.response;
if (guard.session.role !== "customer" || !guard.session.userId) {
return fail("FORBIDDEN", "仅客户账号可在此修改密码", 403);
}
let body: unknown;
try {
body = await req.json();
} catch {
return fail("VALIDATION", "Invalid JSON", 400);
}
const parsed = BodySchema.safeParse(body);
if (!parsed.success) {
return fail("VALIDATION", parsed.error.issues[0]?.message ?? "Invalid", 400);
}
try {
await changeOwnPassword({
userId: BigInt(guard.session.userId),
currentPassword: parsed.data.current_password,
newPassword: parsed.data.new_password,
});
await writeAudit({
actor: guard.session.username!,
action: "CUSTOMER_PASSWORD_CHANGE",
payload: { userId: guard.session.userId },
});
return ok({ ok: true });
} catch (err) {
if (err instanceof CustomerAccountError) {
return fail(err.code, err.message, err.status);
}
throw err;
}
}