From da921f870a3f927b465d84712f4e0e2e8a4e34b8 Mon Sep 17 00:00:00 2001 From: Chandresh Kerkar Date: Sun, 21 Dec 2025 15:09:21 +0530 Subject: [PATCH] Latest code --- src/routes/authRoutes.js | 74 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/src/routes/authRoutes.js b/src/routes/authRoutes.js index 9c21521..cc73fb4 100644 --- a/src/routes/authRoutes.js +++ b/src/routes/authRoutes.js @@ -1188,16 +1188,27 @@ router.post( // Endpoint for other services (like BuySellService) to validate JWT tokens // This allows centralized token validation router.post('/validate-token', async (req, res) => { + const clientIp = req.ip || req.headers['x-forwarded-for']?.split(',')[0]?.trim() || req.headers['x-real-ip'] || 'unknown'; + const userAgent = req.headers['user-agent'] || 'unknown'; + + console.log(`[Auth Service] POST /auth/validate-token - Request received`); + console.log(`[Auth Service] Client IP: ${clientIp}`); + console.log(`[Auth Service] User-Agent: ${userAgent.substring(0, 80)}`); + console.log(`[Auth Service] Request body contains token: ${!!req.body?.token}`); + try { const { token } = req.body; if (!token) { + console.log(`[Auth Service] ❌ FAILED: Token is missing in request body`); return res.status(400).json({ valid: false, error: 'Token is required' }); } + console.log(`[Auth Service] Token received (length: ${token.length} characters)`); + // Use the auth middleware logic to validate token const jwt = require('jsonwebtoken'); const { getKeySecret, getAllKeys, validateTokenClaims } = require('../services/jwtKeys'); @@ -1208,9 +1219,17 @@ router.post('/validate-token', async (req, res) => { try { decoded = jwt.decode(token, { complete: true }); if (!decoded || !decoded.header) { + console.log(`[Auth Service] ❌ FAILED: Invalid token format - unable to decode header`); return res.json({ valid: false, error: 'Invalid token format' }); } + console.log(`[Auth Service] Token decoded successfully`); + console.log(`[Auth Service] Token header:`, { + alg: decoded.header.alg, + kid: decoded.header.kid || 'NOT SET', + typ: decoded.header.typ, + }); } catch (err) { + console.log(`[Auth Service] ❌ FAILED: Error decoding token - ${err.message}`); return res.json({ valid: false, error: 'Invalid token' }); } @@ -1218,44 +1237,75 @@ router.post('/validate-token', async (req, res) => { const keyId = decoded.header.kid; let payload = null; let verified = false; + let verificationMethod = null; if (keyId) { + console.log(`[Auth Service] Key ID found in token: ${keyId}`); const secret = getKeySecret(keyId); if (secret) { + console.log(`[Auth Service] Attempting verification with key ID: ${keyId}`); try { payload = jwt.verify(token, secret); verified = true; + verificationMethod = `keyId: ${keyId}`; + console.log(`[Auth Service] ✅ Token verified successfully using key ID: ${keyId}`); } catch (err) { + console.log(`[Auth Service] ❌ Verification failed with key ID ${keyId}: ${err.message}`); return res.json({ valid: false, error: 'Invalid or expired token' }); } + } else { + console.log(`[Auth Service] ⚠️ Key ID ${keyId} not found in available keys, will try all keys`); } + } else { + console.log(`[Auth Service] ⚠️ No key ID in token header, trying all available keys`); } // If key ID not found or not specified, try all keys (for rotation support) if (!verified) { const allKeys = getAllKeys(); + console.log(`[Auth Service] Attempting verification with ${Object.keys(allKeys).length} available keys`); for (const [kid, keySecret] of Object.entries(allKeys)) { try { payload = jwt.verify(token, keySecret); verified = true; + verificationMethod = `allKeys: ${kid}`; + console.log(`[Auth Service] ✅ Token verified successfully using key: ${kid}`); break; } catch (err) { + // Try next key silently continue; } } + if (!verified) { + console.log(`[Auth Service] ❌ FAILED: Token verification failed with all available keys`); + } } if (!verified || !payload) { + console.log(`[Auth Service] ❌ FINAL RESULT: Token is invalid or expired`); return res.json({ valid: false, error: 'Invalid or expired token' }); } + console.log(`[Auth Service] Token payload extracted:`, { + userId: payload.sub, + role: payload.role, + userType: payload.user_type, + exp: payload.exp ? new Date(payload.exp * 1000).toISOString() : 'NOT SET', + iat: payload.iat ? new Date(payload.iat * 1000).toISOString() : 'NOT SET', + tokenVersion: payload.token_version || 1, + }); + // Validate JWT claims (iss, aud, exp, iat, nbf) + console.log(`[Auth Service] Validating JWT claims...`); const claimsValidation = validateTokenClaims(payload); if (!claimsValidation.valid) { + console.log(`[Auth Service] ❌ FAILED: Claims validation failed - ${claimsValidation.reason}`); return res.json({ valid: false, error: 'Invalid token claims' }); } + console.log(`[Auth Service] ✅ Claims validation passed`); // Validate token_version to ensure token hasn't been invalidated by logout-all-devices + console.log(`[Auth Service] Checking token version in database for user: ${payload.sub}`); try { const { rows } = await db.query( `SELECT COALESCE(token_version, 1) as token_version FROM users WHERE id = $1`, @@ -1263,28 +1313,45 @@ router.post('/validate-token', async (req, res) => { ); if (rows.length === 0) { + console.log(`[Auth Service] ❌ FAILED: User not found in database: ${payload.sub}`); return res.json({ valid: false, error: 'User not found' }); } const userTokenVersion = rows[0].token_version; const tokenVersion = payload.token_version || 1; + console.log(`[Auth Service] Token version check:`, { + tokenVersion, + userTokenVersion, + match: tokenVersion === userTokenVersion, + }); + // If token version doesn't match, token has been invalidated if (tokenVersion !== userTokenVersion) { + console.log(`[Auth Service] ❌ FAILED: Token version mismatch - token has been invalidated`); return res.json({ valid: false, error: 'Token has been invalidated' }); } + console.log(`[Auth Service] ✅ Token version check passed`); } catch (dbErr) { // Handle missing token_version column gracefully if (dbErr.code === '42703' && dbErr.message && dbErr.message.includes('token_version')) { - console.warn('token_version column not found in database, skipping version check'); + console.warn('[Auth Service] ⚠️ token_version column not found in database, skipping version check'); // Continue without token version validation } else { - console.error('Error validating token version:', dbErr); + console.error('[Auth Service] ❌ Error validating token version:', dbErr); return res.status(500).json({ valid: false, error: 'Internal server error' }); } } // Token is valid - return user info + console.log(`[Auth Service] ✅ FINAL RESULT: Token is VALID`); + console.log(`[Auth Service] Returning user info:`, { + userId: payload.sub, + role: payload.role, + userType: payload.user_type, + verificationMethod, + }); + return res.json({ valid: true, payload: { @@ -1297,7 +1364,8 @@ router.post('/validate-token', async (req, res) => { }, }); } catch (err) { - console.error('validate-token error:', err); + console.error('[Auth Service] ❌ UNEXPECTED ERROR in validate-token:', err); + console.error('[Auth Service] Error stack:', err.stack); return res.status(500).json({ valid: false, error: 'Internal server error' }); } });