const express = require('express'); const router = express.Router(); /** * Página simples de login */ router.get('/login', (req, res) => { res.send(`

Login necessário

Entrar com Microsoft `); }); /** * Inicia login Microsoft */ router.get('/auth/microsoft', (req, res) => { const params = new URLSearchParams({ client_id: process.env.OAUTH_CLIENT_ID, response_type: 'code', redirect_uri: process.env.OAUTH_REDIRECT_URI, response_mode: 'query', scope: 'openid profile email', }); res.redirect( `https://login.microsoftonline.com/${process.env.OAUTH_TENANT_ID}/oauth2/v2.0/authorize?${params}` ); }); /** * Callback do Azure */ router.get('/auth/microsoft/callback', async (req, res) => { const code = req.query.code; // Verbose logging for debugging the OAuth callback flow console.log('[OAuth callback] incoming query:', { code: req.query.code ? '[present]' : '[absent]', state: req.query.state, error: req.query.error, error_description: req.query.error_description ? '[present]' : undefined, }); if (!code) { console.warn('[OAuth callback] no authorization code present, redirecting to /login'); return res.redirect('/login'); } try { console.log('[OAuth callback] exchanging code for tokens (will not log secrets)'); const tokenRespRaw = await fetch( `https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}/oauth2/v2.0/token`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ client_id: process.env.OAUTH_CLIENT_ID, client_secret: process.env.OAUTH_CLIENT_SECRET, grant_type: 'authorization_code', code, redirect_uri: process.env.OAUTH_REDIRECT_URI, }), } ); console.log('[OAuth callback] token endpoint HTTP status:', tokenRespRaw.status); const tokenResp = await tokenRespRaw.json(); // Log token response keys but never print tokens or client secret console.log('[OAuth callback] token response keys:', Object.keys(tokenResp)); if (tokenResp.error) { console.error('[OAuth callback] token endpoint returned error:', tokenResp.error, tokenResp.error_description || ''); return res.redirect('/login'); } if (!tokenResp.id_token) { console.warn('[OAuth callback] No id_token received — token response:', Object.keys(tokenResp)); } // decodificar id_token (JWT) com cuidado — não logar o token inteiro let payload = {}; try { const parts = (tokenResp.id_token || '').split('.'); if (parts.length >= 2) { payload = JSON.parse(Buffer.from(parts[1], 'base64').toString()); } else { console.warn('[OAuth callback] id_token malformed'); } } catch (e) { console.error('[OAuth callback] failed to decode id_token payload:', e && (e.message || e)); } // Log a few safe user-identifying fields console.log('[OAuth callback] id_token payload (safe fields):', { name: payload.name, preferred_username: payload.preferred_username || payload.upn || payload.email, oid: payload.oid, }); // salva sessão req.session.user = { authenticated: true, email: payload.preferred_username, name: payload.name, oid: payload.oid, }; console.log('[OAuth callback] session created for user:', req.session.user && { email: req.session.user.email, name: req.session.user.name }); res.redirect('/'); } catch (err) { console.error('[OAuth callback] unexpected error during token exchange or session creation:', err && (err.stack || err.message || err)); res.redirect('/login'); } }); router.get('/logout', (req, res) => { req.session.destroy(() => res.redirect('/login')); }); module.exports = router;