2025-11-24 01:00:50 +01:00
|
|
|
import * as CONSTANTS from './constants';
|
2025-11-01 15:49:29 +01:00
|
|
|
import * as schema from '@db/schema';
|
|
|
|
|
|
|
|
|
|
import { admin, anonymous } from 'better-auth/plugins';
|
2025-11-24 01:00:50 +01:00
|
|
|
import { sendChangeEmailConfirmation, sendVerificationEmail } from './auth/email-verification';
|
2025-11-01 15:49:29 +01:00
|
|
|
|
2025-11-24 01:00:50 +01:00
|
|
|
import { betterAuth } from 'better-auth/minimal';
|
|
|
|
|
import { createProfileHook } from './auth/hooks/create-profile';
|
2025-11-01 15:49:29 +01:00
|
|
|
import { db } from '@db/drizzle';
|
|
|
|
|
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
|
2025-11-24 01:00:50 +01:00
|
|
|
import { config as emailAndPassword } from './auth/email-password';
|
2026-03-09 11:18:22 +01:00
|
|
|
import { sso } from '@better-auth/sso';
|
2025-11-24 01:00:50 +01:00
|
|
|
import { syncUserWithProfile } from './auth/hooks/sync-user';
|
2026-03-09 11:18:22 +01:00
|
|
|
import { tokenExchange } from './auth/plugins/token-exchange';
|
2025-11-01 15:49:29 +01:00
|
|
|
|
2025-12-24 04:18:39 +00:00
|
|
|
export const auth: ReturnType<typeof betterAuth> = betterAuth({
|
2025-11-24 01:00:50 +01:00
|
|
|
baseURL: CONSTANTS.BASE_URL,
|
2025-11-01 15:49:29 +01:00
|
|
|
database: drizzleAdapter(db, {
|
|
|
|
|
provider: 'pg',
|
2025-12-02 09:54:38 +01:00
|
|
|
schema
|
|
|
|
|
// debugLogs: true
|
2025-11-01 15:49:29 +01:00
|
|
|
}),
|
2025-11-24 01:00:50 +01:00
|
|
|
emailAndPassword: emailAndPassword,
|
|
|
|
|
user: {
|
|
|
|
|
changeEmail: {
|
|
|
|
|
enabled: true,
|
|
|
|
|
sendChangeEmailConfirmation
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
emailVerification: {
|
|
|
|
|
enabled: true,
|
|
|
|
|
sendVerificationEmail
|
2025-11-01 15:49:29 +01:00
|
|
|
},
|
|
|
|
|
socialProviders: {
|
|
|
|
|
google: {
|
|
|
|
|
clientId: process.env.GOOGLE_CLIENT_ID!,
|
2025-11-24 01:00:50 +01:00
|
|
|
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
|
|
|
accessType: 'offline',
|
|
|
|
|
prompt: 'select_account consent'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
trustedOrigins: CONSTANTS.TRUSTED_ORIGINS,
|
|
|
|
|
advanced: {
|
|
|
|
|
cookiePrefix: 'classroomio',
|
|
|
|
|
crossSubDomainCookies: {
|
2026-03-09 11:18:22 +01:00
|
|
|
enabled: true,
|
|
|
|
|
...(CONSTANTS.AUTH_COOKIE_DOMAIN ? { domain: CONSTANTS.AUTH_COOKIE_DOMAIN } : {})
|
2025-11-24 01:00:50 +01:00
|
|
|
},
|
|
|
|
|
database: {
|
|
|
|
|
generateId: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
account: {
|
|
|
|
|
storeAccountCookie: true
|
|
|
|
|
},
|
|
|
|
|
session: {
|
|
|
|
|
expiresIn: 60 * 60 * 24 * 7, // 7 days
|
|
|
|
|
updateAge: 60 * 60 * 24, // 1 day (every 1 day the session expiration is updated)
|
|
|
|
|
cookieCache: {
|
|
|
|
|
enabled: true,
|
|
|
|
|
maxAge: 60 * 60 // 1 hour
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
databaseHooks: {
|
|
|
|
|
user: {
|
|
|
|
|
create: {
|
|
|
|
|
after: async (user) => {
|
|
|
|
|
await createProfileHook(user);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
update: {
|
|
|
|
|
after: async (user) => {
|
2025-12-02 09:54:38 +01:00
|
|
|
console.log('update user', user);
|
2025-11-24 01:00:50 +01:00
|
|
|
await syncUserWithProfile(user);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-01 15:49:29 +01:00
|
|
|
}
|
|
|
|
|
},
|
2026-03-09 11:18:22 +01:00
|
|
|
plugins: [
|
|
|
|
|
admin(),
|
|
|
|
|
anonymous(),
|
|
|
|
|
sso({
|
|
|
|
|
// OIDC providers are registered dynamically per organization
|
|
|
|
|
// via the admin API (auth.api.registerSSOProvider)
|
|
|
|
|
}),
|
|
|
|
|
tokenExchange()
|
|
|
|
|
]
|
2025-11-01 15:49:29 +01:00
|
|
|
});
|