stadtwerke/innungsapp/apps/admin/lib/auth.ts

73 lines
2.1 KiB
TypeScript

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
}