129 lines
4.0 KiB
TypeScript
129 lines
4.0 KiB
TypeScript
import { betterAuth } from "better-auth";
|
|
import { prismaAdapter } from "better-auth/adapters/prisma";
|
|
import { getPrisma } from "./db";
|
|
import { loadSystemConfig } from "./system-config";
|
|
import { setCached, getCached, deleteCached, cacheKeys } from "./redis";
|
|
|
|
let authInstance: ReturnType<typeof betterAuth> | null = null;
|
|
|
|
export async function getAuth() {
|
|
if (authInstance) {
|
|
return authInstance;
|
|
}
|
|
|
|
const prisma = await getPrisma();
|
|
const cfg = await loadSystemConfig();
|
|
|
|
if (!prisma) {
|
|
throw new Error("Database not configured");
|
|
}
|
|
|
|
const isDevelopment = process.env.NODE_ENV === "development";
|
|
const baseURL = process.env.APP_BASE_URL ||
|
|
(isDevelopment ? "http://localhost:3001" : "https://estate-platform.com");
|
|
|
|
authInstance = betterAuth({
|
|
database: prismaAdapter(prisma, {
|
|
provider: "postgresql",
|
|
}),
|
|
secret: cfg.auth?.jwtSecret || process.env.BETTER_AUTH_SECRET || "default-secret-change-me",
|
|
baseURL: baseURL,
|
|
trustHost: true,
|
|
// Disable origin validation in development
|
|
...(isDevelopment && {
|
|
skipOriginValidation: true,
|
|
}),
|
|
csrfProtection: false, // Disable CSRF protection completely
|
|
advanced: {
|
|
useSecureCookies: !isDevelopment, // Allow non-secure cookies in development
|
|
disableMultipleTabsWarning: isDevelopment,
|
|
sessionTimeout: 86400 * 7, // 7 days
|
|
defaultCookieMaxAge: 86400 * 7, // 7 days
|
|
},
|
|
emailAndPassword: {
|
|
enabled: true,
|
|
autoSignUpDisabled: false,
|
|
minPasswordLength: 8,
|
|
maxPasswordLength: 20,
|
|
requireEmailVerification: cfg.email?.enabled || false,
|
|
},
|
|
socialProviders: {
|
|
google: {
|
|
clientId: cfg.oauth?.google?.clientId || process.env.GOOGLE_CLIENT_ID || "",
|
|
clientSecret: cfg.oauth?.google?.clientSecret || process.env.GOOGLE_CLIENT_SECRET || "",
|
|
},
|
|
github: {
|
|
clientId: cfg.oauth?.github?.clientId || process.env.GITHUB_CLIENT_ID || "",
|
|
clientSecret: cfg.oauth?.github?.clientSecret || process.env.GITHUB_CLIENT_SECRET || "",
|
|
},
|
|
facebook: {
|
|
clientId: cfg.oauth?.facebook?.clientId || process.env.FACEBOOK_CLIENT_ID || "",
|
|
clientSecret: cfg.oauth?.facebook?.clientSecret || process.env.FACEBOOK_CLIENT_SECRET || "",
|
|
},
|
|
discord: {
|
|
clientId: cfg.oauth?.discord?.clientId || process.env.DISCORD_CLIENT_ID || "",
|
|
clientSecret: cfg.oauth?.discord?.clientSecret || process.env.DISCORD_CLIENT_SECRET || "",
|
|
},
|
|
},
|
|
});
|
|
|
|
return authInstance;
|
|
}
|
|
|
|
// Session caching helper
|
|
export async function cacheSession(sessionId: string, sessionData: any) {
|
|
try {
|
|
await setCached(cacheKeys.session(sessionId), sessionData, 604800); // 7 days
|
|
} catch (error) {
|
|
console.error("[Auth] Error caching session:", error);
|
|
}
|
|
}
|
|
|
|
export async function getCachedSession(sessionId: string) {
|
|
try {
|
|
return await getCached(cacheKeys.session(sessionId));
|
|
} catch (error) {
|
|
console.error("[Auth] Error getting cached session:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function invalidateSessionCache(sessionId: string) {
|
|
try {
|
|
await deleteCached(cacheKeys.session(sessionId));
|
|
} catch (error) {
|
|
console.error("[Auth] Error invalidating session cache:", error);
|
|
}
|
|
}
|
|
|
|
// User caching helper
|
|
export async function cacheUser(userId: string, userData: any) {
|
|
try {
|
|
await setCached(cacheKeys.user(userId), userData, 3600); // 1 hour
|
|
} catch (error) {
|
|
console.error("[Auth] Error caching user:", error);
|
|
}
|
|
}
|
|
|
|
export async function getCachedUser(userId: string) {
|
|
try {
|
|
return await getCached(cacheKeys.user(userId));
|
|
} catch (error) {
|
|
console.error("[Auth] Error getting cached user:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function invalidateUserCache(userId: string) {
|
|
try {
|
|
await deleteCached(cacheKeys.user(userId));
|
|
} catch (error) {
|
|
console.error("[Auth] Error invalidating user cache:", error);
|
|
}
|
|
}
|
|
|
|
// Re-export BetterAuth session types
|
|
export type { Session } from "better-auth";
|
|
export type { User } from "better-auth";
|
|
|