"use server"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; import { ADMIN_COOKIE, ADMIN_COOKIE_MAX_AGE, verifyAdminToken } from "@/lib/admin-api"; export interface LoginState { error?: string; } function safeNext(v: unknown): string { if (typeof v !== "string") return "/admin"; // only same-origin admin paths, no protocol-relative tricks if (!v.startsWith("/admin") || v.startsWith("//") || v.includes("\\")) return "/admin"; if (v.startsWith("/admin/login") || v.startsWith("/admin/logout") || v.startsWith("/admin/api")) return "/admin"; return v; } export async function loginAction(_prev: LoginState, formData: FormData): Promise { const token = String(formData.get("token") ?? "").trim(); if (!token) return { error: "Enter the admin token." }; const res = await verifyAdminToken(token); if (!res.ok) return { error: res.error ?? "Invalid token" }; const jar = await cookies(); jar.set(ADMIN_COOKIE, token, { httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", path: "/admin", maxAge: ADMIN_COOKIE_MAX_AGE, }); redirect(safeNext(formData.get("next"))); }