mirror of
https://github.com/tale/headplane.git
synced 2026-07-26 15:58:14 +00:00
fix: use headscale.api_key where possible
This commit is contained in:
+1
-1
@@ -34,7 +34,7 @@ export async function loader({ request, context, ...rest }: Route.LoaderArgs) {
|
||||
try {
|
||||
const principal = await context.auth.require(request);
|
||||
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
|
||||
const user =
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function aclAction({ request, context }: Route.ActionArgs) {
|
||||
});
|
||||
}
|
||||
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
try {
|
||||
const { policy, updatedAt } = await api.setPolicy(policyData);
|
||||
|
||||
@@ -29,7 +29,7 @@ export async function aclLoader({ request, context }: Route.LoaderArgs) {
|
||||
};
|
||||
|
||||
// Try to load the ACL policy from the API.
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
try {
|
||||
const { policy, updatedAt } = await api.getPolicy();
|
||||
|
||||
@@ -107,7 +107,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
});
|
||||
|
||||
try {
|
||||
const hsApi = context.hsApi.getRuntimeClient(context.oidc!.apiKey);
|
||||
const hsApi = context.hsApi.getRuntimeClient(context.headscaleApiKey!);
|
||||
const hsUsers = await hsApi.getUsers();
|
||||
const hsUser = findHeadscaleUserBySubject(hsUsers, claims.sub, userInfo.email);
|
||||
if (hsUser) {
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
principal.kind === "oidc" &&
|
||||
!principal.user.headscaleUserId
|
||||
) {
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
|
||||
let headscaleUsers: { id: string; name: string }[] = [];
|
||||
@@ -64,7 +64,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
}
|
||||
|
||||
// No UI access — show the download/connect page
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
|
||||
let linkedUserName: string | undefined;
|
||||
|
||||
@@ -10,9 +10,7 @@ export async function machineAction({ request, context }: Route.ActionArgs) {
|
||||
const principal = await context.auth.require(request);
|
||||
|
||||
const formData = await request.formData();
|
||||
const api = context.hsApi.getRuntimeClient(
|
||||
context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey),
|
||||
);
|
||||
const api = context.hsApi.getRuntimeClient(context.auth.getHeadscaleApiKey(principal));
|
||||
|
||||
const action = formData.get("action_id")?.toString();
|
||||
if (!action) {
|
||||
|
||||
@@ -38,9 +38,7 @@ export async function loader({ request, params, context }: Route.LoaderArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
const api = context.hsApi.getRuntimeClient(
|
||||
context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey),
|
||||
);
|
||||
const api = context.hsApi.getRuntimeClient(context.auth.getHeadscaleApiKey(principal));
|
||||
const [nodesSnap, usersSnap] = await Promise.all([
|
||||
context.hsLive.get(nodesResource, api),
|
||||
context.hsLive.get(usersResource, api),
|
||||
|
||||
@@ -30,9 +30,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
|
||||
const writablePermission = context.auth.can(principal, Capabilities.write_machines);
|
||||
|
||||
const api = context.hsApi.getRuntimeClient(
|
||||
context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey),
|
||||
);
|
||||
const api = context.hsApi.getRuntimeClient(context.auth.getHeadscaleApiKey(principal));
|
||||
const [nodesSnap, usersSnap] = await Promise.all([
|
||||
context.hsLive.get(nodesResource, api),
|
||||
context.hsLive.get(usersResource, api),
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { Route } from "./+types/overview";
|
||||
|
||||
export async function authKeysAction({ request, context }: Route.ActionArgs) {
|
||||
const principal = await context.auth.require(request);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
|
||||
const canGenerateAny = context.auth.can(principal, Capabilities.generate_authkeys);
|
||||
|
||||
@@ -20,7 +20,7 @@ import AddAuthKey from "./dialogs/add-auth-key";
|
||||
|
||||
export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
const principal = await context.auth.require(request);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
|
||||
const usersSnap = await context.hsLive.get(usersResource, api);
|
||||
|
||||
@@ -41,7 +41,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
throw data("Only OAuth users are allowed to use WebSSH", 403);
|
||||
}
|
||||
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
const users = await api.getUsers();
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
let apiError: string | undefined;
|
||||
|
||||
try {
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
const [nodesSnap, usersSnap] = await Promise.all([
|
||||
context.hsLive.get(nodesResource, api),
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function userAction({ request, context }: Route.ActionArgs) {
|
||||
});
|
||||
}
|
||||
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
switch (action) {
|
||||
case "create_user": {
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Route } from "./+types/live";
|
||||
|
||||
export async function loader({ request, context }: Route.LoaderArgs) {
|
||||
const principal = await context.auth.require(request);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
|
||||
// Ensure resources are loaded before streaming
|
||||
|
||||
@@ -18,7 +18,7 @@ export async function pruneEphemeralNodes({ context, request }: Route.LoaderArgs
|
||||
return;
|
||||
}
|
||||
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
||||
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||
const nodes = await api.getNodes();
|
||||
const toPrune = nodes.filter((node) => {
|
||||
|
||||
+2
-1
@@ -84,6 +84,7 @@ const appLoadContext = {
|
||||
|
||||
auth: createAuthService({
|
||||
secret: config.server.cookie_secret,
|
||||
headscaleApiKey,
|
||||
db,
|
||||
cookie: {
|
||||
name: "_hp_auth",
|
||||
@@ -93,13 +94,13 @@ const appLoadContext = {
|
||||
},
|
||||
}),
|
||||
|
||||
headscaleApiKey,
|
||||
hsApi,
|
||||
agents,
|
||||
integration: await loadIntegration(config.integration),
|
||||
oidc:
|
||||
config.oidc && config.oidc.enabled !== false && headscaleApiKey
|
||||
? {
|
||||
apiKey: headscaleApiKey,
|
||||
connector: createLazyOidcConnector(
|
||||
config.server.base_url,
|
||||
config.oidc,
|
||||
|
||||
@@ -58,6 +58,7 @@ interface CookiePayload {
|
||||
|
||||
export interface AuthServiceOptions {
|
||||
secret: string;
|
||||
headscaleApiKey?: string;
|
||||
db: NodeSQLiteDatabase;
|
||||
cookie: {
|
||||
name: string;
|
||||
@@ -230,21 +231,16 @@ export class AuthService {
|
||||
return this.encodeCookie({ sid, api_key: apiKey }, Math.floor(maxAge / 1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Headscale API key for making API calls.
|
||||
* OIDC sessions use the configured oidc.headscale_api_key.
|
||||
* API key sessions use the user-provided key stored in the cookie.
|
||||
*/
|
||||
getHeadscaleApiKey(principal: Principal, oidcApiKey?: string): string {
|
||||
getHeadscaleApiKey(principal: Principal): string {
|
||||
if (principal.kind === "api_key") {
|
||||
return principal.apiKey;
|
||||
}
|
||||
|
||||
if (!oidcApiKey) {
|
||||
throw new Error("OIDC sessions require oidc.headscale_api_key");
|
||||
if (!this.opts.headscaleApiKey) {
|
||||
throw new Error("OIDC sessions require headscale.api_key to be configured");
|
||||
}
|
||||
|
||||
return oidcApiKey;
|
||||
return this.opts.headscaleApiKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user