mirror of
https://github.com/vas3k/TaxHacker.git
synced 2026-01-03 04:00:32 -06:00
112 lines
2.9 KiB
TypeScript
112 lines
2.9 KiB
TypeScript
import config from "@/lib/config"
|
|
import { getSelfHostedUser, getUserByEmail, getUserById, SELF_HOSTED_USER } from "@/models/users"
|
|
import { User } from "@/prisma/client"
|
|
import { betterAuth } from "better-auth"
|
|
import { prismaAdapter } from "better-auth/adapters/prisma"
|
|
import { APIError } from "better-auth/api"
|
|
import { nextCookies } from "better-auth/next-js"
|
|
import { emailOTP } from "better-auth/plugins/email-otp"
|
|
import { headers } from "next/headers"
|
|
import { redirect } from "next/navigation"
|
|
import { prisma } from "./db"
|
|
import { resend, sendOTPCodeEmail } from "./email"
|
|
|
|
export type UserProfile = {
|
|
id: string
|
|
name: string
|
|
email: string
|
|
avatar?: string
|
|
membershipPlan: string
|
|
storageUsed: number
|
|
storageLimit: number
|
|
aiBalance: number
|
|
}
|
|
|
|
export const auth = betterAuth({
|
|
database: prismaAdapter(prisma, { provider: "postgresql" }),
|
|
appName: config.app.title,
|
|
baseURL: config.app.baseURL,
|
|
secret: config.auth.secret,
|
|
email: {
|
|
provider: "resend",
|
|
from: config.email.from,
|
|
resend,
|
|
},
|
|
session: {
|
|
strategy: "jwt",
|
|
expiresIn: 180 * 24 * 60 * 60, // 365 days
|
|
updateAge: 24 * 60 * 60, // 24 hours
|
|
cookieCache: {
|
|
enabled: true,
|
|
maxAge: 365 * 24 * 60 * 60, // 365 days
|
|
},
|
|
},
|
|
advanced: {
|
|
generateId: false,
|
|
cookiePrefix: "taxhacker",
|
|
},
|
|
plugins: [
|
|
emailOTP({
|
|
disableSignUp: config.auth.disableSignup,
|
|
otpLength: 6,
|
|
expiresIn: 10 * 60, // 10 minutes
|
|
sendVerificationOTP: async ({ email, otp }) => {
|
|
const user = await getUserByEmail(email)
|
|
if (!user) {
|
|
throw new APIError("NOT_FOUND", { message: "User with this email does not exist" })
|
|
}
|
|
await sendOTPCodeEmail({ email, otp })
|
|
},
|
|
}),
|
|
nextCookies(), // make sure this is the last plugin in the array
|
|
],
|
|
})
|
|
|
|
export async function getSession() {
|
|
if (config.selfHosted.isEnabled) {
|
|
const user = await getSelfHostedUser()
|
|
return user ? { user } : null
|
|
}
|
|
|
|
return await auth.api.getSession({
|
|
headers: await headers(),
|
|
})
|
|
}
|
|
|
|
export async function getCurrentUser(): Promise<User> {
|
|
if (config.selfHosted.isEnabled) {
|
|
const user = await getSelfHostedUser()
|
|
if (user) {
|
|
return user
|
|
} else {
|
|
redirect(config.selfHosted.redirectUrl)
|
|
}
|
|
}
|
|
|
|
// Try to return user from session
|
|
const session = await getSession()
|
|
if (session && session.user) {
|
|
const user = await getUserById(session.user.id)
|
|
if (user) {
|
|
return user
|
|
}
|
|
}
|
|
|
|
// No session or user found
|
|
redirect(config.auth.loginUrl)
|
|
}
|
|
|
|
export function isSubscriptionExpired(user: User) {
|
|
if (config.selfHosted.isEnabled) {
|
|
return false
|
|
}
|
|
return user.membershipExpiresAt && user.membershipExpiresAt < new Date()
|
|
}
|
|
|
|
export function isAiBalanceExhausted(user: User) {
|
|
if (config.selfHosted.isEnabled || user.membershipPlan === SELF_HOSTED_USER.membershipPlan) {
|
|
return false
|
|
}
|
|
return user.aiBalance <= 0
|
|
}
|