Spaces:
Runtime error
Runtime error
| const express = require('express'); | |
| const passport = require('passport'); | |
| const User = require('../models/User'); | |
| const router = express.Router(); | |
| // --- LOCAL AUTHENTICATION --- | |
| // Register with username/password | |
| router.post('/register', async (req, res) => { | |
| try { | |
| const { email, username, password } = req.body; | |
| const existingUser = await User.findOne({ email: email.toLowerCase() }); | |
| if (existingUser) { | |
| return res.status(400).json({ message: 'Email already registered' }); | |
| } | |
| const user = await User.create({ | |
| email: email.toLowerCase(), | |
| username, | |
| password, | |
| }); | |
| req.login(user, (err) => { | |
| if (err) { | |
| return res.status(500).json({ message: 'Error logging in after registration' }); | |
| } | |
| res.status(201).json({ | |
| user: { | |
| id: user._id, | |
| email: user.email, | |
| username: user.username, | |
| avatar: user.avatar, | |
| }, | |
| }); | |
| }); | |
| } catch (error) { | |
| res.status(500).json({ message: 'Server error', error: error.message }); | |
| } | |
| }); | |
| // Login with username/password | |
| router.post('/login', (req, res, next) => { | |
| passport.authenticate('local', (err, user, info) => { | |
| if (err) { | |
| return res.status(500).json({ message: 'Server error' }); | |
| } | |
| if (!user) { | |
| return res.status(401).json({ message: info.message || 'Invalid credentials' }); | |
| } | |
| req.login(user, (err) => { | |
| if (err) { | |
| return res.status(500).json({ message: 'Error logging in' }); | |
| } | |
| res.json({ | |
| user: { | |
| id: user._id, | |
| email: user.email, | |
| username: user.username, | |
| avatar: user.avatar, | |
| }, | |
| }); | |
| }); | |
| })(req, res, next); | |
| }); | |
| // --- GOOGLE OAUTH ROUTES --- | |
| // 1. Trigger Route - Starts the flow | |
| // URL: /api/auth/google | |
| router.get('/google', (req, res, next) => { | |
| console.log('>>> Google Auth Trigger Route Hit'); | |
| passport.authenticate('google', { | |
| scope: ['profile', 'email'], | |
| prompt: 'select_account' | |
| })(req, res, next); | |
| }); | |
| // 2. Callback Route - Google sends the user back here | |
| // URL: /api/auth/google/callback | |
| router.get('/google/callback', (req, res, next) => { | |
| console.log('>>> GOOGLE CALLBACK HIT: Processing code...'); | |
| passport.authenticate('google', (err, user, info) => { | |
| // ERROR HANDLING | |
| if (err) { | |
| console.error('>>> AUTH ERROR:', err); | |
| if (err.message && err.message.includes('timed out')) { | |
| console.error('!!! CRITICAL: Database Timeout. CHECK ATLAS IP WHITELIST (0.0.0.0/0) !!!'); | |
| } | |
| // Redirect to Vercel frontend with error | |
| return res.redirect(`${process.env.FRONTEND_URL}/login?error=${encodeURIComponent(err.message)}`); | |
| } | |
| // NO USER FOUND | |
| if (!user) { | |
| console.error('>>> NO USER RETURNED:', info); | |
| return res.redirect(`${process.env.FRONTEND_URL}/login?error=auth_failed`); | |
| } | |
| // LOGIN SUCCESS | |
| console.log(`>>> USER FOUND: ${user.email}. Logging in session...`); | |
| req.logIn(user, (err) => { | |
| if (err) { | |
| console.error('>>> SESSION LOGIN ERROR:', err); | |
| return res.redirect(`${process.env.FRONTEND_URL}/login?error=session_error`); | |
| } | |
| // SAVE SESSION EXPLICITLY | |
| // This ensures the cookie is written before we redirect | |
| req.session.save((err) => { | |
| if (err) { | |
| console.error('>>> SESSION SAVE ERROR:', err); | |
| return res.redirect(`${process.env.FRONTEND_URL}/login?error=save_error`); | |
| } | |
| console.log('>>> SESSION SAVED SUCCESSFULLY'); | |
| console.log('>>> Session ID:', req.sessionID); | |
| console.log('>>> REDIRECTING TO DASHBOARD'); | |
| // CORRECTION: Redirect directly to Dashboard, not root ("/") | |
| // This ensures the user sees the internal app immediately. | |
| res.redirect(`${process.env.FRONTEND_URL}/dashboard`); | |
| }); | |
| }); | |
| })(req, res, next); | |
| }); | |
| // --- UTILITY ROUTES --- | |
| // Logout | |
| router.post('/logout', (req, res) => { | |
| req.logout((err) => { | |
| if (err) { | |
| return res.status(500).json({ message: 'Error logging out' }); | |
| } | |
| req.session.destroy(); | |
| res.json({ message: 'Logged out successfully' }); | |
| }); | |
| }); | |
| // Get current user (Used by Frontend to check login status) | |
| router.get('/me', (req, res) => { | |
| console.log('>>> /me endpoint hit. Authenticated:', req.isAuthenticated()); | |
| if (req.isAuthenticated()) { | |
| res.json({ | |
| user: { | |
| id: req.user._id, | |
| email: req.user.email, | |
| username: req.user.username, | |
| avatar: req.user.avatar, | |
| }, | |
| }); | |
| } else { | |
| // Return 401 so frontend knows to show "Login" button | |
| res.status(401).json({ message: 'Not authenticated' }); | |
| } | |
| }); | |
| // Debug session endpoint (Useful for checking if cookies are working) | |
| router.get('/check-session', (req, res) => { | |
| res.json({ | |
| authenticated: req.isAuthenticated(), | |
| sessionID: req.sessionID, | |
| user: req.user || null, | |
| cookie: req.session.cookie | |
| }); | |
| }); | |
| module.exports = router; |