Skip to content

Phase 2: Authentication Migration (OAuth + Sessions) #91

@renderghost

Description

@renderghost

Phase 2: Authentication Migration (OAuth + Sessions)

Replace custom OAuth and session management with Quickslice-managed authentication.

Depends On

  • Completion of Phase 1 (architecture assessment)
  • Critical decision: OAuth strategy (Quickslice vs AT Protocol)

Objectives

  1. Replace custom OAuth flow with Quickslice
  2. Replace iron-session with Quickslice tokens
  3. Update session retrieval in route handlers
  4. Maintain all downstream compatibility

Tasks

Task 1: Create Quickslice Client Module

  • Create src/lib/quickslice/client.ts

    • Instantiate GraphQL client for Quickslice
    • Configure authentication headers (bearer token)
    • Export client instance
  • Create src/lib/quickslice/auth.ts

    • Export getQuicksliceSession() function
    • Handle session token from cookies
    • Implement session refresh logic
    • Handle session expiry

Task 2: Replace OAuth Initiate Endpoint

  • Update src/app/api/oauth/initiate/route.ts
    • Replace createOAuthClient() call with Quickslice OAuth
    • Generate Quickslice OAuth URL
    • Return same response format (redirectUrl)
    • Test with real AT Protocol handle

Task 3: Replace OAuth Callback Handler

  • Update src/app/oauth/callback/route.ts
    • Receive callback from Quickslice OAuth
    • Extract session token from callback
    • Verify token signature (if applicable)
    • Set HTTP-only cookie with token
    • Redirect to /dashboard
    • Test full OAuth flow

Task 4: Update Session Management

  • Rewrite src/lib/auth/session.ts
    • Replace getSession() to read Quickslice token from cookies
    • Replace handleLogout() to clear token cookie
    • Export same functions (backward compatible)
    • No changes needed to callers

Task 5: Update Agent Creation

  • Rewrite src/lib/auth/atproto.ts
    • Replace getAgent() function
    • Get Quickslice session token
    • TODO: Understand how to use Quickslice token to access AT Protocol
    • Keep same function signature (backward compatible)

Task 6: Update Middleware

  • Update src/proxy.ts
    • Change cookie name from sid to Quickslice format
    • Update session validation logic
    • Verify protected routes still work
    • Verify auth redirects work

Task 7: Delete Old OAuth Code

  • Delete src/lib/oauth/client.ts
  • Delete src/lib/oauth/storage.ts
  • Delete src/lib/oauth/normalize-url.ts
  • Remove oauth directory entirely
  • Update imports in all files that used src/lib/oauth/

Task 8: Update Database (if needed)

  • IF Quickslice manages sessions:
    • Drop auth_session table from database
    • Drop auth_state table from database
    • Remove from src/lib/db.ts migrations
  • IF Quickslice uses same database:
    • Verify table names and schema match
    • No migration needed

Task 9: Update Environment Variables

  • Add QUICKSLICE_URL or similar env vars
  • Add QUICKSLICE_CLIENT_ID if needed
  • Add QUICKSLICE_SECRET if needed
  • Document in .env.example

Task 10: Testing

OAuth Flow Testing

  • Test OAuth initiate: GET/POST /api/oauth/initiate with handle
  • Test OAuth callback: Verify cookie is set correctly
  • Test session persistence: Refresh page, session still valid
  • Test logout: Delete session cookie properly
  • Test multiple concurrent sessions
  • Test session expiry handling
  • Test invalid/expired tokens

Integration Testing

  • Verify /dashboard redirect works (authenticated users)
  • Verify /auth redirect works (unauthenticated users)
  • Verify protected API routes require valid session
  • Verify public routes work without session
  • Verify session token in GraphQL requests (Phase 3)

Files Modified

File Changes Backward Compat
src/lib/oauth/client.ts DELETE -
src/lib/oauth/storage.ts DELETE -
src/lib/oauth/normalize-url.ts DELETE -
src/app/api/oauth/initiate/route.ts Rewrite Yes (same endpoint)
src/app/oauth/callback/route.ts Rewrite Yes (same path)
src/lib/auth/session.ts Rewrite Yes (same functions)
src/lib/auth/atproto.ts Update Yes (same functions)
src/proxy.ts Update Yes (same behavior)
src/lib/db.ts Update Conditional

No Changes Needed

These work as-is because we maintain function signatures:

  • All API routes in src/app/api/profile/*
  • All dashboard pages
  • All form components
  • All auth checks (still call same functions)

Files to Create

src/lib/quickslice/
├── client.ts          # GraphQL client instance
└── auth.ts            # Session retrieval, token refresh

Risks

Risk Mitigation
Session cookie format wrong Test before/after, verify browser DevTools
OAuth callback doesn't set cookie Debug with console.log, verify Set-Cookie headers
Existing user sessions invalidate Document that users need to re-login once
Token refresh fails Implement proper error handling, retry logic
Multi-environment config issues Test on both local (http://) and prod (https://)

Success Criteria

  • OAuth initiate endpoint working
  • OAuth callback endpoint working
  • Session cookie set correctly
  • Authenticated users access /dashboard without redirect
  • Unauthenticated users redirected to /auth
  • Session persists across page reloads
  • Logout clears session properly
  • Token refresh works for expired sessions
  • All tests passing
  • Old OAuth code deleted
  • No breaking changes to downstream code

Estimated Duration

2-3 weeks depending on Quickslice OAuth complexity

Next Phase

Once Phase 2 complete:
#91: Phase 3: GraphQL Client & Hooks Setup
#92: Phase 4: REST to GraphQL Migration (start with Affiliations)

Notes

  • Keep backward compatibility with function signatures
  • Any existing frontend code calling getSession() or getAgent() continues to work
  • Test extensively before moving to Phase 3
  • Document Quickslice-specific patterns for team

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions