# Authentication Specification ## Job to Be Done When I access PhaseFlow, I want to securely log in with my email, so that my personal health data remains private. ## Auth Provider Using PocketBase for authentication and data storage. **Connection:** - `POCKETBASE_URL` environment variable - `src/lib/pocketbase.ts` initializes client ## Login Flow ### Email/Password Authentication 1. User enters email and password on `/login` 2. App calls PocketBase `authWithPassword` 3. On success, PocketBase sets auth cookie 4. User redirected to dashboard ### Session Management - PocketBase manages session tokens automatically - Auth state persisted in browser (cookie/localStorage) - Session expires after 14 days of inactivity ## Pages ### `/login` **Elements:** - Email input - Password input - "Sign In" button - Error message display - Link to password reset (future) **Behavior:** - Redirect to `/` on successful login - Show error message on failed attempt - Rate limit: 5 attempts per minute ### Protected Routes All routes except `/login` require authentication. **Middleware Check:** 1. Check for valid PocketBase auth token 2. If invalid/missing, redirect to `/login` 3. If valid, proceed to requested page ## API Authentication ### User Context API routes access current user via: ```typescript const pb = new PocketBase(process.env.POCKETBASE_URL); // Auth token from request cookies const user = pb.authStore.model; ``` ### Protected Endpoints All `/api/*` routes except: - `/api/calendar/[userId]/[token].ics` (token-based auth) - `/api/cron/*` (CRON_SECRET auth) ## User API ### GET `/api/user` Returns current authenticated user profile. **Response:** ```json { "id": "user123", "email": "user@example.com", "garminConnected": true, "cycleLength": 31, "lastPeriodDate": "2024-01-01", "notificationTime": "07:00", "timezone": "America/New_York" } ``` ### PATCH `/api/user` Updates user profile fields. **Request Body (partial update):** ```json { "cycleLength": 28, "notificationTime": "06:30" } ``` ## User Schema See `src/types/index.ts` for full `User` interface. **Auth-related fields:** - `id` - PocketBase record ID - `email` - Login email **Profile fields:** - `cycleLength` - Personal cycle length (days) - `notificationTime` - Preferred notification hour - `timezone` - User's timezone ## PocketBase Client (`src/lib/pocketbase.ts`) **Exports:** - `pb` - Initialized PocketBase client - `getCurrentUser()` - Get authenticated user - `isAuthenticated()` - Check auth status ## Settings Page (`/settings`) User profile management: - View/edit cycle length - View/edit notification time - View/edit timezone - Link to Garmin settings ## Success Criteria 1. Login completes in under 2 seconds 2. Session persists across browser refreshes 3. Unauthorized access redirects to login 4. User data isolated by authentication ## Acceptance Tests - [ ] Valid credentials authenticate successfully - [ ] Invalid credentials show error message - [ ] Session persists after page refresh - [ ] Protected routes redirect when not authenticated - [ ] GET `/api/user` returns current user data - [ ] PATCH `/api/user` updates user record - [ ] Logout clears session completely - [ ] Auth cookie is HttpOnly and Secure