import { SvelteKitAuth } from '@auth/sveltekit'; import type { OIDCConfig } from '@auth/core/providers'; import { env } from '$env/dynamic/private'; interface AuthentikProfile { sub: string; email: string; name: string; preferred_username: string; groups: string[]; } export const { handle, signIn, signOut } = SvelteKitAuth({ trustHost: true, providers: [ { id: 'authentik', name: 'Authentik', type: 'oidc', issuer: env.AUTHENTIK_ISSUER, clientId: env.AUTHENTIK_CLIENT_ID, clientSecret: env.AUTHENTIK_CLIENT_SECRET, authorization: { params: { scope: 'openid email profile offline_access' } }, checks: ['pkce', 'state'], profile(profile: AuthentikProfile) { return { id: profile.sub, name: profile.name ?? profile.preferred_username, email: profile.email }; } } satisfies OIDCConfig ], callbacks: { jwt({ token, profile }) { // profile is only available on initial sign-in, not on refresh. // Store authentik_sub in the token so it persists across refreshes. if (profile?.sub) { token.authentik_sub = profile.sub; } return token; }, session({ session, token }) { if (session.user) { // Use Authentik sub as user ID (not @auth/sveltekit's internal ID) session.user.id = (token.authentik_sub ?? token.sub) as string; } return session; } } });