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
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;
|
|
}
|
|
}
|