lldap and OpenLDAP's memberof overlay omit memberOf from "*", so every
lldap login fell through to the default group. Request memberOf by name
when the schema defines it, and on non-AD directories also search the
directory root for groupOfNames/groupOfUniqueNames entries listing the
user, since groups often sit outside the user search base and the
overlay tracks only one group class.
Also: skip ldap3's anonymous schema read after StartTLS, which AD and
Samba AD reject, so StartTLS works there; reword a server's StartTLS
refusal with an LDAPS hint; stop the bundle sanitizer masking part of
an OID as an IP; skip the sync right after auto-provisioning so the
default-group warning logs once.
Spoolman keeps a full spool's net weight on the spool (initial_weight)
and falls back to the filament's weight, but Bambuddy read only the
filament, so a 250 g spool of a 1000 g filament showed and synced as
1000 g. The list, weigh, AMS sync, SpoolBuddy scale, remain-% tracking,
fill bar and cost now share one lookup. Create writes initial_weight,
and a label-weight edit writes it instead of patching or duplicating the
filament. The spool form's cost per kg is converted at the spool's size
to and from Spoolman's per-spool price.
Spoolman resolves a spool's tare from the spool, then the filament, then
the vendor's empty_spool_weight. Bambuddy skipped the vendor and fell
back to 250 g, so weighing a spool whose tare was set only on its vendor
gave the wrong remaining weight. The inventory weigh action, the
SpoolBuddy scale and the displayed core weight now share one lookup, and
"keep old weight" on a filament change stamps a vendor-inherited tare.
Raise the brace-expansion override from ^5.0.9 to ^5.0.12. Earlier
versions can run out of stack on deeply nested brace groups and take
quadratic time on the {a},b} rewrite. brace-expansion is a dev-only
transitive dependency of eslint (through minimatch) and only expands
the fixed globs in eslint.config.js.
Raise the js-yaml override from ^5.2.3 to ^5.4.1. Versions up to 5.4.0
do not count empty mappings towards maxTotalMergeKeys, so a small YAML
file can keep the CPU busy for a long time. js-yaml is a dev-only
transitive dependency of eslint and only parses our own ESLint configs.
C11 is the P1P, C12 the P1S, C13 the X1E and N7 the P2S, as the virtual
printer and a real P1P 3MF already say. The frontend map had them shifted,
so discovery pre-filled a P1S as a P1P and an X1E as a P2S. The backend
map read C11/C12 as X1C/X1 and lacked N7, the firmware check sent C13 to
the P2S line, and the capability lists never matched BL-P001 because
their lookup strips the dash.
-----
Post work PR #3134
The changelog named Settings -> Print Queue -> Auto-Drying; the toggle
lives in the Queue Auto-Drying card under Settings -> Workflow. The
scheduler comment and a test docstring called print_drying a permission
overlay rather than a trigger, but since #1816 it starts mid-print
cycles on its own regardless of queue state.
A PUT /settings with null for a number setting stored the literal
"None". From then on int()/float() raised inside the response builder,
and every settings read returned 503 until the row was fixed by hand.
Explicit null for any boolean or numeric setting is now refused with a
422 that names the keys, and nothing in that request is saved. A numeric
row that does not parse reads back as its default with a warning, so an
install that already stored one recovers. The typed-key lists moved to
module constants so the save check and the read path share them.
-----
Give each test worker its own scratch folder in the #3025 and #3029 tests (issue #3025)
Both modules wrote into one shared folder under settings.base_dir and deleted
it after every test. Under xdist, one worker's cleanup removed files another
worker was still serving, so tests failed at random with a 404. The folder name
now includes the process ID.
POST /notifications/app-message delivers an app's message to every channel
with the new "Messages from connected apps" switch on (off by default),
through quiet hours, the digest and the log. API keys need the new "Send
notifications" permission, and their owner notifications:update; plain text,
http(s) links, 20 messages a minute per key. The electricity-price door and
this one now share one scoped-key check. /queue?batch=<id> opens and
highlights one batch order.
Print commands carry the external spool as -1 in the flat ams_mapping
(the firmware rejects 254/255 there) and the real target only in
ams_mapping2. We captured only the flat list, so external-spool prints
looked unmapped and the usage tracker's position-based fallback
charged them to the first loaded AMS tray.
- Resolve external spools from ams_mapping2 when capturing a
project_file (dual-nozzle keeps 254/255, single-nozzle -> 254)
- Tracker: an explicit -1 no longer falls back to a positional tray;
a mapping naming no tray for any used slot defers to tray_now
- Keep the #1822 H2S tray_now override working with resolved mappings
An app opened from the sidebar signs in inside Bambuddy's iframe, but every
page sent frame-ancestors 'none', so the browser refused to show
/connect/authorize there. That path now gets 'self', like the streaming
overlay: every ancestor must be Bambuddy itself, so foreign pages still
cannot frame it.
Minimal OAuth 2.0 authorization-code flow with PKCE (S256): admins register
an app with one exact callback URL (Settings > API Keys > Connected Apps);
/connect/authorize asks for consent once and returns a single-use, 60 s code
bound to app, callback and challenge; POST /api/v1/connect/token swaps it,
with the client secret, for the user's identity and permissions. Codes and
secrets stored hashed, exchanges rate-limited per client and IP, no redirect
before the callback is validated, API keys cannot authorize, refused while
auth is disabled. i18n for all 15 locales.
-----
fix(db): upgrading from 0.2.4.0 or older no longer crashes at startup
The #2974 failure-reason conversion ran before the #1378 migration that adds
print_log_entries.failure_reason, so older databases stopped with "no such
column: failure_reason". It now skips a table without the column, only runs
where a legacy label exists, and on SQLite rebuilds archive_fts first, since
archives created before that index existed trip "database disk image is
malformed" when updated.
POST /queue/batches accepts external_source + external_ref; both are
returned on every batch and filterable on GET /queue/batches. The pair is
unique (index uq_print_batches_external), so a retried create answers 409
instead of queueing the same order twice. Migration covers SQLite and
PostgreSQL.
The support bundle gives each printer's connection diagnostic 15 s and
discarded the whole result on overrun, recording only "timed_out". A
14-printer farm's bundle carried that marker for every printer and
nothing else, so it could not say which check was slow.
run_connection_diagnostic now keeps an optional progress dict current
(finished checks + the step in flight). On timeout the snapshot records
stalled_in, elapsed_s and the checks that completed.