-
Notifications
You must be signed in to change notification settings - Fork 1
Pipeline Plan 15
Let me write the plan directly. Here's the implementation plan:
The OAuth flow is already 90% implemented in dashboard/server.ts. The existing code includes: OAuth redirect, callback/token exchange, session cookies, auth gate, login page, PAT fallback, logout, and /api/me. This plan focuses on the security gaps and missing features.
| File | Action | Purpose |
|---|---|---|
dashboard/server.ts |
Modify | Add CSRF state param, developer auto-registration, secure cookie flag, heartbeat identity validation, admin vs. write distinction |
dashboard/server-auth-test.ts |
Create | Unit tests for auth flow |
Step 1: Add OAuth CSRF state parameter protection
- In
handleAuthGitHub()(line 1922): Generate a randomstatetoken usingcrypto.randomUUID(), store it in a short-lived map with a 10-minute TTL - Add
stateto the OAuth authorize URL params - In
handleAuthCallback()(line 1939): Validate thestateparameter matches the stored value before exchanging the code
Step 2: Add Secure flag to session cookies in production
- In
sessionCookie()(line 214): Detect if running behind HTTPS (checkDASHBOARD_SECUREenv var or default to true whenNODE_ENV=production) and addSecureflag conditionally - Update
clearSessionCookie()(line 218) to match
Step 3: Distinguish admin vs. write permission
- In
handleAuthCallback()(line 1958-1959): SetisAdmintotrueonly for "admin" and "maintain" permissions. Users with "write"/"push" permission still get access butisAdmin = false - Same change in
handlePatLogin()(line 2019-2020) - Update
ALLOWED_PERMISSIONS(line 41) to include "maintain"
Step 4: Developer auto-registration on first OAuth login
- After session creation in
handleAuthCallback()(after line 1974): Register the user in the developer registry if not already present - Create a
registerOAuthDeveloper(username, avatarUrl)helper that adds an entry todeveloperRegistrywithdeveloper_idset to the GitHub username,machine_nameas "dashboard", and a current heartbeat timestamp - Same logic in
handlePatLogin()after session creation
Step 5: Heartbeat endpoint validates developer identity
- In the
/api/connect/heartbeathandler (line 3764): When auth is enabled, check if the request has a valid session cookie. If it does, verify thedeveloper_idin the body matches the session'sgithubUser - Allow existing invite-token auth as fallback for CLI-based heartbeats (which don't have browser sessions)
- This means heartbeats can be authenticated via either: (a) session cookie (dashboard), or (b) invite token (CLI)
Step 6: Write auth tests
- Create
dashboard/server-auth-test.tswith Bun test runner - Test cases: OAuth state generation/validation, session creation/expiry, cookie flags, public vs. protected route access, developer auto-registration, admin vs. write distinction, heartbeat identity validation
- Task 1: Add OAuth
stateparameter to/auth/githubredirect and validate in/auth/callback(CSRF protection) - Task 2: Add
Securecookie flag when serving over HTTPS (env-controlled) - Task 3: Distinguish admin (admin/maintain) vs. collaborator (write/push) permissions — both get access, only admin gets
isAdmin: true - Task 4: Auto-register developers in the registry on first OAuth/PAT login
- Task 5: Validate developer identity on heartbeat endpoint when auth is enabled
- Task 6: Add
ALLOWED_PERMISSIONSto include "maintain" and "push" for access (keep admin distinction separate) - Task 7: Write unit tests for the auth flow
- Task 8: Update
/api/meto return admin vs. collaborator role info - Task 9: Run existing test suite to ensure no regressions
-
Unit tests (
dashboard/server-auth-test.ts): Test OAuth state generation/validation, session lifecycle, cookie flags, route protection, developer registration, permission mapping -
Existing test suite: Run
npm testto verify no regressions in the 22 existing test suites -
Manual verification: Set
GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET,DASHBOARD_REPOenv vars and test the full OAuth flow in a browser
- OAuth flow includes CSRF
stateparameter validation - Session cookies include
Secureflag when configured for HTTPS - Public routes (
/login,/auth/callback,/api/health) work without authentication - All other routes redirect to
/loginwhen no session exists - First-time OAuth login auto-registers developer in registry
- Admin flag correctly distinguishes admin/maintain from write/push permissions
- Heartbeat endpoint validates developer identity against session when auth is enabled
- All existing tests pass (
npm test) - New auth-specific tests pass
Shall I proceed with the implementation? The changes are concentrated in a single file (dashboard/server.ts) plus a new test file, making this well-suited for sequential work rather than a team.