← back to Professional Directory

agents/api-agent/routes/auth.js

62 lines

/**
 * /auth/* routes — Google OAuth login, logout, /whoami.
 *
 * Mounted in agents/api-agent/server.js after session middleware.
 */
const express = require('express');
const { passport, authConfigured } = require('../auth');

const router = express.Router();

// Google OAuth start.
router.get('/google', (req, res, next) => {
  if (!authConfigured()) return res.status(503).json({ error: 'Google OAuth not configured (set GOOGLE_OAUTH_CLIENT_ID / SECRET)' });
  // Passport reads `returnTo` and bounces back here after callback.
  // SECURITY: `/foo` is OK; `//evil.com/x` is NOT — that's an open-redirect
  // (browser treats it as protocol-relative, sends user off-site).
  const returnTo = String(req.query.returnTo || '/');
  req.session.returnTo = /^\/(?!\/)/.test(returnTo) ? returnTo : '/';
  passport.authenticate('google', { scope: ['email', 'profile'] })(req, res, next);
});

// Google OAuth callback — passport completes session login here.
router.get('/google/callback',
  (req, res, next) => {
    if (!authConfigured()) return res.status(503).json({ error: 'Google OAuth not configured' });
    next();
  },
  passport.authenticate('google', { failureRedirect: '/auth/google?failed=1' }),
  (req, res) => {
    const target = req.session.returnTo || '/';
    delete req.session.returnTo;
    res.redirect(target);
  });

router.post('/logout', (req, res, next) => {
  req.logout(err => {
    if (err) return next(err);
    req.session.destroy(() => res.json({ ok: true }));
  });
});

// JSON identity endpoint — returns session user or null.
router.get('/whoami', (req, res) => {
  if (!req.user) return res.json({ user: null });
  const u = req.user;
  res.json({
    user: {
      id: u.id,
      email: u.email,
      role: u.role,
      tier: u.tier,
      display_name: u.display_name,
      avatar_url: u.avatar_url,
      claimed_professional_id: u.claimed_professional_id,
      claimed_organization_id: u.claimed_organization_id,
      synthetic: !!u._synthetic,
    },
  });
});

module.exports = router;