import { admin, customSession, multiSession, username, } from "better-auth/plugins"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { UserRoleMap } from "@domains/user/data"; import { getRedisInstance } from "@pkg/keystore"; import { settings } from "@core/settings"; import { betterAuth } from "better-auth"; import { logger } from "@pkg/logger"; import { db, schema } from "@pkg/db"; const COOKIE_CACHE_MAX_AGE = 60 * 5; const USERNAME_REGEX = /^[a-zA-Z0-9_]+$/; export const auth = betterAuth({ trustedOrigins: ["http://localhost:5173", settings.betterAuthUrl], advanced: { useSecureCookies: settings.nodeEnv === "production" }, appName: settings.appName, emailAndPassword: { enabled: true, disableSignUp: true, requireEmailVerification: false, }, plugins: [ customSession(async ({ user, session }) => { session.id = session.token; return { user, session }; }), username({ minUsernameLength: 5, maxUsernameLength: 20, usernameValidator: async (username) => { return USERNAME_REGEX.test(username); }, }), admin({ defaultRole: UserRoleMap.admin, defaultBanReason: "Stop fanum taxing the server bub, losing aura points fr", defaultBanExpiresIn: 60 * 60 * 24, }), multiSession({ maximumSessions: 5 }), ], logger: { log: (level, message, metadata) => { logger.log(level, message, metadata); }, level: "debug", }, database: drizzleAdapter(db, { provider: "pg", schema: { ...schema } }), secondaryStorage: { get: async (key) => { const redis = getRedisInstance(); return await redis.get(key); }, set: async (key, value, ttl) => { const redis = getRedisInstance(); if (ttl) { await redis.setex(key, ttl, value); } else { await redis.set(key, value); } }, delete: async (key) => { const redis = getRedisInstance(); const out = await redis.del(key); if (!out && out !== 0) { return null; } return out.toString() as any; }, }, session: { modelName: "session", expiresIn: 60 * 60 * 24 * 7, updateAge: 60 * 60 * 24, cookieCache: { enabled: true, maxAge: COOKIE_CACHE_MAX_AGE, }, }, user: { modelName: "user", additionalFields: { onboardingDone: { type: "boolean", defaultValue: false, required: false, }, last2FAVerifiedAt: { type: "date", required: false }, parentId: { required: false, type: "string" }, }, }, }); // - - -