'use server' import { createClient } from '@/lib/supabase/server' import { createAdminClient } from '@/lib/supabase/admin' import { headers } from 'next/headers' import { sendLockoutEmail } from '@/lib/utils/email' import { sendMail } from '@/utils/mail' export async function signIn(email: string, password: string) { try { const supabase = await createClient() const { data, error } = await supabase.auth.signInWithPassword({ email, password, }) if (error) { // Track failed attempts const { data: usr, error: usrError } = await supabase .from('users') .select('failed_attempts, email') .eq('email', email) .single() const attempts = (usr?.failed_attempts ?? 0) + 1 // Update attempts count await supabase .from('users') .update({ failed_attempts: attempts }) .eq('email', email) // Lock account on 5th failure if (attempts >= 5) { await supabase .from('users') .update({ role: 'gesperrt' }) .eq('email', email) // Notify admin await sendLockoutEmail('info@hephex.de') return { success: false, error: 'Konto gesperrt nach 5 Fehlversuchen.' } } return { success: false, error: error.message } } const userId = data.user?.id if (userId) { const adminClient = createAdminClient() let { data: userData, error: userError } = await adminClient .from('users') .select('role') .eq('id', userId) .single() if (userError || !userData) { // Fallback: create database records if missing for this authenticated user try { const adminSupabase = createAdminClient() // Ensure profile exists await adminSupabase.from('profiles').insert([{ id: userId }]).select() // Ensure user exists const { data: insertedUser, error: insertError } = await adminSupabase .from('users') .insert([{ id: userId, role: 'partner' }]) .select('role') .single() if (!insertError && insertedUser) { userData = insertedUser userError = null } } catch (adminErr) { console.error("Failed to backfill user records:", adminErr) } } if (userError || !userData || (userData.role !== 'partner' && userData.role !== 'admin')) { await supabase.auth.signOut() if (userData?.role === 'gesperrt') { return { success: false, error: "Ihr Konto wurde gesperrt. Bitte wenden Sie sich an den Administrator." } } return { success: false, error: "Zugriff verweigert. Nur registrierte Partner dürfen sich anmelden." } } // Andere aktive Sitzungen beenden await supabase.auth.signOut({ scope: 'others' }) return { success: true, role: userData.role } } return { success: true, role: 'partner' } } catch (err: any) { console.error("SignIn error:", err) return { success: false, error: err?.message || "Ein unerwarteter Fehler ist aufgetreten." } } } export async function signUp(email: string, password: string) { throw new Error("Registrierung ist deaktiviert.") } export async function signOut() { const supabase = await createClient() const { error } = await supabase.auth.signOut() if (error) { throw new Error(error.message) } return { success: true } } function getBeautifulEmailHtml(title: string, messageHtml: string, buttonText?: string, buttonUrl?: string) { return `

${title}

${messageHtml} ${buttonText && buttonUrl ? `
${buttonText}

Falls der Button nicht funktioniert, kopieren Sie bitte diesen Link in Ihren Browser:
${buttonUrl}

` : ''}

Dies ist eine automatisch generierte E-Mail.
© ${new Date().getFullYear()} CASPOS Shop. Alle Rechte vorbehalten.

`; } export async function resetPassword(email: string) { try { const admin = createAdminClient() const { data, error } = await admin.auth.admin.generateLink({ type: 'recovery', email, }) if (error) { return { success: false, error: error.message } } const tokenHash = (data as any)?.properties?.hashed_token; if (!tokenHash) { return { success: false, error: 'Wiederherstellungs-Token konnte nicht generiert werden.' } } const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://staging.hephex.de' const resetLink = `${siteUrl}/auth/verify-link?token_hash=${tokenHash}&type=recovery&next=/auth/update-password` const messageHtml = `

Hallo,

Sie haben das Zurücksetzen Ihres Passworts angefordert.

Bitte klicken Sie auf den untenstehenden Button, um ein neues Passwort festzulegen:

`; await sendMail({ to: email, subject: 'Passwort zurücksetzen – CASPOS Shop', text: `Hallo,\n\nSie haben das Zurücksetzen Ihres Passworts angefordert.\n\nBitte klicken Sie auf den folgenden Link, um ein neues Passwort festzulegen:\n${resetLink}\n\nViele Grüße,\nIhr CASPOS Shop-Team`, html: getBeautifulEmailHtml('Passwort zurücksetzen', messageHtml, 'Passwort zurücksetzen', resetLink) }) return { success: true } } catch (err: any) { console.error('Password reset error:', err) return { success: false, error: err.message || 'Fehler beim Senden der Passwort-Zurücksetzen-E-Mail.' } } } export async function updatePassword(password: string) { try { const supabase = await createClient() const { error } = await supabase.auth.updateUser({ password }) if (error) { return { success: false, error: error.message } } return { success: true } } catch (err: any) { console.error('Update password error:', err) return { success: false, error: err.message || 'Fehler beim Aktualisieren des Passworts.' } } } export async function verifyAdmin() { const supabase = await createClient() const { data: { user } } = await supabase.auth.getUser() if (!user) throw new Error("Nicht authentifiziert.") const { data: userData, error } = await supabase .from('users') .select('role') .eq('id', user.id) .single() if (error || !userData || userData.role !== 'admin') { throw new Error("Zugriff verweigert. Nur Administratoren erlaubt.") } return user }