Files
frontend/specs/001-google-oauth-auth/tasks.md
Andre 130f35c4f8 feat: implement Google OAuth authentication
- Add Google OAuth 2.0 login flow with passport-google-oauth20
- Create User and RefreshToken entities for session management
- Implement JWT access tokens (15min) + HttpOnly refresh cookies (7 days)
- Add auth endpoints: /google, /google/callback, /refresh, /me, /logout
- Create LoginPage with Google sign-in button (shadcn/ui)
- Add AuthGuard for protected routes with redirect preservation
- Implement silent token refresh on app mount
- Add UserMenu component with avatar and sign-out

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 13:05:18 -03:00

10 KiB

Tasks: Google OAuth Authentication Screen

Input: Design documents from /specs/001-google-oauth-auth/ Prerequisites: plan.md , spec.md , research.md , data-model.md , contracts/

Tests: Not explicitly requested - manual testing via quickstart.md

Organization: Tasks grouped by user story to enable independent implementation and testing.

Format: [ID] [P?] [Story] Description

  • [P]: Can run in parallel (different files, no dependencies)
  • [Story]: Which user story this task belongs to (e.g., US1, US2, US3)
  • Include exact file paths in descriptions

Path Conventions

  • Web app: backend/src/, frontend/src/

Phase 1: Setup (Shared Infrastructure)

Purpose: Install dependencies and configure project for OAuth authentication

  • T001 Install backend auth dependencies: cd backend && npm install @nestjs/passport @nestjs/jwt passport passport-google-oauth20 bcrypt
  • T002 Install backend auth type definitions: cd backend && npm install -D @types/passport-google-oauth20 @types/bcrypt
  • T003 [P] Add OAuth environment variables template to backend/.env.example (GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CALLBACK_URL, JWT_SECRET, JWT_ACCESS_EXPIRATION, JWT_REFRESH_EXPIRATION, FRONTEND_URL)
  • T004 [P] Update backend/src/app.module.ts to import ConfigModule with .env support
  • T005 Configure CORS in backend/src/main.ts with credentials: true and FRONTEND_URL origin

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Core entities, auth module structure, and database schema that ALL user stories depend on

⚠️ CRITICAL: No user story work can begin until this phase is complete

  • T006 Create User entity in backend/src/entities/user.entity.ts with fields: id (UUID), googleId, email, displayName, avatarUrl, createdAt, lastLoginAt
  • T007 [P] Create RefreshToken entity in backend/src/entities/refresh-token.entity.ts with fields: id (UUID), userId (FK), token, expiresAt, createdAt, revokedAt
  • T008 Register User and RefreshToken entities in backend/src/app.module.ts TypeORM configuration
  • T009 Create auth module scaffold in backend/src/modules/auth/ with auth.module.ts, auth.controller.ts, auth.service.ts
  • T010 [P] Create DTOs in backend/src/modules/auth/dto/: auth-response.dto.ts, user-response.dto.ts
  • T011 [P] Create auth types in frontend/src/types/auth.ts: User interface, AuthState interface
  • T012 Create auth store in frontend/src/store/authStore.ts using Zustand with: user, accessToken, isLoading, setAuth, clearAuth, setLoading
  • T013 [P] Create auth API client in frontend/src/api/auth.ts with axios instance and methods: refreshToken, getMe, logout

Checkpoint: Foundation ready - user story implementation can now begin


Phase 3: User Story 1 - First-Time User Sign In (Priority: P1) 🎯 MVP

Goal: New user can authenticate via Google OAuth and access the tool page

Independent Test: Visit /tool as logged-out user → redirected to login → click "Sign in with Google" → complete Google OAuth → redirected to /tool with active session

Backend Implementation for User Story 1

  • T014 [US1] Implement GoogleStrategy in backend/src/modules/auth/google.strategy.ts using passport-google-oauth20
  • T015 [US1] Implement JwtStrategy in backend/src/modules/auth/jwt.strategy.ts for access token validation
  • T016 [P] [US1] Create GoogleAuthGuard in backend/src/modules/auth/guards/google-auth.guard.ts
  • T017 [P] [US1] Create JwtAuthGuard in backend/src/modules/auth/guards/jwt-auth.guard.ts
  • T018 [US1] Implement AuthService.validateOAuthUser() in backend/src/modules/auth/auth.service.ts - creates/updates user, issues tokens
  • T019 [US1] Implement AuthService.generateTokens() for JWT access token and refresh token generation with bcrypt hashing
  • T020 [US1] Add GET /auth/google route in backend/src/modules/auth/auth.controller.ts with GoogleAuthGuard
  • T021 [US1] Add GET /auth/google/callback route in backend/src/modules/auth/auth.controller.ts - handle OAuth callback, set HttpOnly cookie, redirect to frontend
  • T022 [US1] Add GET /auth/me route in backend/src/modules/auth/auth.controller.ts with JwtAuthGuard
  • T023 [US1] Register AuthModule in backend/src/app.module.ts imports

Frontend Implementation for User Story 1

  • T024 [P] [US1] Create LoginPage component in frontend/src/pages/LoginPage.tsx with "Sign in with Google" button using shadcn/ui Button and Card
  • T025 [P] [US1] Create AuthCallbackPage component in frontend/src/pages/AuthCallbackPage.tsx to handle OAuth callback token from URL
  • T026 [US1] Implement useAuth hook in frontend/src/hooks/useAuth.ts with checkAuth, login redirect, and loading state
  • T027 [US1] Create AuthGuard component in frontend/src/components/AuthGuard.tsx - redirects to /login if not authenticated, preserves intended destination in location.state
  • T028 [US1] Update frontend/src/App.tsx - add /login route, /auth/callback route, wrap /tool with AuthGuard
  • T029 [US1] Handle OAuth errors in LoginPage - display error message from URL params if authentication failed

Checkpoint: User Story 1 complete - new users can sign in via Google and access protected routes


Phase 4: User Story 2 - Returning User Session (Priority: P2)

Goal: Returning user with valid session bypasses login; expired session redirects to login

Independent Test: Sign in → close browser → return within 7 days → automatically access /tool without login prompt

Backend Implementation for User Story 2

  • T030 [US2] Add POST /auth/refresh route in backend/src/modules/auth/auth.controller.ts - validate HttpOnly refresh cookie, rotate token, return new access token
  • T031 [US2] Implement AuthService.refreshTokens() in backend/src/modules/auth/auth.service.ts - validate stored token, check expiry, issue new pair
  • T032 [US2] Implement AuthService.revokeRefreshToken() for token rotation (mark old token as revoked)

Frontend Implementation for User Story 2

  • T033 [US2] Add silent token refresh on app mount in frontend/src/hooks/useAuth.ts - call /auth/refresh on startup
  • T034 [US2] Add Axios response interceptor in frontend/src/api/auth.ts - on 401, attempt refresh, retry original request
  • T035 [US2] Update AuthGuard in frontend/src/components/AuthGuard.tsx - show loading state during session check, then redirect or render

Checkpoint: User Story 2 complete - returning users have seamless session persistence


Phase 5: User Story 3 - User Sign Out (Priority: P3)

Goal: Authenticated user can sign out, which clears session and returns to login

Independent Test: Sign in → click sign out in user menu → redirected to login → cannot access /tool

Backend Implementation for User Story 3

  • T036 [US3] Add POST /auth/logout route in backend/src/modules/auth/auth.controller.ts with JwtAuthGuard - revoke refresh token, clear cookie

Frontend Implementation for User Story 3

  • T037 [P] [US3] Create UserMenu component in frontend/src/components/UserMenu.tsx - display user avatar, name, sign out button using shadcn/ui
  • T038 [US3] Implement logout function in frontend/src/store/authStore.ts - call /auth/logout, clear local state
  • T039 [US3] Add UserMenu to ToolPage header in frontend/src/pages/ToolPage.tsx

Checkpoint: User Story 3 complete - users can sign out securely


Phase 6: Polish & Cross-Cutting Concerns

Purpose: Error handling, edge cases, and final validation

  • T040 [P] Add error handling for OAuth failures in backend/src/modules/auth/auth.controller.ts - redirect to frontend with error param
  • T041 [P] Add error display component for auth errors in frontend/src/pages/LoginPage.tsx - show user-friendly messages
  • T042 Update Vite proxy configuration in frontend/vite.config.ts if needed for /api/auth routes
  • T043 Validate implementation against quickstart.md test scenarios
  • T044 Run ESLint and fix any linting errors in new files

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): No dependencies - can start immediately
  • Foundational (Phase 2): Depends on Setup completion - BLOCKS all user stories
  • User Stories (Phase 3-5): All depend on Foundational phase completion
  • Polish (Phase 6): Depends on all user stories being complete

User Story Dependencies

  • User Story 1 (P1): Can start after Foundational (Phase 2) - Core sign-in flow
  • User Story 2 (P2): Can start after Foundational (Phase 2) - Extends US1 with token refresh, but independently testable
  • User Story 3 (P3): Can start after Foundational (Phase 2) - Adds logout to US1, independently testable

Within Each User Story

  • Backend before frontend (API must exist before UI calls it)
  • Entity/strategy before service
  • Service before controller
  • Controller before frontend integration

Parallel Opportunities

Phase 1 (Setup):

T003 [P] + T004 [P] can run in parallel

Phase 2 (Foundational):

T006 + T007 [P] can run in parallel (different entity files)
T010 [P] + T011 [P] + T013 [P] can run in parallel (DTOs, types, API client)

Phase 3 (User Story 1):

T016 [P] + T017 [P] can run in parallel (different guard files)
T024 [P] + T025 [P] can run in parallel (different page files)

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 1: Setup (T001-T005)
  2. Complete Phase 2: Foundational (T006-T013)
  3. Complete Phase 3: User Story 1 (T014-T029)
  4. STOP and VALIDATE: Test sign-in flow per quickstart.md
  5. Deploy/demo if ready - users can now sign in!

Incremental Delivery

  1. Complete Setup + Foundational → Foundation ready
  2. Add User Story 1 → Test independently → Deploy (MVP with sign-in)
  3. Add User Story 2 → Test independently → Deploy (session persistence)
  4. Add User Story 3 → Test independently → Deploy (full auth with logout)
  5. Complete Polish → Final validation → Production ready

Task Count by Story

Phase Task Count
Setup 5
Foundational 8
User Story 1 16
User Story 2 6
User Story 3 4
Polish 5
Total 44

Notes

  • [P] tasks = different files, no dependencies
  • [Story] label maps task to specific user story for traceability
  • Each user story is independently completable and testable
  • Backend entities use UUID primary keys per constitution
  • Frontend uses shadcn/ui components per constitution
  • HttpOnly cookies for refresh tokens per research.md security recommendations