initial production version

This commit is contained in:
2025-11-25 16:08:50 +01:00
parent 44ce6e38dd
commit 0144e8df1a
108 changed files with 5502 additions and 1780 deletions

123
src/auth.ts Normal file
View File

@@ -0,0 +1,123 @@
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<any> {
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 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);