Merge current features with security hardening and automatic safe initialization

This commit is contained in:
t.indorf
2026-10-09 23:29:19 +02:00
85 changed files with 13522 additions and 1326 deletions
+32 -13
View File
@@ -1,18 +1,37 @@
"use server";
import { publicActionError } from "@/lib/action-error";
import { revalidatePath } from "next/cache";
import { NotdienstAlertStatus } from "@prisma/client";
import { prisma } from "@/lib/prisma";
import { activeAlertTokenWhere } from "@/lib/alert-tokens";
import { hashToken, isPublicToken } from "@/lib/tokens";
import { respondToAlarm } from "@/lib/alarms/service";
import { deliverAlarmEmails } from "@/lib/alarms/email";
import { limitPublicAction } from "@/lib/rate-limit";
import { hashToken, isPublicToken } from "@/lib/tokens";
export async function respondAlertAction(token: string, approve: boolean) {
if (!isPublicToken(token) || typeof approve !== "boolean")
return { error: "Ungültiger Rückmeldelink." };
if (!(await limitPublicAction("alarm-response", hashToken(token), 12, 60)))
return { error: "Bitte kurz warten und erneut versuchen." };
try {
const result = await respondToAlarm(token, approve);
// The household response is already committed; transport failure must not undo it.
try {
await deliverAlarmEmails(result.emailIds);
} catch {
/* Persistent jobs will retry. */
}
revalidatePath("/alert/[token]", "page");
revalidatePath("/dashboard");
revalidatePath("/dashboard/notdienst/alarm");
return { success: true };
} catch (error) {
const message = publicActionError(error, "");
if (message) return { error: message };
return {
error:
"Die Rückmeldung konnte nicht gespeichert werden. Bitte den aktuellen Stand prüfen.",
};
}
}
export async function confirmAlertAction(token: string) {
if (!isPublicToken(token)) return { error: "Ungültiger Bestätigungs-Link." };
if (!(await limitPublicAction("alert-confirm", hashToken(token), 10, 900))) return { error: "Bitte versuche es später erneut." };
const updated = await prisma.notdienstAlert.updateMany({
where: activeAlertTokenWhere(token),
data: { status: NotdienstAlertStatus.CONFIRMED, confirmedAt: new Date() },
});
if (updated.count !== 1) return { error: "Dieser Link ist abgelaufen oder wurde bereits verwendet." };
revalidatePath("/dashboard");
return { success: true };
return respondAlertAction(token, true);
}