Skip to content

feat(core): implement experimental stateful session strategy"#228

Merged
halvaradop merged 2 commits into
masterfrom
feat/stateful-strategy
Jul 15, 2026
Merged

feat(core): implement experimental stateful session strategy"#228
halvaradop merged 2 commits into
masterfrom
feat/stateful-strategy

Conversation

@halvaradop

@halvaradop halvaradop commented Jul 14, 2026

Copy link
Copy Markdown
Member

Description

This pull request introduces the experimental Stateful session strategy for @aura-stack/auth, adding support for database-backed session management alongside the existing stateless strategy.

With this change, Aura Auth now supports two session strategies:

  • Stateless — Session data is stored in encrypted cookies.
  • Stateful — Session data is persisted in a database and managed through a database adapter.

The new Stateful strategy provides the foundation for applications that require centralized session storage, server-side session revocation, multi-device session management, and other database-driven authentication features.

Usage

import { createAuth } from "@aura-stack/auth"

export const auth = createAuth({
  oauth: [],
  session: {
    strategy: "database",
    adapter: {} as DatabaseAdapter,
  },
})

Note

This PR introduces the initial implementation of the Stateful session strategy. While the core functionality is available, additional features and improvements will be introduced in subsequent pull requests.

Note

Database adapters are still under development and will be introduced in future PRs. This PR focuses on integrating the Stateful strategy into the authentication core and establishing the foundation for adapter implementations.

@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
auth Skipped Skipped Jul 15, 2026 12:58am

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a database-backed stateful session strategy with hashed tokens, cookie and adapter lifecycle operations, strategy-specific JWT handling, new public types and diagnostics, and comprehensive endpoint tests.

Changes

Stateful session strategy

Layer / File(s) Summary
Stateful contracts and strategy guards
packages/core/src/@types/entities.ts, packages/core/src/@types/index.ts, packages/core/src/@types/session.ts, packages/core/src/shared/assert.ts
Session entities use tokenHash; stateful option and return types are exported; strategy type guards and JWT mode handling distinguish stateful and stateless configurations.
Stateful session lifecycle
packages/core/src/session/stateful.ts, packages/core/src/shared/errors.ts, packages/core/src/shared/logger.ts
Cookie-backed retrieval, creation, refresh, revocation, and destruction use adapter persistence, hashed tokens, expiration checks, CSRF validation, error catalog entries, and stateful log messages.
Strategy routing and JWT isolation
packages/core/src/session/strategy.ts, packages/core/src/jose.ts, packages/core/src/router/context.ts
Database sessions route to createStatefulStrategy; JWT configuration and manager initialization apply only to stateless sessions.
Stateful endpoint validation
packages/core/test/session/stateful.test.ts
Tests cover session retrieval, creation, refresh, revocation, destruction, CSRF behavior, expiration, adapter calls, serialization, and skipped schema validation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant StatefulStrategy
  participant CookieStore
  participant SessionAdapter
  Client->>StatefulStrategy: session request
  StatefulStrategy->>CookieStore: read session token
  StatefulStrategy->>SessionAdapter: load or persist session
  SessionAdapter-->>StatefulStrategy: session and user data
  StatefulStrategy-->>Client: session response and cookie headers
Loading

Possibly related PRs

Suggested labels: experimental

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately summarizes the main change: implementing a stateful session strategy in core.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/stateful-strategy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/router/context.ts`:
- Line 64: Make jwtManager conditional in the router context construction so
database sessions do not call createJoseManager at all; only initialize it for
stateless sessions. Update the context contract and any consumers to represent
the manager as absent when using database sessions, while preserving JWT
operations for stateless sessions.

In `@packages/core/src/session/stateful.ts`:
- Line 114: Update the user object construction in the session state flow and
the corresponding sessionByToken.user construction so session.user and
session.user.attributes are spread first, then the authenticated user ID is
assigned last as the authoritative sub value.
- Around line 509-526: Update the session destruction flow around the catch
block and cookieConfig.clear() so cookie clearing always occurs even when
database revocation fails. Preserve the existing error logging and ensure
revocation remains best-effort while destruction returns cleared headers; do not
rethrow before the cleanup completes.
- Around line 461-488: Update destroySession to enforce the existing CSRF
validation before calling config.adapter.revokeSession, honoring the
_skipCSRFCheck flag consistently with refreshSession. Preserve session-token
extraction and lookup, but prevent revocation when the CSRF check fails unless
explicitly skipped.
- Around line 321-338: Update the session validation in the refresh flow around
sessionByToken before the expiration check to reject sessions whose status is
inactive or revoked, returning the same cleared-cookie unauthenticated result
used for missing users. Ensure only active sessions proceed to expiration
renewal and authenticated return handling.

In `@packages/core/src/shared/assert.ts`:
- Around line 127-128: Update getJWTMode to return undefined for
stateful/database configurations instead of "sealed", while preserving the
existing sealed default for stateless configurations without an explicit JWT
mode. Adjust the JWTMode return type and any dependent mode guards or type
predicates so database configs are not classified as sealed and no longer imply
config.jwt exists.

In `@packages/core/test/session/stateful.test.ts`:
- Around line 513-541: The destroySession test should verify cookie expiration
in addition to session revocation. In the test using authInstance and the POST
sign-out response, inspect the Set-Cookie header and assert that
__Secure-aura-auth.session_token is expired, while preserving the existing
status, response, and mock assertions.
- Around line 155-173: Update the mock in the “should return null session on
adapter error” test to reject with the database error instead of resolving an
Error object. Keep the existing GET request, response assertions, and mock
invocation verification unchanged so the test exercises the adapter-error path.
- Around line 483-510: Strengthen the revokeSession test in the “should revoke
session by ID using createAuth” case by asserting the exact arguments passed to
revokeSessionMock, including the expected session identifier and revocation
reason. Keep the existing response assertions and ensure the test fails when a
different session or reason is used.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3ea4443d-8ef4-483d-bd05-9356a9c3efc7

📥 Commits

Reviewing files that changed from the base of the PR and between 9fc78a9 and 9c3fe8e.

📒 Files selected for processing (11)
  • packages/core/src/@types/entities.ts
  • packages/core/src/@types/index.ts
  • packages/core/src/@types/session.ts
  • packages/core/src/jose.ts
  • packages/core/src/router/context.ts
  • packages/core/src/session/stateful.ts
  • packages/core/src/session/strategy.ts
  • packages/core/src/shared/assert.ts
  • packages/core/src/shared/errors.ts
  • packages/core/src/shared/logger.ts
  • packages/core/test/session/stateful.test.ts

Comment thread packages/core/src/router/context.ts
Comment thread packages/core/src/session/stateful.ts Outdated
Comment thread packages/core/src/session/stateful.ts
Comment thread packages/core/src/session/stateful.ts Outdated
Comment thread packages/core/src/session/stateful.ts
Comment thread packages/core/src/shared/assert.ts
Comment thread packages/core/test/session/stateful.test.ts
Comment thread packages/core/test/session/stateful.test.ts
Comment thread packages/core/test/session/stateful.test.ts
@halvaradop halvaradop merged commit fd5d2da into master Jul 15, 2026
7 checks passed
@halvaradop halvaradop deleted the feat/stateful-strategy branch July 15, 2026 01:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant