# Authentication Specification ## Job to Be Done When I access PhaseFlow, I want to securely log in with my identity provider, so that my personal health data remains private. ## Auth Provider Using PocketBase for authentication and data storage, with OIDC (Pocket-ID) as the primary identity provider. **Connection:** - `NEXT_PUBLIC_POCKETBASE_URL` environment variable - `src/lib/pocketbase.ts` initializes client ## Login Flow ### OIDC Authentication (Pocket-ID) 1. User clicks "Sign In" on `/login` 2. App redirects to Pocket-ID authorization endpoint 3. User authenticates with Pocket-ID (handles MFA if configured) 4. Pocket-ID redirects back with authorization code 5. PocketBase exchanges code for tokens 6. User redirected to dashboard ### OIDC Configuration Configure in PocketBase Admin UI: **Settings → Auth providers → OpenID Connect** **Required Settings:** - `Client ID` - From Pocket-ID application - `Client Secret` - From Pocket-ID application - `Issuer URL` - Your Pocket-ID instance URL (e.g., `https://id.yourdomain.com`) **Environment Variables:** ```env POCKETBASE_OIDC_CLIENT_ID=phaseflow POCKETBASE_OIDC_CLIENT_SECRET=xxx POCKETBASE_OIDC_ISSUER_URL=https://id.yourdomain.com ``` ### Session Management - PocketBase manages session tokens automatically - Auth state persisted in browser (cookie/localStorage) - Session expires after 14 days of inactivity ## Pages ### `/login` **Elements:** - "Sign In with Pocket-ID" button - Error message display **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.NEXT_PUBLIC_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. OIDC login flow completes in under 5 seconds (including redirect) 2. Session persists across browser refreshes 3. Unauthorized access redirects to login 4. User data isolated by authentication ## Acceptance Tests - [ ] OIDC redirect initiates correctly - [ ] Successful OIDC callback creates/updates user - [ ] 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 ## Future Enhancements ### Open Registration When open registration is enabled: - Add `/signup` page with OIDC provider selection - New users created automatically on first OIDC login - Admin approval workflow (optional) ### Additional OAuth2 Providers PocketBase supports multiple OAuth2 providers. Future options: - Google - GitHub - Apple - Other OIDC-compliant providers Each provider configured separately in PocketBase Admin UI.