import { betterAuth } from 'better-auth' import Database from 'better-sqlite3' import { organization, jwt } from 'better-auth/plugins' import { resend } from './mail' import { accessControl, employerRole, worksCouncilMemberRole, employeeRole, adminRole, ownerRole, ROLES, type LegalRole } from './permissions' const db = new Database('./sqlite.db') export const auth = betterAuth({ database: db, onAPIError: { throw: true }, emailAndPassword: { enabled: true, autoSignIn: false, minPasswordLength: 1 }, trustedOrigins: ['http://localhost:3001'], plugins: [ jwt({ jwt: { issuer: 'http://192.168.178.114:3001', expirationTime: '1yr', definePayload: ({ user, session }) => { let userRoles: string[] = [] if (session.activeOrganizationId) { try { const roleQuery = db.prepare(` SELECT role FROM member WHERE userId = ? AND organizationId = ? `) const memberRole = roleQuery.get(user.id, session.activeOrganizationId) as { role: string } | undefined if (memberRole?.role) { userRoles = [memberRole.role] } } catch (error) { console.error('Error querying user role:', error) } } return { id: user.id, name: user.name, roles: userRoles, organizationId: session.activeOrganizationId } } }, jwks: { keyPairConfig: { // Supported by NimbusJwtDecoder alg: 'ES512' } } }), organization({ // Pass the access control instance and roles ac: accessControl, roles: { [ROLES.EMPLOYER]: employerRole, [ROLES.WORKS_COUNCIL_MEMBER]: worksCouncilMemberRole, [ROLES.EMPLOYEE]: employeeRole, [ROLES.ADMIN]: adminRole, [ROLES.OWNER]: ownerRole }, creatorRole: ROLES.ADMIN, // OWNER fixen here! async sendInvitationEmail(data) { console.log('Sending invitation email', data) const inviteLink = `http://192.168.178.114:3001/accept-invitation/${data.id}` const roleDisplayNames = { [ROLES.EMPLOYER]: 'Arbeitgeber', [ROLES.EMPLOYEE]: 'Arbeitnehmer', [ROLES.WORKS_COUNCIL_MEMBER]: 'Betriebsrat', [ROLES.ADMIN]: 'Administrator', [ROLES.OWNER]: 'Eigentümer' } const roleDisplayName = roleDisplayNames[data.role as LegalRole] || data.role try { const result = await resend.emails.send({ from: 'Acme ', to: data.email, subject: `Einladung als ${roleDisplayName} - ${data.organization.name}`, html: `

Einladung zur Organisation ${data.organization.name}

Sie wurden als ${roleDisplayName} eingeladen.

Einladung annehmen

Diese Einladung läuft ab am: ${new Date(data.invitation.expiresAt).toLocaleDateString('de-DE')}

` }) if (result.error) { throw new Error(`Email sending failed: ${result.error.message || result.error.name || 'Unknown error'}`) } console.log('Email invite link:', inviteLink) console.log('Invitation email sent successfully to:', data.email, 'with ID:', result.data?.id) } catch (error) { console.error('Failed to send invitation email:', error) // Log specific error details for debugging const errorObj = error as { response?: { status: number; data: unknown }; message?: string } if (errorObj.response) { console.error('HTTP Status:', errorObj.response.status) console.error('Response data:', errorObj.response.data) } // Re-throw the error so BetterAuth knows the email failed const message = errorObj.message || String(error) throw new Error(`Email sending failed: ${message}`) } } }) ] }) export { ROLES } export type { LegalRole }