import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { genericOAuth } from "better-auth/plugins"; import { db } from "@/db/index"; import * as schema from "@/db/schema"; import { buildSocialProviders } from "@/lib/build-social-providers"; // --------------------------------------------------------------------------- // Required vars — the app cannot start without these // --------------------------------------------------------------------------- if (!process.env.BETTER_AUTH_SECRET) { throw new Error("BETTER_AUTH_SECRET is required"); } if (!process.env.BETTER_AUTH_URL) { throw new Error("BETTER_AUTH_URL is required"); } // --------------------------------------------------------------------------- // Authentik is optional: only configured when all three vars are present. // Google and Apple are also optional via buildSocialProviders(). // --------------------------------------------------------------------------- const authentikConfig = process.env.AUTH_AUTHENTIK_CLIENT_ID && process.env.AUTH_AUTHENTIK_CLIENT_SECRET && process.env.AUTH_AUTHENTIK_ISSUER ? [ { providerId: "authentik" as const, clientId: process.env.AUTH_AUTHENTIK_CLIENT_ID, clientSecret: process.env.AUTH_AUTHENTIK_CLIENT_SECRET, discoveryUrl: `${process.env.AUTH_AUTHENTIK_ISSUER}/.well-known/openid-configuration`, scopes: ["openid", "email", "profile"], }, ] : []; const socialProviders = buildSocialProviders( process.env as Record, ); export const auth = betterAuth({ secret: process.env.BETTER_AUTH_SECRET, baseURL: process.env.BETTER_AUTH_URL, trustedOrigins: [ process.env.BETTER_AUTH_URL, // Required for Sign in with Apple's form_post redirect ...(socialProviders.apple ? ["https://appleid.apple.com"] : []), ], database: drizzleAdapter(db, { provider: "pg", schema, }), socialProviders, plugins: [ ...(authentikConfig.length > 0 ? [genericOAuth({ config: authentikConfig })] : []), ], });