feat: add better auth sqlite runtime and server-side session flow
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import "server-only";
|
||||
|
||||
import { betterAuth } from "better-auth";
|
||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||
import { nextCookies } from "better-auth/next-js";
|
||||
import { getServerConfig } from "@/server/config";
|
||||
import { getSqliteConnection } from "@/server/db/client";
|
||||
import * as schema from "@/server/db/schema";
|
||||
import {
|
||||
completeFirstFreelancerSetup,
|
||||
recordAuthAuditEvent,
|
||||
reserveFirstFreelancerSetup,
|
||||
} from "@/server/auth/setup";
|
||||
|
||||
const config = getServerConfig();
|
||||
|
||||
export const auth = betterAuth({
|
||||
appName: "Neta",
|
||||
baseURL: config.appUrl,
|
||||
trustedOrigins: config.trustedOrigins,
|
||||
secret: config.betterAuthSecret,
|
||||
database: drizzleAdapter(getSqliteConnection().db, {
|
||||
provider: "sqlite",
|
||||
schema,
|
||||
transaction: true,
|
||||
}),
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
minPasswordLength: 8,
|
||||
maxPasswordLength: 128,
|
||||
requireEmailVerification: false,
|
||||
},
|
||||
rateLimit: {
|
||||
enabled: true,
|
||||
window: 60,
|
||||
max: 60,
|
||||
customRules: {
|
||||
"/sign-in/email": {
|
||||
window: 60,
|
||||
max: 10,
|
||||
},
|
||||
"/sign-up/email": {
|
||||
window: 300,
|
||||
max: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
advanced: {
|
||||
useSecureCookies: config.nodeEnv === "production",
|
||||
cookiePrefix: "neta",
|
||||
defaultCookieAttributes: {
|
||||
httpOnly: true,
|
||||
sameSite: "lax",
|
||||
secure: config.nodeEnv === "production",
|
||||
path: "/",
|
||||
},
|
||||
},
|
||||
databaseHooks: {
|
||||
user: {
|
||||
create: {
|
||||
before: async (user) => {
|
||||
const isReserved = await reserveFirstFreelancerSetup(user.email);
|
||||
return isReserved;
|
||||
},
|
||||
after: async (user) => {
|
||||
await completeFirstFreelancerSetup(user);
|
||||
},
|
||||
},
|
||||
},
|
||||
session: {
|
||||
create: {
|
||||
after: async (session) => {
|
||||
await recordAuthAuditEvent({
|
||||
type: "login_succeeded",
|
||||
authUserId: session.userId,
|
||||
metadata: { source: "session_create" },
|
||||
});
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
after: async (session) => {
|
||||
await recordAuthAuditEvent({
|
||||
type: "logout_succeeded",
|
||||
authUserId: session.userId,
|
||||
metadata: { source: "session_delete" },
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [nextCookies()],
|
||||
});
|
||||
|
||||
export type Auth = typeof auth;
|
||||
|
||||
Reference in New Issue
Block a user