Auth flow, middleware, and role-based access
Authentication
Surflink uses Supabase Auth for user authentication, with server-side session management via the @supabase/ssr package.
Auth Flow
- Sign Up / Sign In -- Users authenticate via email/password or OAuth through the
/loginand/signuppages - Session Management -- Supabase stores the session in HTTP cookies, managed by the SSR middleware
- Token Refresh -- The middleware automatically refreshes the auth token on every request
- Profile Creation -- On first OAuth callback, a
coachesprofile row is auto-created for the authenticated user
Middleware
The auth middleware (src/middleware.js) runs on every request except static assets and the video stream endpoint. It performs these tasks:
- Creates a Supabase SSR client with cookie-based session management
- Refreshes the auth token via
supabase.auth.getUser() - Cleans up stale chunked cookies -- Supabase SSR creates chunked cookies (
sb-xxx-auth-token.0,.1,.2, etc.) that can accumulate and cause 431 (Header Too Large) errors - Enforces route protection -- Unauthenticated users are redirected to
/loginon protected routes - Redirects authenticated users away from
/loginand/signupto/dashboard
Public Routes
These routes are accessible without authentication:
| Route | Purpose |
|---|---|
/ | Landing page |
/login | Sign in |
/signup | Create account |
/auth/callback | OAuth callback |
/reports/* | Shareable session reports |
/invite/* | Student invite acceptance |
/highlights/* | Public highlight reels |
/docs/* | Documentation |
/api/auth/frameio/* | Frame.io OAuth flow |
Supabase Clients
The project maintains three Supabase client configurations:
| File | Usage |
|---|---|
src/lib/supabase-browser.js | Client-side queries from React components |
src/lib/supabase-server.js | Server-side queries in API routes |
src/lib/supabase.js | Legacy client (maintained for compatibility) |
Role-Based Routing
| Role | Route Prefix | Description |
|---|---|---|
| Coach | /dashboard, /sessions, /students, etc. | Full platform access |
| Student | /student/* | Read-only access to own data |
| Parent | /parent/* | View-only access to linked student |
The AuthProvider context exposes the current user, coach profile, and loading state. Components use the useAuth() hook to access this context.
OAuth Callback
The OAuth callback handler at /auth/callback exchanges the authorization code for a session, then checks if a coaches row exists for the authenticated user. If not, it creates one automatically with the user's email and metadata.