fix: login 2FA bloque sans erreur BUG-069 (challenge montait dans .login-box inexistant -> .login-card + erreur visible)
CI / lint (push) Successful in 1m56s
CI / security (push) Successful in 1m20s
CI / test (push) Successful in 4m17s
CI / build (push) Successful in 1m16s
CI / e2e (push) Successful in 12m35s

This commit is contained in:
2026-09-22 20:38:37 -04:00
parent 60da957f13
commit bca0fdd941
14 changed files with 78 additions and 15 deletions
+27
View File
@@ -31,6 +31,7 @@ const ROOT = path.join(__dirname, "..", "..");
const auth = readFileSync(path.join(ROOT, "frontend", "js", "auth.js"), "utf8");
const css = readFileSync(path.join(ROOT, "frontend", "style.css"), "utf8");
const router = readFileSync(path.join(ROOT, "backend", "auth", "router.py"), "utf8");
const indexHtml = readFileSync(path.join(ROOT, "frontend", "index.html"), "utf8");
const fr = JSON.parse(readFileSync(path.join(ROOT, "frontend", "locales", "fr.json"), "utf8"));
const en = JSON.parse(readFileSync(path.join(ROOT, "frontend", "locales", "en.json"), "utf8"));
@@ -96,12 +97,38 @@ test("i18n — password + QR strings exist in FR and EN", () => {
"mfa.password_change_btn",
"mfa.password_mismatch",
"mfa.password_changed",
"mfa.challenge_unavailable",
]) {
assert.ok(fr[key], `fr.json missing ${key}`);
assert.ok(en[key], `en.json missing ${key}`);
}
});
// ── BUG-069: the MFA challenge must mount into a real DOM node ──────────────
test("auth.js — challenge mounts into .login-card (exists in index.html)", () => {
assert.doesNotMatch(
auth,
/querySelector\("\.login-box"\)/,
"showMfaChallenge queried .login-box, which never existed in index.html → silent return, login stuck with no error",
);
assert.match(
auth,
/querySelector\("\.login-card"\)/,
"the challenge must mount into the real login container",
);
assert.ok(
indexHtml.includes('class="login-card"'),
"index.html must contain the .login-card mount point",
);
});
test("auth.js — showMfaChallenge never fails silently", () => {
const fn = auth.match(/function showMfaChallenge\(username, rememberMe, loginBtn, loginErrorEl, mfaMethod\) \{([\s\S]*?)\n \/\/ WebAuthn second factor/);
assert.ok(fn, "showMfaChallenge helper not found");
assert.match(fn[1], /challenge_unavailable/, "a missing mount point must surface an error, not silently return");
assert.doesNotMatch(fn[1], /if \(!loginBox\) return;/, "bare silent return is forbidden in the challenge flow");
});
if (process.exitCode) {
console.error("\nMFA settings tests FAILED");
} else {