Files
frontend/specs/001-google-oauth-auth/plan.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

127 lines
6.0 KiB
Markdown

# Implementation Plan: Google OAuth Authentication Screen
**Branch**: `001-google-oauth-auth` | **Date**: 2026-01-29 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/001-google-oauth-auth/spec.md`
## Summary
Implement a Google OAuth 2.0 authentication screen that gates access to the ThumbPreview tool. Users must authenticate via Google before accessing protected routes (/tool). The implementation uses redirect-based OAuth flow with session persistence (7-day validity), preserving the user's originally requested destination after login. Backend handles OAuth callback and session management; frontend provides auth UI and route protection.
## Technical Context
**Language/Version**: TypeScript 5.x (frontend + backend)
**Primary Dependencies**:
- Frontend: React 19.x, React Router 7.x, Zustand 5.x, @tanstack/react-query 5.x, shadcn/ui
- Backend: NestJS 11.x, TypeORM 0.3.x, @nestjs/passport, passport-google-oauth20
**Storage**: PostgreSQL (users, sessions via TypeORM)
**Testing**: Jest (backend), manual testing (frontend)
**Target Platform**: Web (desktop + mobile browsers)
**Project Type**: Web application (frontend + backend monorepo)
**Performance Goals**: OAuth flow completion < 30 seconds, session validation < 100ms
**Constraints**: Must work with existing Vite proxy setup, no .env in frontend
**Scale/Scope**: Single user role, 7-day session validity with refresh
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
| Principle | Status | Notes |
|-----------|--------|-------|
| I. Tech Stack | ✅ PASS | Using React 19, NestJS 11, TypeORM, PostgreSQL per constitution |
| II. Architecture | ✅ PASS | Following monorepo structure: frontend/src/, backend/src/modules/ |
| III. Styling & UI | ✅ PASS | Will use shadcn/ui Button, Card components with Tailwind |
| IV. Data Management | ✅ PASS | Zustand for auth state, React Query for user data, TypeORM for persistence |
| V. Development Practices | ✅ PASS | TypeScript strict mode, class-validator DTOs, ESLint |
**New Dependencies Required**:
- `@nestjs/passport` + `passport` + `passport-google-oauth20` - OAuth authentication (NestJS official, MIT license)
- `@types/passport-google-oauth20` - TypeScript types
**Justification**: Passport.js is the de facto standard for Node.js authentication. @nestjs/passport provides official NestJS integration. These are well-maintained, MIT-licensed, and have minimal bundle impact (backend only).
## Project Structure
### Documentation (this feature)
```text
specs/001-google-oauth-auth/
├── plan.md # This file
├── research.md # Phase 0 output
├── data-model.md # Phase 1 output
├── quickstart.md # Phase 1 output
├── contracts/ # Phase 1 output
│ └── auth-api.yaml # OpenAPI spec for auth endpoints
└── tasks.md # Phase 2 output (/speckit.tasks command)
```
### Source Code (repository root)
```text
backend/
├── src/
│ ├── modules/
│ │ ├── auth/ # NEW: Authentication module
│ │ │ ├── auth.module.ts
│ │ │ ├── auth.controller.ts
│ │ │ ├── auth.service.ts
│ │ │ ├── google.strategy.ts
│ │ │ ├── jwt.strategy.ts
│ │ │ ├── guards/
│ │ │ │ ├── jwt-auth.guard.ts
│ │ │ │ └── google-auth.guard.ts
│ │ │ └── dto/
│ │ │ └── auth-response.dto.ts
│ │ ├── thumbnails/ # Existing
│ │ └── youtube/ # Existing
│ └── entities/
│ ├── user.entity.ts # NEW
│ ├── thumbnail.entity.ts # Existing
│ └── youtube-cache.entity.ts # Existing
└── tests/
frontend/
├── src/
│ ├── components/
│ │ ├── AuthGuard.tsx # NEW: Route protection wrapper
│ │ └── UserMenu.tsx # NEW: User avatar + sign out
│ ├── pages/
│ │ ├── LoginPage.tsx # NEW: Auth screen
│ │ ├── AuthCallbackPage.tsx # NEW: OAuth callback handler
│ │ ├── LandingPage.tsx # Existing (public)
│ │ └── ToolPage.tsx # Existing (protected)
│ ├── store/
│ │ └── authStore.ts # NEW: Auth state (Zustand)
│ ├── api/
│ │ └── auth.ts # NEW: Auth API client
│ └── hooks/
│ └── useAuth.ts # NEW: Auth hook
└── tests/
```
**Structure Decision**: Web application structure with frontend/backend separation per constitution. Auth module added to backend following NestJS module pattern. Frontend gets new pages for login flow and components for route protection.
## Complexity Tracking
No constitution violations. All implementation follows established patterns.
---
## Post-Design Constitution Re-Check
*Re-validated after Phase 1 design completion.*
| Principle | Status | Validation |
|-----------|--------|------------|
| I. Tech Stack | ✅ PASS | Dependencies align: @nestjs/passport, passport-google-oauth20 (MIT, maintained) |
| II. Architecture | ✅ PASS | Auth module follows NestJS pattern, frontend follows components/pages/store structure |
| III. Styling & UI | ✅ PASS | LoginPage will use shadcn/ui Button, Card; Tailwind for layout |
| IV. Data Management | ✅ PASS | User entity uses UUID PK, Zustand for auth state, TypeORM for persistence |
| V. Development Practices | ✅ PASS | DTOs with class-validator, explicit TypeScript types, ESLint compliance |
**Phase 1 Artifacts Generated**:
-`research.md` - OAuth implementation patterns documented
-`data-model.md` - User and RefreshToken entities defined
-`contracts/auth-api.yaml` - OpenAPI spec for 5 auth endpoints
-`quickstart.md` - Setup and testing guide
-`CLAUDE.md` - Agent context updated with new technologies