diff --git a/docs/configs/docker.md b/docs/configs/docker.md index 1dcacbf0a..0fffc9626 100644 --- a/docs/configs/docker.md +++ b/docs/configs/docker.md @@ -189,6 +189,8 @@ labels: ... - homepage.widgets[1].slug=youreventslughere ``` +To pass custom HTTP headers with a widget request when using labels, use the same dot-notation: `homepage.widget.headers.X-Auth-Key=secret` (or `homepage.widgets[0].headers.X-Auth-Key=secret` when multiple widgets are present). + You can add specify fields for e.g. the [CustomAPI](../widgets/services/customapi.md) widget by using array-style dot notation: ```yaml diff --git a/docs/configs/kubernetes.md b/docs/configs/kubernetes.md index 51cd4b5dd..88748f177 100644 --- a/docs/configs/kubernetes.md +++ b/docs/configs/kubernetes.md @@ -94,6 +94,7 @@ metadata: gethomepage.dev/name: Emby gethomepage.dev/widget.type: "emby" gethomepage.dev/widget.url: "https://emby.example.com" + gethomepage.dev/widget.headers.X-Auth-Key: "your-secret-here" gethomepage.dev/pod-selector: "" gethomepage.dev/weight: 10 # optional gethomepage.dev/instance: "public" # optional diff --git a/docs/configs/services.md b/docs/configs/services.md index 06067bf6c..6e1b15761 100644 --- a/docs/configs/services.md +++ b/docs/configs/services.md @@ -101,6 +101,25 @@ Each service can have multiple widgets attached to it, for example: Multiple widgets per service are not yet supported with Kubernetes ingress annotations. +#### Custom HTTP headers + +Widgets that make HTTP calls support extra request headers via `headers`. This is useful when a reverse proxy expects a secret header. + +```yaml +- UptimeRobot: + icon: uptimekuma.png + href: https://uptimerobot.com/ + widget: + type: uptimerobot + url: https://api.uptimerobot.com + key: ${UPTIMEROBOT_API_KEY} + headers: + User-Agent: homepage + X-Auth-Key: your-secret-here +``` + +If you define services via Docker labels or Kubernetes annotations, use the same key with dot-notation (for example `homepage.widget.headers.X-Auth-Key=secret` or `gethomepage.dev/widget.headers.X-Auth-Key: "secret"`). + #### Field Visibility Each widget can optionally provide a list of which fields should be visible via the `fields` widget property. If no fields are specified, then all fields will be displayed. The `fields` property must be a valid YAML array of strings. As an example, here is the entry for Sonarr showing only a couple of fields. diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js index f5e9cf51a..3c61aa00e 100644 --- a/src/utils/proxy/handlers/credentialed.js +++ b/src/utils/proxy/handlers/credentialed.js @@ -27,6 +27,9 @@ export default async function credentialedProxyHandler(req, res, map) { const headers = { "Content-Type": "application/json", + ...(widgets[widget.type].headers ?? {}), + ...(widget.headers ?? {}), + ...(req.extraHeaders ?? {}), }; if (widget.type === "stocks") { diff --git a/src/utils/proxy/handlers/generic.js b/src/utils/proxy/handlers/generic.js index 166dc145c..e7653c708 100644 --- a/src/utils/proxy/handlers/generic.js +++ b/src/utils/proxy/handlers/generic.js @@ -25,7 +25,11 @@ export default async function genericProxyHandler(req, res, map) { } const url = new URL(urlString); - const headers = req.extraHeaders ?? widget.headers ?? widgets[widget.type].headers ?? {}; + const headers = { + ...(widgets[widget.type].headers ?? {}), + ...(widget.headers ?? {}), + ...(req.extraHeaders ?? {}), + }; if (widget.username && widget.password) { headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;