Initial commit: Lageplan v1.0 - Next.js 15.5, React 19
This commit is contained in:
111
src/lib/email.ts
Normal file
111
src/lib/email.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import nodemailer from 'nodemailer'
|
||||
import { prisma } from './db'
|
||||
|
||||
export interface SmtpConfig {
|
||||
host: string
|
||||
port: number
|
||||
secure: boolean
|
||||
user: string
|
||||
pass: string
|
||||
fromName: string
|
||||
fromEmail: string
|
||||
}
|
||||
|
||||
// Get SMTP settings from DB (SystemSetting table)
|
||||
export async function getSmtpConfig(): Promise<SmtpConfig | null> {
|
||||
try {
|
||||
const settings = await (prisma as any).systemSetting.findMany({
|
||||
where: { category: 'smtp' },
|
||||
})
|
||||
if (!settings || settings.length === 0) return null
|
||||
|
||||
const map: Record<string, string> = {}
|
||||
for (const s of settings) {
|
||||
map[s.key] = s.value
|
||||
}
|
||||
|
||||
if (!map['smtp_host'] || !map['smtp_user']) return null
|
||||
|
||||
return {
|
||||
host: map['smtp_host'],
|
||||
port: parseInt(map['smtp_port'] || '587'),
|
||||
secure: map['smtp_secure'] === 'true',
|
||||
user: map['smtp_user'],
|
||||
pass: map['smtp_pass'] || '',
|
||||
fromName: map['smtp_from_name'] || 'Lageplan',
|
||||
fromEmail: map['smtp_from_email'] || map['smtp_user'],
|
||||
}
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// Save SMTP settings to DB
|
||||
export async function saveSmtpConfig(config: Partial<SmtpConfig>): Promise<void> {
|
||||
const entries: { key: string; value: string; isSecret: boolean }[] = []
|
||||
if (config.host !== undefined) entries.push({ key: 'smtp_host', value: config.host, isSecret: false })
|
||||
if (config.port !== undefined) entries.push({ key: 'smtp_port', value: String(config.port), isSecret: false })
|
||||
if (config.secure !== undefined) entries.push({ key: 'smtp_secure', value: String(config.secure), isSecret: false })
|
||||
if (config.user !== undefined) entries.push({ key: 'smtp_user', value: config.user, isSecret: false })
|
||||
if (config.pass !== undefined) entries.push({ key: 'smtp_pass', value: config.pass, isSecret: true })
|
||||
if (config.fromName !== undefined) entries.push({ key: 'smtp_from_name', value: config.fromName, isSecret: false })
|
||||
if (config.fromEmail !== undefined) entries.push({ key: 'smtp_from_email', value: config.fromEmail, isSecret: false })
|
||||
|
||||
for (const entry of entries) {
|
||||
await (prisma as any).systemSetting.upsert({
|
||||
where: { key: entry.key },
|
||||
update: { value: entry.value, isSecret: entry.isSecret },
|
||||
create: { key: entry.key, value: entry.value, isSecret: entry.isSecret, category: 'smtp' },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Create nodemailer transport from DB settings
|
||||
async function createTransport() {
|
||||
const config = await getSmtpConfig()
|
||||
if (!config) throw new Error('SMTP nicht konfiguriert')
|
||||
|
||||
return nodemailer.createTransport({
|
||||
host: config.host,
|
||||
port: config.port,
|
||||
secure: config.secure,
|
||||
auth: {
|
||||
user: config.user,
|
||||
pass: config.pass,
|
||||
},
|
||||
tls: {
|
||||
rejectUnauthorized: false,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Send email
|
||||
export async function sendEmail(to: string, subject: string, html: string): Promise<boolean> {
|
||||
try {
|
||||
const config = await getSmtpConfig()
|
||||
if (!config) throw new Error('SMTP nicht konfiguriert')
|
||||
const transport = await createTransport()
|
||||
|
||||
await transport.sendMail({
|
||||
from: `"${config.fromName}" <${config.fromEmail}>`,
|
||||
to,
|
||||
subject,
|
||||
html,
|
||||
})
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Email send error:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// Test SMTP connection
|
||||
export async function testSmtpConnection(): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const transport = await createTransport()
|
||||
await transport.verify()
|
||||
return { success: true }
|
||||
} catch (error) {
|
||||
return { success: false, error: error instanceof Error ? error.message : 'Verbindung fehlgeschlagen' }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user