mirror of
https://github.com/tale/headplane.git
synced 2026-08-28 16:07:07 +00:00
fix: harden user linking and session pruning
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
This commit is contained in:
@@ -80,9 +80,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
})()
|
||||
: userInfo.picture;
|
||||
|
||||
const hasUsers = await context.auth.hasAnyUsers();
|
||||
const defaultRole = hasUsers ? "member" : "owner";
|
||||
const userId = await context.auth.findOrCreateUser(claims.sub, defaultRole);
|
||||
const userId = await context.auth.findOrCreateUser(claims.sub);
|
||||
|
||||
try {
|
||||
const hsApi = context.hsApi.getRuntimeClient(context.oidc!.apiKey);
|
||||
|
||||
@@ -34,7 +34,10 @@ export async function action({ request, context }: Route.ActionArgs) {
|
||||
const headscaleUserId = formData.get("headscale_user_id")?.toString();
|
||||
|
||||
if (headscaleUserId) {
|
||||
await context.auth.linkHeadscaleUser(principal.user.id, headscaleUserId);
|
||||
const linked = await context.auth.linkHeadscaleUser(principal.user.id, headscaleUserId);
|
||||
if (!linked) {
|
||||
return redirect("/onboarding");
|
||||
}
|
||||
}
|
||||
|
||||
await context.db
|
||||
|
||||
@@ -74,10 +74,13 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
firstMachine = nodes.find((n) => n.user?.id === matched.id);
|
||||
} else {
|
||||
needsUserLink = true;
|
||||
headscaleUsers = apiUsers.map((u) => ({
|
||||
id: u.id,
|
||||
name: getUserDisplayName(u),
|
||||
}));
|
||||
const claimed = await context.auth.claimedHeadscaleUserIds();
|
||||
headscaleUsers = apiUsers
|
||||
.filter((u) => !claimed.has(u.id))
|
||||
.map((u) => ({
|
||||
id: u.id,
|
||||
name: getUserDisplayName(u),
|
||||
}));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user