Skip to content

Authentication

Production Ready

Google OAuth 2.0 authentication is fully implemented with JWT session management and email domain restrictions.

Production Authentication

Google OAuth 2.0

Authentication Flow:

  1. User visits https://os.supershyft.capital and clicks "Sign in with Google"
  2. API redirects to /api/auth/google which initiates OAuth flow
  3. User authenticates with Google OAuth consent screen
  4. Google redirects back with authorization code
  5. API validates email domain (@capcoib.com or louis.decuypere@gmail.com)
  6. API creates JWT session token (7-day expiry)
  7. Sets HttpOnly session cookie (supershyft_session)
  8. Redirects user to /home
  9. Subsequent requests include session cookie for authentication

API Endpoints:

  • GET /api/auth/google - Initiates OAuth flow & handles callback
  • POST /api/auth/logout - Clears session cookie
  • GET /api/auth/me - Returns authenticated user info
  • GET /api/auth/status - Health check for auth system

JWT Payload:

json
{
  "sub": "google_123456789",
  "email": "louis.decuypere@gmail.com",
  "name": "Louis De Cuypere",
  "picture": "https://...",
  "iat": 1642000000,
  "exp": 1642604800
}

Backend Middleware:

typescript
// apps/api-worker/src/middleware/auth.ts
export async function authMiddleware(c: Context, next: Next) {
  // Production: Extract from session cookie
  const sessionCookie = getCookie(c, 'supershyft_session');
  if (sessionCookie) {
    const payload = await jwt.verify(sessionCookie, c.env.JWT_SECRET);
    c.set('userEmail', payload.email);
    c.set('user', payload);
  }
  // Dev: Fall back to X-User-Email header
  else {
    const devEmail = c.req.header('X-User-Email');
    if (devEmail) c.set('userEmail', devEmail);
  }
  await next();
}

Email Domain Restrictions

Only the following email domains are allowed:

  • @capcoib.com - Team members
  • louis.decuypere@gmail.com - Specific allowlist

Attempts to authenticate with other emails will be rejected with a 403 error.

Session Management

Session Cookies:

  • Cookie name: supershyft_session
  • Duration: 7 days
  • HttpOnly: Yes (not accessible via JavaScript)
  • SameSite: Lax (CSRF protection)
  • Secure: Yes in production (HTTPS only)

Logout:

typescript
// POST /api/auth/logout
fetch('/api/auth/logout', { method: 'POST' })
  .then(() => window.location.href = '/')

Dev Mode (Local Development)

User Selection

For local development, frontend provides user selector with test accounts:

Stored in localStorage: supershyft_dev_user_email

API Requests

Frontend sends X-User-Email header on dev requests:

typescript
fetch('/api/companies', {
  headers: {
    'X-User-Email': localStorage.getItem('supershyft_dev_user_email')
  }
})

Enabling Dev Mode

  1. Click "Dev Mode" button in top-right header
  2. Select a user or enter custom email
  3. All API requests will use X-User-Email header
  4. No OAuth flow required

Setup Guide

Complete OAuth setup instructions: GOOGLE_OAUTH_SETUP.md

Required Environment Variables:

bash
# .dev.vars (local)
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
FRONTEND_URL=http://localhost:5173
JWT_SECRET=random-32-byte-secret

# Production (set via wrangler secret put)
wrangler secret put GOOGLE_CLIENT_ID
wrangler secret put GOOGLE_CLIENT_SECRET
wrangler secret put JWT_SECRET

Security

Current Implementation:

  • ✅ JWT session tokens signed with secret
  • ✅ HttpOnly cookies (XSS protection)
  • ✅ Email domain restrictions
  • ✅ HTTPS enforced in production
  • ✅ CORS restricted to whitelisted origins
  • ✅ Rate limiting on all routes
  • ✅ Automatic user creation on first login
  • ✅ 7-day session expiry

Security Headers:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • X-XSS-Protection: 1; mode=block
  • Referrer-Policy: strict-origin-when-cross-origin
  • Strict-Transport-Security: max-age=31536000 (production)

Rate Limiting:

  • High-frequency routes: 100 req/min
  • AI operations: 50 req/min
  • Bulk actions: 5 req/min

Troubleshooting

"Unauthorized" errors

  • Check session cookie is present in browser DevTools
  • Verify JWT_SECRET is set correctly
  • Check cookie hasn't expired (7 days)
  • Try logging out and back in

OAuth redirect fails

  • Verify FRONTEND_URL matches your frontend URL
  • Check Google OAuth redirect URIs in Google Cloud Console
  • Ensure GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set

Email not allowed

  • Only @capcoib.com and louis.decuypere@gmail.com are allowed
  • Contact admin to add your email domain

Dev mode not working

  • Check X-User-Email header is being sent
  • Verify localStorage has supershyft_dev_user_email set
  • Ensure API worker is running locally

Built for Supershyft Capital