mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 22:07:24 +00:00
fix(zigbee,authelia): admin buttons read access URL from API (Lyrion pattern)
Apply the source-of-truth pattern from secubox-lyrion d4adc1a3 to two
sibling admin panels:
- Zigbee /zigbee/ admin webui: "Open Zigbee Manager →" button now reads
the public URL (or LAN fallback) from /api/v1/zigbee/access instead
of hardcoding https://zigbee.gk2.secubox.in/. The PUBLIC_URL env var
the FastAPI already exposed is now the only place the URL lives.
- Authelia /authelia/ admin webui: same treatment for "Open SSO Portal"
button. Plus autheliactl gets the same fixes lyrionctl did:
* config_get strips inline TOML comments instead of concatenating
them into the value (HTTP_PORT used to land as "9091 # comment")
* emit_access_json drops the /authelia/ admin suffix from URLs —
the SSO portal itself serves at the root of the dedicated vhost,
not under a subpath
* lan_url uses the LXC IP + http_port (10.100.0.20:9091) instead
of the public-facing host's address
* PUBLIC_HOSTNAME defaults to sso.gk2.secubox.in (was empty,
legacy auth.maegia.tv only in the toml example)
* stray `""|""` case pattern in cmd_status changed to `""|list`
to match the cmd_components / cmd_access conventions
- conf/authelia.toml.example: public_hostname default
auth.maegia.tv -> sso.gk2.secubox.in.
Live verified on gk2 — all three modules return the same shape:
lyrion lan http://192.168.1.200:9000/ public https://lyrion.gk2.secubox.in/
zigbee lan http://10.100.0.111:8080/ public https://zigbee.gk2.secubox.in/
authelia lan http://10.100.0.20:9091/ public https://sso.gk2.secubox.in/
And the admin button on each module's /XXX/ page reads from /api/v1/
XXX/access, so any future hostname/port change in the toml propagates
automatically — no more hardcoded URL drift.
This commit is contained in:
parent
d4adc1a3e1
commit
54da8a7cb1
|
|
@ -34,8 +34,9 @@ inactivity = "5m"
|
|||
enabled = false
|
||||
|
||||
[exposure]
|
||||
# Public hostname for the Authelia login portal.
|
||||
public_hostname = "auth.maegia.tv"
|
||||
# Public hostname for the Authelia login portal. Used by the SecuBox
|
||||
# admin webui's "Open SSO Portal" button + the /access endpoint.
|
||||
public_hostname = "sso.gk2.secubox.in"
|
||||
waf_inspect = true # route through mitmproxy (canonical maegia.tv pattern)
|
||||
|
||||
[oidc]
|
||||
|
|
|
|||
|
|
@ -29,20 +29,33 @@ err() { printf '%b[error]%b %s\n' "$RED" "$NC" "$*" >&2; }
|
|||
|
||||
# ── TOML config (best-effort, grep-style — same as giteactl) ─────────────────
|
||||
config_get() {
|
||||
local key="$1" default="${2:-}"
|
||||
# Strips TOML inline `# comment`, surrounding whitespace, and quotes.
|
||||
# Previous version concatenated `# comment text` into the value
|
||||
# (eg HTTP_PORT became "9091 # comment"), breaking URL construction.
|
||||
local key="$1" default="${2:-}" raw=""
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
grep -E "^[[:space:]]*${key}[[:space:]]*=" "$CONFIG_FILE" 2>/dev/null \
|
||||
| head -1 | cut -d= -f2- | tr -d ' "' | tr -d "'" || echo "$default"
|
||||
else
|
||||
raw=$(grep -E "^[[:space:]]*${key}[[:space:]]*=" "$CONFIG_FILE" 2>/dev/null | head -1)
|
||||
fi
|
||||
if [ -z "$raw" ]; then
|
||||
echo "$default"
|
||||
return
|
||||
fi
|
||||
local val
|
||||
val=$(echo "$raw" | cut -d= -f2- | sed 's/[[:space:]]*#.*$//' \
|
||||
| sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//' \
|
||||
| tr -d '"' | tr -d "'")
|
||||
if [ -z "$val" ]; then
|
||||
echo "$default"
|
||||
else
|
||||
echo "$val"
|
||||
fi
|
||||
}
|
||||
|
||||
LXC_NAME=$(config_get "name" "authelia")
|
||||
LXC_IP=$(config_get "ip" "10.100.0.20")
|
||||
LXC_PATH=$(config_get "path" "/data/lxc")
|
||||
HTTP_PORT=$(config_get "http_port" "3000")
|
||||
PUBLIC_HOSTNAME=$(config_get "public_hostname" "")
|
||||
HTTP_PORT=$(config_get "http_port" "9091")
|
||||
PUBLIC_HOSTNAME=$(config_get "public_hostname" "sso.gk2.secubox.in")
|
||||
|
||||
# ── LXC helpers ───────────────────────────────────────────────────────────────
|
||||
lxc_state() {
|
||||
|
|
@ -126,10 +139,15 @@ EOF
|
|||
}
|
||||
|
||||
emit_access_json() {
|
||||
# Real Authelia login portal URLs — NOT the /authelia/ admin subpath.
|
||||
# The admin webui's "Open SSO Portal" button reads this; consistency
|
||||
# comes from one source.
|
||||
# lan: http://<lxc_ip>:9091/ direct to Authelia daemon (LAN-only)
|
||||
# public: https://<PUBLIC_HOSTNAME>/ dedicated vhost
|
||||
local lan_url public_url
|
||||
lan_url="https://$(hostname -I | awk '{print $1}')/authelia/"
|
||||
lan_url="http://${LXC_IP}:${HTTP_PORT}/"
|
||||
if [ -n "$PUBLIC_HOSTNAME" ]; then
|
||||
public_url="https://${PUBLIC_HOSTNAME}/authelia/"
|
||||
public_url="https://${PUBLIC_HOSTNAME}/"
|
||||
else
|
||||
public_url=""
|
||||
fi
|
||||
|
|
@ -137,9 +155,9 @@ emit_access_json() {
|
|||
{
|
||||
"module": "authelia",
|
||||
"access": [
|
||||
{"url": "$lan_url", "auth": "jwt|authelia-admin", "scope": "lan"}$( [ -n "$public_url" ] && echo ',' )
|
||||
{"url": "$lan_url", "auth": "lan-only", "scope": "lan"}$( [ -n "$public_url" ] && echo ',' )
|
||||
$( [ -n "$public_url" ] && cat <<PUB
|
||||
{"url": "$public_url", "auth": "jwt|authelia-admin", "scope": "public"}
|
||||
{"url": "$public_url", "auth": "Authelia SSO", "scope": "public"}
|
||||
PUB
|
||||
)
|
||||
]
|
||||
|
|
@ -159,7 +177,7 @@ cmd_components() {
|
|||
cmd_status() {
|
||||
case "${1:-}" in
|
||||
--json) emit_status_json ;;
|
||||
""|"") emit_components_text ; echo ; emit_status_json | python3 -c 'import json,sys; d=json.load(sys.stdin); print("overall:", d["overall"])' ;;
|
||||
""|list) emit_components_text ; echo ; emit_status_json | python3 -c 'import json,sys; d=json.load(sys.stdin); print("overall:", d["overall"])' ;;
|
||||
*) err "unknown verb for 'status': $1"; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@
|
|||
<h1><span class="icon">🎯</span> Auth — SSO control</h1>
|
||||
<div class="header-actions">
|
||||
<a class="btn" href="/" title="Back to SecuBox hub">← hub</a>
|
||||
<a class="btn primary" href="https://sso.gk2.secubox.in/" title="Open the Authelia SSO portal (login surface)">Open SSO Portal →</a>
|
||||
<a class="btn primary" id="open-sso" href="#" target="_blank" rel="noopener" title="Open the Authelia SSO portal (login surface)">Open SSO Portal →</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -191,8 +191,15 @@
|
|||
document.getElementById('stat-cookies-sub').textContent = cookies.map(function (c) { return c.domain || c; }).join(', ') || 'session.cookies[]';
|
||||
document.getElementById('stat-rules').textContent = String(rules.length || '?');
|
||||
|
||||
var v = (d.access || []).map(function (a) { return '<div>' + (a.scope || '') + ': <a href="' + (a.url || '#') + '">' + (a.url || '?') + '</a></div>'; }).join('');
|
||||
var access = d.access || [];
|
||||
var v = access.map(function (a) { return '<div>' + (a.scope || '') + ': <a href="' + (a.url || '#') + '">' + (a.url || '?') + '</a></div>'; }).join('');
|
||||
document.getElementById('access-v').innerHTML = v || '<span style="color:var(--muted)">no access points</span>';
|
||||
// Single source of truth for the "Open SSO Portal" button.
|
||||
var pub = access.find(function (a) { return a.scope === 'public'; });
|
||||
var lan = access.find(function (a) { return a.scope === 'lan'; });
|
||||
var target = (pub && pub.url) || (lan && lan.url) || '#';
|
||||
var btn = document.getElementById('open-sso');
|
||||
if (btn) btn.href = target;
|
||||
}).catch(function () {
|
||||
document.getElementById('access-v').innerHTML = '<span style="color:var(--muted)">unavailable</span>';
|
||||
});
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
<h1><span class="icon">📡</span> Zigbee — Mesh manager</h1>
|
||||
<div class="header-actions">
|
||||
<a class="btn" href="/" title="Back to SecuBox hub">← hub</a>
|
||||
<a class="btn primary" href="https://zigbee.gk2.secubox.in/" title="Open the full zigbee2mqtt manager (SSO-gated)">Open Zigbee Manager →</a>
|
||||
<a class="btn primary" id="open-z2m" href="#" target="_blank" rel="noopener" title="Open the full zigbee2mqtt manager (SSO-gated)">Open Zigbee Manager →</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -179,8 +179,16 @@
|
|||
}).catch(function () { document.getElementById('status-v').innerHTML = '<span style="color:var(--muted)">unavailable</span>'; });
|
||||
|
||||
get('/access').then(function (d) {
|
||||
var list = (d.access || []).map(function (a) { return '<div>' + a.scope + ': <a href="' + a.url + '">' + a.url + '</a></div>'; }).join('');
|
||||
var access = d.access || [];
|
||||
var list = access.map(function (a) { return '<div>' + a.scope + ': <a href="' + a.url + '">' + a.url + '</a></div>'; }).join('');
|
||||
document.getElementById('access-v').innerHTML = list || '<span style="color:var(--muted)">no access points</span>';
|
||||
// Single source of truth for the "Open Zigbee Manager" button:
|
||||
// prefer the public (Authelia-gated) URL, fall back to LAN.
|
||||
var pub = access.find(function (a) { return a.scope === 'public'; });
|
||||
var lan = access.find(function (a) { return a.scope === 'lan'; });
|
||||
var target = (pub && pub.url) || (lan && lan.url) || '#';
|
||||
var btn = document.getElementById('open-z2m');
|
||||
if (btn) btn.href = target;
|
||||
}).catch(function () { document.getElementById('access-v').innerHTML = '<span style="color:var(--muted)">unavailable</span>'; });
|
||||
|
||||
// ── Backups card ─────────────────────────────────────────────
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user