-
Notifications
You must be signed in to change notification settings - Fork 0
feat: setup next auth #11
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
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThis update introduces authentication and session management to the web application. It adds NextAuth integration with Google as an OAuth provider, sets up related API routes, and implements middleware to manage authentication-based routing. New React hooks and components are provided for session handling and user interface updates, including login and logout functionality. The chat application layout is updated to support session context, and navigation flows are adjusted to direct users to the appropriate pages based on authentication state. The Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ChatPage
participant useUserSession
participant NextAuth API
participant Middleware
User->>ChatPage: Navigates to /chat
ChatPage->>useUserSession: Retrieve session
useUserSession->>NextAuth API: Request session data
NextAuth API-->>useUserSession: Return session or null
useUserSession-->>ChatPage: Provide { user, isLoading }
alt isLoading
ChatPage-->>User: Render nothing (wait)
else Authenticated
ChatPage-->>User: Render chat UI
end
sequenceDiagram
participant User
participant GoogleLoginButton
participant NextAuth API
User->>GoogleLoginButton: Click "Sign in with Google"
GoogleLoginButton->>NextAuth API: signIn("google", { callbackUrl: "/" })
NextAuth API-->>User: OAuth flow with Google
NextAuth API-->>User: Redirect to "/"
sequenceDiagram
participant User
participant Browser
participant Middleware
User->>Browser: Request /chat or /login
Browser->>Middleware: Forward request
Middleware->>Browser: Check auth token in cookies
alt No token and not /login
Middleware-->>User: Redirect to /login
else Token and on /login
Middleware-->>User: Redirect to /
else
Middleware-->>Browser: Allow request to proceed
end
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 6
🧹 Nitpick comments (8)
apps/web/components/logout-button.tsx (2)
1-12: Logout button implementation needs improvementsThe component is functional but has several opportunities for improvement.
Consider these enhancements:
- Add accessibility attributes for screen readers
- Consider adding confirmation before logout for better UX
- Remove duplicated styling between button and icon
"use client"; import { Button } from "@eligius/ui"; import { signOut } from "next-auth/react"; import { LogOut } from "lucide-react"; export default function LogoutButton() { - return <Button variant="ghost" size="sm" className="h-5 w-5 text-gray-600" onClick={() => signOut()}> - <LogOut className="h-5 w-5 text-gray-600" /> + return <Button + variant="ghost" + size="sm" + className="text-gray-600" + onClick={() => signOut()} + aria-label="Logout"> + <LogOut className="h-5 w-5" /> </Button>; }
8-12: Add typings for the signOut functionConsider handling potential errors from the signOut function and providing proper typings.
export default function LogoutButton() { - return <Button variant="ghost" size="sm" className="h-5 w-5 text-gray-600" onClick={() => signOut()}> + return <Button + variant="ghost" + size="sm" + className="h-5 w-5 text-gray-600" + onClick={() => { + signOut() + .catch(error => console.error('Logout failed:', error)); + }}> <LogOut className="h-5 w-5 text-gray-600" /> </Button>; }apps/web/app/chat/layout.tsx (1)
18-20: Consider adding configuration options to SessionProviderThe SessionProvider is implemented without any configuration options. For better user experience, consider adding options like
refetchIntervalto keep the session data fresh.- <SessionProvider> + <SessionProvider + refetchInterval={5 * 60} // Refresh session every 5 minutes + refetchOnWindowFocus={true} + >apps/web/actions/loginAction.ts (2)
6-17: Add type annotations for better type safetyThe return type of the function is not explicitly defined, which would provide better type safety.
-export const loginAction = async () => { +export const loginAction = async (): Promise<{ user: { id: string; name?: string; email?: string; image?: string } }> => {
14-15: Enhance error loggingThe current error logging doesn't distinguish between different types of errors that might occur.
- console.error("loginAction error:", error); - throw new Error("Unable to log in. Please try again."); + const errorMessage = error instanceof Error ? error.message : "Unknown error"; + console.error("loginAction error:", errorMessage); + throw new Error("Unable to log in. Please try again.");apps/web/middleware.ts (3)
24-24: Inconsistent string formatting in matcher arrayThere's an inconsistent use of quote style in the matcher array.
- matcher: ["/club", "/chat", '/login'], + matcher: ["/club", "/chat", "/login"],
10-18: Preserve the original URL when redirectingThe current implementation loses any query parameters when redirecting. Consider preserving them for a better user experience.
- return NextResponse.redirect(new URL("/login", request.url)); + const loginUrl = new URL("/login", request.url); + // Preserve the original URL for redirecting back after login + loginUrl.searchParams.set("callbackUrl", request.nextUrl.pathname + request.nextUrl.search); + return NextResponse.redirect(loginUrl);Same improvement can be applied to the redirect on line 17.
5-8: Add typed interface for tokenThe token variable is not typed, which could lead to bugs if the structure changes.
+ interface SessionToken { + name: string; + value: string; + } + const getSessionToken = (): SessionToken | undefined => { + return process.env.NEXT_PUBLIC_APP_ENV === "production" + ? request.cookies.get("__Secure-next-auth.session-token") + : request.cookies.get("next-auth.session-token"); + }; - const token = - process.env.NEXT_PUBLIC_APP_ENV === "production" - ? request.cookies.get("__Secure-next-auth.session-token") - : request.cookies.get("next-auth.session-token"); + const token = getSessionToken();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
apps/web/.gitignore(1 hunks)apps/web/actions/loginAction.ts(1 hunks)apps/web/app/api/auth/[...nextauth]/route.ts(1 hunks)apps/web/app/chat/layout.tsx(1 hunks)apps/web/app/chat/page.tsx(3 hunks)apps/web/app/page.tsx(1 hunks)apps/web/components/chat-header.tsx(2 hunks)apps/web/components/google-login.tsx(1 hunks)apps/web/components/logout-button.tsx(1 hunks)apps/web/hooks/use-session.tsx(1 hunks)apps/web/middleware.ts(1 hunks)apps/web/package.json(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
apps/web/components/chat-header.tsx (1)
apps/web/components/logout-button.tsx (1)
LogoutButton(8-12)
apps/web/hooks/use-session.tsx (1)
apps/web/app/api/auth/[...nextauth]/route.ts (1)
session(19-27)
apps/web/actions/loginAction.ts (1)
apps/web/app/api/auth/[...nextauth]/route.ts (2)
session(19-27)authOptions(5-29)
🔇 Additional comments (14)
apps/web/.gitignore (1)
28-28: Good security practice to ignore .env fileAdding .env to .gitignore is a security best practice to prevent committing sensitive credentials like OAuth client IDs and secrets to the repository.
apps/web/app/page.tsx (1)
20-20:Details
✅ Verification successful
Updated navigation flow for authentication
Changing the "Start Chatting" button link from "/login" to "/chat" aligns with the new authentication flow implemented in the app.
🏁 Script executed:
#!/bin/bash # Check if middleware handles unauthenticated users trying to access the chat route echo "Checking for middleware implementation that redirects unauthenticated users" fd middleware.tsLength of output: 202
🏁 Script executed:
#!/bin/bash # Display the middleware implementation to verify unauthenticated access handling sed -n '1,200p' apps/web/middleware.tsLength of output: 763
Updated navigation flow for authentication
The “Start Chatting” button now points to
/chat, and the middleware inapps/web/middleware.tsprotects this route:
- apps/web/app/page.tsx (line 20):
<Link href="/chat">- apps/web/middleware.ts:
• Redirects unauthenticated users accessing/chatto/login
• Allows authenticated users to reach/chatand blocks them from/loginNo further changes needed.
apps/web/components/chat-header.tsx (2)
5-5: Well-structured component organization.Good job importing the dedicated LogoutButton component, which improves code modularity and separates concerns.
28-28: Clean implementation of logout functionality.Replacing the inline logout button with the dedicated component simplifies the JSX structure while maintaining the same functionality.
apps/web/components/google-login.tsx (2)
4-4: Proper NextAuth integration.Good addition of the NextAuth signIn function, which is necessary for implementing OAuth authentication.
12-14: Functional Google authentication implementation.The implementation correctly uses the signIn function with the "google" provider and sets an appropriate callback URL to redirect users after successful login.
apps/web/app/chat/page.tsx (2)
22-22: Good integration of session management.The useUserSession hook import is a good practice for centralizing authentication state management across the app.
39-39: Properly destructured session information.Correctly destructuring the user and loading state from the session hook.
apps/web/hooks/use-session.tsx (3)
1-4: Good setup for client-side hook.Properly marked as a client component with the "use client" directive and correctly imported the NextAuth useSession hook.
5-10: Well-structured session management hook.The hook definition properly extracts session data and derives meaningful authentication states to simplify usage across the application.
11-17: Clean and comprehensive return object.The return object provides all necessary session information in a well-structured format, making it easy for components to access authentication data.
apps/web/app/chat/layout.tsx (1)
1-24: Good implementation of SessionProvider with appropriate structureThe layout component properly wraps the children with a SessionProvider to make authentication context available throughout the chat application. The Inter font and necessary stylesheets are correctly imported.
apps/web/actions/loginAction.ts (1)
1-17: Server action implementation for authentication looks correctThe server action correctly retrieves and validates the authentication session with proper error handling.
apps/web/middleware.ts (1)
4-21: Good implementation of authentication middlewareThe middleware correctly checks for the session token and handles redirects appropriately based on authentication state.
| "clsx": "^2.1.1", | ||
| "lucide-react": "^0.487.0", | ||
| "next": "^15.2.1", | ||
| "next-auth": "^4.24.11", |
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.
💡 Verification agent
🧩 Analysis chain
NextAuth dependency added correctly
The addition of next-auth package is appropriate for implementing authentication features as described in the PR objectives.
🌐 Web query:
Is next-auth version 4.24.11 compatible with Next.js 15.2.x?
💡 Result:
Compatibility of next-auth v4.24.11 with Next.js 15.2.x
Summary:
next-auth v4.24.11 is not fully compatible with Next.js 15.2.x (and React 19), as users have reported runtime errors due to architectural changes in React 19 and Next.js 15[4].
Details:
- A reported issue on GitHub shows that using next-auth 4.24.11 with React 19 and Next.js 15 leads to runtime errors, specifically related to invalid React hook calls (e.g., errors from
SessionProviderattempting to use hooks in the new React architecture)[4]. - The error appears when combining:
next-auth: 4.24.11react: 19.0.0next: 15.x
- Downgrading to React 18 resolves the issue, indicating next-auth 4.24.11 is not designed for React 19/Next.js 15's new architecture[4].
- There is currently no official fix for this compatibility problem with v4.24.11. Users affected by this limitation are awaiting updates or considering migration to authentication solutions that explicitly support React 19/Next.js 15[4][6].
Official Documentation and Support:
- The official next-auth documentation and upgrade guides do not yet specifically note support for Next.js 15 or React 19 for v4.24.11[2][7].
- No evidence from the current documentation or release notes suggests official compatibility between next-auth 4.24.11 and Next.js 15.2.x[2][8].
Alternatives and Recommendations:
- If you require Next.js 15.2.x or React 19 features, consider:
- Downgrading to React 18 and Next.js 14 (if feasible) to maintain compatibility with next-auth v4.24.11[4].
- Monitoring the next-auth GitHub repository for updates or announcements about React 19/Next.js 15 support.
- Investigating alternative authentication libraries such as Better Auth, which has explicit tutorials for Next.js 15[6].
Conclusion:
next-auth v4.24.11 is not currently compatible with Next.js 15.2.x (and React 19) due to unaddressed breaking changes in underlying architecture. For stable authentication, use older versions of Next.js/React, monitor for updates, or consider alternatives better aligned with the latest Next.js releases[4].
Citations:
- 1: https://www.npmjs.com/package/next-auth
- 2: https://next-auth.js.org/getting-started/upgrade-v4
- 3: https://cloudsmith.com/navigator/npm/next-auth
- 4: Fix: React 19 & Next.js 15 Compatibility Issue: "Cannot read properties of null (reading 'useState')" nextauthjs/next-auth#12757
- 5: https://next-auth.js.org
- 6: https://www.youtube.com/watch?v=D2f_gN1uZbc
- 7: https://next-auth.js.org/faq
- 8: https://github.com/nextauthjs/next-auth/releases
- 9: https://www.legitsecurity.com/blog/next-js-vulnerability-what-you-need-to-know
- 10: Is next-auth compatible with NextJS Edge Runtime ? nextauthjs/next-auth#5855
Incompatible next-auth v4.24.11 with Next.js 15.2.x – action required
Based on community reports and the upstream issue tracker, next-auth v4.24.11 is not yet compatible with React 19/Next.js 15.x. Users combining these versions encounter runtime errors (invalid hook calls in SessionProvider and related components).
Please address this before merging:
- Either downgrade your Next.js/React stack to Next.js 14 / React 18 to stay on a supported path for next-auth 4.24.11
- Or postpone upgrading to Next.js 15 until next-auth publishes an official patch for React 19 compatibility
- As an alternative, evaluate other authentication libraries with explicit Next.js 15 support
| }, 1500); | ||
| }; | ||
|
|
||
| if(isLoading) return; |
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.
🛠️ Refactor suggestion
Improve loading state handling.
The current implementation returns undefined when isLoading is true, which could cause React warnings. Consider returning a loading indicator or an empty fragment.
- if(isLoading) return;
+ if(isLoading) return <div className="flex h-screen items-center justify-center">Loading...</div>;📝 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.
| if(isLoading) return; | |
| // … | |
| - if(isLoading) return; | |
| + if (isLoading) return <div className="flex h-screen items-center justify-center">Loading...</div>; | |
| // … |
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.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/ui/package.json (1)
27-27: Document build changes in package docs
With the shift from inline CLI flags to a standalonetsup.config.ts, update any relevant documentation (e.g.,packages/ui/README.md) to describe how the build is now configured and where to adjust formats, output path, or cleaning behavior. This will help onboard new contributors and avoid confusion.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/ui/package.json(1 hunks)packages/ui/tsup.config.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/ui/tsup.config.ts
🔇 Additional comments (1)
packages/ui/package.json (1)
27-27:Details
❓ Verification inconclusive
Verify tsup configuration alignment
Since the explicit CLI flags (--format,--out-dir,--clean) were removed from thebuildscript, ensure thatpackages/ui/tsup.config.tsfully defines these settings (formats, output directory, clean behavior). Otherwise, tsup’s defaults may not match expectations.You can run a quick check:
🏁 Script executed:
#!/bin/bash # Check that tsup.config.ts specifies both esm and cjs formats rg -Hn "format\s*:" packages/ui/tsup.config.tsLength of output: 103
🏁 Script executed:
#!/bin/bash # Verify that tsup.config.ts specifies outDir and clean behavior rg -HnE "outDir\s*:" packages/ui/tsup.config.ts || echo "No outDir found in tsup.config.ts" rg -HnE "clean\s*:" packages/ui/tsup.config.ts || echo "No clean option found in tsup.config.ts"Length of output: 359
🏁 Script executed:
#!/bin/bash # Properly search for outDir and clean options in tsup.config.ts rg -Hn "outDir" packages/ui/tsup.config.ts || echo "No outDir found in tsup.config.ts" rg -Hn "clean" packages/ui/tsup.config.ts || echo "No clean option found in tsup.config.ts"Length of output: 205
Confirm tsup
outDirbehavior
Thetsup.config.tsalready specifies the formats (["cjs","esm"]) andclean: true, but does not set anoutDir. As a result, tsup will emit to its defaultdistfolder.Please verify that using
distis intentional. If you need a custom output directory, add anoutDirfield in packages/ui/tsup.config.ts:export default defineConfig({ entry: ["src/**/*.{ts,tsx}"], format: ["cjs", "esm"], dts: true, clean: true, outDir: "your-desired-dir", // e.g. "build" or "lib" });
Summary by CodeRabbit
New Features
Improvements
Chores