Skip to content

feat(auth): implement state-transition invariants for sign-in, refres… - #1698

Open
sulaimonifeoluwa4-blip wants to merge 1 commit into
Remitwise-Org:mainfrom
sulaimonifeoluwa4-blip:feat/auth-state-transition-invariants
Open

feat(auth): implement state-transition invariants for sign-in, refres…#1698
sulaimonifeoluwa4-blip wants to merge 1 commit into
Remitwise-Org:mainfrom
sulaimonifeoluwa4-blip:feat/auth-state-transition-invariants

Conversation

@sulaimonifeoluwa4-blip

Copy link
Copy Markdown

…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/)

  • 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.

…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>
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.

[Quality][High] authentication and account recovery: state-transition invariants — QE-2026-08

2 participants