import { betterAuth } from 'better-auth' import { prismaAdapter } from 'better-auth/adapters/prisma' import { magicLink } from 'better-auth/plugins' import { admin as adminPlugin } from 'better-auth/plugins' import { prisma } from '@innungsapp/shared' import { sendMagicLinkEmail } from './email' import { headers } from 'next/headers' export const auth = betterAuth({ database: prismaAdapter(prisma, { provider: 'postgresql', }), emailAndPassword: { enabled: true, }, secret: process.env.BETTER_AUTH_SECRET!, baseURL: process.env.BETTER_AUTH_URL!, trustedOrigins: [ process.env.NEXT_PUBLIC_APP_URL ?? 'http://localhost:3010', process.env.EXPO_PUBLIC_API_URL ?? 'http://localhost:3010', 'http://localhost:3000', 'http://localhost:3001', 'http://localhost:3010', 'http://localhost:8081', 'http://*.localhost:3010', 'http://*.localhost:3000', 'https://*.innungsapp.de', 'https://*.innungsapp.com', // Additional origins from env (comma-separated) ...(process.env.BETTER_AUTH_TRUSTED_ORIGINS ?? '').split(',').map((o) => o.trim()).filter(Boolean), ], user: { additionalFields: { mustChangePassword: { type: 'boolean', defaultValue: false, }, }, }, plugins: [ magicLink({ sendMagicLink: async ({ email, url }) => { await sendMagicLinkEmail({ to: email, magicUrl: url }) }, }), adminPlugin(), ], session: { cookieCache: { enabled: false, }, }, }) export type Auth = typeof auth export async function getSanitizedHeaders(sourceHeaders?: HeadersInit) { const baseHeaders = sourceHeaders ? new Headers(sourceHeaders) : new Headers(await headers()) const sanitizedHeaders = new Headers(baseHeaders) // Avoid ENOTFOUND by forcing host to localhost for internal better-auth fetches // We use the host defined in BETTER_AUTH_URL try { const betterAuthUrl = new URL(process.env.BETTER_AUTH_URL || 'http://localhost:3010') sanitizedHeaders.set('host', betterAuthUrl.host) } catch (e) { sanitizedHeaders.set('host', 'localhost:3010') } return sanitizedHeaders }