Commit Graph
924 Commits
Author SHA1 Message Date
maziggy 70622e6e53 Add proxy mode for virtual printer (cross-LAN slicer support)
Enable Bambu Studio on a remote network to print through BamBuddy
acting as a TLS-terminating proxy for both MQTT and FTP connections.

- Add TLSProxy base class and FTPTLSProxy with PASV response rewriting,
  EPSV→PASV translation, PROT P/C tracking, and one-shot data proxies
- Add SlicerProxyManager to coordinate per-slicer MQTT + FTP proxy pairs
- Support additional SAN IPs in certificate generation for proxy mode
- Broadcast SSDP on LAN B so slicers discover the proxy as a printer
- Narrow FTP passive port range to 50000-50100 with retry logic
- Expose proxy ports (8883, 9990, 50000-50100) in Dockerfile
- Document passive port range in docker-compose.yml
2026-02-07 15:17:19 +01:00
maziggy 4dc3aaea5b Fix energy cost showing 0.00 in "Total Consumption" mode (fixes #284)
homeassistant_service.get_energy() was called without first configuring
the service with the HA URL and token, so it returned None for all
Home Assistant smart plugs. Added configure() call before the plug
loop, matching the pattern used in main.py and smart_plugs.py.
2026-02-07 11:08:18 +01:00
maziggy cfd5dd66e5 Fix filament usage charts inflated by quantity multiplier (fixes #229)
filament_used_grams already represents the total for the entire print
job. The daily, weekly, and filament-type charts were multiplying it
by quantity, e.g. a 26-object print using 126g was counted as 3,276g.

Removed the erroneous `* qty` from three aggregations in
FilamentTrends.tsx. Monthly comparison and summary cards were already
correct.

Fixes #229
2026-02-07 11:02:05 +01:00
maziggy f2468077fe Add mock FTPS server and comprehensive FTP test suite (67 tests)
FTP bugs have been the #1 recurring issue across releases (0.1.8+).
This adds a real implicit FTPS mock server and 67 test cases covering
every known failure mode — connection, upload, download, delete, storage
info, model-specific SSL behavior, async wrappers, and failure injection.

New files:
- mock_ftp_server.py: implicit FTPS server on pyftpdlib with failure injection
- conftest.py: FTP test fixtures (certs, server, client factory)
- test_bambu_ftp.py: 67 tests across 10 test classes

Also adds pyOpenSSL to requirements-dev.txt (needed by pyftpdlib
TLS_FTPHandler in the Docker test image).
2026-02-07 10:55:05 +01:00
maziggy 600f4261fc Bumped version 2026-02-07 10:19:21 +01:00
maziggy 70e7cba5e7 Fix FTP download reporting success on 0-byte files
download_to_file() returned True when retrbinary transferred 0 bytes
without raising an exception. This caused the /cover endpoint to hit
the empty file check and raise HTTP 500 instead of retrying or
returning 404.

Now treats 0-byte downloads as failures, allowing the cover endpoint's
retry logic to work and falling back to 404 if all attempts fail.
2026-02-07 10:04:17 +01:00
MartinNYHC e87a41795c Merge branch 'main' into 0.1.8.1 2026-02-07 09:40:40 +01:00
maziggy c77c9c38fd Fix critical FTP upload failure and revert dangerous exception narrowing
The CodeQL cleanup in "Housekeeping" (2b11efd) bulk-narrowed except
clauses across 50+ files, breaking FTP uploads on ALL printer models.
ftplib.error_perm (550 errors) is not a subclass of ftplib.error_reply,
so diagnose_storage() CWD failures escaped the handler and prevented
STOR from ever executing — causing 100% upload failure and HTTP 500s
on /api/v1/archives/{id}/reprint and /api/v1/library/files/{id}/print.

FTP fixes:
- Remove diagnose_storage() from upload hot path
- Change all except (OSError, ftplib.error_reply) to
  except (OSError, ftplib.Error) across bambu_ftp.py

Exception handling reverts (9 files):
- Revert narrowed except clauses back to except Exception in route
  handlers and service code where broad catches are intentional
  defensive programming (archive parsing, HTTP clients, 3MF/ZIP
  processing, Home Assistant, firmware checks)
- Keep narrow exceptions only where safe (single-op blocks like
  int(), file.unlink(), socket.close())
- Remove unused XMLParseError imports from archive.py, threemf_tools.py

Version system:
- Add 4-segment version support (e.g. 0.1.8.1) for patch releases
- Bump version to 0.1.8.1

Closes #287
2026-02-07 09:29:51 +01:00
maziggy 4b46e443dc Fix critical FTP upload failure and revert dangerous exception narrowing
The CodeQL cleanup in "Housekeeping" (2b11efd) bulk-narrowed except
clauses across 50+ files, breaking FTP uploads on ALL printer models.
ftplib.error_perm (550 errors) is not a subclass of ftplib.error_reply,
so diagnose_storage() CWD failures escaped the handler and prevented
STOR from ever executing — causing 100% upload failure and HTTP 500s
on /api/v1/archives/{id}/reprint and /api/v1/library/files/{id}/print.

FTP fixes:
- Remove diagnose_storage() from upload hot path
- Change all except (OSError, ftplib.error_reply) to
  except (OSError, ftplib.Error) across bambu_ftp.py

Exception handling reverts (9 files):
- Revert narrowed except clauses back to except Exception in route
  handlers and service code where broad catches are intentional
  defensive programming (archive parsing, HTTP clients, 3MF/ZIP
  processing, Home Assistant, firmware checks)
- Keep narrow exceptions only where safe (single-op blocks like
  int(), file.unlink(), socket.close())
- Remove unused XMLParseError imports from archive.py, threemf_tools.py

Closes #287
2026-02-07 09:20:06 +01:00
maziggy 2b11efd882 Housekeeping 2026-02-06 16:36:08 +01:00
maziggy 8e9d252ad3 Housekeeping 2026-02-06 16:35:46 +01:00
maziggy aa3482e48b Add printer_model to 18 FTP call sites for A1/A1 Mini, PS1 compatibility
Several FTP operations (file browser, timelapse scan, storage info,
cover download, skip objects, etc.) were missing the printer_model
parameter. Without it, A1/A1 Mini and PS1 printers can't use the prot_p/prot_c
auto-detection and fallback logic, causing FTP failures on these models
when the mode cache isn't already populated.
2026-02-06 16:29:01 +01:00
maziggy c15fb83af8 Updated CONTRIBUTING.md 2026-02-06 14:56:05 +01:00
maziggy 92308a8afa Updated CONTRIBUTING.md 2026-02-06 14:55:46 +01:00
maziggy 22187ac363 Updated README 2026-02-06 14:16:27 +01:00
maziggy 0d0ed0e4c1 Updated README 2026-02-06 14:15:49 +01:00
maziggy 5803c8ceb1 Added missing toast messages to Spoolman settings 2026-02-06 14:12:12 +01:00
maziggy dccf85de74 Bumped version 2026-02-06 13:48:16 +01:00
MartinNYHC 1fd765017a Merge pull request #282 from maziggy/0.1.8
v0.1.8
v0.1.8
2026-02-06 13:36:12 +01:00
MartinNYHC 3c3781be32 Merge branch 'main' into 0.1.8 2026-02-06 13:33:51 +01:00
maziggy 74e84277cf Add CodeQL advanced setup workflow with accepted-risk exclusions 2026-02-06 13:25:23 +01:00
maziggy cfc97f8cc4 Add CodeQL advanced setup workflow with accepted-risk exclusions 2026-02-06 13:23:44 +01:00
maziggy dec89186e9 Updated CHANGELOG 2026-02-06 13:08:32 +01:00
maziggy 01cb23ee85 Add .trivyignore to suppress Dockerfile USER directive finding (DS-0002)
Bambuddy runs as a single-host Docker container where root is needed
for device access and FFmpeg. Trivy picks up the file automatically.
2026-02-06 13:05:35 +01:00
maziggy 7b90c743c2 Strip explanatory text from nosec comments to silence Bandit warnings
Bandit parses all words after `# nosec BXXX` as test IDs, producing
~35 "not a test name or id" warnings. Trim to just `# nosec BXXX`.
2026-02-06 12:57:37 +01:00
maziggy 598cc699d4 Add CodeQL query suites for zero-finding scans and fix remaining security issues
- Create .codeql/python-bambuddy.qls excluding 14 accepted-risk rule
  categories (all reviewed and documented with justifications)
- Create .codeql/javascript-bambuddy.qls excluding false-positive
  XSS findings (generated coverage file + blob URL in audio src)
- Fix stack trace exposure in updates.py: replace str(e) with generic
  error messages in HTTP responses (2 locations)
- Fix SSRF in homeassistant.py: add _validate_url() with scheme
  validation and metadata-service blocking
- Fix SSRF in tasmota.py: add _validate_ip() blocking loopback and
  link-local addresses
- Add --threads=0 to all CodeQL CLI commands in test_security.sh for
  parallel query evaluation (67s → 43s wall clock)
2026-02-06 12:51:17 +01:00
maziggy 93f416b922 Fix trivial conditionals, commented-out code, and dead variables (CodeQL)
Simplify always-true authEnabled ternary and localSettings truthiness
checks in SettingsPage.tsx. Remove commented-out auth re-setup guard
and its dead _existing_setting/_user_count queries from auth.py.
Add clarifying comments to firmware_check.py api_key logs (model
identifier, not a secret).
2026-02-06 12:32:29 +01:00
maziggy 42fd6d95a0 Fix unused globals and redundant JS conditions (CodeQL)
Remove vestigial _debug_logging_enabled and _debug_logging_enabled_at
globals from support.py (written but never read; DB is queried directly).
Simplify hue classification in PrintersPage.tsx and colors.ts by removing
always-true h < 345 checks and dead 'Unknown' fallbacks. Narrow
getWifiStrength param type to remove always-false null guard.
2026-02-06 12:26:38 +01:00
maziggy b99536cc33 Remove unused imports, variables, and fix minor CodeQL findings
- Remove 28 unused imports across 22 test files
- Prefix 4 unused local variables with _ in app code
  (archives, bambu_mqtt, main) and remove 1 dead store
- Consolidate import/import-from in test_plate_detection.py
- Fix unreachable statement in test_archive_service.py
- Simplify redundant comparison in timelapse_processor.py

Resolves ~50 CodeQL py/unused-import, py/unused-local-variable,
py/import-and-import-from, py/unreachable-statement, and
py/redundant-comparison findings.
2026-02-06 12:19:17 +01:00
maziggy 5dcabbdda8 Remove 30 redundant function-level imports
These modules were already imported at the top of each file.
Removes re-imports of re, json, zipfile, and logging from
inside functions in archive.py, library.py, main.py,
printers.py, support.py, and test_library_api.py.

Resolves all 30 CodeQL py/repeated-import findings.
2026-02-06 12:06:51 +01:00
maziggy 5b0a985da2 Add explanatory comments to 265 empty except blocks
CodeQL flags except blocks where `pass` has no comment explaining
why the exception is silently ignored (py/empty-except rule).

Added context-specific comments to all 265 instances across 31 files:
- database.py (~112): ALTER TABLE migrations — "Already applied"
- archive/library/3MF parsing (~64): "Skip unparseable metadata"
- virtual_printer network cleanup (~32): "Best-effort socket cleanup"
- discovery/SSDP (~13): "SO_REUSEPORT not available" / socket cleanup
- bambu_ftp/mqtt (~13): FTP cleanup, JSON decode, signal parsing
- remaining routes/services (~31): context-specific comments
2026-02-06 11:58:38 +01:00
maziggy a0133fb43b Fix safe security findings: hashlib, log injection, broad excepts, bandit suppressions
- Add usedforsecurity=False to MD5 (AMS fingerprint) and SHA1 (git blob
  hash) calls to silence Bandit B303 / CodeQL weak-crypto findings
- Convert ~996 f-string logging calls to parameterized %s-style across
  55 files to prevent log injection (Bandit G201 / CodeQL log-injection)
- Narrow ~199 broad except Exception blocks to specific types:
  OperationalError for DB migrations, OSError for network/file cleanup,
  (OSError, ftplib.error_reply) for FTP, and targeted tuples for
  ZIP/XML/JSON parsing — 36 intentionally left broad (mixed async,
  re-raise patterns)
- Add # nosec comments to 9 known-safe lines (0.0.0.0 virtual printer
  binds, ftplib imports) and exclude backend/tests/ from bandit scan
- Bandit now reports 0 medium/high findings
2026-02-06 11:45:12 +01:00
maziggy 53bd4fadb3 Fix safe security findings: hashlib, log injection, broad excepts
- Add usedforsecurity=False to MD5 (AMS fingerprint) and SHA1 (git blob
  hash) calls to silence Bandit B303 / CodeQL weak-crypto findings
- Convert ~996 f-string logging calls to parameterized %s-style across
  55 files to prevent log injection (Bandit G201 / CodeQL log-injection)
- Narrow ~199 broad except Exception blocks to specific types:
  OperationalError for DB migrations, OSError for network/file cleanup,
  (OSError, ftplib.error_reply) for FTP, and targeted tuples for
  ZIP/XML/JSON parsing — 36 intentionally left broad (mixed async,
  re-raise patterns)
2026-02-06 11:37:59 +01:00
maziggyandClaude Opus 4.6 91662d9c5d Add usedforsecurity=False to non-security hashlib calls
MD5 in bambu_mqtt.py is used for AMS tray change detection fingerprinting,
and SHA1 in github_backup.py matches Git's blob hash format. Neither is
used for security purposes, so mark them explicitly to satisfy Bandit B303
and CodeQL py/weak-cryptographic-algorithm findings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 11:15:26 +01:00
maziggy dc82b5ff2a Refactor Spoolman per-filament tracking (PR #277 follow-up)
Extract Spoolman tracking from main.py into dedicated service module,
DRY up repeated helpers, add i18n for new settings UI, and add tests.

- Move ~460 lines from main.py to services/spoolman_tracking.py
- Extract _resolve_spool_tag, _resolve_global_tray_id, build_ams_tray_lookup helpers
- Replace fragile tuple return in get_spoolman_settings() with dict
- Wire 4 new UI strings through i18n (en/de/ja)
- Add 42 backend unit tests (spoolman tracking helpers + 3MF parsing)
- Add 6 frontend tests for weight sync and partial usage toggles
- Update CHANGELOG, wiki, and website docs

Closes PR #277
2026-02-06 10:03:27 +01:00
MartinNYHC 73be96497c Merge pull request #277 from bambuman/feature/accurate-usage-tracking
Feature/accurate usage tracking
2026-02-06 09:35:20 +01:00
MartinNYHC 0dcb154ae3 Merge branch '0.1.8b' into feature/accurate-usage-tracking 2026-02-06 09:21:44 +01:00
maziggy 905e1762de Fix FTP settings UI: add selects, persist connection timeout
- Replace number inputs with select dropdowns for retry attempts,
  retry delay, and connection timeout to avoid auto-save race conditions
- Move connection timeout inside the FTP retry toggle section
- Add ftp_timeout to backend settings schema and integer parsing list
  so the value actually persists (was silently dropped before)

Closes #275
2026-02-06 09:20:33 +01:00
maziggy b4285913a9 Remove 24-hour queue item expiration logic
Queue items were being marked as "expired" if older than 24 hours,
which breaks legitimate use cases like weekend print queues or
printers that are offline for extended periods.
2026-02-06 08:32:28 +01:00
bambuman ce4683ad3f Use defusedxml in test files for Bandit compliance 2026-02-05 19:55:18 +02:00
BambuMan 0a39b12064 Merge branch 'maziggy:main' into feature/accurate-usage-tracking 2026-02-05 19:53:52 +02:00
MartinNYHC 996f78870f Merge pull request #279 from maziggy/0.1.8b
v0.1.8b
2026-02-05 18:37:48 +01:00
maziggyandClaude Opus 4.5 17c8301b4b Use defusedxml in test files for Bandit compliance
Replace xml.etree.ElementTree with defusedxml in test files to satisfy
Bandit B314 scanner. While test XML is trusted, using defusedxml
consistently across the codebase prevents CI failures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 18:34:51 +01:00
MartinNYHC 85d0b91411 Merge branch 'main' into 0.1.8b 2026-02-05 18:28:55 +01:00
maziggy 9ceefc19bc Changed version 2026-02-05 18:26:20 +01:00
maziggy 4d94286e53 Fix CodeQL path injection vulnerabilities
- projects.py: Add path traversal validation to attachment endpoints
  - Reject filenames containing /, \, or ..
  - Prevents directory traversal attacks via URL parameters

- archives.py: Strengthen timelapse processing input validation
  - Validate audio suffix against whitelist (not just filename check)
  - Reject output filenames with .., empty, or dot-prefixed names
  - Fall back to safe default filename if validation fails
2026-02-05 18:09:42 +01:00
bambuman 33b9360e7a pre-commit changes 2026-02-05 18:58:00 +02:00
maziggy 46ba5ff417 Fix Bandit detection and update Trivy to v0.69.1
- Fix defusedxml import style in print_queue.py to be recognized by Bandit
  (use `import defusedxml.ElementTree as ET` not `from defusedxml import`)
- Update Trivy scanner version from 0.65.0 to 0.69.1
2026-02-05 17:50:16 +01:00
bambuman 2c086dd91a ruff format changes 2026-02-05 18:49:34 +02:00
MartinNYHC bada186101 Merge pull request #274 from MisterBeardy/fix/print-queue-time
Fix/print-queue-time
2026-02-05 17:46:56 +01:00