'use server' import { createAdminClient } from '@/lib/supabase/admin' import { revalidatePath } from 'next/cache' import nodemailer from 'nodemailer' export type AdminSetupData = { email: string password: string companyName: string firstName: string lastName: string } export type BrandingSetupData = { street: string zip: string city: string billingStreet: string billingZip: string billingCity: string sameBillingAddress: boolean colorScheme: string primaryColor: string accentColor: string } export type SmtpSetupData = { host: string port: number secure: boolean user: string pass: string } /** * Checks if any user exists in the public.users table. * If count is 0, setup is required. */ export async function isSetupNeeded(): Promise { try { const admin = createAdminClient() // 1. Check if any user exists in Supabase Auth const { data: authData, error: authError } = await admin.auth.admin.listUsers({ perPage: 1 }) if (!authError && authData && authData.users && authData.users.length > 0) { // Mindestens ein Auth-Benutzer vorhanden -> Setup ist beendet! return false } // 2. Zusatzprüfung public.users Tabelle const { count, error: dbError } = await admin .from('users') .select('id', { count: 'exact' }) if (!dbError && typeof count === 'number' && count > 0) { return false } return true } catch (e) { console.error('Exception checking setup status:', e) return false } } /** * Completes the initial setup by creating the first admin user, * updating their role and profile, and storing branding & SMTP settings. */ export async function completeSetup( adminData: AdminSetupData, brandingData: BrandingSetupData, smtpData: SmtpSetupData ): Promise<{ success: boolean; error?: string }> { try { const needed = await isSetupNeeded() if (!needed) { return { success: false, error: 'Setup bereits abgeschlossen.' } } const admin = createAdminClient() // 1. Create user in Supabase Auth const { data: authData, error: authError } = await admin.auth.admin.createUser({ email: adminData.email, password: adminData.password, email_confirm: true, }) if (authError || !authData.user) { return { success: false, error: `Fehler beim Erstellen des Admin-Kontos: ${authError?.message}` } } const userId = authData.user.id // 2. Set user role to admin in public.users using Service Role Client const { error: roleError } = await admin .from('users') .upsert({ id: userId, role: 'admin', }, { onConflict: 'id' }) if (roleError) { console.error('Error setting user role to admin:', roleError) return { success: false, error: `Fehler beim Zuweisen der Admin-Rolle: ${roleError.message}` } } // 3. Update company and name details in public.profiles const { error: profileError } = await admin .from('profiles') .update({ company_name: adminData.companyName, first_name: adminData.firstName, last_name: adminData.lastName, email: adminData.email, }) .eq('id', userId) if (profileError) { console.error('Error updating admin profile:', profileError) } // 4. Store Branding settings in public.settings (id = 'branding') const { error: brandingError } = await admin .from('settings') .upsert({ id: 'branding', company_name: adminData.companyName, street: brandingData.street, zip: brandingData.zip, city: brandingData.city, billing_street: brandingData.sameBillingAddress ? brandingData.street : brandingData.billingStreet, billing_zip: brandingData.sameBillingAddress ? brandingData.zip : brandingData.billingZip, billing_city: brandingData.sameBillingAddress ? brandingData.city : brandingData.billingCity, same_billing_address: brandingData.sameBillingAddress, color_scheme: brandingData.colorScheme, primary_color: brandingData.primaryColor, accent_color: brandingData.accentColor, updated_at: new Date().toISOString(), }) if (brandingError) { console.error('Error saving branding settings:', brandingError) } // 5. Store SMTP configuration in public.settings (id = 'smtp') if (smtpData.host && smtpData.host.trim().length > 0) { const { error: smtpError } = await admin .from('settings') .upsert({ id: 'smtp', host: smtpData.host, port: smtpData.port, secure: smtpData.secure, user: smtpData.user, pass: smtpData.pass, updated_at: new Date().toISOString(), }) if (smtpError) { console.error('Error saving SMTP settings:', smtpError) } } revalidatePath('/') return { success: true } } catch (e: any) { console.error('Exception during completeSetup:', e) return { success: false, error: e.message || 'Unerwarteter Fehler beim Setup.' } } } export async function testSmtpConfig( smtpData: SmtpSetupData, recipient: string ): Promise<{ success: boolean; message: string }> { try { if (!smtpData.host || !smtpData.user) { return { success: false, message: 'Bitte Host und Benutzername ausfüllen.' } } const transporter = nodemailer.createTransport({ host: smtpData.host, port: Number(smtpData.port) || 587, secure: smtpData.secure, auth: { user: smtpData.user, pass: smtpData.pass || '', }, tls: { rejectUnauthorized: false, }, }) const info = await transporter.sendMail({ from: smtpData.user, to: recipient || smtpData.user, subject: 'CASPOS Setup Test-E-Mail', text: 'Diese Test-E-Mail wurde erfolgreich während des Webshop-Setups versendet.', html: 'Diese Test-E-Mail wurde erfolgreich während des Webshop-Setups versendet.', }) return { success: true, message: `Test-E-Mail erfolgreich gesendet an ${recipient || smtpData.user}! (ID: ${info.messageId})`, } } catch (err: any) { console.error('SMTP test error:', err) return { success: false, message: `SMTP-Fehler: ${err.message || err}`, } } }