Auth Flow
Auth Provider: Supabase Auth
Session Strategy: JWT (managed by Supabase)
Flow Overview
mermaid
sequenceDiagram
participant B as Browser
participant SK as SvelteKit
participant SB as Supabase Auth
participant DB as Database
B->>SK: Request page
SK->>SB: getSession()
alt Session valid
SB-->>SK: { user, session }
SK->>DB: Fetch user profile + agency
SK-->>B: Render page with data
else No session
SK-->>B: redirect('/login')
endSvelteKit Integration
Root Layout Load (+layout.server.ts)
typescript
import { createServerClient } from '@supabase/ssr'
export const load = async ({ cookies }) => {
const supabase = createServerClient(
PUBLIC_SUPABASE_URL,
PUBLIC_SUPABASE_ANON_KEY,
{ cookies: { getAll: () => cookies.getAll(), setAll: (c) => c.forEach(({ name, value, options }) => cookies.set(name, value, options)) } }
)
const { data: { session } } = await supabase.auth.getSession()
return { session }
}Protecting Routes
typescript
// src/routes/(app)/+layout.server.ts
import { redirect } from '@sveltejs/kit'
export const load = async ({ locals }) => {
if (!locals.session) {
redirect(303, '/login')
}
return { user: locals.user }
}Role-Based Access
| Role | Permissions |
|---|---|
owner | Full agency management, billing, all projects |
admin | All projects, user management (no billing) |
editor | Own projects + assigned projects |
viewer | Read-only access to assigned projects |
Checking Roles in Server Code
typescript
// In Hono middleware
app.use('/api/admin/*', async (c, next) => {
const user = c.get('user')
if (!['owner', 'admin'].includes(user.role)) {
return c.json({ error: 'Forbidden' }, 403)
}
await next()
})Password Reset / OAuth
Uses Supabase default flows. Configure providers in Supabase Dashboard → Authentication → Providers.
Supported:
- Email + Password
- Google OAuth
- GitHub OAuth (for developer accounts)