Repository navigation
Fix untracked cache files and CI flake in TOTP verification - #19
Merged
Merged
Conversation
.playwright-mcp/ (Playwright MCP's own session cache -- console logs and page-snapshot YAML, regenerated on every browser-automation run) had no .gitignore entry and was committed straight into the tracked tree in bed804c "Testing Plugin". Untrack all 11 files and add the entry so it can't happen again. Also add .DS_Store preventively. frontend/vite.config.js had its dev proxy target repointed from port 5000 to 5001 in 2852ec2 "Vite config" -- a single developer's local workaround for macOS AirPlay occupying port 5000 on their own machine, never meant to be shared. Reverted to the shared default; the override stays uncommitted locally, as this session has kept it throughout. Also removes navbar-fixed.png, a stray verification screenshot that was never project content. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CI failed on main at bed804c: Backend / tests + coverage floor, test_mfa_enroll_reset_rejects_the_wrong_password - KeyError: 'csrf_token'. The traceback shows the failure at the test's own /mfa/verify call -- the server rejected a TOTP code the test itself generated as correct. Root cause: verify_totp() called pyotp.TOTP(secret).verify(code) with the library's default valid_window=0 -- zero tolerance on either side of the current 30-second window. The test computes a code, then makes two sequential HTTP round trips (login, then verify); under CI's load that's enough latency for the code to roll into a new window before the server checks it, rejecting a genuinely correct code nondeterministically. Confirmed as a flake, not a regression: bd02376's CI run (identical backend source -- bed804c changed zero backend files) passed all 798 tests, this one included. Fixed at the source: valid_window=1 accepts the current window plus one either side (+-30s), RFC 6238's recommended tolerance for clock drift and network latency. This is a real production fix, not just a test workaround -- without it, a real staff member whose request is delayed by ordinary network jitter can have a correct code rejected. Verified: tests/api/test_auth.py and the full backend suite, each run twice -- 798 passed both times, no regressions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem 1: cache/dot files not gitignored
.playwright-mcp/— Playwright MCP's own session cache (console logs + page-snapshot YAML,regenerated on every browser-automation run) — had no
.gitignoreentry and was committedstraight into the tracked tree in
bed804c("Testing Plugin"), 11 files.Separately,
2852ec2("Vite config") repointedfrontend/vite.config.js's dev proxy from port5000to5001— a single developer's local workaround for macOS AirPlay occupying port 5000 ontheir own machine, never meant to be shared, and this session had deliberately kept it uncommitted
every time it was touched before this.
Problem 2: CI failure on main
Backend / tests + coverage floorfailed onbed804c:FAILED tests/api/test_auth.py::test_mfa_enroll_reset_rejects_the_wrong_password - KeyError: 'csrf_token'.The traceback shows the failure at the test's own
/mfa/verifycall — the server rejected a TOTPcode the test itself generated as correct.
Root cause:
verify_totp()calledpyotp.TOTP(secret).verify(code)with the library'sdefault
valid_window=0— zero tolerance on either side of the current 30-second window. The testcomputes a code, then makes two sequential HTTP round trips (login, then verify); under CI's load
that's enough latency for the code to roll into a new window before the server checks it.
Confirmed as a flake, not a regression:
bd02376's CI run(34046551983) — identical
backend source, since
bed804cchanged zero backend files — passed all 798 tests, this oneincluded. The failing run was
34047197048.
Implementation
.gitignore: added.playwright-mcp/and.DS_Store(preventive)..playwright-mcp/files (git rm --cached).navbar-fixed.pngverification screenshot from the repo root (untracked, nevercommitted).
frontend/vite.config.js's proxy port to the shared default5000— confirmed thediff nets to zero against the pre-
2852ec2state.verify_totp()now passesvalid_window=1— accepts the current window plus one either side(±30s), RFC 6238's recommended tolerance for clock drift and network latency. This is a real
production fix, not just a test workaround: without it, a real staff member whose request is
delayed by ordinary network jitter can have a correct code rejected.
Validation
tests/api/test_auth.py— 24 passed, run twice.uv run pytest) — 798 passed, 7 skipped, 2 xpassed, run twice,matching the known-good baseline exactly both times.
uv run ruff check/uv run mypy --stricton the touched file: clean, aside from onepre-existing, out-of-scope line-length warning on an untouched line (confirmed present on
origin/mainalready) and two pre-existing, unrelated mypy errors inopenai_agent_adapter.py.git status --shortclean;git ls-files | grep playwrightempty.Security / DB / API impact
the RFC 6238-recommended default and is what most TOTP implementations (Google Authenticator,
AWS, GitHub 2FA) use; it does not materially increase brute-force exposure given the existing
rate limits on
/auth/mfa/verify.🤖 Generated with Claude Code