diff --git a/tests/e2e/medewerker-login.spec.ts b/tests/e2e/medewerker-login.spec.ts new file mode 100644 index 0000000..b4e83bb --- /dev/null +++ b/tests/e2e/medewerker-login.spec.ts @@ -0,0 +1,14 @@ +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 +});