feat(erinnerungen): mailserver in der app einrichten
SMTP-Server, Port, Verschluesselung, Zugang und Absender unter Mehr -> Erinnerungen, gespeichert in der neuen Tabelle app_setting. Das Passwort liegt mit AES-256-GCM verschluesselt (Schluessel aus BETTER_AUTH_SECRET), wird nie angezeigt und nicht exportiert. Die .env hat weiter Vorrang. Der Zeitplan laeuft jetzt immer und prueft je Durchlauf, ob ein Server da ist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ebdd6c313a
commit
01bbb3ba9a
@@ -1,9 +1,23 @@
|
||||
'use server';
|
||||
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { actionData, actionError, type ActionResult } from '@/lib/action-result';
|
||||
import {
|
||||
actionData,
|
||||
actionError,
|
||||
actionOk,
|
||||
formToObject,
|
||||
parseForm,
|
||||
type ActionResult,
|
||||
} from '@/lib/action-result';
|
||||
import { env } from '@/env';
|
||||
import {
|
||||
deleteMailSettings,
|
||||
getMailConfig,
|
||||
isMailConfigured,
|
||||
saveMailSettings,
|
||||
} from '@/lib/mail-settings';
|
||||
import { sendMail, verifyMailConnection } from '@/lib/mailer';
|
||||
import { mailSettingsSchema } from '@/lib/validation';
|
||||
import { runReminderJob, type ReminderRun } from '@/lib/reminder-job';
|
||||
import { requireAdmin } from '@/lib/session';
|
||||
|
||||
@@ -17,7 +31,7 @@ export async function testMailConnection(): Promise<ActionResult> {
|
||||
export async function sendTestMail(): Promise<ActionResult> {
|
||||
const admin = await requireAdmin();
|
||||
|
||||
if (!env.isMailConfigured) {
|
||||
if (!isMailConfigured()) {
|
||||
return actionError('Es ist kein SMTP-Server konfiguriert.');
|
||||
}
|
||||
|
||||
@@ -41,7 +55,7 @@ export async function sendTestMail(): Promise<ActionResult> {
|
||||
export async function runRemindersNow(): Promise<ActionResult<ReminderRun>> {
|
||||
await requireAdmin();
|
||||
|
||||
if (!env.isMailConfigured) {
|
||||
if (!isMailConfigured()) {
|
||||
return actionError('Es ist kein SMTP-Server konfiguriert.');
|
||||
}
|
||||
|
||||
@@ -49,3 +63,26 @@ export async function runRemindersNow(): Promise<ActionResult<ReminderRun>> {
|
||||
revalidatePath('/verwaltung/erinnerungen');
|
||||
return actionData(run);
|
||||
}
|
||||
|
||||
/** Stores the SMTP server set up on the reminders page. */
|
||||
export async function saveMailSettingsAction(formData: FormData): Promise<ActionResult> {
|
||||
await requireAdmin();
|
||||
|
||||
if (getMailConfig()?.source === 'env') {
|
||||
return actionError('Der Mailserver kommt aus der .env. Änderungen bitte dort vornehmen.');
|
||||
}
|
||||
|
||||
const parsed = parseForm(mailSettingsSchema, formToObject(formData));
|
||||
if (!parsed.ok) return parsed;
|
||||
|
||||
saveMailSettings(parsed.data);
|
||||
revalidatePath('/verwaltung/erinnerungen');
|
||||
return actionOk();
|
||||
}
|
||||
|
||||
export async function deleteMailSettingsAction(): Promise<ActionResult> {
|
||||
await requireAdmin();
|
||||
deleteMailSettings();
|
||||
revalidatePath('/verwaltung/erinnerungen');
|
||||
return actionOk();
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ import { eq, sql } from 'drizzle-orm';
|
||||
import { db } from '@/db';
|
||||
import { wishlist } from '@/db/schema';
|
||||
import { env } from '@/env';
|
||||
import { MailSettingsForm } from '@/components/verwaltung/mail-settings-form';
|
||||
import {
|
||||
ReminderSettings,
|
||||
type ReminderListRow,
|
||||
} from '@/components/verwaltung/reminder-settings';
|
||||
import { getMailSettingsView } from '@/lib/mail-settings';
|
||||
import { daysUntil } from '@/lib/reminders';
|
||||
import { requireAdmin } from '@/lib/session';
|
||||
|
||||
@@ -41,11 +43,16 @@ export default async function ErinnerungenPage() {
|
||||
}))
|
||||
.sort((a, b) => (a.daysLeft ?? 0) - (b.daysLeft ?? 0));
|
||||
|
||||
const mail = getMailSettingsView();
|
||||
|
||||
return (
|
||||
<ReminderSettings
|
||||
configured={env.isMailConfigured}
|
||||
daysBefore={env.REMINDER_DAYS_BEFORE}
|
||||
lists={lists}
|
||||
/>
|
||||
<div className="space-y-6">
|
||||
<ReminderSettings
|
||||
configured={mail.source !== null}
|
||||
daysBefore={env.REMINDER_DAYS_BEFORE}
|
||||
lists={lists}
|
||||
/>
|
||||
<MailSettingsForm view={mail} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user