mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 03:01:21 +02:00
fix(printer): add X2D to add/edit printer model dropdowns (#988)
Both the Add Printer and Edit Printer modals had hardcoded model lists missing the X2D — manual printer setup had no way to select the new model. Auto-discovery via SSDP and virtual printer model selection (dynamic from backend) were unaffected.
This commit is contained in:
+1
-1
@@ -26,7 +26,7 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
- **Dependency Updates for Published Advisories** — Bumped two dependencies flagged by vulnerability scanners. `python-multipart` 0.0.22 → 0.0.26 closes CVE-2026-40347 (GHSA-mj87-hwqh-73pj), a denial-of-service triggered by large preamble or epilogue data around a multipart boundary — the 0.0.26 release now skips the preamble before the first boundary and silently discards the epilogue after the closing one. Bambuddy uses `python-multipart` transitively through FastAPI/Starlette for form and file-upload parsing, so any authenticated endpoint accepting `multipart/form-data` (e.g. backup restore, project thumbnail upload) was exposed. `dompurify` 3.3.3 → 3.4.0 picks up the fix for GHSA-39q2-94rc-95cp (the function-form `ADD_TAGS` could bypass `FORBID_TAGS`); Bambuddy's two call sites (`ProjectDetailPage`, `ProjectPageModal`) only use array-form `ALLOWED_TAGS`/`ALLOWED_ATTR`, so the specific bypass was not reachable, but the bump still hardens the sanitizer against future misconfiguration and clears the audit warning.
|
||||
|
||||
### Fixed
|
||||
- **Bambu Lab X2D Support** ([#988](https://github.com/maziggy/bambuddy/issues/988)) — The newly released X2D (dual-nozzle, enclosed, hardened steel rod gantry, AMS 2 Pro compatible) identifies itself as internal model code `N6` via SSDP/MQTT, and serials begin with `20P9`. Because neither the code nor the prefix existed in any of Bambuddy's model tables, multiple paths silently fell back to wrong defaults: the camera service routed to the chamber-image protocol on port 6000 (which the X2D doesn't speak) instead of RTSP on port 322 — the reporter saw `Chamber image: data is not a valid JPEG` spam and no stream; the K-profile edit/delete path conditioned its in-place `cali_idx` write on the H2D serial prefix `094` and would therefore have treated X2D as a single-nozzle printer even though its dual-extruder layout matches H2D; the firmware-update check logged `Unknown printer model: N6`; and the virtual-printer model registry had no way to emulate X2D. Added the `N6 → X2D` mapping across every registry (`PRINTER_MODEL_ID_MAP`, `PRINTER_MODEL_MAP`, `ETHERNET_MODELS`, `STEEL_ROD_MODELS`, `CHAMBER_TEMP_SUPPORTED_MODELS`, firmware-check API keys and wiki path, virtual-printer SSDP product names and serial prefix, DB migration `vp_model_fixes`), extended `supports_rtsp()` to match `X2` display names and the `N6` internal code (camera now goes to port 322), expanded the dual-nozzle serial prefix check in `kprofiles.py` and the K-profile delete command in `bambu_mqtt.py` to also accept `20P9` so the H2D-style `cali_idx` in-place edit path runs on X2D, added X2D to the `is_h2d` model-family gate that selects the integer-format `timelapse`/`bed_leveling`/`flow_cali`/`vibration_cali`/`layer_inspect` fields in the MQTT print command, and added X2D to the frontend's door-badge and airduct-mode whitelists, `mapModelCode` lookups on both the Printers page and Spoolbuddy AMS page, and the MaintenancePage wiki-URL resolver (X2D inherits P2S's steel-rod lubrication, belt-tension, nozzle cold-pull and PTFE wiki pages, since its hardware is closer to P2S than to H2). Credit to @krautech for the report and the debug bundle, and to @legend813 for the initial PR (#989) that seeded most of the registry changes — the classification was corrected (X2D uses hardened steel rods like P2S, not carbon rods) and the dual-nozzle/K-profile gaps were added on top.
|
||||
- **Bambu Lab X2D Support** ([#988](https://github.com/maziggy/bambuddy/issues/988)) — Added X2D to the Add Printer and Edit Printer model dropdowns (both were missing the new model, so manual printer setup had no X2D option — auto-discovery via SSDP was unaffected). The newly released X2D (dual-nozzle, enclosed, hardened steel rod gantry, AMS 2 Pro compatible) identifies itself as internal model code `N6` via SSDP/MQTT, and serials begin with `20P9`. Because neither the code nor the prefix existed in any of Bambuddy's model tables, multiple paths silently fell back to wrong defaults: the camera service routed to the chamber-image protocol on port 6000 (which the X2D doesn't speak) instead of RTSP on port 322 — the reporter saw `Chamber image: data is not a valid JPEG` spam and no stream; the K-profile edit/delete path conditioned its in-place `cali_idx` write on the H2D serial prefix `094` and would therefore have treated X2D as a single-nozzle printer even though its dual-extruder layout matches H2D; the firmware-update check logged `Unknown printer model: N6`; and the virtual-printer model registry had no way to emulate X2D. Added the `N6 → X2D` mapping across every registry (`PRINTER_MODEL_ID_MAP`, `PRINTER_MODEL_MAP`, `ETHERNET_MODELS`, `STEEL_ROD_MODELS`, `CHAMBER_TEMP_SUPPORTED_MODELS`, firmware-check API keys and wiki path, virtual-printer SSDP product names and serial prefix, DB migration `vp_model_fixes`), extended `supports_rtsp()` to match `X2` display names and the `N6` internal code (camera now goes to port 322), expanded the dual-nozzle serial prefix check in `kprofiles.py` and the K-profile delete command in `bambu_mqtt.py` to also accept `20P9` so the H2D-style `cali_idx` in-place edit path runs on X2D, added X2D to the `is_h2d` model-family gate that selects the integer-format `timelapse`/`bed_leveling`/`flow_cali`/`vibration_cali`/`layer_inspect` fields in the MQTT print command, and added X2D to the frontend's door-badge and airduct-mode whitelists, `mapModelCode` lookups on both the Printers page and Spoolbuddy AMS page, and the MaintenancePage wiki-URL resolver (X2D inherits P2S's steel-rod lubrication, belt-tension, nozzle cold-pull and PTFE wiki pages, since its hardware is closer to P2S than to H2). Credit to @krautech for the report and the debug bundle, and to @legend813 for the initial PR (#989) that seeded most of the registry changes — the classification was corrected (X2D uses hardened steel rods like P2S, not carbon rods) and the dual-nozzle/K-profile gaps were added on top.
|
||||
- **Print Speed Icon Not Updating Live When Changed on Printer** ([#993](https://github.com/maziggy/bambuddy/issues/993)) — Changing the print speed mode from the printer's own panel (instead of from Bambuddy) did not update the speed icon on the Printers page card; the new value only appeared after a full page reload. The MQTT parser was already tracking `spd_lvl` and updating `state.speed_level` correctly, but the WebSocket serializer (`printer_state_to_dict`) was missing the field — so live status pushes never carried `speed_level`, and the frontend's merge-over-old-cache update left the icon stuck on its previous value. The REST `/status` endpoint used on initial page load already included it, which is why reloads worked. Added `speed_level` to the WebSocket payload. Thanks to @chesterakl for reporting.
|
||||
- **Camera Popup Shows "Valid camera stream token required" With Auth Enabled** ([#979](https://github.com/maziggy/bambuddy/issues/979)) — When Camera View Mode was set to "Window" and authentication was enabled, clicking the camera button opened a popup that immediately failed with `"Valid camera stream token required"`, while the embedded overlay kept working. Two root causes: (1) `window.open(...)` passed `noopener` in the popup features, which severed the opener link and prevented the browser from copying sessionStorage (where the auth token lives) into the popup — so the new window booted unauthenticated and the `POST /printers/camera/stream-token` fetch returned 401, leaving the `<img>` src without the required `?token=` query param; (2) even once the token arrived, `CameraPage` computed its URL from the module-level stream-token cache on render and never re-rendered when the cache was updated in a `useEffect`, so the first paint locked in a tokenless URL that the backend kept rejecting. Fixed by dropping `noopener` from the camera popup features (same-origin, trusted window) so sessionStorage is inherited, subscribing `CameraPage` to the `camera-stream-token` React Query so it re-renders the moment the token resolves, and appending the token directly from the reactive query value instead of the effect-synced module cache — the `<img>` src stays empty until the token is ready, so no tokenless request ever leaves the popup. Embedded-overlay mode was unaffected. Thanks to @VREmma for the reproducer.
|
||||
- **Obico ML API Got 401 When Fetching Snapshot with Auth Enabled** ([#172](https://github.com/maziggy/bambuddy/issues/172)) — The Obico failure-detection service handed the ML API container a snapshot URL (`/api/v1/printers/{id}/camera/snapshot`) for it to `GET` directly, but when Bambuddy authentication was enabled the endpoint returned 401 and the ML API surfaced "Failed to get image" (visible as a 400 from the ML API back to Bambuddy). The detection service now appends a short-lived camera-stream token to the snapshot URL — the same token scheme already used by `<img>`-based camera consumers, which the snapshot endpoint already accepts. The token is cached on the service and refreshed before its 60-minute expiry, so no extra per-call DB churn. When auth is disabled the token is simply ignored. Thanks to @fblix for reporting.
|
||||
|
||||
@@ -5271,6 +5271,9 @@ function AddPrinterModal({
|
||||
<option value="H2D Pro">H2D Pro</option>
|
||||
<option value="H2S">H2S</option>
|
||||
</optgroup>
|
||||
<optgroup label="X2 Series">
|
||||
<option value="X2D">X2D</option>
|
||||
</optgroup>
|
||||
<optgroup label="X1 Series">
|
||||
<option value="X1E">X1E</option>
|
||||
<option value="X1C">X1 Carbon</option>
|
||||
@@ -5725,6 +5728,9 @@ function EditPrinterModal({
|
||||
<option value="H2D Pro">H2D Pro</option>
|
||||
<option value="H2S">H2S</option>
|
||||
</optgroup>
|
||||
<optgroup label="X2 Series">
|
||||
<option value="X2D">X2D</option>
|
||||
</optgroup>
|
||||
<optgroup label="X1 Series">
|
||||
<option value="X1E">X1E</option>
|
||||
<option value="X1C">X1 Carbon</option>
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -26,7 +26,7 @@
|
||||
|
||||
<!-- Splash screens for iOS -->
|
||||
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
||||
<script type="module" crossorigin src="/assets/index-Bre7b40i.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DEBOSiPG.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-3s5orqQ4.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user