fix(e2e): spend a fresh TOTP counter per medewerker login (refs #132)
Keycloak refuses a TOTP code it has already accepted (otpPolicyCodeReusable defaults to false), so the beheer specs — two serial logins as bram-beheerder, well inside one 30-second window — sent the same code twice and the second was rejected: the portal stayed on the OTP prompt and the Catalogus heading never appeared. The Playwright retry ran inside the same window too, so it failed identically. loginMedewerker now spends the first counter the medewerker has left, persisting it in tmpdir because Playwright restarts the worker process between retries, and waits out the window when that counter is still ahead. Verified against keycloak:26.1 with the real realm export: three back-to-back logins as bram-beheerder now all succeed, where reusing one code is refused with 401 invalid_grant. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -63,5 +63,11 @@ Or enrol a phone once: the secret in base32 is `IJEUOTKFIRCVORKSJNCVET2UKBJUKRKE
|
||||
(`otpauth://totp/medewerker?secret=IJEUOTKFIRCVORKSJNCVET2UKBJUKRKE`). The e2e computes its
|
||||
own code in `tests/e2e/medewerker-login.ts`.
|
||||
|
||||
**A code is single-use.** Keycloak's `otpPolicyCodeReusable` defaults to false, so it refuses a
|
||||
code it has already accepted — a second login as the same medewerker inside the same 30-second
|
||||
window fails with `invalid_grant` / *Invalid user credentials*, even though the code is current.
|
||||
Nothing to fix in the realm: wait for the next window, or spend the following counter, which is
|
||||
what `nextUnusedCounter` in `tests/e2e/medewerker-login.ts` does for back-to-back specs.
|
||||
|
||||
**Fixture only.** A shared, committed secret is a demo convenience, never a production
|
||||
posture — see the ADR's consequences.
|
||||
|
||||
Reference in New Issue
Block a user