From 90f0937f739eb6631c51634773c333084d169bc1 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Fri, 2 Jan 2026 12:11:40 -0300 Subject: [PATCH] portal: improve jellyfin/mailu status --- backend/atlas_portal/routes/account.py | 20 +++++++++++++++----- frontend/src/views/AccountView.vue | 6 +++--- frontend/src/views/AppsView.vue | 16 ++++++++-------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/backend/atlas_portal/routes/account.py b/backend/atlas_portal/routes/account.py index 18a880f..b95fc5a 100644 --- a/backend/atlas_portal/routes/account.py +++ b/backend/atlas_portal/routes/account.py @@ -37,6 +37,7 @@ def register(app) -> None: jellyfin_status = "ready" jellyfin_sync_status = "unknown" jellyfin_sync_detail = "" + jellyfin_user_is_ldap = False if not admin_client().ready(): mailu_status = "server not configured" @@ -46,6 +47,8 @@ def register(app) -> None: elif username: try: user = admin_client().find_user(username) or {} + if isinstance(user, dict): + jellyfin_user_is_ldap = bool(user.get("federationLink")) if not keycloak_email: keycloak_email = str(user.get("email") or "") @@ -82,17 +85,24 @@ def register(app) -> None: elif username: mailu_username = f"{username}@{settings.MAILU_DOMAIN}" + if not mailu_app_password and mailu_status == "ready": + mailu_status = "needs app password" + if jellyfin_status == "ready": - if _tcp_check( + ldap_reachable = _tcp_check( settings.JELLYFIN_LDAP_HOST, settings.JELLYFIN_LDAP_PORT, settings.JELLYFIN_LDAP_CHECK_TIMEOUT_SEC, - ): - jellyfin_sync_status = "ok" - jellyfin_sync_detail = "LDAP reachable" - else: + ) + if not ldap_reachable: jellyfin_sync_status = "degraded" jellyfin_sync_detail = "LDAP unreachable" + elif not jellyfin_user_is_ldap: + jellyfin_sync_status = "degraded" + jellyfin_sync_detail = "Keycloak user is not LDAP-backed" + else: + jellyfin_sync_status = "ok" + jellyfin_sync_detail = "LDAP-backed (Keycloak is source of truth)" return jsonify( { diff --git a/frontend/src/views/AccountView.vue b/frontend/src/views/AccountView.vue index 1e771ba..65f702c 100644 --- a/frontend/src/views/AccountView.vue +++ b/frontend/src/views/AccountView.vue @@ -35,7 +35,7 @@ {{ mailu.smtp }}
- Username + Email {{ mailu.username }}
@@ -87,13 +87,13 @@

Jellyfin

{{ jellyfin.syncStatus === "ok" ? "in sync" : jellyfin.syncStatus === "degraded" - ? "check sync" + ? "out of sync" : jellyfin.status }} diff --git a/frontend/src/views/AppsView.vue b/frontend/src/views/AppsView.vue index 1efb78a..8917e9c 100644 --- a/frontend/src/views/AppsView.vue +++ b/frontend/src/views/AppsView.vue @@ -44,7 +44,7 @@ const sections = [ { title: "Cloud", - description: "Files, photos, mail, calendars, and documents — the primary hub for Atlas users.", + description: "Your personal cloud hub: files, photos, mail, calendars, and collaborative documents.", groups: [ { title: "Nextcloud", @@ -53,7 +53,7 @@ const sections = [ name: "Cloud", url: "https://cloud.bstein.dev", target: "_blank", - description: "Your personal cloud storage and productivity suite.", + description: "Storage, mail, photos, and office docs — the main Atlas hub.", }, ], }, @@ -61,7 +61,7 @@ const sections = [ }, { title: "Security", - description: "Password security, secrets, and account hygiene.", + description: "Passwords for humans, secrets for infrastructure.", groups: [ { title: "Personal", @@ -89,16 +89,16 @@ const sections = [ }, { title: "Communications", - description: "Discord-like chat, calls, and rooms — plus Atlas AI chat bots.", + description: "Chat rooms, calls, and bots. Element X (mobile) is the recommended client.", groups: [ { title: "Chat", apps: [ { - name: "Element", + name: "Element X", url: "https://live.bstein.dev", target: "_blank", - description: "Matrix chat rooms with voice/video powered by local infra.", + description: "Matrix rooms with calls powered by Atlas infra.", }, { name: "AI Chat", @@ -112,7 +112,7 @@ const sections = [ }, { title: "Streaming", - description: "Family media streaming and upload workflows.", + description: "Stream media and publish uploads into your library.", groups: [ { title: "Media", @@ -135,7 +135,7 @@ const sections = [ }, { title: "Dev", - description: "Source control, CI, registry, GitOps, and observability.", + description: "Build and ship: source control, CI, registry, and GitOps.", groups: [ { title: "Source & CI",