diff --git a/deploy/base/deployment.yaml b/deploy/base/deployment.yaml index 47c767b..c9eb437 100644 --- a/deploy/base/deployment.yaml +++ b/deploy/base/deployment.yaml @@ -60,16 +60,31 @@ spec: secretKeyRef: name: taskarr-app key: BETTER_AUTH_SECRET - - name: GITEA_CLIENT_SECRET + - name: GITHUB_CLIENT_SECRET valueFrom: secretKeyRef: name: taskarr-app - key: GITEA_CLIENT_SECRET - - name: GITEA_CLIENT_ID + key: GITHUB_CLIENT_SECRET + - name: GITHUB_CLIENT_ID valueFrom: secretKeyRef: name: taskarr-app - key: GITEA_CLIENT_ID + key: GITHUB_CLIENT_ID + - name: GITHUB_APP_ID + valueFrom: + secretKeyRef: + name: taskarr-app + key: GITHUB_APP_ID + - name: GITHUB_APP_SLUG + valueFrom: + secretKeyRef: + name: taskarr-app + key: GITHUB_APP_SLUG + - name: GITHUB_APP_PRIVATE_KEY + valueFrom: + secretKeyRef: + name: taskarr-app + key: GITHUB_APP_PRIVATE_KEY restartPolicy: Always --- diff --git a/src/lib/server/auth.ts b/src/lib/server/auth.ts index c58e3b0..71cc40c 100644 --- a/src/lib/server/auth.ts +++ b/src/lib/server/auth.ts @@ -5,23 +5,35 @@ import { env } from '$env/dynamic/private'; import { getRequestEvent } from '$app/server'; import { db } from '$lib/server/db'; -if (!env.ORIGIN) throw new Error('ORIGIN is not set'); -if (!env.BETTER_AUTH_SECRET) throw new Error('BETTER_AUTH_SECRET is not set'); -if (!env.GITHUB_CLIENT_ID) throw new Error('GITHUB_CLIENT_ID is not set'); -if (!env.GITHUB_CLIENT_SECRET) throw new Error('GITHUB_CLIENT_SECRET is not set'); +function createAuth() { + const origin = env.ORIGIN; + if (!origin) throw new Error('ORIGIN is not set'); + const secret = env.BETTER_AUTH_SECRET; + if (!secret) throw new Error('BETTER_AUTH_SECRET is not set'); + const clientId = env.GITHUB_CLIENT_ID; + if (!clientId) throw new Error('GITHUB_CLIENT_ID is not set'); + const clientSecret = env.GITHUB_CLIENT_SECRET; + if (!clientSecret) throw new Error('GITHUB_CLIENT_SECRET is not set'); -export const auth = betterAuth({ - baseURL: env.ORIGIN, - secret: env.BETTER_AUTH_SECRET, - database: drizzleAdapter(db, { provider: 'pg' }), - emailAndPassword: { enabled: true }, - socialProviders: { - github: { - clientId: env.GITHUB_CLIENT_ID, - clientSecret: env.GITHUB_CLIENT_SECRET - } - }, - plugins: [ - sveltekitCookies(getRequestEvent) // make sure this is the last plugin in the array - ] + return betterAuth({ + baseURL: origin, + secret, + database: drizzleAdapter(db, { provider: 'pg' }), + emailAndPassword: { enabled: true }, + socialProviders: { + github: { clientId, clientSecret } + }, + plugins: [ + sveltekitCookies(getRequestEvent) + ] + }); +} + +let _auth: ReturnType; + +export const auth = new Proxy({} as ReturnType, { + get(target, prop) { + if (!_auth) _auth = createAuth(); + return Reflect.get(_auth, prop, target); + } }); diff --git a/src/lib/server/db/index.ts b/src/lib/server/db/index.ts index fef0d6d..0be7a9d 100644 --- a/src/lib/server/db/index.ts +++ b/src/lib/server/db/index.ts @@ -2,7 +2,4 @@ import { drizzle } from 'drizzle-orm/node-postgres'; import * as schema from './schema'; import { env } from '$env/dynamic/private'; -if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set'); - - export const db = drizzle(env.DATABASE_URL, { schema }); diff --git a/src/lib/server/github-app.ts b/src/lib/server/github-app.ts index ca43f4e..c765562 100644 --- a/src/lib/server/github-app.ts +++ b/src/lib/server/github-app.ts @@ -14,25 +14,6 @@ type InstallState = { userId: string; }; -function requireEnv(name: string) { - switch (name) { - case 'GITHUB_APP_ID': - if (!env.GITHUB_APP_ID) throw new Error('GITHUB_APP_ID is not set'); - return env.GITHUB_APP_ID; - case 'GITHUB_APP_SLUG': - if (!env.GITHUB_APP_SLUG) throw new Error('GITHUB_APP_SLUG is not set'); - return env.GITHUB_APP_SLUG; - case 'GITHUB_APP_PRIVATE_KEY': - if (!env.GITHUB_APP_PRIVATE_KEY) throw new Error('GITHUB_APP_PRIVATE_KEY is not set'); - return env.GITHUB_APP_PRIVATE_KEY; - case 'BETTER_AUTH_SECRET': - if (!env.BETTER_AUTH_SECRET) throw new Error('BETTER_AUTH_SECRET is not set'); - return env.BETTER_AUTH_SECRET; - default: - throw new Error(`${name} is not supported`); - } -} - export function hasGitHubAppPrivateKey() { return Boolean(env.GITHUB_APP_PRIVATE_KEY); } @@ -64,32 +45,32 @@ function verifyState(state: string, secret: string) { } export function getGitHubInstallUrl(input: { redirect?: string; userId: string }) { - const slug = requireEnv('GITHUB_APP_SLUG'); - const secret = requireEnv('BETTER_AUTH_SECRET'); + if (!env.GITHUB_APP_SLUG) throw new Error('GITHUB_APP_SLUG is not set'); + if (!env.BETTER_AUTH_SECRET) throw new Error('BETTER_AUTH_SECRET is not set'); const redirect = input.redirect ?? '/integrations'; - const base = new URL(`https://github.com/apps/${slug}/installations/new`); - base.searchParams.set('state', signState({ redirect, userId: input.userId }, secret)); + const base = new URL(`https://github.com/apps/${env.GITHUB_APP_SLUG}/installations/new`); + base.searchParams.set('state', signState({ redirect, userId: input.userId }, env.BETTER_AUTH_SECRET)); return base.toString(); } export function decodeInstallState(state?: string) { if (!state) return { redirect: '/integrations' }; - const secret = requireEnv('BETTER_AUTH_SECRET'); - const parsed = verifyState(state, secret); + if (!env.BETTER_AUTH_SECRET) throw new Error('BETTER_AUTH_SECRET is not set'); + const parsed = verifyState(state, env.BETTER_AUTH_SECRET); if (!parsed) return { redirect: '/integrations' }; return { redirect: parsed.redirect || '/integrations', userId: parsed.userId }; } function createGitHubAppJwt() { - const appId = requireEnv('GITHUB_APP_ID'); - const privateKey = requireEnv('GITHUB_APP_PRIVATE_KEY'); + if (!env.GITHUB_APP_ID) throw new Error('GITHUB_APP_ID is not set'); + if (!env.GITHUB_APP_PRIVATE_KEY) throw new Error('GITHUB_APP_PRIVATE_KEY is not set'); const now = Math.floor(Date.now() / 1000); const header = base64urlJson({ alg: 'RS256', typ: 'JWT' }); - const payload = base64urlJson({ iat: now - 60, exp: now + 9 * 60, iss: appId }); + const payload = base64urlJson({ iat: now - 60, exp: now + 9 * 60, iss: env.GITHUB_APP_ID }); const signer = createSign('RSA-SHA256'); signer.update(`${header}.${payload}`); signer.end(); - const key = createPrivateKey(normalizePrivateKey(privateKey)); + const key = createPrivateKey(normalizePrivateKey(env.GITHUB_APP_PRIVATE_KEY)); const signature = signer.sign(key, 'base64url'); return `${header}.${payload}.${signature}`; }