From d0cd42e2a17a0cf872a479c0acc2d74d52ae38ab Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Mon, 16 Mar 2026 07:35:18 +0100 Subject: [PATCH] fix(luci): Performance and UX improvements for exposure and portal - Optimize exposure RPCD: O(n) single-pass awk parsing for vhost_list and ssl_list (fixes XHR timeout on 200+ vhosts) - Fix portal tree URLs: Use get_menu_path() to read actual LuCI menu paths from JSON instead of hardcoded paths - Add Downloads category to portal tree (torrent, droplet patterns) - Add new apps to System category (config-vault, reporter, smtp-relay, rtty, dpi-dual, metacatalog) - Enhance KISS theme menu: Add Downloads, Monitoring categories - Fix Lyrion URL: Use HTTPS vhost instead of dynamic port URL Co-Authored-By: Claude Opus 4.5 --- .../root/usr/libexec/rpcd/luci.exposure | 313 ++++++++++++------ .../resources/view/lyrion/overview.js | 4 +- .../root/usr/libexec/rpcd/luci.secubox-portal | 72 ++-- .../resources/secubox/kiss-theme.js | 39 ++- 4 files changed, 290 insertions(+), 138 deletions(-) diff --git a/package/secubox/luci-app-exposure/root/usr/libexec/rpcd/luci.exposure b/package/secubox/luci-app-exposure/root/usr/libexec/rpcd/luci.exposure index b9df5123..5fe0de52 100755 --- a/package/secubox/luci-app-exposure/root/usr/libexec/rpcd/luci.exposure +++ b/package/secubox/luci-app-exposure/root/usr/libexec/rpcd/luci.exposure @@ -270,44 +270,52 @@ case "$1" in ;; ssl_list) - TMP_SSLLIST="/tmp/exposure_ssllist_$$" - > "$TMP_SSLLIST" - - # Read from HAProxy UCI config (vhosts with their backends) - for vhost in $(uci show haproxy 2>/dev/null | grep "=vhost$" | cut -d'.' -f2 | cut -d'=' -f1); do - domain=$(uci -q get "haproxy.${vhost}.domain") - backend=$(uci -q get "haproxy.${vhost}.backend") - enabled=$(uci -q get "haproxy.${vhost}.enabled") - - [ "$enabled" != "1" ] && continue - [ -z "$domain" ] && continue - - # Get server address from backend config - server="" - if [ -n "$backend" ]; then - server=$(uci -q get "haproxy.${backend}.server" 2>/dev/null | head -1 | awk '{print $2}') - fi - - echo "${backend:-$vhost}|${domain}|${server:-N/A}" >> "$TMP_SSLLIST" - done - - json_init - json_add_array "backends" - - if [ -s "$TMP_SSLLIST" ]; then - while IFS='|' read service domain server; do - [ -z "$service" ] && continue - json_add_object "" - json_add_string "service" "$service" - json_add_string "domain" "$domain" - json_add_string "backend" "$server" - json_close_object - done < "$TMP_SSLLIST" - fi - rm -f "$TMP_SSLLIST" - - json_close_array - json_dump + # OPTIMIZED: Single-pass awk parsing + uci show haproxy 2>/dev/null | awk ' + BEGIN { + printf "{\"backends\":[" + first = 1 + } + /=vhost$/ { + if (vh_domain != "" && vh_enabled == "1") { + if (first == 0) printf "," + first = 0 + printf "{\"service\":\"%s\",\"domain\":\"%s\",\"backend\":\"%s\"}", + (vh_backend != "" ? vh_backend : vh_id), vh_domain, "N/A" + } + gsub(/^haproxy\./, "", $0) + gsub(/=vhost$/, "", $0) + vh_id = $0 + vh_domain = "" + vh_backend = "" + vh_enabled = "0" + in_vhost = 1 + } + /=backend$/ || /=server$/ { in_vhost = 0 } + /\.domain=/ && in_vhost { + gsub(/.*\.domain=/, "", $0) + gsub(/'\''/, "", $0) + vh_domain = $0 + } + /\.backend=/ && in_vhost { + gsub(/.*\.backend=/, "", $0) + gsub(/'\''/, "", $0) + vh_backend = $0 + } + /\.enabled=/ && in_vhost { + gsub(/.*\.enabled=/, "", $0) + gsub(/'\''/, "", $0) + vh_enabled = $0 + } + END { + if (vh_domain != "" && vh_enabled == "1") { + if (first == 0) printf "," + printf "{\"service\":\"%s\",\"domain\":\"%s\",\"backend\":\"%s\"}", + (vh_backend != "" ? vh_backend : vh_id), vh_domain, "N/A" + } + printf "]}" + } + ' ;; get_config) @@ -479,80 +487,171 @@ case "$1" in ;; vhost_list) - json_init + # OPTIMIZED: Single-pass awk parsing instead of O(n²) uci calls + uci show haproxy 2>/dev/null | awk ' + BEGIN { + printf "{\"haproxy\":[" + first_vh = 1 + } - # HAProxy vhosts (domain -> backend with resolved port) - json_add_array "haproxy" - for vhost in $(uci show haproxy 2>/dev/null | grep "=vhost$" | cut -d'.' -f2 | cut -d'=' -f1); do - domain=$(uci -q get "haproxy.${vhost}.domain") - backend=$(uci -q get "haproxy.${vhost}.backend") - enabled=$(uci -q get "haproxy.${vhost}.enabled") - ssl=$(uci -q get "haproxy.${vhost}.ssl") - acme=$(uci -q get "haproxy.${vhost}.acme") + # Collect server backend->port mappings + /\.backend=/ && /=server$/ == 0 { + # This is a vhost or backend .backend= line, skip for server collection + } + /=server$/ { + gsub(/^haproxy\./, "", $0) + gsub(/=server$/, "", $0) + current_srv = $0 + } + /^haproxy\.[^.]+\.backend=/ && prev_type == "server" { + gsub(/^haproxy\.[^.]+\.backend=/, "", $0) + gsub(/'\''/, "", $0) + srv_backends[current_srv] = $0 + } + /^haproxy\.[^.]+\.port=/ && prev_type == "server" { + gsub(/^haproxy\.[^.]+\.port=/, "", $0) + gsub(/'\''/, "", $0) + srv_ports[current_srv] = $0 + } - [ -z "$domain" ] && continue + # Track section type + /=vhost$/ { prev_type = "vhost" } + /=server$/ { prev_type = "server" } + /=backend$/ { prev_type = "backend" } - # Check for original_backend (when mitmproxy is intercepting) - original_backend=$(uci -q get "haproxy.${vhost}.original_backend") - resolve_backend="${original_backend:-$backend}" + # Process vhosts + /=vhost$/ { + # Output previous vhost + if (vh_id != "" && vh_domain != "") { + if (first_vh == 0) printf "," + first_vh = 0 + # Resolve backend port + resolve_be = (vh_orig_be != "") ? vh_orig_be : vh_backend + port = 0 + for (s in srv_backends) { + if (srv_backends[s] == resolve_be && srv_ports[s] != "") { + port = srv_ports[s] + break + } + } + printf "{\"id\":\"%s\",\"domain\":\"%s\",\"backend\":\"%s\",\"backend_port\":%d,\"ssl\":%s,\"acme\":%s,\"enabled\":%s}", + vh_id, vh_domain, resolve_be, port, + (vh_ssl == "1" ? "true" : "false"), + (vh_acme == "1" ? "true" : "false"), + (vh_enabled == "1" ? "true" : "false") + } + # Start new vhost + gsub(/^haproxy\./, "", $0) + gsub(/=vhost$/, "", $0) + vh_id = $0 + vh_domain = "" + vh_backend = "" + vh_orig_be = "" + vh_ssl = "0" + vh_acme = "0" + vh_enabled = "0" + } + /\.domain=/ && prev_type == "vhost" { + gsub(/.*\.domain=/, "", $0) + gsub(/'\''/, "", $0) + vh_domain = $0 + } + /\.backend=/ && prev_type == "vhost" { + gsub(/.*\.backend=/, "", $0) + gsub(/'\''/, "", $0) + vh_backend = $0 + } + /\.original_backend=/ && prev_type == "vhost" { + gsub(/.*\.original_backend=/, "", $0) + gsub(/'\''/, "", $0) + vh_orig_be = $0 + } + /\.ssl=/ && prev_type == "vhost" { + gsub(/.*\.ssl=/, "", $0) + gsub(/'\''/, "", $0) + vh_ssl = $0 + } + /\.acme=/ && prev_type == "vhost" { + gsub(/.*\.acme=/, "", $0) + gsub(/'\''/, "", $0) + vh_acme = $0 + } + /\.enabled=/ && prev_type == "vhost" { + gsub(/.*\.enabled=/, "", $0) + gsub(/'\''/, "", $0) + vh_enabled = $0 + } - # Resolve backend port from the target backend - backend_port="" - if [ -n "$resolve_backend" ]; then - # Try inline server option: 'name IP:PORT check' - server_line=$(uci -q get "haproxy.${resolve_backend}.server" 2>/dev/null) - if [ -n "$server_line" ]; then - backend_port=$(echo "$server_line" | awk '{print $2}' | grep -o ':[0-9]*' | tr -d ':') - fi - # Try server sections referencing this backend - if [ -z "$backend_port" ]; then - for srv in $(uci show haproxy 2>/dev/null | grep "=server$" | cut -d'.' -f2 | cut -d'=' -f1); do - srv_backend=$(uci -q get "haproxy.${srv}.backend") - if [ "$srv_backend" = "$resolve_backend" ]; then - backend_port=$(uci -q get "haproxy.${srv}.port") - break - fi - done - fi - fi + END { + # Output last vhost + if (vh_id != "" && vh_domain != "") { + if (first_vh == 0) printf "," + resolve_be = (vh_orig_be != "") ? vh_orig_be : vh_backend + port = 0 + for (s in srv_backends) { + if (srv_backends[s] == resolve_be && srv_ports[s] != "") { + port = srv_ports[s] + break + } + } + printf "{\"id\":\"%s\",\"domain\":\"%s\",\"backend\":\"%s\",\"backend_port\":%d,\"ssl\":%s,\"acme\":%s,\"enabled\":%s}", + vh_id, vh_domain, resolve_be, port, + (vh_ssl == "1" ? "true" : "false"), + (vh_acme == "1" ? "true" : "false"), + (vh_enabled == "1" ? "true" : "false") + } + printf "]," + } + ' - json_add_object "" - json_add_string "id" "$vhost" - json_add_string "domain" "$domain" - json_add_string "backend" "${resolve_backend:-${backend:-}}" - json_add_int "backend_port" "${backend_port:-0}" - json_add_boolean "ssl" "${ssl:-0}" - json_add_boolean "acme" "${acme:-0}" - json_add_boolean "enabled" "${enabled:-0}" - json_close_object - done - json_close_array - - # uhttpd vhosts (non-main instances) - json_add_array "uhttpd" - for section in $(uci show uhttpd 2>/dev/null | grep "=uhttpd$" | cut -d'.' -f2 | cut -d'=' -f1); do - [ "$section" = "main" ] && continue - [ "$section" = "acme" ] && continue - - listen=$(uci -q get "uhttpd.${section}.listen_http") - home=$(uci -q get "uhttpd.${section}.home") - [ -z "$listen" ] && continue - - port=$(echo "$listen" | grep -o '[0-9]*$') - - # Derive friendly name from section id - fname=$(echo "$section" | sed 's/^metablog_site_//' | sed 's/_/ /g') - - json_add_object "" - json_add_string "id" "$section" - json_add_int "port" "${port:-0}" - json_add_string "name" "$fname" - json_add_string "home" "${home:-}" - json_close_object - done - json_close_array - - json_dump + # uhttpd vhosts - also optimized with awk + uci show uhttpd 2>/dev/null | awk ' + BEGIN { + printf "\"uhttpd\":[" + first = 1 + } + /=uhttpd$/ { + if (section != "" && section != "main" && section != "acme" && listen != "") { + if (first == 0) printf "," + first = 0 + # Extract port from listen + match(listen, /[0-9]+$/) + port = substr(listen, RSTART, RLENGTH) + gsub(/^metablog_site_/, "", section) + gsub(/_/, " ", section) + printf "{\"id\":\"%s\",\"port\":%s,\"name\":\"%s\",\"home\":\"%s\"}", + orig_section, (port != "" ? port : "0"), section, home + } + gsub(/^uhttpd\./, "", $0) + gsub(/=uhttpd$/, "", $0) + orig_section = $0 + section = $0 + listen = "" + home = "" + } + /\.listen_http=/ { + gsub(/.*\.listen_http=/, "", $0) + gsub(/'\''/, "", $0) + listen = $0 + } + /\.home=/ { + gsub(/.*\.home=/, "", $0) + gsub(/'\''/, "", $0) + home = $0 + } + END { + if (section != "" && section != "main" && section != "acme" && listen != "") { + if (first == 0) printf "," + match(listen, /[0-9]+$/) + port = substr(listen, RSTART, RLENGTH) + gsub(/^metablog_site_/, "", section) + gsub(/_/, " ", section) + printf "{\"id\":\"%s\",\"port\":%s,\"name\":\"%s\",\"home\":\"%s\"}", + orig_section, (port != "" ? port : "0"), section, home + } + printf "]}" + } + ' ;; emancipate) diff --git a/package/secubox/luci-app-lyrion/htdocs/luci-static/resources/view/lyrion/overview.js b/package/secubox/luci-app-lyrion/htdocs/luci-static/resources/view/lyrion/overview.js index 2dd7fe36..a84a50f5 100644 --- a/package/secubox/luci-app-lyrion/htdocs/luci-static/resources/view/lyrion/overview.js +++ b/package/secubox/luci-app-lyrion/htdocs/luci-static/resources/view/lyrion/overview.js @@ -145,13 +145,13 @@ return view.extend({ E('h3', {}, _('Web Interface')), E('div', { 'style': 'margin-bottom:12px' }, [ E('a', { - 'href': 'http://' + window.location.hostname + ':' + (s.port || 9000), + 'href': 'https://lyrion.gk2.secubox.in/', 'target': '_blank', 'class': 'cbi-button cbi-button-action', 'style': 'margin-right:8px' }, _('Open Lyrion Web UI')), E('span', { 'style': 'color:#888' }, - 'http://' + window.location.hostname + ':' + (s.port || 9000)) + 'https://lyrion.gk2.secubox.in/') ]) ]), diff --git a/package/secubox/luci-app-secubox-portal/root/usr/libexec/rpcd/luci.secubox-portal b/package/secubox/luci-app-secubox-portal/root/usr/libexec/rpcd/luci.secubox-portal index 596cdb39..e71a3f5d 100644 --- a/package/secubox/luci-app-secubox-portal/root/usr/libexec/rpcd/luci.secubox-portal +++ b/package/secubox/luci-app-secubox-portal/root/usr/libexec/rpcd/luci.secubox-portal @@ -4,6 +4,20 @@ . /usr/share/libubox/jshn.sh +# Get actual menu path for a luci-app package +get_menu_path() { + local pkg="$1" + local menu_file="/usr/share/luci/menu.d/${pkg}.json" + if [ -f "$menu_file" ]; then + local path=$(grep -o '"admin/[^"]*"' "$menu_file" | head -1 | tr -d '"') + if [ -n "$path" ]; then + echo "$path" + return + fi + fi + echo "admin/services/$(echo "$pkg" | sed 's/luci-app-//')" +} + # Discover LuCI menu entries from menu.d JSON files discover_luci_menus() { local menus="" @@ -90,11 +104,11 @@ build_tree() { json_add_array "items" for app in $apps; do case "$app" in - luci-app-crowdsec*|luci-app-mitmproxy*|luci-app-guardian*|luci-app-dnsguard*|luci-app-threat*|luci-app-wazuh*|luci-app-vortex*) + luci-app-crowdsec*|luci-app-mitmproxy*|luci-app-guardian*|luci-app-dnsguard*|luci-app-threat*|luci-app-wazuh*|luci-app-vortex*|luci-app-firewall*|luci-app-device-intel*|luci-app-security*) local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/services/$(echo "$app" | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; @@ -109,11 +123,11 @@ build_tree() { json_add_array "items" for app in $apps; do case "$app" in - luci-app-jellyfin*|luci-app-lyrion*|luci-app-streamlit*|luci-app-peertube*|luci-app-magicmirror*) + luci-app-jellyfin*|luci-app-lyrion*|luci-app-streamlit*|luci-app-peertube*|luci-app-magicmirror*|luci-app-media-flow*|luci-app-icecast*|luci-app-webradio*|luci-app-mmpm*) local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/services/$(echo "$app" | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; @@ -128,11 +142,11 @@ build_tree() { json_add_array "items" for app in $apps; do case "$app" in - luci-app-haproxy*|luci-app-wireguard*|luci-app-tor*|luci-app-cdn*|luci-app-exposure*|luci-app-dns-provider*) + luci-app-haproxy*|luci-app-wireguard*|luci-app-tor*|luci-app-cdn*|luci-app-exposure*|luci-app-dns-provider*|luci-app-vhost*|luci-app-bandwidth*|luci-app-traffic*|luci-app-network-modes*|luci-app-ksmbd*) local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/services/$(echo "$app" | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; @@ -151,7 +165,7 @@ build_tree() { local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/services/$(echo "$app" | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; @@ -166,11 +180,11 @@ build_tree() { json_add_array "items" for app in $apps; do case "$app" in - luci-app-domoticz*|luci-app-zigbee*|luci-app-iot*|luci-app-mqtt*) + luci-app-domoticz*|luci-app-zigbee*|luci-app-iot*|luci-app-mqtt*|luci-app-picobrew*) local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/services/$(echo "$app" | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; @@ -185,11 +199,11 @@ build_tree() { json_add_array "items" for app in $apps; do case "$app" in - luci-app-localai*|luci-app-ollama*|luci-app-simplex*|luci-app-gotosocial*|luci-app-ai-*|luci-app-voip*|luci-app-jabber*|luci-app-jitsi*|luci-app-mail*|luci-app-nextcloud*|luci-app-webradio*) + luci-app-localai*|luci-app-ollama*|luci-app-simplex*|luci-app-gotosocial*|luci-app-ai-*|luci-app-voip*|luci-app-jabber*|luci-app-jitsi*|luci-app-mailserver*|luci-app-nextcloud*|luci-app-matrix*|luci-app-cyberfeed*) local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/services/$(echo "$app" | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; @@ -204,11 +218,11 @@ build_tree() { json_add_array "items" for app in $apps; do case "$app" in - luci-app-cloner*|luci-app-backup*|luci-app-system*|luci-app-config-advisor*|luci-app-service-registry*) + luci-app-cloner*|luci-app-backup*|luci-app-system*|luci-app-config-advisor*|luci-app-service-registry*|luci-app-watchdog*|luci-app-glances*|luci-app-netdata*|luci-app-package-manager*|luci-app-master-link*|luci-app-uhttpd*|luci-app-config-vault*|luci-app-reporter*|luci-app-smtp-relay*|luci-app-rtty*|luci-app-dpi-dual*|luci-app-metacatalog*) local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/services/$(echo "$app" | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; @@ -217,24 +231,36 @@ build_tree() { json_close_array json_close_object - # Other SecuBox Apps (catch-all) + # Downloads Apps json_add_object "" - json_add_string "cat" "Other SecuBox Apps" + json_add_string "cat" "Downloads" + json_add_array "items" + for app in $apps; do + case "$app" in + luci-app-torrent*|luci-app-droplet*|luci-app-aria*|luci-app-transmission*|luci-app-nzb*|luci-app-sabnzbd*) + local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') + json_add_object "" + json_add_string "name" "$name" + json_add_string "path" "$(get_menu_path "$app")" + json_add_string "package" "$app" + json_close_object + ;; + esac + done + json_close_array + json_close_object + + # SecuBox Core Apps + json_add_object "" + json_add_string "cat" "SecuBox Core" json_add_array "items" for app in $apps; do case "$app" in - luci-app-crowdsec*|luci-app-mitmproxy*|luci-app-guardian*|luci-app-dnsguard*|luci-app-threat*|luci-app-wazuh*|luci-app-vortex*) continue ;; - luci-app-jellyfin*|luci-app-lyrion*|luci-app-streamlit*|luci-app-peertube*|luci-app-magicmirror*) continue ;; - luci-app-haproxy*|luci-app-wireguard*|luci-app-tor*|luci-app-cdn*|luci-app-exposure*|luci-app-dns-provider*) continue ;; - luci-app-gitea*|luci-app-hexo*|luci-app-metablog*|luci-app-metabol*) continue ;; - luci-app-domoticz*|luci-app-zigbee*|luci-app-iot*|luci-app-mqtt*) continue ;; - luci-app-localai*|luci-app-ollama*|luci-app-simplex*|luci-app-gotosocial*|luci-app-ai-*|luci-app-voip*|luci-app-jabber*|luci-app-jitsi*|luci-app-mail*|luci-app-nextcloud*|luci-app-webradio*) continue ;; - luci-app-cloner*|luci-app-backup*|luci-app-system*|luci-app-config-advisor*|luci-app-service-registry*) continue ;; luci-app-secubox*|luci-app-*secubox*) local name=$(echo "$app" | sed 's/luci-app-//' | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++)$i=toupper(substr($i,1,1))tolower(substr($i,2))}1') json_add_object "" json_add_string "name" "$name" - json_add_string "path" "admin/secubox/$(echo "$app" | sed 's/luci-app-secubox-//' | sed 's/luci-app-//')" + json_add_string "path" "$(get_menu_path "$app")" json_add_string "package" "$app" json_close_object ;; diff --git a/package/secubox/luci-theme-secubox/htdocs/luci-static/resources/secubox/kiss-theme.js b/package/secubox/luci-theme-secubox/htdocs/luci-static/resources/secubox/kiss-theme.js index 8ad2e0ee..67ffa13c 100644 --- a/package/secubox/luci-theme-secubox/htdocs/luci-static/resources/secubox/kiss-theme.js +++ b/package/secubox/luci-theme-secubox/htdocs/luci-static/resources/secubox/kiss-theme.js @@ -96,7 +96,7 @@ var KissThemeClass = baseclass.extend({ ]}, { icon: 'šŸ“¶', name: 'Traffic Shaper', path: 'admin/secubox/network/traffic-shaper' }, { icon: 'šŸ“”', name: 'Bandwidth', path: 'admin/secubox/network/bandwidth-manager' }, - { icon: '🌐', name: 'Network Modes', path: 'admin/secubox/network/network-modes' }, + { icon: '🌐', name: 'Network Modes', path: 'admin/secubox/network/modes' }, { icon: 'šŸ”Œ', name: 'Interfaces', path: 'admin/network/network' }, { icon: 'šŸ”§', name: 'Net Diagnostics', path: 'admin/services/network-diagnostics' } ]}, @@ -119,6 +119,7 @@ var KissThemeClass = baseclass.extend({ // ═══════════════════════════════════════════════════════════════ { cat: 'Communication', icon: 'šŸ’¬', collapsed: true, items: [ { icon: 'āœ‰ļø', name: 'Mail Server', path: 'admin/services/mailserver' }, + { icon: 'šŸ“§', name: 'SMTP Relay', path: 'admin/secubox/system/smtp-relay' }, { icon: 'šŸ’¬', name: 'Jabber/XMPP', path: 'admin/services/jabber' }, { icon: 'šŸ”', name: 'Matrix', path: 'admin/services/matrix' }, { icon: 'šŸ”’', name: 'SimpleX', path: 'admin/services/simplex' }, @@ -145,7 +146,10 @@ var KissThemeClass = baseclass.extend({ { name: 'Settings', path: 'admin/services/metablogizer/settings' } ]}, { icon: 'šŸŽÆ', name: 'Streamlit', path: 'admin/services/streamlit' }, + { icon: 'šŸ”§', name: 'Streamlit Forge', path: 'admin/services/streamlit-forge' }, { icon: 'šŸ“°', name: 'CyberFeed', path: 'admin/services/cyberfeed' }, + { icon: 'šŸ“š', name: 'Meta Catalog', path: 'admin/secubox/metacatalog' }, + { icon: 'šŸŽ­', name: 'Avatar Tap', path: 'admin/services/avatar-tap' }, { icon: 'šŸ ', name: 'Domoticz', path: 'admin/services/domoticz' }, { icon: 'šŸŗ', name: 'PicoBrew', path: 'admin/services/picobrew' } ]}, @@ -168,13 +172,12 @@ var KissThemeClass = baseclass.extend({ // P2P & MESH - Distributed networking // ═══════════════════════════════════════════════════════════════ { cat: 'P2P & Mesh', icon: 'šŸ”—', collapsed: true, items: [ - { icon: 'šŸ”—', name: 'Master Link', path: 'admin/secubox/master-link' }, + { icon: 'šŸ”—', name: 'Master Link', path: 'admin/services/secubox-mesh' }, { icon: '🌐', name: 'P2P Network', path: 'admin/services/secubox-p2p' }, - { icon: 'šŸ”—', name: 'Mesh Network', path: 'admin/services/secubox-mesh' }, - { icon: 'šŸ“”', name: 'Exposure', path: 'admin/services/exposure' }, + { icon: 'šŸ“”', name: 'Exposure', path: 'admin/secubox/network/exposure' }, { icon: 'šŸ“‹', name: 'Service Registry', path: 'admin/services/service-registry' }, { icon: 'ā˜ļø', name: 'SaaS Relay', path: 'admin/services/saas-relay' }, - { icon: '🌳', name: 'Netifyd', path: 'admin/services/secubox-netifyd' } + { icon: '🌳', name: 'Netifyd', path: 'admin/secubox/netifyd' } ]}, // ═══════════════════════════════════════════════════════════════ @@ -187,7 +190,31 @@ var KissThemeClass = baseclass.extend({ { icon: 'šŸ“', name: 'File Sharing', path: 'admin/services/ksmbd' }, { icon: '🌳', name: 'LuCI Menu', path: 'admin/secubox/luci-tree' }, { icon: 'šŸ”§', name: 'Software', path: 'admin/system/opkg' }, - { icon: 'šŸ–„ļø', name: 'uhttpd', path: 'admin/services/uhttpd' } + { icon: 'šŸ–„ļø', name: 'uhttpd', path: 'admin/services/uhttpd' }, + { icon: 'šŸ”', name: 'Config Vault', path: 'admin/secubox/system/config-vault' }, + { icon: 'šŸ“‹', name: 'Reporter', path: 'admin/secubox/system/reporter' }, + { icon: 'šŸ•', name: 'Watchdog', path: 'admin/secubox/system/watchdog' }, + { icon: 'šŸ–„ļø', name: 'Remote RTTY', path: 'admin/secubox/system/system-hub/rtty-remote' } + ]}, + + // ═══════════════════════════════════════════════════════════════ + // DOWNLOADS - Torrent and Usenet clients + // ═══════════════════════════════════════════════════════════════ + { cat: 'Downloads', icon: 'šŸ“„', collapsed: true, items: [ + { icon: '🧲', name: 'Torrent', path: 'admin/services/torrent' }, + { icon: 'šŸ’§', name: 'Droplet', path: 'admin/services/droplet' }, + { icon: '🌊', name: 'WebTorrent', path: 'admin/services/webtorrent' } + ]}, + + // ═══════════════════════════════════════════════════════════════ + // MONITORING - System and network monitoring + // ═══════════════════════════════════════════════════════════════ + { cat: 'Monitoring', icon: 'šŸ“ˆ', collapsed: true, items: [ + { icon: 'šŸ‘ļø', name: 'Glances', path: 'admin/secubox/monitoring/glances' }, + { icon: 'šŸ“Š', name: 'Netdata', path: 'admin/secubox/monitoring/netdata' }, + { icon: 'šŸ”', name: 'Device Intel', path: 'admin/secubox/device-intel' }, + { icon: 'šŸ“”', name: 'Threat Analyst', path: 'admin/services/threat-analyst' }, + { icon: 'šŸ”¬', name: 'DPI Dual', path: 'admin/secubox/dpi-dual' } ]} ],