betterAuth({ // Account management account: { accountLinking: { enabled: true, trustedProviders: ['google', 'facebook'] } }, // Advanced configuration advanced: { cookies: { dont_remember: { name: 'dont_remember' }, session_data: { name: 'session_data' }, session_token: { name: 'session_token' } }, crossSubDomainCookies: { domain: import.meta.env.APP_COOKIE_DOMAIN, enabled: true }, database: { generateId() { return v7() } }, defaultCookieAttributes: { httpOnly: import.meta.env.PROD, partitioned: true, sameSite: 'lax', secure: import.meta.env.PROD }, ipAddress: { ipAddressHeaders: ['x-forwarded-for', 'x-real-ip'] }, useSecureCookies: import.meta.env.PROD }, // Core configuration appName: import.meta.env.APP_NAME, basePath: '/auth/v1', baseURL: import.meta.env.APP_BASE_URL, database: drizzleAdapter(proxy(), { provider: 'pg', schema: tables, usePlural: true }), disabledPaths: [ '/sign-in/email', '/sign-up/email', '/get-session', '/sign-out', '/forget-password', '/reset-password', '/verify-email', '/send-verification-email', '/change-email', '/change-password', '/update-user', '/delete-user', '/list-sessions', '/revoke-session', '/revoke-sessions', '/revoke-other-sessions', '/list-accounts', // '/unlink-account', // "/link-social", '/refresh-token' ], emailAndPassword: { enabled: true, requireEmailVerification: true, resetPasswordTokenExpiresIn: Number(import.meta.env.APP_AUTH_RESET_PASSWORD_TOKEN_EXPIRES_IN) || 600, async sendResetPassword(data, _request) { const { sendResetPasswordEmail } = await import('./email') await sendResetPasswordEmail({ resetLink: data.url, token: data.token, user: data.user }) } }, emailVerification: { autoSignInAfterVerification: true, expiresIn: Number(import.meta.env.APP_AUTH_EMAIL_VERIFICATION_TOKEN_EXPIRES_IN) || 600, sendOnSignUp: true, async sendVerificationEmail(data, _request) { const { sendVerificationEmail } = await import('./email') await sendVerificationEmail({ token: data.token, user: data.user, verificationUrl: data.url }) } }, logger: { log(level, message, ...args) { console.log(level, message, ...args) } }, onAPIError: { errorURL: import.meta.env.PROD ? `https://posimply.com/error` : `http://localhost:3000/error` }, // Plugins plugins: [ openAPI(), ...(import.meta.env.PROD ? [haveIBeenPwned({ customPasswordCompromisedMessage: 'Please use a more secure password.' })] : []), captcha({ endpoints: [ '/sign-up/email', '/sign-in/email', '/forget-password', '/reset-password', '/change-email', '/change-password' ], provider: 'cloudflare-turnstile', secretKey: import.meta.env.APP_CLOUDFLARE_TURNSTILE_SECRET_KEY }), jwt({ jwt: { audience: `${import.meta.env.APP_NAME}.${import.meta.env.MODE}`, issuer: `${import.meta.env.APP_BASE_URL}` } }) ], secret: import.meta.env.APP_AUTH_SECRET, // Session management session: { cookieCache: { enabled: true, maxAge: Number(import.meta.env.APP_SESSION_COOKIE_CACHE_MAX_AGE) || 60 // 60 seconds Cache duration in seconds }, // 7 days expiresIn: Number(import.meta.env.APP_SESSION_EXPIRES_IN) || 604800, // 5 minutes (the session is fresh if created within the last 5 minutes) freshAge: Number(import.meta.env.APP_SESSION_FRESH_AGE) || 300, // 5 minutes (every 5 minutes the session expiration is updated) updateAge: Number(import.meta.env.APP_SESSION_UPDATE_AGE) || 86400 }, socialProviders: { facebook: { clientId: import.meta.env.APP_AUTH_FACEBOOK_CLIENT_ID, clientSecret: import.meta.env.APP_AUTH_FACEBOOK_SECRET, enabled: true, prompt: 'select_account' }, google: { clientId: import.meta.env.APP_AUTH_GOOGLE_CLIENT_ID, clientSecret: import.meta.env.APP_AUTH_GOOGLE_CLIENT_SECRET, enabled: true, prompt: 'select_account' } }, trustedOrigins: import.meta.env.APP_TRUSTED_ORIGINS, // User management user: { changeEmail: { enabled: true, async sendChangeEmailVerification(data, _request) { const { sendChangeEmailVerification } = await import('./email') await sendChangeEmailVerification(data) } }, deleteUser: { deleteTokenExpiresIn: Number(import.meta.env.APP_AUTH_DELETE_TOKEN_EXPIRES_IN) || 600, enabled: true, async sendDeleteAccountVerification(data, _request) { const { sendDeleteAccountVerification } = await import('./email') await sendDeleteAccountVerification(data) } } }, // Authentication features verification: { disableCleanup: false } })