Skip to main content

Setting Up validateSession

Each app should wrap validateAccessInSvelte with its own validateSession function to define redirect behavior for 401 (unauthenticated) and 403 (unauthorized) errors.

Create the Wrapper

// src/lib/auth.ts
import type { Gate } from '@repo/auth'
import { validateAccessInSvelte } from '@repo/auth/server'
import { getRequestEvent } from '$app/server'
import { redirect } from '@sveltejs/kit'

export async function validateSession(gates?: Gate[]) {
await validateAccessInSvelte({
gates,
onUnauthenticated: async () => {
const request = getRequestEvent()
const redirectTarget = encodeURIComponent(request.url.pathname + request.url.search)
redirect(307, `/login?redirect=${redirectTarget}`)
},
onUnauthorized: async () => {
redirect(307, '/dashboard')
},
})
}

Callbacks

CallbackTriggerTypical Action
onUnauthenticatedGate returns 401 or no sessionRedirect to login with return URL
onUnauthorizedGate returns 403 (default)Redirect to a safe page

If neither callback is provided, the error is re-thrown.

Usage in Remote Functions

Call validateSession at the top of any server function that requires authentication:

import { isAuthenticatedGate, permissionGate } from '@repo/auth'
import { validateSession } from '$lib/auth'

export async function deleteUser(userId: string) {
await validateSession([
isAuthenticatedGate,
permissionGate('users', ['delete']),
])

// proceed with deletion
}

Usage Without Gates

Calling validateSession() with no arguments still runs through validateAccess which checks that a session exists. If the session is null, it throws NotAuthorized(403).

await validateSession() // ensures a session exists

How It Works

  1. validateAccessInSvelte calls validateAccess internally.
  2. validateAccess reads the session via getSession(), runs all gates through hasAccess, and throws NotAuthorized on failure.
  3. validateAccessInSvelte catches the error, inspects the code (401 vs 403), and calls the corresponding callback.
  4. The error is re-thrown after the callback runs so SvelteKit can handle the redirect or error.