import { betterAuth } from 'better-auth'; import { drizzleAdapter } from 'better-auth/adapters/drizzle'; import { admin } from 'better-auth/plugins'; import { genericOAuth, type GenericOAuthConfig } from 'better-auth/plugins/generic-oauth'; import type { Db } from '@mosaic/db'; import { buildGenericOidcProviderConfigs } from './sso.js'; export interface AuthConfig { db: Db; baseURL?: string; secret?: string; } export function buildOAuthProviders(): GenericOAuthConfig[] { return buildGenericOidcProviderConfigs() as GenericOAuthConfig[]; } export function createAuth(config: AuthConfig) { const { db, baseURL, secret } = config; const oidcConfigs = buildOAuthProviders(); const plugins = oidcConfigs.length > 0 ? [ genericOAuth({ config: oidcConfigs, }), ] : undefined; const corsOrigin = process.env['GATEWAY_CORS_ORIGIN'] ?? 'http://localhost:3000'; const trustedOrigins = corsOrigin.split(',').map((o) => o.trim()); return betterAuth({ database: drizzleAdapter(db, { provider: 'pg', usePlural: true, }), baseURL: baseURL ?? process.env['BETTER_AUTH_URL'] ?? 'http://localhost:14242', secret: secret ?? process.env['BETTER_AUTH_SECRET'], basePath: '/api/auth', trustedOrigins, emailAndPassword: { enabled: true, }, user: { additionalFields: { role: { type: 'string', required: false, defaultValue: 'member', input: false, }, }, }, session: { expiresIn: 60 * 60 * 24 * 7, // 7 days updateAge: 60 * 60 * 24, // refresh daily }, plugins: [...(plugins ?? []), admin({ defaultRole: 'member', adminRoles: ['admin'] })], }); } export type Auth = ReturnType;