mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 22:02:16 +00:00
feat(auth): warn on breached passwords at password set
Check a newly chosen password against HaveIBeenPwned through the k-anonymity range API: only the first five hex characters of the SHA-1 digest leave the host, the suffix is matched locally, and Add-Padding hides the bucket size. A confirmed match is rejected so a fresh credential is never a known-breached one; the check fails open, so an unreachable HIBP never blocks the operation. Covers registration, password change, and admin reset. Existing passwords are never retroactively blocked at login. Also lands the six-locale strings for the password-breach notice and the account-security surfaces that follow.
This commit is contained in:
1 parent
01689f77bc
commit
b882698a44
10 files changed
+427
-18
No files matched your search
@@ -13,6 +13,8 @@ import { checkRateLimit, rateLimitHeaders } from "@/lib/rate-limit";
|
||||
import { destroyAllSessions } from "@/lib/auth/session";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { resolveServerLocale } from "@/lib/i18n/server-locale";
|
||||
import { checkPasswordBreach } from "@/lib/auth/hibp";
|
||||
import { getServerTranslator } from "@/lib/i18n/server-translator";
|
||||
|
||||
export const POST = apiHandler(
|
||||
async (
|
||||
@@ -65,6 +67,16 @@ export const POST = apiHandler(
|
||||
);
|
||||
}
|
||||
|
||||
// v1.23 — reject an admin-set password found in a known breach corpus
|
||||
// (HIBP k-anonymity). Fail-open on an unreachable HIBP.
|
||||
const breach = await checkPasswordBreach(password);
|
||||
if (breach?.breached) {
|
||||
return apiError(
|
||||
getServerTranslator(locale).t("auth.passwordBreached"),
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
const passwordHash = await hashPassword(password);
|
||||
await prisma.user.update({
|
||||
where: { id },
|
||||
|
||||
Reference in new issue
Block a user