Initial commit
This commit is contained in:
128
lib/auth.ts
Normal file
128
lib/auth.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
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";
|
||||
|
||||
Reference in New Issue
Block a user