Authentik sin OIDC sub-claim er en SHA256-hash, ikke PostgreSQL UUID. @auth/sveltekit sin interne user.id er en annen UUID som ikke matcher. Løsning: lagre profile.sub som authentik_sub i JWT-tokenet og bruk den som session.user.id. Ny erfaringsfil: docs/erfaringer/authentik_oidc.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
import type { Handle } from '@sveltejs/kit';
|
|
import { sequence } from '@sveltejs/kit/hooks';
|
|
import { env } from '$env/dynamic/private';
|
|
import { handle as authHandle } from '$lib/server/auth';
|
|
import { getWorkspaceForUser, getUserWorkspaces } from '$lib/server/db';
|
|
|
|
const WORKSPACE_COOKIE = 'sidelinja_workspace';
|
|
const isDev = env.NODE_ENV !== 'production' && !env.AUTHENTIK_CLIENT_ID;
|
|
|
|
/**
|
|
* Dev-only auth: simulerer innlogget bruker uten OIDC.
|
|
* Setter locals.auth() til å returnere en fast dev-bruker.
|
|
*/
|
|
const devAuthHandle: Handle = async ({ event, resolve }) => {
|
|
const DEV_USER = { id: 'dev-user-1', name: 'Vegard', email: 'vegard@localhost' };
|
|
|
|
// Legg til auth()-metode som hooks og layout forventer
|
|
event.locals.auth = async () => ({ user: DEV_USER, expires: '' });
|
|
return resolve(event);
|
|
};
|
|
|
|
/**
|
|
* Workspace-resolving: les aktiv workspace fra cookie,
|
|
* verifiser tilgang, og legg i locals.
|
|
*/
|
|
const workspaceHandle: Handle = async ({ event, resolve }) => {
|
|
const session = await event.locals.auth();
|
|
const user = session?.user;
|
|
|
|
if (user?.id) {
|
|
event.locals.user = {
|
|
id: user.id,
|
|
name: user.name ?? '',
|
|
email: user.email ?? '',
|
|
image: user.image ?? undefined
|
|
};
|
|
|
|
const workspaceId = event.cookies.get(WORKSPACE_COOKIE);
|
|
if (workspaceId) {
|
|
event.locals.workspace = await getWorkspaceForUser(workspaceId, user.id);
|
|
}
|
|
|
|
// Hvis ingen gyldig workspace i cookie, velg den første
|
|
if (!event.locals.workspace) {
|
|
const workspaces = await getUserWorkspaces(user.id);
|
|
if (workspaces.length > 0) {
|
|
event.locals.workspace = workspaces[0];
|
|
event.cookies.set(WORKSPACE_COOKIE, workspaces[0].id, {
|
|
path: '/',
|
|
httpOnly: true,
|
|
sameSite: 'lax',
|
|
maxAge: 60 * 60 * 24 * 365
|
|
});
|
|
}
|
|
}
|
|
} else {
|
|
event.locals.user = null;
|
|
event.locals.workspace = null;
|
|
}
|
|
|
|
return resolve(event);
|
|
};
|
|
|
|
export const handle = isDev
|
|
? sequence(devAuthHandle, workspaceHandle)
|
|
: sequence(authHandle, workspaceHandle);
|