import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { db, users, sessions, accounts, verifications, eq, count } from "@epicure/db"; import { sendEmail, verifyEmailHtml, resetPasswordHtml, welcomeHtml } from "@/lib/email"; export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", schema: { user: users, session: sessions, account: accounts, verification: verifications }, }), emailAndPassword: { enabled: true, requireEmailVerification: true, sendResetPassword: async ({ user, url }) => { await sendEmail({ to: user.email, subject: "Reset your Epicure password", html: resetPasswordHtml(url), }); }, }, emailVerification: { sendOnSignUp: true, autoSignInAfterVerification: true, sendVerificationEmail: async ({ user, url }) => { await sendEmail({ to: user.email, subject: "Verify your Epicure email", html: verifyEmailHtml(url), }); }, }, socialProviders: { google: { clientId: process.env["GOOGLE_CLIENT_ID"] ?? "", clientSecret: process.env["GOOGLE_CLIENT_SECRET"] ?? "", }, }, session: { cookieCache: { enabled: true, maxAge: 60 * 5, }, }, databaseHooks: { user: { create: { after: async (user) => { // First registered user becomes admin const result = await db.select({ total: count() }).from(users); if ((result[0]?.total ?? 0) === 1) { await db.update(users).set({ role: "admin" }).where(eq(users.id, user.id)); } // Welcome email (fire and forget) sendEmail({ to: user.email, subject: "Welcome to Epicure", html: welcomeHtml(user.name), }).catch(() => {}); }, }, }, }, user: { additionalFields: { role: { type: "string", defaultValue: "user", input: false, }, tier: { type: "string", defaultValue: "free", input: false, }, username: { type: "string", required: false, }, bio: { type: "string", required: false, }, unitPref: { type: "string", defaultValue: "metric", }, locale: { type: "string", defaultValue: "en", }, }, changeEmail: { enabled: true, sendChangeEmailVerification: async ({ newEmail, url }) => { await sendEmail({ to: newEmail, subject: "Verify your new Epicure email", html: verifyEmailHtml(url), }); }, }, }, }); export type Session = typeof auth.$Infer.Session; export type User = typeof auth.$Infer.Session.user;