Add Google OAuth authentication system #4

Merged
stephen merged 6 commits from dev into main 2026-01-21 19:15:22 -07:00
Owner

Summary

  • Implement complete Google OAuth 2.0 authentication with Passport.js
  • Add JWT tokens stored in HTTP-only cookies with sliding window refresh
  • Create user activity logging system for tracking auth events
  • Add security hardening (OAuth state validation, input sanitization)
  • Fix timezone handling for date-based queries

Changes

Authentication Infrastructure

  • Passport.js Google OAuth strategy with safe profile extraction
  • JWT middleware with 7-day expiry and 1-day refresh threshold
  • User model with findOrCreate upsert pattern
  • Auth routes for login, logout, callback, and status check

Activity Logging

  • Activity logger service with configurable log levels
  • TTL indexes for automatic cleanup of old logs
  • Tracks LOGIN, LOGOUT, and other auth events

Security

  • OAuth state parameter validation (CSRF protection)
  • Input validation for unit codes (prevent NoSQL injection)
  • Environment variable validation at startup
  • .dockerignore to prevent secrets in images

Bug Fixes

  • Fix timezone mismatch: use latest database date instead of UTC
  • Fix OAuth profile field access for Google callback
  • Fix MongoDB conflict error with loginCount field

Test plan

  • Google OAuth login flow works end-to-end
  • JWT cookie is set with correct flags (httpOnly, secure, sameSite)
  • Protected endpoints return 401 without valid token
  • User data persists across sessions
  • Activity logging captures login/logout events
  • Data loads correctly regardless of server timezone
## Summary - Implement complete Google OAuth 2.0 authentication with Passport.js - Add JWT tokens stored in HTTP-only cookies with sliding window refresh - Create user activity logging system for tracking auth events - Add security hardening (OAuth state validation, input sanitization) - Fix timezone handling for date-based queries ## Changes ### Authentication Infrastructure - Passport.js Google OAuth strategy with safe profile extraction - JWT middleware with 7-day expiry and 1-day refresh threshold - User model with findOrCreate upsert pattern - Auth routes for login, logout, callback, and status check ### Activity Logging - Activity logger service with configurable log levels - TTL indexes for automatic cleanup of old logs - Tracks LOGIN, LOGOUT, and other auth events ### Security - OAuth state parameter validation (CSRF protection) - Input validation for unit codes (prevent NoSQL injection) - Environment variable validation at startup - .dockerignore to prevent secrets in images ### Bug Fixes - Fix timezone mismatch: use latest database date instead of UTC - Fix OAuth profile field access for Google callback - Fix MongoDB conflict error with loginCount field ## Test plan - [x] Google OAuth login flow works end-to-end - [x] JWT cookie is set with correct flags (httpOnly, secure, sameSite) - [x] Protected endpoints return 401 without valid token - [x] User data persists across sessions - [x] Activity logging captures login/logout events - [x] Data loads correctly regardless of server timezone
stephen added 6 commits 2026-01-21 18:59:48 -07:00
- Add passport, passport-google-oauth20, jsonwebtoken, cookie-parser, uuid deps
- Create config/auth.js with JWT, cookie, and OAuth configuration
- Create models/user.js with MongoDB user model and indexes
- Create middleware/passport.js with Google OAuth strategy
- Create middleware/auth.js with requireAuth middleware and sliding window refresh
- Create routes/auth.js with OAuth flow endpoints
- Update server.js to integrate auth, protect all data endpoints (except /health)
- Configure CORS for cookie-based authentication
- Create services/activityLogger.js with configurable log levels (all, navigation, none)
- Create routes/activity.js with endpoints for logging and admin statistics
- Integrate login/logout activity logging into auth routes
- Add TTL index for automatic 90-day cleanup of activity records
- Mount activity routes at /activity
Security fixes:
- Remove hardcoded MongoDB credentials from server.js (fail fast in production)
- Add OAuth state parameter validation for CSRF protection
- Add input validation for unitCode parameter to prevent NoSQL injection
- Add isValidUnitCode helper function

Deployment:
- Update docker-compose.yml to use env_file and environment variables
- Create .env.example with all required configuration variables
- Add getLatestDateWithData() helper that queries the most recent date
  with price data instead of using server UTC time
- Cache latest date for 5 minutes to reduce database queries
- Update all date-dependent endpoints to use database-relative dates
- Fix OAuth callback profile field access (use profile.email instead
  of profile.emails[0].value)
- Remove loginCount from $setOnInsert to avoid MongoDB conflict error
stephen merged commit ef4ddc0de0 into main 2026-01-21 19:15:22 -07:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: stephen/apartment-dashboard-api#4
No description provided.