// @/lib/auth/index.ts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/lib/db";
import { redis } from "../rateLimiter";
import { sendPassResetMail, sendVerificationMail } from "../email/auth-mails";
import { pageLinks } from "../constants/links";
import { nextCookies } from "better-auth/next-js";
export const auth = betterAuth({
basePath: "http://localhost:3000/",
database: drizzleAdapter(db, { provider: "pg" }),
secondaryStorage: {
get: async (key) => await redis.get(key),
set: async (key, value, ttl) => {
if (ttl) await redis.set(key, value, { ex: ttl });
else await redis.set(key, value);
},
delete: async (key) => {
await redis.del(key);
},
prefix: "auth-ratelimit",
},
rateLimit: {
window: 60,
max: 6,
customRules: {
"/sign-in/email": { window: 3600, max: 6 },
},
storage: "secondary-storage",
},
emailAndPassword: {
enabled: true,
minPasswordLength: 6,
maxPasswordLength: 64,
autoSignIn: false,
requireEmailVerification: true,
sendResetPassword: async ({ user, url }) =>
await sendPassResetMail({ email: user.email, url }),
},
account: { accountLinking: { enabled: true, trustedProviders: ["google"] } },
socialProviders: {
google: {
prompt: "select_account",
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
const link = `${url}?callback=${pageLinks.onSignIn}`;
return await sendVerificationMail({ email: user.email, url: link });
},
autoSignInAfterVerification: true,
sendOnSignUp: true,
},
plugins: [nextCookies()],
});
// @/lib/auth/index.ts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/lib/db";
import { redis } from "../rateLimiter";
import { sendPassResetMail, sendVerificationMail } from "../email/auth-mails";
import { pageLinks } from "../constants/links";
import { nextCookies } from "better-auth/next-js";
export const auth = betterAuth({
basePath: "http://localhost:3000/",
database: drizzleAdapter(db, { provider: "pg" }),
secondaryStorage: {
get: async (key) => await redis.get(key),
set: async (key, value, ttl) => {
if (ttl) await redis.set(key, value, { ex: ttl });
else await redis.set(key, value);
},
delete: async (key) => {
await redis.del(key);
},
prefix: "auth-ratelimit",
},
rateLimit: {
window: 60,
max: 6,
customRules: {
"/sign-in/email": { window: 3600, max: 6 },
},
storage: "secondary-storage",
},
emailAndPassword: {
enabled: true,
minPasswordLength: 6,
maxPasswordLength: 64,
autoSignIn: false,
requireEmailVerification: true,
sendResetPassword: async ({ user, url }) =>
await sendPassResetMail({ email: user.email, url }),
},
account: { accountLinking: { enabled: true, trustedProviders: ["google"] } },
socialProviders: {
google: {
prompt: "select_account",
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
const link = `${url}?callback=${pageLinks.onSignIn}`;
return await sendVerificationMail({ email: user.email, url: link });
},
autoSignInAfterVerification: true,
sendOnSignUp: true,
},
plugins: [nextCookies()],
});