/** POST /api/admin/auth/step-up {password, code}: re-proves both factors; dangerous actions then work for 10 minutes. */
export const POST = adminRoute(null, async (request, ctx, _context, { session }) => {
const { password, code } = await readBody(request, stepUpSchema);
await limitLogin(request, ctx.admin.email);
const audit = { actorSub: ctx.admin.sub, role: ctx.admin.role, sessionId: ctx.sessionId, requestId: ctx.requestId, ip: ctx.ip, userAgent: ctx.userAgent };
let sub: string;
try {
sub = await reauthenticate(ctx.admin.email, password, code);
} catch (error) {
await authAudit({ action: "admin.step_up.denied", outcome: "denied", ...audit });
throw staffAuthFailure(error, "step-up");
}
if (sub !== ctx.admin.sub) {
await authAudit({ action: "admin.step_up.denied", outcome: "denied", ...audit });
throw new CloudError(401, "step_up_failed", "That password or code didn't match.");
}
const updated = await markStepUp(session);
await authAudit({ action: "admin.step_up", outcome: "ok", ...audit });
return adminJson({ stepUpUntil: updated ? stepUpUntil(updated) : null });
}, { rateLimit: "step-up" });