import { db } from "@/app/server/db"; import { env } from "@/env"; import { betterAuth } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import { nextCookies } from "better-auth/next-js"; import { admin, bearer, oAuthProxy, organization, twoFactor, username, } from "better-auth/plugins"; import { passkey } from "better-auth/plugins/passkey"; import { adminUserId, appUrl, isDevEnv } from "../appConfig"; import { reactInvitationEmail } from "./email/invitation"; import { resend } from "./email/resend"; import { reactResetPasswordEmail } from "./email/reset-password"; import VerificationEmail from "./email/verification"; import { userRole } from "./globalFunctions"; import getCurrentUser from "./user/getCurrentUser"; export const auth = betterAuth({ appName: "قطاف", secret: env.BETTER_AUTH_SECRET, baseURL: appUrl, trustedOrigins: [appUrl, "https://*-qitaff.vercel.app"], database: prismaAdapter(db, { provider: "postgresql", }), session: { expiresIn: 259200, // 3 days, then expires updateAge: 86400, // 1 day, check daily }, account: { accountLinking: { trustedProviders: ["google"], }, }, emailVerification: { async sendVerificationEmail({ user, url }) { console.log("جاري إرسال بريد التحقق إلى", user.email); const res = await resend.emails.send({ from: env.BETTER_AUTH_EMAIL, to: user.email, subject: "تحقق من عنوان بريدك الإلكتروني", react: VerificationEmail({ url }), }); console.log(res, user.email); }, sendOnSignUp: true, }, emailAndPassword: { enabled: true, requireEmailVerification: true, emailVerification: { sendOnSignUp: true, }, sendResetPassword: async ({ user, url, token }, request) => { await resend.emails.send({ from: env.BETTER_AUTH_EMAIL, to: user.email, subject: "إعادة تعيين كلمة المرور", react: reactResetPasswordEmail({ username: user.email, resetLink: url, }), }); }, }, socialProviders: { google: { clientId: env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, clientSecret: env.GOOGLE_CLIENT_SECRET, redirectURI: `${appUrl}/api/auth/callback/google`, }, }, verification: { modelName: "Verification", }, plugins: [ organization({ allowUserToCreateOrganization: async (user) => { const currentUser = await getCurrentUser(); const { isADMIN, isCOMPANY } = userRole(currentUser!); const allowedUsers = isADMIN || isCOMPANY; return allowedUsers; }, async sendInvitationEmail(data) { await resend.emails.send({ from: env.BETTER_AUTH_EMAIL, to: data.email, subject: "تمت دعوتك للانضمام إلى شركة تخليص", react: reactInvitationEmail({ username: data.email, invitedByUsername: data.inviter.user.name, invitedByEmail: data.inviter.user.email, teamName: data.organization.name, inviteLink: `${appUrl}/accept-invitation/${data.id}`, }), }); }, }), twoFactor({ issuer: "qitaff", otpOptions: { async sendOTP({ user, otp }) { await resend.emails.send({ from: env.BETTER_AUTH_EMAIL, to: user.email, subject: "رمز التحقق الخاص بك", html: `رمز التحقق الخاص بك هو ${otp}`, }); }, }, }), passkey({ rpID: isDevEnv ? "localhost" : "qitaff.com", }), bearer(), admin({ adminRole: ["ADMIN"], defaultRole: "COMPANY", adminUserIds: [adminUserId], }), oAuthProxy(), nextCookies(), username(), ], onAPIError: { throw: false, onError: (error, ctx) => { console.error("Auth error:", error); const errorMessage = encodeURIComponent(JSON.stringify(error)); window.location.href = `/auth/error#${errorMessage}`; }, errorURL: "/auth/error", }, });