From d878d3b20cec6d288f1ff65e00c8c2bd43cbf058 Mon Sep 17 00:00:00 2001 From: ediblerope Date: Tue, 7 Apr 2026 13:13:17 +0100 Subject: [PATCH] Auto-extract API keys for Homepage dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a systemd oneshot that runs before homepage-dashboard and: - Reads *arr API keys from their config.xml files - Reads Bazarr key from config.ini - Creates a Jellyfin API key in the DB if one named "Homepage" doesn't exist - Uses localhost for qBittorrent (LocalHostAuth=false, no creds needed) - Writes everything to /etc/homepage-secrets Zero manual setup — all keys are extracted or generated automatically. Co-Authored-By: Claude Sonnet 4.6 --- services/homepage.nix | 91 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/services/homepage.nix b/services/homepage.nix index 1583d50..6da1911 100644 --- a/services/homepage.nix +++ b/services/homepage.nix @@ -1,7 +1,85 @@ { config, lib, pkgs, ... }: +let + # Script that extracts API keys from all services and writes /etc/homepage-secrets + extractSecrets = pkgs.writeShellScript "extract-homepage-secrets" '' + set -euo pipefail + + SECRETS_FILE="/etc/homepage-secrets" + + # --- *arr apps: API keys live in config.xml as ... --- + extract_arr_key() { + local name="$1" path="$2" + if [ -f "$path" ]; then + ${pkgs.gnused}/bin/sed -n 's/.*\(.*\)<\/ApiKey>.*/\1/p' "$path" + fi + } + + SONARR_KEY=$(extract_arr_key "sonarr" "/var/lib/sonarr/config.xml") + RADARR_KEY=$(extract_arr_key "radarr" "/var/lib/radarr/config.xml") + PROWLARR_KEY=$(extract_arr_key "prowlarr" "/var/lib/prowlarr/config.xml") + + # --- Bazarr: API key in config.ini under [auth] section --- + BAZARR_KEY="" + if [ -f "/var/lib/bazarr/data/config/config.ini" ]; then + BAZARR_KEY=$(${pkgs.gnugrep}/bin/grep -oP '(?<=apikey = ).*' /var/lib/bazarr/data/config/config.ini || true) + fi + # Fallback: Bazarr sometimes stores it in config.yaml + if [ -z "$BAZARR_KEY" ] && [ -f "/var/lib/bazarr/config/config.yaml" ]; then + BAZARR_KEY=$(${pkgs.gnugrep}/bin/grep -oP '(?<=apikey: ).*' /var/lib/bazarr/config/config.yaml || true) + fi + + # --- Jellyfin: create an API key in the DB if one doesn't exist --- + JELLYFIN_KEY="" + JELLYFIN_DB="/var/lib/jellyfin/data/jellyfin.db" + if [ -f "$JELLYFIN_DB" ]; then + # Check if a "Homepage" key already exists + JELLYFIN_KEY=$(${pkgs.sqlite}/bin/sqlite3 "$JELLYFIN_DB" \ + "SELECT AccessToken FROM ApiKeys WHERE Name = 'Homepage' LIMIT 1;" 2>/dev/null || true) + + if [ -z "$JELLYFIN_KEY" ]; then + # Generate a random 32-char hex token + JELLYFIN_KEY=$(${pkgs.coreutils}/bin/head -c 16 /dev/urandom | ${pkgs.coreutils}/bin/od -An -tx1 | ${pkgs.gnused}/bin/sed 's/ //g' | ${pkgs.coreutils}/bin/head -c 32) + NOW=$(${pkgs.coreutils}/bin/date -u '+%Y-%m-%d %H:%M:%S') + ${pkgs.sqlite}/bin/sqlite3 "$JELLYFIN_DB" \ + "INSERT INTO ApiKeys (DateCreated, DateLastActivity, Name, AccessToken) VALUES ('$NOW', '0001-01-01 00:01:00', 'Homepage', '$JELLYFIN_KEY');" + fi + fi + + # --- Write the secrets file --- + cat > "$SECRETS_FILE" <