3.2 KiB
3.2 KiB
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_URLenvironment variablesrc/lib/pocketbase.tsinitializes client
Login Flow
Email/Password Authentication
- User enters email and password on
/login - App calls PocketBase
authWithPassword - On success, PocketBase sets auth cookie
- 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:
- Check for valid PocketBase auth token
- If invalid/missing, redirect to
/login - If valid, proceed to requested page
API Authentication
User Context
API routes access current user via:
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:
{
"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):
{
"cycleLength": 28,
"notificationTime": "06:30"
}
User Schema
See src/types/index.ts for full User interface.
Auth-related fields:
id- PocketBase record IDemail- Login email
Profile fields:
cycleLength- Personal cycle length (days)notificationTime- Preferred notification hourtimezone- User's timezone
PocketBase Client (src/lib/pocketbase.ts)
Exports:
pb- Initialized PocketBase clientgetCurrentUser()- Get authenticated userisAuthenticated()- 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
- Login completes in under 2 seconds
- Session persists across browser refreshes
- Unauthorized access redirects to login
- 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/userreturns current user data - PATCH
/api/userupdates user record - Logout clears session completely
- Auth cookie is HttpOnly and Secure