Repository navigation
Conversation
…g session (libredb#1942) - Introduce readSession() returning discriminated SessionReading union, with getSession() wrapping it to preserve the no-throw contract. - Return 503 ACCOUNT_STORE_UNAVAILABLE from guardRoute, GET /api/auth/me, and /api/mcp when the account store is unreadable. - Preserve session cookie and MCP bearer tokens on store outage, avoiding /login redirect loops. - Clean up unused introspect test helpers and address effect set-state lint warning in DataProfiler. - Update API and storage documentation with store outage error specifications.
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.
Summary
Resolves #1942.
With password sign-in and
STORAGE_PROVIDER=sqliteorpostgres,getSessioninsrc/lib/auth.tspreviously returnednullwhengetStorageProvider,reconcileOnce, orgetAccountthrew. While followinggetSession's no-throw contract, it collapsed transient storage store read outages into a refused account:guardRouteanswered401 AUTH_REQUIREDand recorded apermission_deniedaudit event.GET /api/auth/meanswered401 { authenticated: false }.mcpTokenOwnerAllowedtreated valid bearer tokens as revoked and answered401 invalid_token.auth-tokencookie still verified, creating redirect oscillations between/loginand the editor.This change separates a store read failure from a missing or refused session across all three authentication surfaces.
Changes
1.
readSession()andgetSession()(src/lib/auth.ts)readSession()which returns a discriminated unionSessionReading:{ kind: "authenticated", session: UserPayload }{ kind: "anonymous", reason: "no_cookie" | "invalid_jwt" | "account_refused" }(callinglogout()to clear the cookie when refused){ kind: "store_unavailable", error: unknown }(preserving the client cookie)getSession()now wrapsreadSession(), returningsessionon"authenticated"andnullotherwise to preserve its existing non-throwing contract.2. Route Guards & Endpoints
guardRoute(src/lib/api/require-session.ts):503 { "error": "The account store is unavailable. Try again.", "code": "ACCOUNT_STORE_UNAVAILABLE" }onstore_unavailablewithout logging an erroneouspermission_deniedaudit entry.401 AUTH_REQUIREDonanonymous.GET /api/auth/me(src/app/api/auth/me/route.ts):503 ACCOUNT_STORE_UNAVAILABLEonstore_unavailable.401 { "authenticated": false }onanonymous.src/lib/mcp/account-check.ts,src/app/api/mcp/route.ts):mcpTokenOwnerAllowedreturns"store_unavailable"when the account store throws./api/mcpanswers503 ACCOUNT_STORE_UNAVAILABLEwithout revoking tokens or recording denial audits.3. Client & Browser Handling
appFetchinsrc/lib/config/base-path.tstriggers sign-in redirection only on401withcode: AUTH_REQUIRED. AnACCOUNT_STORE_UNAVAILABLE503 avoids triggering/loginredirects.WorkspaceOwnerGate(src/components/auth/WorkspaceOwnerGate.tsx), an unreadable account via 503 triggers the"failed"alert state, holding the session cookie in the browser so that reloading when the store recovers restores the workspace without re-authenticating.4. Cleanup & Documentation
ACCOUNT_STORE_UNAVAILABLEindocs/API_DOCS.mdand added store outage troubleshooting guidelines indocs/STORAGE.md.tests/unit/db/search/introspect.test.ts.react-hooks/set-state-in-effectlint warning insrc/components/DataProfiler.tsx.Testing
bun run typecheck(tsc --noEmit) passes with 0 errors.bun x eslintandbun x biome checkpass with 0 errors / 0 warnings.bun test tests/api/auth/me.test.ts(5/5 pass)bun test tests/security/route-auth.test.ts(48/48 pass)bun test tests/security/mcp-auth.test.ts(52/52 pass)bun test tests/unit/lib/auth.test.ts(44/44 pass)bun test tests/components/auth/WorkspaceOwnerGate.test.tsx(23/23 pass)bun test tests/components/DataProfiler.test.tsx(52/52 pass)bun test tests/unit/db/search/introspect.test.ts(10/10 pass)