diff --git a/CHANGELOG.md b/CHANGELOG.md index 027f0f332..e17236fbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ All notable changes to Bambuddy will be documented in this file. - **Docker data-volume ownership normalised at startup via gosu entrypoint** ([#1211](https://github.com/maziggy/bambuddy/issues/1211)) — Two long-standing failure modes have been biting Docker users repeatedly: (1) Docker named volumes are created by the daemon as `root:root`, and the previous `chmod 777 /app/data` Dockerfile workaround only covered the named-volume root — so subdirs Bambuddy creates at runtime (`virtual_printer/uploads`, `virtual_printer/certs`, etc.) inherited wrong ownership when the container ran as `1000:1000`. (2) The shipped `docker-compose.yml` ships `./virtual_printer:/app/data/virtual_printer` uncommented, and dockerd creates a missing bind-mount source on the host as root before the container starts — leaving the host directory unwritable by uid 1000 inside the container even though the named volume above it had the chmod-777 workaround. Symptom either way: `[Errno 13] Permission denied: '/app/data/virtual_printer/uploads'`, no virtual printer ever starts, "VP doesn't work" support reports follow. **Replaces the chmod-777 hack with a proper entrypoint:** `deploy/docker-entrypoint.sh` runs as root, chowns `/app/data` and `/app/logs` (and `/app/data/virtual_printer` when bind-mounted) to `PUID:PGID`, then drops to that uid via `gosu` before `exec`'ing the app. The chown is gated behind a top-level ownership check so subsequent restarts skip the recursive traversal — no multi-second startup penalty on multi-GB archive directories. A sentinel `.bambuddy` file in each data path prevents Docker from re-syncing image directory metadata on every mount (otherwise empty volumes have their ownership reverted from the image on each restart, defeating the idempotency). When the container is started with an explicit `user:` directive or `--user` flag the entrypoint detects it isn't root and falls through to direct `exec` — preserving compatibility for users who pin a specific uid. **Compose template changes:** removes `user: "${PUID:-1000}:${PGID:-1000}"` (the entrypoint owns privilege drop now), adds `PUID` / `PGID` env vars with the same defaults, and comments out the `./virtual_printer:/app/data/virtual_printer` bind mount by default with explicit "only needed if you also run a native install of Bambuddy on the same host and want both to share the VP CA cert" guidance. The entrypoint chowns the host-side dir through the bind mount the first time it sees wrong ownership, so existing uncommented installs continue to work and #1211 specifically gets fixed. - **Label picker modal clipped the 4th template option and Cancel button on short viewports** ([#1230](https://github.com/maziggy/bambuddy/issues/1230), reported by @elit3ge) — Clicking "Print labels" from Inventory opened the picker with only 3 of the 4 templates visible (Avery 5160 was half-cut at the bottom) and no Cancel button reachable, with no way to scroll to them. Surfaced reliably on Windows 11 + Brave at 1080p with browser chrome / DPI scaling shrinking the effective viewport, but the layout bug hits anywhere the modal's `max-h-[90vh]` lands below ~770 px. **Cause:** `LabelTemplatePickerModal.tsx` uses a flex column with `overflow-hidden` on the outer modal, the spool list as the `flex-1` shrinkable child, and the templates section + footer as fixed siblings below it. The spool list had `min-h-[160px]`, which combined with the default `min-height: auto` for flex items meant the spool list couldn't yield space when the modal was tight — the templates and footer overflowed the modal's bottom edge and got clipped. **First fix (insufficient):** `min-h-[160px]` → `min-h-0` on the spool list scroller, which both removes the fixed floor and overrides the implicit `min-height: auto`. That made the spool list shrink, but on the user's 838 px viewport with browser chrome eating into 90 vh the four stacked templates (~310 px) plus footer still didn't fit, leaving Avery 5160 half-cut and the Cancel button below the modal's clipped bottom edge — `elit3ge` confirmed the dev build was still broken after that fix. **Second fix:** the templates section now renders as a responsive grid (`grid-cols-1 sm:grid-cols-2 gap-2`) so the four buttons pack into a 2×2 grid above the `sm` breakpoint, trimming ~150 px of vertical inside the modal. Each cell tightens its label/hint to `text-sm` + `truncate` (with the full strings reachable via the new `title=label — hint` on the button so the truncation never hides information), padding shrinks to `p-2.5`, and the footer's `py-3` is dropped to `py-2` for a few extra pixels. The earlier `min-h-0` on the spool list is kept as a belt-and-braces shrink for any viewport tighter still. Pre-existing on `dev` since 0.2.4b2 (commit `864e5c99`, the original PR #809 that introduced the modal); not a regression from the spoolman-inventory rebase. **Test:** the regression test in `LabelTemplatePickerModal.test.tsx` is upgraded to pin the new structural shape — the templates container has `grid` + `grid-cols-1` + `sm:grid-cols-2` and exactly 4 child buttons, plus the existing assertions that all 4 template names + the Cancel button render and the spool list scroller still has `min-h-0` with no fixed `min-h-[…]` literal. So a future refactor that drops the grid and reintroduces stacked rows fails CI. +### Security +- **python-multipart bumped to 0.0.27 to clear CVE-2026-42561** — `requirements.txt` floor raised from `>=0.0.26` to `>=0.0.27`. python-multipart is the multipart/form-data parser FastAPI uses for `UploadFile` body parsing, so it sits on every Bambuddy upload path (3MF/STEP/STL upload, label-template imports, OIDC certificate upload, backup restore, etc.). The advisory is a parser-side issue against malformed multipart input; Bambuddy doesn't expose unauthenticated upload endpoints (every multipart route is gated on either `Permission.LIBRARY_UPLOAD` / `SETTINGS_UPDATE` / `INVENTORY_UPDATE`), so blast radius is bounded to authenticated callers — but the bump is mechanical and the floor was already loose, so no reason to wait. + ## [0.2.4b2] - 2026-05-05 ### Changed diff --git a/requirements.txt b/requirements.txt index 7474da2e7..406174d0a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,7 +35,7 @@ openpyxl>=3.1.0 pywebpush>=2.0.0 # Utilities -python-multipart>=0.0.26 +python-multipart>=0.0.27 aiofiles>=23.0.0 # QR Code generation