SPB Git forge
7commits 1branches 0releases
229.0 KBsize
maindefault branch
12 days agolast push
TypeScript 91.8% HTML 3.2% JavaScript 3% SQL 1.4% CSS 0.7%
2.0 KB · 40 lines tsx
Raw Blame History
1import { cookies } from "next/headers";2import { redirect } from "next/navigation";3import { COOKIE, checkPasscode, gateEnabled, makeToken } from "@/lib/auth";4import { Brand } from "@/components/Brand";56export const dynamic = "force-dynamic";78async function login(formData: FormData) {9  "use server";10  const code = String(formData.get("passcode") ?? "");11  const next = String(formData.get("next") ?? "/");12  if (!checkPasscode(code)) redirect(`/access?error=1&next=${encodeURIComponent(next)}`);13  const jar = await cookies();14  jar.set(COOKIE, makeToken(), { httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", path: "/", maxAge: 30 * 24 * 3600 });15  redirect(next.startsWith("/") ? next : "/");16}1718export default async function AccessPage({ searchParams }: { searchParams: Promise<{ error?: string; next?: string }> }) {19  const sp = await searchParams;20  if (!gateEnabled()) redirect("/");21  return (22    <main className="min-h-screen grid place-items-center grid-bg px-6">23      <form action={login} className="panel w-full max-w-sm p-8 space-y-6">24        <Brand size="lg" />25        <div className="space-y-1">26          <h1 className="text-lg font-semibold">Research console</h1>27          <p className="text-sm text-fg-2">This console observes live social runtimes and can start browser sessions on the cluster. Enter the access code.</p>28        </div>29        <input type="hidden" name="next" value={sp.next ?? "/"} />30        <label className="block space-y-2">31          <span className="text-xs uppercase tracking-widest text-dim">Access code</span>32          <input name="passcode" type="password" autoFocus required className="w-full rounded-lg bg-bg-2 border border-line-2 px-3 py-2 mono text-fg outline-none focus:border-cyan/60 focus:glow-cyan" />33        </label>34        {sp.error && <p className="text-sm text-red">Wrong code.</p>}35        <button className="w-full rounded-lg bg-cyan/90 hover:bg-cyan text-bg font-semibold py-2 transition">Enter</button>36      </form>37    </main>38  );39}40