feat(auth): implement state-transition invariants for sign-in, refres… - #1698
Open
sulaimonifeoluwa4-blip wants to merge 1 commit into
Open
Conversation
…h, logout, and recovery flows Closes Remitwise-Org#1644 This change defines and enforces a formal transition matrix for the three core auth objects (Session, Token, RecoveryRequest) so that every sign-in, refresh, verification, logout, and account-recovery flow is deterministically safe across expiry, retries, multiple tabs, and device changes. ## What changed ### Rust backend (`meridian-api/src/auth/`) - **state_machine.rs** (new) — formal transition matrices for SessionState, TokenState, and RecoveryRequestState with every legal and illegal transition defined. Exhaustive unit tests cover every cell in the matrix plus stale, repeated, out-of-order, and concurrent transitions. - **errors.rs** — added `InvalidStateTransition(String)` variant to `AuthError` with Display impl. - **mod.rs** — exports the new `state_machine` module and its public types. - **flows.rs** — improved borrow management in `logout` and `logout_all` to snapshot token ids before borrowing the session, removing borrow-checker workarounds. - **recovery.rs** — applied `cargo fmt` formatting fixes. - **tokens.rs** — removed a spurious blank line. ### TypeScript / NestJS layer (`meridian-api/src/auth/providers/`) - **auth-state-machine.ts** (new) — mirrors the Rust transition matrices in TypeScript with `validateSessionTransition`, `validateTokenTransition`, and `validateRecoveryTransition` functions, an `InvalidStateTransitionError` class, and an append-only `TransitionLog` for audit. - **auth-state-machine.spec.ts** (new) — exhaustive Jest tests for every legal transition, illegal transition, full lifecycle integration, and edge cases (stale, repeated, out-of-order). - **state-transition-guard.service.ts** (new) — NestJS guard service wrapping every auth entry point with transition validation and structured logging. - **state-transition-guard.service.spec.ts** (new) — integration tests for the guard service covering session, token, and recovery flows. ## Design invariants 1. **Deterministic** — `(currentState, event)` uniquely determines the next state. 2. **Closed** — every event has a defined outcome for every state (including rejections for illegal transitions). 3. **No partial state** — a rejected transition leaves the store unchanged; all multi-step operations use atomic snapshot/rollback. 4. **Auditable** — every transition (legal or rejected) is recorded in an append-only transition log. ## Validation results - `cargo test` — 161 passed, 0 failed - `cargo fmt --check` — clean - `cargo clippy` — 0 warnings - `jest --testPathPattern="auth-state-machine|state-transition-guard"` — 145 passed, 0 failed - `eslint` on all new TypeScript files — 0 errors ## Compatibility No public API changes. The `InvalidStateTransition` error variant is new and only surfaces when an illegal transition is attempted — callers that never trigger illegal transitions see no difference. No database migrations, no secret changes, no disabled checks. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.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.
…h, logout, and recovery flows
Closes #1644
This change defines and enforces a formal transition matrix for the three core auth objects (Session, Token, RecoveryRequest) so that every sign-in, refresh, verification, logout, and account-recovery flow is deterministically safe across expiry, retries, multiple tabs, and device changes.
What changed
Rust backend (
meridian-api/src/auth/)InvalidStateTransition(String)variant toAuthErrorwith Display impl.state_machinemodule and its public types.logoutandlogout_allto snapshot token ids before borrowing the session, removing borrow-checker workarounds.cargo fmtformatting fixes.TypeScript / NestJS layer (
meridian-api/src/auth/providers/)validateSessionTransition,validateTokenTransition, andvalidateRecoveryTransitionfunctions, anInvalidStateTransitionErrorclass, and an append-onlyTransitionLogfor audit.Design invariants
(currentState, event)uniquely determines the next state.Validation results
cargo test— 161 passed, 0 failedcargo fmt --check— cleancargo clippy— 0 warningsjest --testPathPattern="auth-state-machine|state-transition-guard"— 145 passed, 0 failedeslinton all new TypeScript files — 0 errorsCompatibility
No public API changes. The
InvalidStateTransitionerror variant is new and only surfaces when an illegal transition is attempted — callers that never trigger illegal transitions see no difference. No database migrations, no secret changes, no disabled checks.