220 lines
6.2 KiB
TypeScript
220 lines
6.2 KiB
TypeScript
'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<boolean> {
|
|
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: '<b>Diese Test-E-Mail wurde erfolgreich während des Webshop-Setups versendet.</b>',
|
|
})
|
|
|
|
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}`,
|
|
}
|
|
}
|
|
}
|