From b5fb747271e7d48928ddd14f0b6ac443db22f481 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Sat, 12 Sep 2026 10:54:36 +0200 Subject: [PATCH] Section icons in the change journal, and admin scope on secret reveal --- AppImage/components/audit-changes.tsx | 20 +++++++++++++++---- AppImage/components/settings.tsx | 4 ++-- AppImage/messages/de/common.json | 2 +- AppImage/messages/en/common.json | 2 +- AppImage/messages/es/common.json | 2 +- AppImage/messages/fr/common.json | 2 +- AppImage/messages/it/common.json | 2 +- AppImage/messages/pt/common.json | 2 +- AppImage/messages/sk/common.json | 2 +- AppImage/messages/sv/common.json | 2 +- AppImage/scripts/flask_notification_routes.py | 14 +++++++++---- .../post_install/customizable_post_install.sh | 2 +- 12 files changed, 37 insertions(+), 19 deletions(-) diff --git a/AppImage/components/audit-changes.tsx b/AppImage/components/audit-changes.tsx index ee1964ff..3b4ab654 100644 --- a/AppImage/components/audit-changes.tsx +++ b/AppImage/components/audit-changes.tsx @@ -5,7 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "./ui/card" import { Badge } from "./ui/badge" import { ChevronDown, ChevronRight, FileCode, HelpCircle, Loader2, Package, - Play, Settings2, + Play, Settings2, Sparkles, Terminal, Wrench, } from "lucide-react" import { fetchApi } from "../lib/api-config" import { useT, useI18n } from "../lib/i18n/provider" @@ -299,8 +299,10 @@ function ChangeCard({ change, expanded, onToggle, t, when }: { ) } -function GroupSection({ title, groups, openFn, toggleFn, open, toggle, t, when }: { +function GroupSection({ title, icon: Icon, iconClass, groups, openFn, toggleFn, open, toggle, t, when }: { title: string + icon: typeof Settings2 + iconClass: string groups: { key: string; label: string; version: string; last: number; items: Change[] }[] openFn: Set; toggleFn: (k: string) => void open: Set; toggle: (id: number) => void @@ -309,8 +311,15 @@ function GroupSection({ title, groups, openFn, toggleFn, open, toggle, t, when } }) { if (groups.length === 0) return null return ( -
-

{title}

+ // Padding on the child: the container's space-y-4 overrides any mt-*. +
+ {/* Same type and icon size as CardTitle, so a block heading here reads + exactly like a card heading on the Settings page. */} +

+ + {title} +

{groups.map((g) => { const fnOpen = openFn.has(g.key) return ( @@ -460,12 +469,15 @@ export function AuditChanges() { {summary && summary.total > 0 diff --git a/AppImage/components/settings.tsx b/AppImage/components/settings.tsx index a110b439..dc6ae31e 100644 --- a/AppImage/components/settings.tsx +++ b/AppImage/components/settings.tsx @@ -2,7 +2,7 @@ import { useState, useEffect } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card" -import { Wrench, Package, Ruler, HeartPulse, Cpu, MemoryStick, HardDrive, CircleDot, Network, Server, Settings2, FileText, RefreshCw, Shield, AlertTriangle, Info, Loader2, Check, Database, CloudOff, Code, X, Copy, Sparkles, ArrowUpCircle, BellOff, Globe2, Github } from "lucide-react" +import { Package, Ruler, HeartPulse, Cpu, MemoryStick, HardDrive, CircleDot, Network, Server, Settings2, FileText, RefreshCw, Shield, AlertTriangle, Info, Loader2, Check, Database, CloudOff, Code, X, Copy, Sparkles, ArrowUpCircle, BellOff, Globe2, Github } from "lucide-react" import { Badge } from "./ui/badge" import { Button } from "./ui/button" import { NotificationSettings } from "./notification-settings" @@ -2034,7 +2034,7 @@ export function Settings() {
- + {t("settings.optimizations.title")}
{t("settings.optimizations.description")} diff --git a/AppImage/messages/de/common.json b/AppImage/messages/de/common.json index beeb9c32..96806035 100644 --- a/AppImage/messages/de/common.json +++ b/AppImage/messages/de/common.json @@ -1754,7 +1754,7 @@ "configure": "Konfigurieren", "tokenLabel": "Persönliches Zugriffstoken", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "Das Token wird verschlüsselt gespeichert. ProxMenux verwendet es ausschließlich für schreibgeschützte GitHub-API-Anfragen und zeigt es danach nicht erneut an.", + "tokenHelp": "Das Token wird verschlüsselt gespeichert. ProxMenux verwendet es ausschließlich für schreibgeschützte GitHub-API-Anfragen und zeigt es danach nicht erneut an. Ein Fine-grained-Token mit Lesezugriff auf öffentliche Repositories und ohne Kontoberechtigungen genügt.", "configured": "Token konfiguriert", "notConfigured": "Anonymes GitHub-Anfragekontingent wird verwendet", "removeToken": "Token entfernen", diff --git a/AppImage/messages/en/common.json b/AppImage/messages/en/common.json index 70fa0899..c6791134 100644 --- a/AppImage/messages/en/common.json +++ b/AppImage/messages/en/common.json @@ -1753,7 +1753,7 @@ "configure": "Configure", "tokenLabel": "Personal access token", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "The token is stored encrypted. ProxMenux uses it only for read-only GitHub API requests and never displays it again.", + "tokenHelp": "The token is stored encrypted. ProxMenux uses it only for read-only GitHub API requests and never displays it again. A fine-grained token with read-only access to public repositories and no account permissions is enough.", "configured": "Token configured", "notConfigured": "Using GitHub's anonymous request quota", "removeToken": "Remove token", diff --git a/AppImage/messages/es/common.json b/AppImage/messages/es/common.json index 2ec950ea..620e694e 100644 --- a/AppImage/messages/es/common.json +++ b/AppImage/messages/es/common.json @@ -1754,7 +1754,7 @@ "configure": "Configurar", "tokenLabel": "Token de acceso personal", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "El token se guarda cifrado. ProxMenux solo lo utiliza para consultas de solo lectura a la API de GitHub y no vuelve a mostrarlo.", + "tokenHelp": "El token se guarda cifrado. ProxMenux solo lo utiliza para consultas de solo lectura a la API de GitHub y no vuelve a mostrarlo. Basta con un token fine-grained con acceso de solo lectura a repositorios públicos y sin permisos de cuenta.", "configured": "Token configurado", "notConfigured": "Usando la cuota de solicitudes anónimas de GitHub", "removeToken": "Eliminar token", diff --git a/AppImage/messages/fr/common.json b/AppImage/messages/fr/common.json index b434d8ef..5bff160c 100644 --- a/AppImage/messages/fr/common.json +++ b/AppImage/messages/fr/common.json @@ -1754,7 +1754,7 @@ "configure": "Configurer", "tokenLabel": "Jeton d'accès personnel", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "Le jeton est stocké sous forme chiffrée. ProxMenux l'utilise uniquement pour des requêtes en lecture seule vers l'API GitHub et ne l'affiche plus ensuite.", + "tokenHelp": "Le jeton est stocké sous forme chiffrée. ProxMenux l'utilise uniquement pour des requêtes en lecture seule vers l'API GitHub et ne l'affiche plus ensuite. Un jeton fine-grained avec un accès en lecture seule aux dépôts publics et sans autorisation de compte suffit.", "configured": "Jeton configuré", "notConfigured": "Utilisation du quota de requêtes anonymes de GitHub", "removeToken": "Supprimer le jeton", diff --git a/AppImage/messages/it/common.json b/AppImage/messages/it/common.json index 90e72a11..f29679a6 100644 --- a/AppImage/messages/it/common.json +++ b/AppImage/messages/it/common.json @@ -1754,7 +1754,7 @@ "configure": "Configura", "tokenLabel": "Token di accesso personale", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "Il token viene archiviato in forma cifrata. ProxMenux lo utilizza solo per richieste di sola lettura all'API GitHub e non lo mostra più dopo il salvataggio.", + "tokenHelp": "Il token viene archiviato in forma cifrata. ProxMenux lo utilizza solo per richieste di sola lettura all'API GitHub e non lo mostra più dopo il salvataggio. È sufficiente un token fine-grained con accesso in sola lettura ai repository pubblici e senza permessi sull'account.", "configured": "Token configurato", "notConfigured": "Utilizzo della quota di richieste anonime di GitHub", "removeToken": "Rimuovi token", diff --git a/AppImage/messages/pt/common.json b/AppImage/messages/pt/common.json index 8e0a8d95..3b35eee9 100644 --- a/AppImage/messages/pt/common.json +++ b/AppImage/messages/pt/common.json @@ -1754,7 +1754,7 @@ "configure": "Configurar", "tokenLabel": "Token de acesso pessoal", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "O token é armazenado de forma cifrada. O ProxMenux utiliza-o apenas para pedidos de leitura à API do GitHub e não volta a apresentá-lo.", + "tokenHelp": "O token é armazenado de forma cifrada. O ProxMenux utiliza-o apenas para pedidos de leitura à API do GitHub e não volta a apresentá-lo. Basta um token fine-grained com acesso de leitura a repositórios públicos e sem permissões de conta.", "configured": "Token configurado", "notConfigured": "A utilizar a quota de pedidos anónimos do GitHub", "removeToken": "Remover token", diff --git a/AppImage/messages/sk/common.json b/AppImage/messages/sk/common.json index 4b1f20d3..0acd2e04 100644 --- a/AppImage/messages/sk/common.json +++ b/AppImage/messages/sk/common.json @@ -1753,7 +1753,7 @@ "configure": "Nastaviť", "tokenLabel": "Osobný prístupový token", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "Token sa ukladá šifrovane. ProxMenux ho používa iba na požiadavky GitHub API určené na čítanie a po uložení ho už nezobrazí.", + "tokenHelp": "Token sa ukladá šifrovane. ProxMenux ho používa iba na požiadavky GitHub API určené na čítanie a po uložení ho už nezobrazí. Postačuje fine-grained token s prístupom na čítanie k verejným repozitárom a bez oprávnení k účtu.", "configured": "Token je nastavený", "notConfigured": "Používa sa anonymná kvóta požiadaviek GitHubu", "removeToken": "Odstrániť token", diff --git a/AppImage/messages/sv/common.json b/AppImage/messages/sv/common.json index 1ea645a9..4fbccd0c 100644 --- a/AppImage/messages/sv/common.json +++ b/AppImage/messages/sv/common.json @@ -1754,7 +1754,7 @@ "configure": "Konfigurera", "tokenLabel": "Personlig åtkomsttoken", "tokenPlaceholder": "github_pat_...", - "tokenHelp": "Token lagras krypterad. ProxMenux använder den endast för skrivskyddade anrop till GitHub API och visar den inte igen efter att den har sparats.", + "tokenHelp": "Token lagras krypterad. ProxMenux använder den endast för skrivskyddade anrop till GitHub API och visar den inte igen efter att den har sparats. Det räcker med en fine-grained token med läsbehörighet till publika repositorier och utan kontobehörigheter.", "configured": "Token konfigurerad", "notConfigured": "GitHubs anonyma förfrågningskvot används", "removeToken": "Ta bort token", diff --git a/AppImage/scripts/flask_notification_routes.py b/AppImage/scripts/flask_notification_routes.py index ba38b804..a264575f 100644 --- a/AppImage/scripts/flask_notification_routes.py +++ b/AppImage/scripts/flask_notification_routes.py @@ -12,7 +12,7 @@ from collections import deque from flask import Blueprint, jsonify, request from notification_manager import notification_manager, SENSITIVE_PLACEHOLDER, validate_external_url from notification_channels import CHANNEL_TYPES as _NOTIF_CHANNEL_TYPES -from jwt_middleware import require_auth +from jwt_middleware import require_auth, require_admin_scope def _resolve_masked_api_key(provider, api_key): @@ -314,15 +314,21 @@ def save_notification_settings(): @notification_bp.route('/api/notifications/reveal-secret', methods=['POST']) -@require_auth +@require_admin_scope def reveal_notification_secret(): """Return one sensitive config value in cleartext. Backs the "eye" toggle in the Settings UI. The settings GET masks every entry in SENSITIVE_KEYS with `'************'` so the secret never leaves the server just because someone loaded the page; this - endpoint lets an authenticated operator explicitly request the - real value for a single key when they need to inspect it. + endpoint lets an operator explicitly request the real value for a + single key when they need to inspect it. + + Requires `full_admin` scope: this is the one route that hands back a + stored credential in cleartext, so a read-only API token — which is + handed out precisely because it cannot reach credentials — must not + reach it. Session logins carry full_admin implicitly, so the eye + toggle in the UI is unaffected. Body schema (one of): {"ai_provider": "groq" | "anthropic" | …} diff --git a/scripts/post_install/customizable_post_install.sh b/scripts/post_install/customizable_post_install.sh index 7aaf2ecc..056ac8a1 100644 --- a/scripts/post_install/customizable_post_install.sh +++ b/scripts/post_install/customizable_post_install.sh @@ -2322,7 +2322,7 @@ EOF remove_subscription_banner() { - local FUNC_VERSION="1.1" + local FUNC_VERSION="1.0" # description: Patch the Proxmox web UI to suppress the "no valid subscription" dialog (PVE 8 + 9 variants supported). local pve_version pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+' | head -1)