Add social login (Discord/Google) + batch-6 pages

Auth: NextAuth Discord + Google providers (enabled when env id+secret set);
OAuth signIn allowed only if a hotel account matches the email; jwt binds the
session to that account (id/rank/username). Login page gets social buttons.

Batch 6 (parallel agents): /friends (messenger_friendships), /guilds/[id]/forum
(threads), /admin/navigation (navigator config), /admin/maintenance (toggle
maintenance settings), /admin/alerts (alert_logs + send hotel alert via RCON).
Header (Friends) + admin nav (Alerts/Maintenance/Navigator) extended.

Verified: tsc exit 0, vitest 48/48, next build exit 0 (57 page routes).
This commit is contained in:
Simo committed 2026-06-28 14:13:41 +02:00
1 parent 73f0f54624
commit 486ce51559
12 files changed
+911 -3

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
"use server";
import { revalidatePath } from "next/cache";
import { requireStaff } from "@/lib/admin/guard";
import { rcon } from "@/lib/services/rcon";
/**
* Broadcast a hotel-wide alert to every online user via RCON.
*
* Faithful to AtomCMS: the emulator's `hotelalert` command takes a single
* `message` payload. Staff-gated; the message is trimmed/bounded before send.
*/
export async function sendHotelAlert(formData: FormData): Promise<void> {
await requireStaff();
const message = String(formData.get("message") ?? "").trim().slice(0, 1000);
if (!message) return;
try {
await rcon.send("hotelalert", { message });
} catch {
// Best-effort delivery (dead socket / emulator offline) — never 500 the
// admin page. The emulator writes its own alert_logs row on receipt.
}
revalidatePath("/admin/alerts");
}