diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index 5186356..45d3401 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -89,9 +89,60 @@ const authOptions = { } }; -// Create a handler with the auth options -const handler = NextAuth(authOptions); +// Wrap NextAuth in a try-catch block to catch initialization errors +let handler; +try { + handler = NextAuth(authOptions); + console.log("NextAuth handler initialized successfully"); +} catch (error) { + console.error("CRITICAL ERROR: NextAuth initialization failed:", error); + // Create a fallback handler that logs the error and returns a 500 + const errorHandler = { + GET: async (req: Request) => { + console.error("NextAuth GET error handler triggered for URL:", req.url); + return new Response( + JSON.stringify({ + error: "Auth system initialization failed", + message: "Check server logs" + }), + { status: 500, headers: { "Content-Type": "application/json" } } + ); + }, + POST: async (req: Request) => { + console.error("NextAuth POST error handler triggered for URL:", req.url); + return new Response( + JSON.stringify({ + error: "Auth system initialization failed", + message: "Check server logs" + }), + { status: 500, headers: { "Content-Type": "application/json" } } + ); + } + }; + handler = { handlers: errorHandler }; +} -// Export the handler functions -export const GET = handler.handlers.GET; -export const POST = handler.handlers.POST; \ No newline at end of file +// Export handlers with additional error handling +export async function GET(req: Request) { + try { + return await handler.handlers.GET(req); + } catch (error) { + console.error("NextAuth GET error:", error); + return new Response( + JSON.stringify({ error: "Auth operation failed", details: String(error) }), + { status: 500, headers: { "Content-Type": "application/json" } } + ); + } +} + +export async function POST(req: Request) { + try { + return await handler.handlers.POST(req); + } catch (error) { + console.error("NextAuth POST error:", error); + return new Response( + JSON.stringify({ error: "Auth operation failed", details: String(error) }), + { status: 500, headers: { "Content-Type": "application/json" } } + ); + } +} \ No newline at end of file diff --git a/src/app/api/debug/auth-check/route.ts b/src/app/api/debug/auth-check/route.ts new file mode 100644 index 0000000..9a496cf --- /dev/null +++ b/src/app/api/debug/auth-check/route.ts @@ -0,0 +1,52 @@ +import { NextRequest, NextResponse } from 'next/server'; +import crypto from 'crypto'; + +export async function GET(request: NextRequest) { + try { + // Test JWT signing with NEXTAUTH_SECRET + let secretStatus = 'missing'; + let secretSha = 'n/a'; + + if (process.env.NEXTAUTH_SECRET) { + secretStatus = 'available'; + // Only show a hash of the secret for security + secretSha = crypto + .createHash('sha256') + .update(process.env.NEXTAUTH_SECRET) + .digest('hex') + .slice(0, 8); + } + + // Check cookie domains + const cookieDomain = new URL(process.env.NEXTAUTH_URL || `https://${request.headers.get('host')}`).hostname; + + // Get basic auth config info + const authCheck = { + success: true, + auth_config: { + nextauth_url: process.env.NEXTAUTH_URL, + has_secret: !!process.env.NEXTAUTH_SECRET, + secret_status: secretStatus, + secret_hash: secretSha, + google_client_configured: !!process.env.GOOGLE_CLIENT_ID && !!process.env.GOOGLE_CLIENT_SECRET, + }, + cookie_config: { + domain: cookieDomain, + secure: process.env.NODE_ENV === 'production', + host_header: request.headers.get('host'), + }, + version_info: { + node_version: process.version, + next_auth: 'next-auth/latest', + } + }; + + return NextResponse.json(authCheck); + } catch (error) { + console.error('Auth check error:', error); + return NextResponse.json({ + success: false, + error: String(error) + }, { status: 500 }); + } +}; \ No newline at end of file diff --git a/src/app/debug/page.tsx b/src/app/debug/page.tsx index 4887231..ab61ef8 100644 --- a/src/app/debug/page.tsx +++ b/src/app/debug/page.tsx @@ -9,15 +9,32 @@ export default function DebugPage() { const { data: session, status } = useSession(); const [authData, setAuthData] = useState(null); const [serverEnv, setServerEnv] = useState(null); + const [authCheck, setAuthCheck] = useState(null); + const [authError, setAuthError] = useState(null); useEffect(() => { const checkAuth = async () => { try { const res = await fetch('/api/auth/session'); - const data = await res.json(); - setAuthData(data); + if (res.ok) { + const data = await res.json(); + setAuthData(data); + } else { + setAuthError(`Session API error: ${res.status} ${res.statusText}`); + // Try to get error details from body + try { + const errorData = await res.json(); + console.error('Auth session error details:', errorData); + if (errorData.error) { + setAuthError(prev => `${prev} - ${errorData.error}`); + } + } catch (e) { + // Couldn't parse body + } + } } catch (error) { console.error('Error fetching auth session', error); + setAuthError(String(error)); } }; @@ -34,9 +51,24 @@ export default function DebugPage() { console.error('Error fetching server environment:', error); } }; + + const checkAuthConfig = async () => { + try { + const res = await fetch('/api/debug/auth-check'); + if (res.ok) { + const data = await res.json(); + setAuthCheck(data); + } else { + console.error('Failed to fetch auth config check:', res.statusText); + } + } catch (error) { + console.error('Error fetching auth config:', error); + } + }; checkAuth(); checkServerEnv(); + checkAuthConfig(); }, []); // Environment variables check (public variables only) @@ -73,11 +105,23 @@ export default function DebugPage() {

Auth API Response

+ {authError ? ( +
+ {authError} +
+ ) : null}
               {JSON.stringify(authData, null, 2)}
             
+
+

Auth Configuration Check

+
+              {authCheck ? JSON.stringify(authCheck, null, 2) : "Loading auth configuration..."}
+            
+
+

Client Environment Variables