Aymeric Rabot 48979ec014 fix raycaster layers, polygon drag, slider undo, and grid events
- Enable EDITOR_LAYER on R3F raycaster for proper hit detection
- Fix polygon editor drag using refs and direct position passing
- Handle pointercancel events and fix pointerId access in polygon editor
- Fix slider undo by reverting to start value before resuming temporal state
- Allow grid:move during camera drag so polygon editor works while panning
- Bump better-auth to ^1.5.2 and turbo to ^2.8.12
- Remove explicit return type on createAuth for better inference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:41:19 -05:00

100 lines
2.8 KiB
TypeScript

import type { Database } from '@pascal-app/db'
import { schema } from '@pascal-app/db'
import type { BetterAuthOptions } from 'better-auth'
import { betterAuth } from 'better-auth'
import { drizzleAdapter } from 'better-auth/adapters/drizzle'
import { lastLoginMethod, magicLink } from 'better-auth/plugins'
export interface SendMagicLinkParams {
email: string
url: string
token: string
}
export interface AuthConfig {
db: Database
appName: string
baseURL: string
secret: string
/** Google OAuth client ID */
googleClientId?: string
/** Google OAuth client secret */
googleClientSecret?: string
/** Callback to send magic link emails */
sendMagicLink?: (params: SendMagicLinkParams) => Promise<void>
/** Additional plugins to add (e.g., nextCookies for web) */
additionalPlugins?: BetterAuthOptions['plugins']
}
/**
* Creates a Better Auth instance with full configuration including:
* - Magic link authentication
* - Custom session with activePropertyId
* - Session cookie caching
*/
export function createAuth(config: AuthConfig) {
return betterAuth({
appName: config.appName,
baseURL: config.baseURL,
secret: config.secret,
basePath: '/api/auth',
database: drizzleAdapter(config.db, {
provider: 'pg',
usePlural: true,
schema,
}),
advanced: {
database: {
generateId: false, // Use our prefixed nanoid IDs from schema
},
},
session: {
// Session caching to reduce database queries
cookieCache: {
enabled: true,
maxAge: 5 * 60, // Cache duration in seconds (5 minutes)
},
additionalFields: {
// Additional fields for the session table
activePropertyId: {
type: 'string',
},
},
},
// Account linking — always enabled so magic link + Google users can share accounts
account: {
accountLinking: {
enabled: true,
trustedProviders: ['google', 'email'],
},
},
// Google OAuth provider (only enabled when credentials are provided)
...(config.googleClientId &&
config.googleClientSecret && {
socialProviders: {
google: {
clientId: config.googleClientId,
clientSecret: config.googleClientSecret,
},
},
}),
plugins: [
...(config.additionalPlugins ?? []),
// Track which login method was last used (e.g., "google", "magic-link")
lastLoginMethod(),
// Magic link authentication
...(config.sendMagicLink
? [
magicLink({
sendMagicLink: config.sendMagicLink,
expiresIn: 300, // 5 minutes
disableSignUp: false, // Allow new users to sign up via magic link
}),
]
: []),
],
})
}
export type Auth = ReturnType<typeof createAuth>