"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jwt = require('jsonwebtoken'); const google_auth_library_1 = require("google-auth-library"); const unifiedDataService_1 = __importDefault(require("./unifiedDataService")); // Simplified authentication service - removes excessive logging and complexity class AuthService { constructor() { this.jwtExpiry = '24h'; // Middleware to check authentication this.requireAuth = async (req, res, next) => { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'Authentication required' }); } const decoded = this.verifyToken(token); if (!decoded) { return res.status(401).json({ error: 'Invalid or expired token' }); } // Get fresh user data const user = await unifiedDataService_1.default.getUserById(decoded.id); if (!user) { return res.status(401).json({ error: 'User not found' }); } req.user = user; next(); }; // Middleware to check role this.requireRole = (roles) => { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: 'Authentication required' }); } if (!roles.includes(req.user.role)) { return res.status(403).json({ error: 'Insufficient permissions' }); } next(); }; }; // Auto-generate a secure JWT secret if not provided if (process.env.JWT_SECRET) { this.jwtSecret = process.env.JWT_SECRET; console.log('Using JWT_SECRET from environment'); } else { // Generate a cryptographically secure random secret const crypto = require('crypto'); this.jwtSecret = crypto.randomBytes(64).toString('hex'); console.log('Generated new JWT_SECRET (this will change on restart)'); console.log('To persist sessions across restarts, set JWT_SECRET in .env'); } // Initialize Google OAuth client this.googleClient = new google_auth_library_1.OAuth2Client(process.env.GOOGLE_CLIENT_ID); } // Generate JWT token generateToken(user) { const payload = { id: user.id, email: user.email, role: user.role }; return jwt.sign(payload, this.jwtSecret, { expiresIn: this.jwtExpiry }); } // Verify Google ID token from frontend async verifyGoogleToken(credential) { try { // Verify the token with Google const ticket = await this.googleClient.verifyIdToken({ idToken: credential, audience: process.env.GOOGLE_CLIENT_ID, }); const payload = ticket.getPayload(); if (!payload || !payload.email) { throw new Error('Invalid token payload'); } // Find or create user let user = await unifiedDataService_1.default.getUserByEmail(payload.email); if (!user) { // Auto-create user with coordinator role user = await unifiedDataService_1.default.createUser({ email: payload.email, name: payload.name || payload.email, role: 'coordinator', googleId: payload.sub }); } // Generate our JWT const token = this.generateToken(user); return { user, token }; } catch (error) { console.error('Token verification error:', error); throw new Error('Failed to verify Google token'); } } // Verify JWT token verifyToken(token) { try { return jwt.verify(token, this.jwtSecret); } catch (error) { return null; } } // Google OAuth helpers getGoogleAuthUrl() { if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_REDIRECT_URI) { throw new Error('Google OAuth not configured. Please set GOOGLE_CLIENT_ID and GOOGLE_REDIRECT_URI in .env file'); } const params = new URLSearchParams({ client_id: process.env.GOOGLE_CLIENT_ID, redirect_uri: process.env.GOOGLE_REDIRECT_URI, response_type: 'code', scope: 'email profile', access_type: 'offline', prompt: 'consent' }); return `https://accounts.google.com/o/oauth2/v2/auth?${params}`; } async exchangeGoogleCode(code) { const response = await fetch('https://oauth2.googleapis.com/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code, client_id: process.env.GOOGLE_CLIENT_ID, client_secret: process.env.GOOGLE_CLIENT_SECRET, redirect_uri: process.env.GOOGLE_REDIRECT_URI, grant_type: 'authorization_code' }) }); if (!response.ok) { throw new Error('Failed to exchange authorization code'); } return response.json(); } async getGoogleUserInfo(accessToken) { const response = await fetch('https://www.googleapis.com/oauth2/v2/userinfo', { headers: { Authorization: `Bearer ${accessToken}` } }); if (!response.ok) { throw new Error('Failed to get user info'); } return response.json(); } // Simplified login/signup async handleGoogleAuth(code) { // Exchange code for tokens const tokens = await this.exchangeGoogleCode(code); // Get user info const googleUser = await this.getGoogleUserInfo(tokens.access_token); // Find or create user let user = await unifiedDataService_1.default.getUserByEmail(googleUser.email); if (!user) { // Auto-create user with coordinator role user = await unifiedDataService_1.default.createUser({ email: googleUser.email, name: googleUser.name, role: 'coordinator', googleId: googleUser.id }); } // Generate JWT const token = this.generateToken(user); return { user, token }; } } exports.default = new AuthService(); //# sourceMappingURL=authService.js.map