Skip to content

fix(magic-link): preserve unreadable token stores - #2995

Open
tang-vu wants to merge 1 commit into
Osmantic:mainfrom
tang-vu:fix/magic-link-preserve-corrupt-store
Open

fix(magic-link): preserve unreadable token stores#2995
tang-vu wants to merge 1 commit into
Osmantic:mainfrom
tang-vu:fix/magic-link-preserve-corrupt-store

Conversation

@tang-vu

@tang-vu tang-vu commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Why this matters

The magic-link store contains active invite hashes, revocation state, and redemption audit history. If the JSON became unreadable, the loader silently treated it as an empty store; the next generate or list operation then overwrote the file, destroying recoverable authorization state.

Root cause and invariant

_ensure_store caught file and JSON errors together and returned an empty token list. The invariant is that a missing store initializes cleanly, but an existing unreadable or structurally invalid store is never interpreted as empty and never overwritten.

The loader now distinguishes a missing file from read errors, invalid JSON, and invalid root shape. Existing corruption returns an operator-visible 503 while preserving the original bytes.

Overlap check

Searched open and closed PRs for magic link corrupt store, unreadable token store, the router, and its test file. No semantic match or open same-file PR was found. This is independent from session signing, proxy readiness, cookie, and redemption behavior already covered by the suite.

Regression coverage

Parameterized FastAPI tests place both invalid JSON and a valid non-object JSON root at the production store path, call the authenticated generate endpoint, assert 503, and verify the file remains byte-for-byte unchanged.

Validation

  • pytest -q ods/extensions/services/dashboard-api/tests/test_magic_link.py -x ? 68 passed
  • python -m py_compile ods/extensions/services/dashboard-api/routers/magic_link.py ods/extensions/services/dashboard-api/tests/test_magic_link.py
  • git diff --check

Tradeoffs and rollback

Operators must repair or intentionally remove a corrupt store before minting new links; this favors preservation over silent recovery. Missing stores still initialize normally. Revert restores the destructive fail-open behavior; no migration is needed.

@tang-vu

tang-vu commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

Batch compatibility receipt (2026-08-23)

Validated merge order: #2989 ? #2990 ? #2993 ? #2991 ? #2992 ? #2994 ? #2995 ? #2996 ? #2997 ? #2998. The changes are independently useful; this order only reconciles shared model-router and magic-link files.

Synthetic integration head: origin/batch/quality-ten-20260822-round2-integration at 91eb730d. The only textual conflict was the two model-router tests inserting at the same class boundary; the integration resolution retains both contracts. Magic-link changes merged cleanly.

Combined validation on that exact head:

  • remote-provider egress contract: 16 passed
  • Token Spy suites: 22 passed, 1 skipped (live PostgreSQL availability)
  • model-router suite: 55 passed
  • APE suite: 29 passed
  • dashboard OAuth + magic-link suites: 118 passed, 2 platform skips
  • Brave Search loopback E2E: all checks passed
  • git diff --check: passed

All required GitHub checks are green across the batch. #2992 initially hit a transient openSUSE repository/mirror failure while installing rsync; a clearly labeled empty retry commit reran the unchanged tree, and openSUSE plus the full matrix passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant