Wird von Caddy für ACME/Let's Encrypt benötigt.
+
+
+
save({ hits_retention_days: e.target.value || "365" })}
+ />
+
Hits älter als diese Anzahl Tage werden täglich gelöscht. 0 = nie löschen.
+
+
+
+
save({ webhook_url: e.target.value.trim() })}
+ />
+
POST mit JSON bei Domain-Verify-Fail / Update-Available. Leer = aus.
+
diff --git a/app/api/domains/[id]/report.pdf/route.ts b/app/api/domains/[id]/report.pdf/route.ts
new file mode 100644
index 0000000..dfede77
--- /dev/null
+++ b/app/api/domains/[id]/report.pdf/route.ts
@@ -0,0 +1,61 @@
+import { NextResponse } from "next/server";
+import path from "path";
+import fs from "fs/promises";
+import { getServerSession } from "next-auth";
+import { authOptions } from "@/lib/auth";
+import { getDb, type DomainRow } from "@/lib/db";
+import { createPdfToken } from "@/lib/pdf-token";
+
+const CHROME_PATHS = [
+ process.env.NEXREDIRECT_CHROME_PATH,
+ "/usr/bin/chromium",
+ "/usr/bin/chromium-browser",
+ "/usr/bin/google-chrome",
+ "/usr/bin/google-chrome-stable",
+].filter(Boolean) as string[];
+
+async function findChrome(): Promise