feat: release design system engine, studio and component contracts
This commit is contained in:
1 parent
ff1065fb27
commit
3943b946d6
693 files changed
+175546
-3894
No files matched your search
@@ -1,6 +1,60 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { Window, type HTMLInputElement, type HTMLElement } from "happy-dom";
|
||||
import { Window, type HTMLInputElement, type HTMLButtonElement, type HTMLElement } from "happy-dom";
|
||||
|
||||
test("MFA resend waits for cooldown, clears old code and replaces the active challenge", async () => {
|
||||
const window = new Window({ url: "https://sso.example.test/mfa" });
|
||||
try {
|
||||
let now = Date.now();
|
||||
window.Date.now = () => now;
|
||||
window.sessionStorage.setItem(
|
||||
"wrnexus.auth.mfa",
|
||||
JSON.stringify({
|
||||
mfaToken: "synthetic-test-challenge",
|
||||
mfaExpiresAt: now + 300_000,
|
||||
requires: { mfa: ["email-otp"] },
|
||||
}),
|
||||
);
|
||||
window.document.body.innerHTML = `<section data-auth-mfa-challenge><form data-auth-mfa-form>
|
||||
<input name="mfaToken"><input name="challengeId"><input name="code"><input type="radio" name="method" value="email-otp">
|
||||
<div data-auth-mfa-pin><input name="otpCode"></div><p data-auth-mfa-status></p><p data-error="_form">Verification failed</p>
|
||||
<div data-auth-mfa-resend-group hidden><button type="button" data-auth-mfa-resend>Resend code</button></div><button type="submit">Verify</button>
|
||||
</form></section>`;
|
||||
const requests: any[] = [];
|
||||
window.fetch = (async (_: unknown, init: RequestInit) => {
|
||||
requests.push(JSON.parse(String(init.body)));
|
||||
return Response.json({
|
||||
id: "challenge-" + requests.length,
|
||||
retryAfter: 60,
|
||||
expiresAt: now + 300_000,
|
||||
});
|
||||
}) as any;
|
||||
window.eval(readFileSync(new URL("../assets/client/auth.js", import.meta.url), "utf8"));
|
||||
(window as any).WRNexusAuth.mount(window.document);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
const button = window.document.querySelector<HTMLButtonElement>("[data-auth-mfa-resend]")!;
|
||||
expect(button.disabled).toBe(true);
|
||||
expect(button.textContent).toContain("60s");
|
||||
button.dispatchEvent(new window.Event("click"));
|
||||
expect(requests.length).toBe(1);
|
||||
const code = window.document.querySelector<HTMLInputElement>("[name=otpCode]")!;
|
||||
code.value = "123456";
|
||||
now += 60_001;
|
||||
button.dispatchEvent(new window.Event("click"));
|
||||
button.dispatchEvent(new window.Event("click"));
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(requests.length).toBe(2);
|
||||
expect(requests[1].resend).toBe(true);
|
||||
expect(window.document.querySelector<HTMLInputElement>("[name=challengeId]")!.value).toBe(
|
||||
"challenge-2",
|
||||
);
|
||||
expect(code.value).toBe("");
|
||||
expect(window.document.querySelector("[data-error=_form]")!.textContent).toBe("");
|
||||
expect(button.disabled).toBe(true);
|
||||
} finally {
|
||||
await window.happyDOM.close();
|
||||
}
|
||||
});
|
||||
|
||||
test("expired and legacy MFA requests are rejected on mount before entering a code", async () => {
|
||||
for (const deadline of [undefined, Date.now() - 1]) {
|
||||
|
||||
Reference in new issue
Block a user