Browse Source

Fix external sidebar link icon missing when auth enabled (#878)

  The sidebar <img> tag in Layout.tsx fetched custom external-link icons
  via a raw /api/v1/external-links/{id}/icon URL. That endpoint is
  protected by the shared camera-stream token (passed as ?token=xxx
  because <img> tags cannot send Authorization headers), so the request
  came back 401 with the "Valid camera stream token required" message.

  The edit dialog already routed through api.getExternalLinkIconUrl(),
  which wraps the URL via withStreamToken(); the sidebar now does the
  same in both the open-in-new-tab and NavLink branches.
maziggy 1 month ago
parent
commit
d65d440cfb
4 changed files with 4 additions and 3 deletions
  1. 1 0
      CHANGELOG.md
  2. 2 2
      frontend/src/components/Layout.tsx
  3. 0 0
      static/assets/index-BLKXbeO0.js
  4. 1 1
      static/index.html

+ 1 - 0
CHANGELOG.md

@@ -11,6 +11,7 @@ All notable changes to Bambuddy will be documented in this file.
 - **LDAP Default Fallback Group** — Settings → Authentication → LDAP → Advanced now has a "Default group" selector. When an LDAP user authenticates but is not listed in any mapped LDAP group, they are automatically assigned to this fallback group instead of being left without permissions. Previously such users could log in successfully but landed on empty pages because every permission check failed. Leave the setting empty to preserve the old behavior. A warning is logged each time the fallback is applied so administrators can spot missing group assignments.
 
 ### Fixed
+- **External Sidebar Link Icon Not Showing** ([#878](https://github.com/maziggy/bambuddy/issues/878)) — Custom icons uploaded for external sidebar links rendered correctly in the edit dialog but were missing from the sidebar itself, and opening the icon URL directly returned `{"detail":"Valid camera stream token required..."}`. The sidebar `<img>` tag in `Layout.tsx` used a raw `/api/v1/external-links/{id}/icon` URL, but that endpoint is protected by a query-string stream token (the same mechanism used for camera streams and archive thumbnails, because `<img>` tags cannot send Authorization headers). The edit dialog already routed through `api.getExternalLinkIconUrl()`, which wraps the URL via `withStreamToken()`; the sidebar now does the same, so icons appear when auth is enabled.
 - **Shortest Job First Toggle Disappears After Clicking** ([#879](https://github.com/maziggy/bambuddy/issues/879)) — The SJF toggle badge on the queue page was rendered inside the Pending Queue section header, which is only shown when there is at least one pending item and the list view is active. Clicking the toggle often coincided with the scheduler starting the only pending print, at which point the Pending section unmounted and the toggle vanished along with it — making it look like the button had disappeared after clicking. The toggle has been moved to the top of the queue page, next to the list/timeline view switcher, so it stays reachable regardless of pending-item count, active filters, or the selected view mode.
 - **SpoolBuddy Update Fails in Docker with "no user exists for uid 1001"** — The SpoolBuddy remote-update flow shelled out to `ssh-keygen` to create its update keypair on first use. Inside the Docker container the process runs under an arbitrary PUID (default 1000, also seen as 1001) that is not listed in `/etc/passwd`, so `ssh-keygen` aborted at the `getpwuid()` home-directory lookup and the update button reported `ssh-keygen failed. no user exists for uid 1001`. The keypair is now generated in-process via the `cryptography` library (already a dependency), which has no user-database lookup and produces the same OpenSSH-format files. Native installs are unaffected — they already worked because the running user was always in `/etc/passwd`.
 - **Camera Stream "6 of 5" Reconnect Counter + ffmpeg Log Flood** ([#925](https://github.com/maziggy/bambuddy/issues/925)) — Two bugs surfaced while investigating camera reconnect behaviour. First, the camera page briefly displayed "Reconnecting attempt 6 of 5" before giving up, because the attempt counter could be incremented to the maximum while the reconnect banner was still rendering. The displayed value is now clamped to the configured maximum. Second, every failed ffmpeg spawn logged the full ~20-line ffmpeg version/configuration banner, producing hundreds of lines of noise per failed camera click (one reported click produced 555 log lines across 30 retries). A new stderr summarizer strips the ffmpeg banner before logging so only the actual error lines remain. The underlying "camera service stops accepting new connections after prolonged uptime" behaviour in the X1C firmware is still under investigation.

+ 2 - 2
frontend/src/components/Layout.tsx

@@ -561,7 +561,7 @@ export function Layout() {
                         )}
                         {link.custom_icon ? (
                           <img
-                            src={`/api/v1/external-links/${link.id}/icon`}
+                            src={api.getExternalLinkIconUrl(link.id)}
                             alt=""
                             className="w-5 h-5 flex-shrink-0"
                           />
@@ -587,7 +587,7 @@ export function Layout() {
                         )}
                         {link.custom_icon ? (
                           <img
-                            src={`/api/v1/external-links/${link.id}/icon`}
+                            src={api.getExternalLinkIconUrl(link.id)}
                             alt=""
                             className="w-5 h-5 flex-shrink-0"
                           />

File diff suppressed because it is too large
+ 0 - 0
static/assets/index-BLKXbeO0.js


+ 1 - 1
static/index.html

@@ -23,7 +23,7 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-wUMtKBja.js"></script>
+    <script type="module" crossorigin src="/assets/index-BLKXbeO0.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-Caj-77TJ.css">
   </head>
   <body>

Some files were not shown because too many files changed in this diff