fix(auth): expire stale MFA forms before accepting codes

This commit is contained in:
Clintchiz committed 2026-08-26 19:17:48 +05:30
1 parent 298e34ef2e
commit 0c77de93b4
8 files changed
+82 -11

No files matched your search

+29 -1
View File
@@ -2,12 +2,39 @@ import { expect, test } from "bun:test";
import { readFileSync } from "node:fs";
import { Window, type HTMLInputElement, type HTMLElement } from "happy-dom";
test("expired and legacy MFA requests are rejected on mount before entering a code", async () => {
for (const deadline of [undefined, Date.now() - 1]) {
const window = new Window({ url: "https://sso.example.test/mfa" });
try {
window.sessionStorage.setItem(
"wrnexus.auth.mfa",
JSON.stringify({ mfaToken: "old-challenge", mfaExpiresAt: deadline }),
);
window.document.body.innerHTML = `<section data-auth-mfa-challenge><form data-auth-mfa-form>
<input name="mfaToken"><input type="radio" name="method" value="totp"><input name="code"><p data-auth-mfa-status hidden></p><button type="submit">Verify</button>
</form><a data-auth-mfa-restart hidden href="/login">Back to sign in</a></section>`;
window.eval(readFileSync(new URL("../assets/client/auth.js", import.meta.url), "utf8"));
(window as any).WRNexusAuth.mount(window.document);
expect(window.document.querySelector("button")!.disabled).toBe(true);
expect(window.document.querySelector<HTMLElement>("[data-auth-mfa-restart]")!.hidden).toBe(
false,
);
expect(window.document.querySelector("[data-auth-mfa-status]")!.textContent).toContain(
"Sign in again",
);
expect(window.sessionStorage.getItem("wrnexus.auth.mfa")).toBeNull();
} finally {
await window.happyDOM.close();
}
}
});
test("selecting delivery radios sends once, ignores stale responses, and never sends for local methods", async () => {
const window = new Window({ url: "https://sso.example.test/mfa" });
try {
window.sessionStorage.setItem(
"wrnexus.auth.mfa",
JSON.stringify({ mfaToken: "synthetic-test-challenge" }),
JSON.stringify({ mfaToken: "synthetic-test-challenge", mfaExpiresAt: Date.now() + 300_000 }),
);
window.document.body.innerHTML = `<section data-auth-mfa-challenge data-mfa-initial-method="totp"><form data-auth-mfa-form>
<input name="mfaToken"><input name="challengeId"><input name="code">
@@ -63,6 +90,7 @@ test("MFA radios preserve allowed methods and restore continuation without reviv
"wrnexus.auth.mfa",
JSON.stringify({
mfaToken: "synthetic-test-challenge",
mfaExpiresAt: Date.now() + 300_000,
requires: { mfa: ["totp"] },
}),
);