mirror of
https://github.com/tale/headplane.git
synced 2026-08-31 17:28: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 {
|
try {
|
||||||
const principal = await context.auth.require(request);
|
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 api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
|
|
||||||
const user =
|
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);
|
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
try {
|
try {
|
||||||
const { policy, updatedAt } = await api.setPolicy(policyData);
|
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.
|
// 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);
|
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
try {
|
try {
|
||||||
const { policy, updatedAt } = await api.getPolicy();
|
const { policy, updatedAt } = await api.getPolicy();
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const hsApi = context.hsApi.getRuntimeClient(context.oidc!.apiKey);
|
const hsApi = context.hsApi.getRuntimeClient(context.headscaleApiKey!);
|
||||||
const hsUsers = await hsApi.getUsers();
|
const hsUsers = await hsApi.getUsers();
|
||||||
const hsUser = findHeadscaleUserBySubject(hsUsers, claims.sub, userInfo.email);
|
const hsUser = findHeadscaleUserBySubject(hsUsers, claims.sub, userInfo.email);
|
||||||
if (hsUser) {
|
if (hsUser) {
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
|||||||
principal.kind === "oidc" &&
|
principal.kind === "oidc" &&
|
||||||
!principal.user.headscaleUserId
|
!principal.user.headscaleUserId
|
||||||
) {
|
) {
|
||||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
|
|
||||||
let headscaleUsers: { id: string; name: string }[] = [];
|
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
|
// 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);
|
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
|
|
||||||
let linkedUserName: string | undefined;
|
let linkedUserName: string | undefined;
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ export async function machineAction({ request, context }: Route.ActionArgs) {
|
|||||||
const principal = await context.auth.require(request);
|
const principal = await context.auth.require(request);
|
||||||
|
|
||||||
const formData = await request.formData();
|
const formData = await request.formData();
|
||||||
const api = context.hsApi.getRuntimeClient(
|
const api = context.hsApi.getRuntimeClient(context.auth.getHeadscaleApiKey(principal));
|
||||||
context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey),
|
|
||||||
);
|
|
||||||
|
|
||||||
const action = formData.get("action_id")?.toString();
|
const action = formData.get("action_id")?.toString();
|
||||||
if (!action) {
|
if (!action) {
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ export async function loader({ request, params, context }: Route.LoaderArgs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const api = context.hsApi.getRuntimeClient(
|
const api = context.hsApi.getRuntimeClient(context.auth.getHeadscaleApiKey(principal));
|
||||||
context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey),
|
|
||||||
);
|
|
||||||
const [nodesSnap, usersSnap] = await Promise.all([
|
const [nodesSnap, usersSnap] = await Promise.all([
|
||||||
context.hsLive.get(nodesResource, api),
|
context.hsLive.get(nodesResource, api),
|
||||||
context.hsLive.get(usersResource, 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 writablePermission = context.auth.can(principal, Capabilities.write_machines);
|
||||||
|
|
||||||
const api = context.hsApi.getRuntimeClient(
|
const api = context.hsApi.getRuntimeClient(context.auth.getHeadscaleApiKey(principal));
|
||||||
context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey),
|
|
||||||
);
|
|
||||||
const [nodesSnap, usersSnap] = await Promise.all([
|
const [nodesSnap, usersSnap] = await Promise.all([
|
||||||
context.hsLive.get(nodesResource, api),
|
context.hsLive.get(nodesResource, api),
|
||||||
context.hsLive.get(usersResource, api),
|
context.hsLive.get(usersResource, api),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import type { Route } from "./+types/overview";
|
|||||||
|
|
||||||
export async function authKeysAction({ request, context }: Route.ActionArgs) {
|
export async function authKeysAction({ request, context }: Route.ActionArgs) {
|
||||||
const principal = await context.auth.require(request);
|
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 api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
|
|
||||||
const canGenerateAny = context.auth.can(principal, Capabilities.generate_authkeys);
|
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) {
|
export async function loader({ request, context }: Route.LoaderArgs) {
|
||||||
const principal = await context.auth.require(request);
|
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 api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
|
|
||||||
const usersSnap = await context.hsLive.get(usersResource, api);
|
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);
|
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 api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
const users = await api.getUsers();
|
const users = await api.getUsers();
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export async function loader({ request, context }: Route.LoaderArgs) {
|
|||||||
let apiError: string | undefined;
|
let apiError: string | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
const [nodesSnap, usersSnap] = await Promise.all([
|
const [nodesSnap, usersSnap] = await Promise.all([
|
||||||
context.hsLive.get(nodesResource, api),
|
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);
|
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "create_user": {
|
case "create_user": {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { Route } from "./+types/live";
|
|||||||
|
|
||||||
export async function loader({ request, context }: Route.LoaderArgs) {
|
export async function loader({ request, context }: Route.LoaderArgs) {
|
||||||
const principal = await context.auth.require(request);
|
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 api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
|
|
||||||
// Ensure resources are loaded before streaming
|
// Ensure resources are loaded before streaming
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export async function pruneEphemeralNodes({ context, request }: Route.LoaderArgs
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiKey = context.auth.getHeadscaleApiKey(principal, context.oidc?.apiKey);
|
const apiKey = context.auth.getHeadscaleApiKey(principal);
|
||||||
const api = context.hsApi.getRuntimeClient(apiKey);
|
const api = context.hsApi.getRuntimeClient(apiKey);
|
||||||
const nodes = await api.getNodes();
|
const nodes = await api.getNodes();
|
||||||
const toPrune = nodes.filter((node) => {
|
const toPrune = nodes.filter((node) => {
|
||||||
|
|||||||
+2
-1
@@ -84,6 +84,7 @@ const appLoadContext = {
|
|||||||
|
|
||||||
auth: createAuthService({
|
auth: createAuthService({
|
||||||
secret: config.server.cookie_secret,
|
secret: config.server.cookie_secret,
|
||||||
|
headscaleApiKey,
|
||||||
db,
|
db,
|
||||||
cookie: {
|
cookie: {
|
||||||
name: "_hp_auth",
|
name: "_hp_auth",
|
||||||
@@ -93,13 +94,13 @@ const appLoadContext = {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
headscaleApiKey,
|
||||||
hsApi,
|
hsApi,
|
||||||
agents,
|
agents,
|
||||||
integration: await loadIntegration(config.integration),
|
integration: await loadIntegration(config.integration),
|
||||||
oidc:
|
oidc:
|
||||||
config.oidc && config.oidc.enabled !== false && headscaleApiKey
|
config.oidc && config.oidc.enabled !== false && headscaleApiKey
|
||||||
? {
|
? {
|
||||||
apiKey: headscaleApiKey,
|
|
||||||
connector: createLazyOidcConnector(
|
connector: createLazyOidcConnector(
|
||||||
config.server.base_url,
|
config.server.base_url,
|
||||||
config.oidc,
|
config.oidc,
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ interface CookiePayload {
|
|||||||
|
|
||||||
export interface AuthServiceOptions {
|
export interface AuthServiceOptions {
|
||||||
secret: string;
|
secret: string;
|
||||||
|
headscaleApiKey?: string;
|
||||||
db: NodeSQLiteDatabase;
|
db: NodeSQLiteDatabase;
|
||||||
cookie: {
|
cookie: {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -230,21 +231,16 @@ export class AuthService {
|
|||||||
return this.encodeCookie({ sid, api_key: apiKey }, Math.floor(maxAge / 1000));
|
return this.encodeCookie({ sid, api_key: apiKey }, Math.floor(maxAge / 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
getHeadscaleApiKey(principal: Principal): string {
|
||||||
* 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 {
|
|
||||||
if (principal.kind === "api_key") {
|
if (principal.kind === "api_key") {
|
||||||
return principal.apiKey;
|
return principal.apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oidcApiKey) {
|
if (!this.opts.headscaleApiKey) {
|
||||||
throw new Error("OIDC sessions require oidc.headscale_api_key");
|
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