Skip to content

Conversation

@fatfingers23
Copy link
Contributor

Moved away from using a cookie and tying the oauth session to a kv store and use useSession for all store needs

concerns:

  • I think those session.update({key: "blah"}) looks to be updating only the property passed in and not the ones
  • Added some comments on how we can support multi atproto account logins if we ever want to

@vercel
Copy link

vercel bot commented Feb 3, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 3, 2026 6:26pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 3, 2026 6:26pm
npmx-lunaria Ignored Ignored Feb 3, 2026 6:26pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 3, 2026

📝 Walkthrough

Walkthrough

This PR centralises server-side session handling by adding useServerSession (returns a SessionManager<UserServerSession>), moving OAuth state/session stores to use that server session instead of event/cookie storage, and introducing UserServerSession and PublicUserSessionSchema. API handlers and utilities now pass and validate the public portion of session data (session.data.public) and store oauthSession/oauthState on the server session. Session sign-out is now performed sequentially (signOut awaited before clearing the server session).

Possibly related PRs

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description accurately describes the changeset, detailing the migration from cookie/KV store-based OAuth storage to session-based storage using useSession.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/utils/atproto/oauth.ts (1)

39-43: ⚠️ Potential issue | 🟡 Minor

Missing generic type parameter on SessionManager.

Line 42 declares serverSession: SessionManager without the generic type parameter. For type safety and consistency with the rest of the codebase (e.g., SessionManager<UserServerSession> in the storage classes), this should be typed explicitly.

🔧 Proposed fix
+import type { UserServerSession } from '#shared/types/userSession'
+
 type EventHandlerWithOAuthSession<T extends EventHandlerRequest, D> = (
   event: H3Event<T>,
   session: OAuthSession | undefined,
-  serverSession: SessionManager,
+  serverSession: SessionManager<UserServerSession>,
 ) => Promise<D>
🧹 Nitpick comments (2)
shared/types/userSession.ts (1)

1-14: Consider optional properties instead of | undefined.

This reads more idiomatically and avoids explicit undefined assignments.

Suggested refactor
-  oauthSession: NodeSavedSession | undefined
-  oauthState: NodeSavedState | undefined
+  oauthSession?: NodeSavedSession
+  oauthState?: NodeSavedState
server/utils/atproto/oauth.ts (1)

45-72: Redundant useServerSession calls for the same request.

useServerSession(event) is called twice per request: once in getOAuthSession (line 47) and again in eventHandlerWithOAuthSession (line 68). Although h3's useSession typically caches by event, this pattern is unclear and potentially inefficient.

Consider passing serverSession as a parameter to getOAuthSession instead of having it fetch its own.

♻️ Proposed refactor
-async function getOAuthSession(event: H3Event): Promise<OAuthSession | undefined> {
+async function getOAuthSession(
+  event: H3Event,
+  serverSession: SessionManager<UserServerSession>,
+): Promise<OAuthSession | undefined> {
   const clientMetadata = getOauthClientMetadata()
-  const serverSession = await useServerSession(event)
   const { stateStore, sessionStore } = useOAuthStorage(serverSession)

   const client = new NodeOAuthClient({
@@ export function eventHandlerWithOAuthSession
   return defineEventHandler(async event => {
     const serverSession = await useServerSession(event)

-    const oAuthSession = await getOAuthSession(event)
+    const oAuthSession = await getOAuthSession(event, serverSession)
     return await handler(event, oAuthSession, serverSession)
   })
 }

Comment on lines +2 to +5
// Even tho the signOut also clears part of the server cache should be done in order
// to let the oAuth package do any other clean up it may need
await oAuthSession?.signOut()
await serverSession.clear()
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Ensure server session is cleared even when sign‑out fails.

If signOut() throws, serverSession.clear() will never run, leaving stale session state.

Proposed fix
-  await oAuthSession?.signOut()
-  await serverSession.clear()
+  try {
+    await oAuthSession?.signOut()
+  } finally {
+    await serverSession.clear()
+  }

Comment on lines +1 to +5
import { PublicUserSessionSchema } from '#shared/schemas/publicUserSession'
import { safeParse } from 'valibot'

export default eventHandlerWithOAuthSession(async (event, oAuthSession, serverSession) => {
const result = safeParse(UserSessionSchema, serverSession.data)
const result = safeParse(PublicUserSessionSchema, serverSession.data.public)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard against missing session data before validation.

serverSession.data can be undefined; accessing .public will throw and bypass the intended validation.

Proposed fix
-  const result = safeParse(PublicUserSessionSchema, serverSession.data.public)
+  const result = safeParse(PublicUserSessionSchema, serverSession.data?.public)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { PublicUserSessionSchema } from '#shared/schemas/publicUserSession'
import { safeParse } from 'valibot'
export default eventHandlerWithOAuthSession(async (event, oAuthSession, serverSession) => {
const result = safeParse(UserSessionSchema, serverSession.data)
const result = safeParse(PublicUserSessionSchema, serverSession.data.public)
import { PublicUserSessionSchema } from '#shared/schemas/publicUserSession'
import { safeParse } from 'valibot'
export default eventHandlerWithOAuthSession(async (event, oAuthSession, serverSession) => {
const result = safeParse(PublicUserSessionSchema, serverSession.data?.public)

@codecov
Copy link

codecov bot commented Feb 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@danielroe danielroe changed the title chore: moved the oauth to useSession refactor: moved the oauth to useSession Feb 3, 2026
@danielroe danielroe enabled auto-merge February 3, 2026 18:27
@danielroe danielroe added this pull request to the merge queue Feb 3, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 3, 2026
@danielroe danielroe added this pull request to the merge queue Feb 3, 2026
Merged via the queue into npmx-dev:main with commit b85af80 Feb 3, 2026
14 checks 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.

2 participants