import type { NextAuthConfig } from 'next-auth' import type { UserRole } from '@prisma/client' type ImpersonationInfo = { originalId: string originalRole: UserRole originalRoles: UserRole[] originalEmail: string } // Extend the built-in session types declare module 'next-auth' { interface Session { user: { id: string email: string name?: string | null role: UserRole roles: UserRole[] mustSetPassword?: boolean impersonating?: ImpersonationInfo } } interface User { role?: UserRole roles?: UserRole[] mustSetPassword?: boolean } } declare module '@auth/core/jwt' { interface JWT { id: string role: UserRole roles?: UserRole[] mustSetPassword?: boolean impersonating?: ImpersonationInfo } } // Edge-compatible auth config (no Node.js-only modules) // This is used by middleware and can be extended in auth.ts for full functionality export const authConfig: NextAuthConfig = { providers: [], // Providers are added in auth.ts callbacks: { authorized({ auth, request: { nextUrl } }) { const isLoggedIn = !!auth?.user const { pathname } = nextUrl // Public paths that don't require authentication const publicPaths = [ '/login', '/verify', '/verify-email', '/error', '/accept-invite', '/forgot-password', '/reset-password', '/apply', '/api/auth', '/api/trpc', // tRPC handles its own auth via procedures ] // Check if it's a public path if (publicPaths.some((path) => pathname.startsWith(path))) { return true } // If not logged in, redirect to login if (!isLoggedIn) { return false // Will redirect to signIn page } // Check if user needs to set password (skip during impersonation) const mustSetPassword = auth?.user?.mustSetPassword const isImpersonating = !!(auth?.user as Record)?.impersonating const passwordSetupAllowedPaths = [ '/set-password', '/api/auth', '/api/trpc', ] if (mustSetPassword && !isImpersonating) { // Allow access to password setup related paths if (passwordSetupAllowedPaths.some((path) => pathname.startsWith(path))) { return true } // Redirect to set-password page return Response.redirect(new URL('/set-password', nextUrl)) } return true }, }, pages: { signIn: '/login', verifyRequest: '/verify-email', error: '/error', newUser: '/set-password', }, session: { strategy: 'jwt', maxAge: parseInt(process.env.SESSION_MAX_AGE || '86400'), // 24 hours }, }