import { SvelteKitAuth } from '@auth/sveltekit'; import { DrizzleAdapter } from '@auth/drizzle-adapter'; import Credentials from '@auth/core/providers/credentials'; import Google from '@auth/core/providers/google'; import type { OAuthConfig } from '@auth/core/providers'; import { db } from '$lib/server/db'; import { users } from '$lib/server/schema'; import { eq } from 'drizzle-orm'; import bcrypt from 'bcrypt'; import { env } from '$env/dynamic/private'; import type { SvelteKitAuthConfig } from '@auth/sveltekit'; function Authentik(config: { clientId: string; clientSecret: string; issuer: string; }): OAuthConfig { return { id: 'authentik', name: 'Authentik', type: 'oidc', clientId: config.clientId, clientSecret: config.clientSecret, issuer: config.issuer, authorization: { params: { scope: 'openid email profile' } }, profile(profile) { return { id: profile.sub, email: profile.email, name: profile.name || profile.preferred_username, image: profile.picture }; } }; } const authConfig: SvelteKitAuthConfig = { adapter: DrizzleAdapter(db), session: { strategy: 'jwt' }, providers: [ ...(env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET ? [ Google({ clientId: env.GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET }) ] : []), ...(env.AUTHENTIK_CLIENT_ID && env.AUTHENTIK_CLIENT_SECRET && env.AUTHENTIK_ISSUER ? [ Authentik({ clientId: env.AUTHENTIK_CLIENT_ID, clientSecret: env.AUTHENTIK_CLIENT_SECRET, issuer: env.AUTHENTIK_ISSUER }) ] : []), Credentials({ id: 'credentials', name: 'credentials', credentials: { username: { label: 'Username', type: 'text' }, password: { label: 'Password', type: 'password' } }, async authorize(credentials) { if (!credentials?.username || !credentials?.password) { return null; } const user = await db.query.users.findFirst({ where: eq(users.username, credentials.username as string) }); if (!user || !user.password) { return null; } const isValidPassword = await bcrypt.compare( credentials.password as string, user.password ); if (!isValidPassword) { return null; } return { id: user.id, email: user.email || undefined, name: user.name, image: user.image }; } }) ], pages: { signIn: '/signin' }, callbacks: { async signIn({ user }) { if (user?.id) { await db.update(users) .set({ lastLogin: new Date() }) .where(eq(users.id, user.id)); } return true; }, async jwt({ token, user }) { if (user) { token.id = user.id; } return token; }, async session({ session, token }) { if (token && session.user) { session.user.id = token.id as string; } return session; } }, secret: env.AUTH_SECRET, trustHost: true }; export const { handle, signIn, signOut } = SvelteKitAuth(authConfig);