-
Notifications
You must be signed in to change notification settings - Fork 37
feat(auth-nextjs): add auth-nextjs package #2765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
packages/passport/sdk-sample-app/src/pages/api/auth/sandbox/[...nextauth].api.ts
Outdated
Show resolved
Hide resolved
|
View your CI Pipeline Execution ↗ for commit bd230a1
☁️ Nx Cloud last updated this comment at |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx affected -t build,lint,test |
❌ Failed | 3m 12s | View ↗ |
nx run-many -p @imtbl/sdk,@imtbl/checkout-widge... |
✅ Succeeded | 3s | View ↗ |
☁️ Nx Cloud last updated this comment at 2025-12-17 04:04:32 UTC
| } finally { | ||
| setIsLoading(false); | ||
| } | ||
| }, [fetcher, getAccessToken]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing fetch cancellation causes stale data race condition
Medium Severity
The useHydratedData hook has a race condition where in-flight fetches are not cancelled when props change. When props change from ssr: false to ssr: true (e.g., during soft navigation after token refresh), the props-sync effect correctly sets the fresh serverData. However, the previously started client-side fetch continues running and when it completes, setData(result) overwrites the correct server data with stale results. There's no AbortController, fetch ID tracking, or staleness check to prevent this.
Additional Locations (1)
|
|
||
| hasFetchedRef.current = true; | ||
| fetchData(); | ||
| }, [needsClientFetch, ssr, auth, fetchData]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Client fetch fails when session not yet loaded
Medium Severity
When ssr=true but fetchError exists (server-side fetch failed), useHydratedData immediately attempts a client-side retry without waiting for the session to load from useSession(). The guard if (!ssr && !auth) return only waits for auth when ssr=false, but when ssr=true with a fetchError, it proceeds immediately. If useSession() is still in 'loading' state, getAccessToken() will throw "No access token available" because session is undefined. After this error, hasFetchedRef.current remains true, blocking retries even after the session loads.
| console.warn('[auth-next-client] Logout cleanup error:', error); | ||
| } | ||
| } | ||
| }, [auth]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double signOut calls during logout flow
Medium Severity
The handleSignOut function calls signOut() from NextAuth, then calls auth.getLogoutUrl(). However, getLogoutUrl() emits the LOGGED_OUT event, which triggers the handleLoggedOut listener that also calls signOut(). This results in NextAuth's signOut being invoked twice during a single logout operation, causing redundant work and potential race conditions if the first signOut hasn't completed.
Additional Locations (1)
| // No auth instance, just sign out from NextAuth directly | ||
| await signOut({ redirect: false }); | ||
| } | ||
| }, [auth]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sign out returns before NextAuth session is cleared
Medium Severity
The handleSignOut function returns before NextAuth signOut() completes in the success path. When auth.getLogoutUrl() emits the LOGGED_OUT event, the handleLoggedOut listener calls signOut() asynchronously, but TypedEventEmitter.emit() doesn't await async handlers. This creates a race condition where code awaiting handleSignOut() may execute while the NextAuth session cookie still exists. The error and no-auth paths correctly await signOut(), making this behavior inconsistent.
| } | ||
| }, | ||
| "scripts": { | ||
| "build": "tsup && pnpm build:types", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing build:types script causes build failure
High Severity
The build script references pnpm build:types but no build:types script is defined in the package. The package defines typegen for type generation. Comparing with @imtbl/auth-next-server which correctly uses "build": "pnpm transpile && pnpm typegen", this appears to be a typo where build:types should be typegen.
| // No auth instance, just sign out from NextAuth directly | ||
| await signOut({ redirect: false }); | ||
| } | ||
| }, [auth]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SignOut doesn't await NextAuth session clearance completion
Medium Severity
The handleSignOut function returns before NextAuth signOut() actually completes. It relies on getLogoutUrl() emitting a LOGGED_OUT event that triggers an async handleLoggedOut handler calling signOut(). However, TypedEventEmitter.emit() invokes handlers synchronously without awaiting their Promises. This causes callers who await handleSignOut() to receive a resolved Promise while the actual session cookie deletion is still in progress, leading to race conditions and potentially inconsistent authentication state.

Summary
Adding auth-nextjs for convenient integration with nextjs + SSR.
Note
Introduces first-class Next.js (Auth.js v5) support with client/server packages, SSR-safe token handling, and sample app integration.
@imtbl/auth-next-client(provider, hooks,CallbackPage, hydration helpers) and@imtbl/auth-next-server(createImmutableAuth/createAuthConfig, JWT/session callbacks, middleware/utilities, constants/types)AuthEvents.TOKEN_REFRESHED; server marks expired tokens (no server-side refresh) to avoid race conditions; robust JWT/session shapingTOKEN_REFRESHEDandUSER_REMOVEDevents; refined refresh error handling; new tests for refresh flowsImmutableAuthProvider, adds OAuthcallbackpage and demo component; Next.js config supports toggling API routesNODE_OPTIONS, serialize network concurrency in.npmrc, relax syncpack peer ranges; widespread dev dep bumps (swc, jest, eslint, types/node, next)Written by Cursor Bugbot for commit bd230a1. This will update automatically on new commits. Configure here.