mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
test(e2e): take the TOTP parameters and the field hooks from the source
The spec re-declared the server's algorithm, digit count and period as literals, so a change to any of them would leave the spec generating codes the server no longer verifies and blaming the product. It imports the three exported constants instead; the recovery-batch size stays a literal, because its module pulls in the database client and would drag the generated client into the Playwright process. The two credential fields on the login form are addressed by test id now, like the submit button beside them, and the recovery toggle at the challenge is renamed to the house's noun-verb order.
This commit is contained in:
1 parent
78789e090e
commit
01fe007f35
3 files changed
+15
-8
No files matched your search
@@ -6,6 +6,12 @@ import type {
|
||||
} from "@playwright/test";
|
||||
import * as OTPAuth from "otpauth";
|
||||
|
||||
import {
|
||||
TOTP_ALGORITHM,
|
||||
TOTP_DIGITS,
|
||||
TOTP_PERIOD_SECONDS,
|
||||
} from "@/lib/auth/mfa/totp";
|
||||
|
||||
import { expect, test } from "./setup/test";
|
||||
import {
|
||||
clearAuthRateLimits,
|
||||
@@ -77,7 +83,6 @@ import {
|
||||
* current step has too little left — instead of hoping the wall clock is kind.
|
||||
*/
|
||||
|
||||
const TOTP_PERIOD_SECONDS = 30;
|
||||
const RECOVERY_CODE_COUNT = 10;
|
||||
const REGENERATE_ENDPOINT = "/api/auth/me/mfa/recovery-codes/regenerate";
|
||||
/** `/api/auth/login`, per IP per 15 minutes (`src/lib/rate-limit.ts`). */
|
||||
@@ -96,8 +101,8 @@ function totpCodeAt(secretBase32: string, atMs: number): string {
|
||||
return new OTPAuth.TOTP({
|
||||
issuer: "HealthLog",
|
||||
label: "HealthLog",
|
||||
algorithm: "SHA1",
|
||||
digits: 6,
|
||||
algorithm: TOTP_ALGORITHM,
|
||||
digits: TOTP_DIGITS,
|
||||
period: TOTP_PERIOD_SECONDS,
|
||||
secret: OTPAuth.Secret.fromBase32(secretBase32),
|
||||
}).generate({ timestamp: atMs });
|
||||
@@ -141,8 +146,8 @@ async function submitPassword(
|
||||
await clearAuthRateLimits();
|
||||
await page.goto("/auth/login");
|
||||
await page.getByTestId("login-use-password").click();
|
||||
await page.locator("#email").fill(account.username);
|
||||
await page.locator("#password").fill(account.password);
|
||||
await page.getByTestId("login-email").fill(account.username);
|
||||
await page.getByTestId("login-password").fill(account.password);
|
||||
const answer = page.waitForResponse(
|
||||
(res) =>
|
||||
res.url().includes("/api/auth/login") &&
|
||||
@@ -394,7 +399,7 @@ test.describe("second factor", () => {
|
||||
});
|
||||
|
||||
await test.step("spends a recovery code once", async () => {
|
||||
await page.getByTestId("mfa-toggle-recovery").click();
|
||||
await page.getByTestId("mfa-recovery-toggle").click();
|
||||
const answer = await submitFactor(page, liveRecoveryCodes[0]);
|
||||
expect(answer.status()).toBe(200);
|
||||
await page.waitForURL("/");
|
||||
@@ -406,7 +411,7 @@ test.describe("second factor", () => {
|
||||
await submitPassword(page, account);
|
||||
await expect(page.getByTestId("mfa-login-step")).toBeVisible();
|
||||
|
||||
await page.getByTestId("mfa-toggle-recovery").click();
|
||||
await page.getByTestId("mfa-recovery-toggle").click();
|
||||
const answer = await submitFactor(page, liveRecoveryCodes[0]);
|
||||
expect(answer.status()).toBe(401);
|
||||
await expect(page.getByTestId("mfa-error")).toBeVisible();
|
||||
|
||||
@@ -438,6 +438,7 @@ export default function LoginPage() {
|
||||
<Label htmlFor="email">{t("auth.emailOrUsername")}</Label>
|
||||
<Input
|
||||
id="email"
|
||||
data-testid="login-email"
|
||||
type="text"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
@@ -459,6 +460,7 @@ export default function LoginPage() {
|
||||
<Label htmlFor="password">{t("auth.password")}</Label>
|
||||
<Input
|
||||
id="password"
|
||||
data-testid="login-password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
|
||||
@@ -198,7 +198,7 @@ export function MfaLoginStep({
|
||||
{hasTotp && (
|
||||
<button
|
||||
type="button"
|
||||
data-testid="mfa-toggle-recovery"
|
||||
data-testid="mfa-recovery-toggle"
|
||||
onClick={() => {
|
||||
setUseRecovery((v) => !v);
|
||||
setCode("");
|
||||
|
||||
Reference in new issue
Block a user