Two beheer specs log in as bram-beheerder back to back, so both submit the code for the same 30-second counter. Keycloak's otpPolicyCodeReusable defaults to false, so it refuses the second one as invalid credentials and the beheer portal never loads — which is how verify-e2e went red on #158. Pins the counter choice as a pure function of "now" and the last counter this medewerker spent, so the guard is checkable without a browser. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
15 lines
955 B
TypeScript
15 lines
955 B
TypeScript
import { expect, test } from '@playwright/test';
|
|
import { OTP_PERIOD_MS, nextUnusedCounter } from './medewerker-login';
|
|
|
|
// Pure check of the TOTP counter guard in loginMedewerker — no browser, no stack. Keycloak refuses
|
|
// a code it has already accepted (its otpPolicyCodeReusable defaults to false), so two logins as
|
|
// the same medewerker inside one 30-second window must not spend the same counter twice (#132).
|
|
test('a login never spends a TOTP counter this medewerker already used', () => {
|
|
const now = 3 * OTP_PERIOD_MS + 1_000; // 1 second into counter 3
|
|
|
|
expect(nextUnusedCounter(now, -1)).toBe(3); // nothing spent yet → the current counter
|
|
expect(nextUnusedCounter(now, 3)).toBe(4); // the current counter is spent → the next one
|
|
expect(nextUnusedCounter(now, 4)).toBe(5); // two logins already in this window → the one after
|
|
expect(nextUnusedCounter(now + OTP_PERIOD_MS, 3)).toBe(4); // window moved on → current again
|
|
});
|