mirror of
https://github.com/tale/headplane.git
synced 2026-08-30 08:49:30 +00:00
684a95b5e8
Security: - Add unique constraint on headscale_user_id to prevent hijacking - linkHeadscaleUser now rejects already-claimed Headscale users - Onboarding dropdown filters out claimed users - onboarding-skip action redirects on rejected claims Maintenance: - Replace probabilistic session pruning with setInterval (15m) - Move pruning out of request path into server startup Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019cce57-c9e1-7732-9709-8288127573a9
53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
import { eq } from "drizzle-orm";
|
|
import { redirect } from "react-router";
|
|
|
|
import { users } from "~/server/db/schema";
|
|
|
|
import type { Route } from "./+types/onboarding-skip";
|
|
|
|
export async function loader({ request, context }: Route.LoaderArgs) {
|
|
try {
|
|
const principal = await context.auth.require(request);
|
|
if (principal.kind !== "oidc") {
|
|
return redirect("/machines");
|
|
}
|
|
|
|
await context.db
|
|
.update(users)
|
|
.set({ onboarded: true })
|
|
.where(eq(users.sub, principal.user.subject));
|
|
|
|
return redirect("/machines");
|
|
} catch {
|
|
return redirect("/login");
|
|
}
|
|
}
|
|
|
|
export async function action({ request, context }: Route.ActionArgs) {
|
|
try {
|
|
const principal = await context.auth.require(request);
|
|
if (principal.kind !== "oidc") {
|
|
return redirect("/machines");
|
|
}
|
|
|
|
const formData = await request.formData();
|
|
const headscaleUserId = formData.get("headscale_user_id")?.toString();
|
|
|
|
if (headscaleUserId) {
|
|
const linked = await context.auth.linkHeadscaleUser(principal.user.id, headscaleUserId);
|
|
if (!linked) {
|
|
return redirect("/onboarding");
|
|
}
|
|
}
|
|
|
|
await context.db
|
|
.update(users)
|
|
.set({ onboarded: true })
|
|
.where(eq(users.sub, principal.user.subject));
|
|
|
|
return redirect("/machines");
|
|
} catch {
|
|
return redirect("/login");
|
|
}
|
|
}
|