test(mfa): fix step-up test to assert the fresh-session path

This commit is contained in:
2026-09-16 14:20:42 +00:00
parent 142b99e408
commit dcdfd3ce52
+11 -12
View File
@@ -135,6 +135,7 @@ test.describe("MFA end-to-end", () => {
await page.getByLabel("I have saved these codes").check();
await page.getByRole("button", { name: "Continue" }).click();
await expect(page.getByText("No passkeys registered.")).toHaveCount(0);
await expect(page.getByText(/Added .* · Last used/)).toBeVisible();
await page.request.post(`${BASE_URL}/auth/logout`);
await fillCredentials(page, email, password);
@@ -198,10 +199,11 @@ test.describe("MFA end-to-end", () => {
await request.post(`${BASE_URL}/auth/logout`);
});
test("step-up on secret reveal", async ({ page, request }) => {
test("fresh sign-in reveals a secret without a step-up prompt", async ({ page, request }) => {
const { email, password } = await createMember(request);
// Enrol TOTP so step-up has a factor to challenge.
// Enrol TOTP so the account has a factor - not exercised in this test,
// since sign-in itself sets StepUpAt and the window has not gone stale.
await fillCredentials(page, email, password);
await page.goto("/account/security");
await page.getByRole("button", { name: "Set up" }).click();
@@ -212,26 +214,23 @@ test.describe("MFA end-to-end", () => {
await page.getByLabel("I have saved these codes").check();
await page.getByRole("button", { name: "Continue" }).click();
// A brand-new session's StepUpAt is fresh from sign-in, so create a secret,
// then create a group via the UI and attempt a reveal - the modal should
// still appear because sign-in only counts as step-up for ten minutes and
// this test does not wait that long; it is testing the prompt fires the
// first time an authenticated caller with no fresh step-up reveals one.
// Sign-in counts as a step-up (mintSession sets StepUpAt), and that is
// valid for ten minutes - a browser test cannot wait that long or age a
// session, so this only asserts the fresh-session path: no prompt on the
// first reveal, and none on a second reveal right after. The stale path
// (StepUpAt older than ten minutes) is covered by TestStepUpFresh in
// server/internal/auth/stepup_test.go.
await request.post(`${BASE_URL}/api/secrets`, { data: { group: "e2e-stepup", values: { KEY: "value" } } });
await page.goto("/secrets/e2e-stepup");
await page.getByRole("button", { name: "Reveal" }).click();
await expect(page.getByText("Confirm it's you")).toBeVisible();
await page.getByLabel("6-digit code").fill(authenticator.generate(secret.trim()));
await page.getByRole("button", { name: "Confirm" }).click();
await expect(page.getByText("Confirm it's you")).toHaveCount(0);
await expect(page.locator("span.font-mono.text-xs.break-all")).toBeVisible();
// Reveal again within the ten-minute step-up window: no prompt this time.
await page.getByRole("button", { name: "Hide" }).click().catch(() => {});
await page.getByRole("button", { name: "Reveal" }).click();
await expect(page.getByText("Confirm it's you")).toHaveCount(0);
await expect(page.locator("span.font-mono.text-xs.break-all")).toBeVisible();
});
});