Commit Graph
799 Commits
Author SHA1 Message Date
MartinNYHC 925cc13669 Merge branch '0.1.8b' into feature/pushover-image-attachments 2026-02-04 16:18:13 +01:00
maziggy 39f90616f3 Post work #2 PR #262 2026-02-04 16:12:57 +01:00
MartinNYHC 2833270e29 Merge branch '0.1.8b' into feature/updated_plate_view_v2 2026-02-04 15:27:02 +01:00
SBCrumb 6aa7a560d8 Add camera image attachments to Pushover notifications 2026-02-04 09:21:59 -05:00
MartinNYHC cf286407fb Merge branch '0.1.8b' into cadtoolbox/248 2026-02-04 14:53:05 +01:00
maziggy 8bdd64e54d Fixed ruff errors 2026-02-04 14:47:15 +01:00
MartinNYHC 31a8016c80 Merge branch '0.1.8b' into fix/virtual_printer_proxy_error 2026-02-04 14:38:53 +01:00
Dennis bf75cd2527 Remove unused import statement for sqlalchemy in main.py 2026-02-04 14:36:32 +01:00
Dennis 84f1347bd0 Reorder import statement for jwt in main.py 2026-02-04 14:36:32 +01:00
maziggy 3571cd1a42 Fix AMS auto-matching when multiple trays have same tray_info_idx
The tray_info_idx field is a filament TYPE identifier (e.g., "GFA00" for
generic PLA), not unique per spool. When multiple AMS trays are loaded
with the same filament type, the previous code used find() which always
returned the first match regardless of color.

Now checks if tray_info_idx is unique among available trays:
- If unique: use that tray as definitive match (existing behavior)
- If not unique: fall back to color matching among matching trays

Fixed in both backend (print_scheduler.py) and frontend (useFilamentMapping.ts).

Closes #245
2026-02-04 14:03:50 +01:00
maziggy 81d18cb8bd Virtual Printer Proxy Mode Improvements
- SSDP proxy for cross-network setups: select slicer network interface for automatic printer discovery via SSDP relay
- FTP proxy now listens on privileged port 990 (matching Bambu Studio expectations) instead of 9990
- For systemd: requires `AmbientCapabilities=CAP_NET_BIND_SERVICE` capability
- Automatic directory permission checking at startup with clear error messages for Docker/bare metal
2026-02-04 12:29:20 +01:00
maziggy fe17a6905f Fix AMS auto-matching to use tray_info_idx from 3MF files
When multiple AMS trays have the same filament type and color, Bambuddy
now uses the tray_info_idx attribute from the 3MF file to identify the
exact spool selected during slicing. This ensures the correct tray is
used rather than just picking the first match.

Matching priority: tray_info_idx > exact color > similar color > type-only

Closes #245
2026-02-04 08:18:05 +01:00
maziggy a0d878a231 Fix AMS auto-matching to use tray_info_idx from 3MF files
When multiple AMS trays have the same filament type and color, Bambuddy
now uses the tray_info_idx attribute from the 3MF file to identify the
exact spool selected during slicing. This ensures the correct tray is
used rather than just picking the first match.

Matching priority: tray_info_idx > exact color > similar color > type-only

Closes #245
2026-02-04 08:13:54 +01:00
maziggy d4ca646581 Fix filament calculation incorrectly multiplied by quantity
The filament_used_grams field already contains the total filament for
the entire print job (all items combined). The code was incorrectly
multiplying this value by quantity, causing inflated filament totals.

Example: A print with 26 objects using 126g total was being calculated
as 126g * 26 = 3,276g instead of the correct 126g.

Fixes:
- backend/app/api/routes/archives.py: Archive stats endpoint
- backend/app/api/routes/metrics.py: Prometheus metrics endpoint
- frontend/src/components/FilamentTrends.tsx: Trends chart calculations

Closes #229
2026-02-04 07:20:17 +01:00
copilot-swe-agent[bot]andcadtoolbox 4cf58f9805 Fix PrintModal to fetch library file sliced_for_model
- Added query to fetch library file details in PrintModal
- Updated backend FileResponse schema to include metadata fields (print_name, print_time_seconds, filament_used_grams, sliced_for_model)
- Updated backend get_file endpoint to extract and return metadata fields
- Updated frontend LibraryFile interface to include metadata fields
- Now slicedForModel is properly extracted from both archives and library files

Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
2026-02-04 03:06:54 +00:00
copilot-swe-agent[bot]andcadtoolbox 4f54251189 Add printer model display to file cards for .3mf files
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
2026-02-04 01:42:05 +00:00
copilot-swe-agent[bot]andcadtoolbox 562b46ad82 Fix PR #1 failures: Add German translations and fix backend linting
Co-authored-by: cadtoolbox <12723486+cadtoolbox@users.noreply.github.com>
2026-02-04 01:15:03 +00:00
MartinNYHC d5f798ad7f Merge branch '0.1.8b' into feature/3d_plate_view_v2 2026-02-03 20:50:58 +01:00
MisterBeardy 87c18e5fcf Add plate object count metadata and viewer display 2026-02-03 14:14:00 -05:00
maziggy b6ce486fba Fix phantom reprint bug in print scheduler
Addresses reports of files being automatically reprinted hours after
the original print completed. The root cause was a race condition where
the queue item status was updated to "printing" AFTER the print command
was sent, allowing stuck "pending" items to be re-triggered on restart.

Changes:
- Set status to "printing" BEFORE sending print command to prevent
  re-triggering if backend crashes after print starts
- Add 24-hour expiration for stale pending queue items
- Add duplicate prevention: skip archives completed within last 4 hours

Trade-off: If backend crashes after status update but before print
command, item will be stuck in "printing" without actually printing.
This is safer than accidentally reprinting and wasting filament.
2026-02-03 17:18:22 +01:00
MartinNYHC 685bf84de1 Merge branch '0.1.8b' into feature/updated_plate_view 2026-02-03 17:15:21 +01:00
MisterBeardy be7aff1f91 Plate management updates 2026-02-03 09:29:13 -05:00
maziggy a2571aaf2e Fix filename matching for files with spaces (Issue #218)
Bambu Studio converts spaces to underscores when saving files to the
printer, but MQTT reports the original name with spaces. This caused
FTP downloads to fail with "550 Failed to open file" because we were
searching for "Battery Storage_giesela.gcode.3mf" but the actual file
was "Battery_Storage_giesela.gcode.3mf".

Changes:
- Add underscore variants to direct download path attempts
- Normalize spaces/underscores in fallback directory search
- Apply fix to archive download, cover extraction, and objects reload

Closes #218
2026-02-03 09:29:13 -05:00
maziggy 11bb34f87a Bumped version 2026-02-03 14:36:38 +01:00
maziggy 84d2517aa1 Fixed backup permissions 2026-02-03 14:04:36 +01:00
maziggy 691b7e262a Fix for Information exposure through an exception #72 2026-02-03 13:36:22 +01:00
maziggy 37b73b8868 Sync 2026-02-03 13:02:36 +01:00
maziggy 8b2bdebb3f Sync 2026-02-03 12:42:55 +01:00
maziggy 89b19cbe4f Sync 2026-02-03 12:40:01 +01:00
maziggy 9787400935 Sync 2026-02-03 12:27:36 +01:00
maziggy a0f3b02287 Bumped version 2026-02-03 11:41:31 +01:00
maziggy 583c374f01 Add Virtual Printer Proxy Mode for remote printing
Introduces a new "Proxy Mode" for the Virtual Printer that enables
remote printing from anywhere in the world without VPN, port forwarding,
or Bambu Cloud dependency.

Bambuddy acts as a TLS relay between a remote slicer (Bambu Studio/
OrcaSlicer) and the local Bambu Lab printer:

  Remote Slicer → Internet → Bambuddy Server → Local Network → Printer

The slicer connects to Bambuddy using the real printer's serial number
and access code. Bambuddy authenticates and relays all FTP (file transfer)
and MQTT (commands/status) traffic with end-to-end TLS encryption.

- No port forwarding required - printer stays safely on local network
- No VPN needed - connect from coffee shops, hotels, work, anywhere
- No Bambu Cloud dependency - fully self-hosted solution
- End-to-end TLS encryption on FTP (port 9990) and MQTT (port 8883)
- Works with Bambu Studio and OrcaSlicer
- Uses real printer credentials for authentication
- Automatic printer selection from connected printers

- Add SlicerProxyManager class for TLS relay (tcp_proxy.py)
  - TLS termination with auto-generated certificates
  - Concurrent FTP and MQTT proxy servers
  - Connection lifecycle management with proper cleanup
- Extend VirtualPrinterManager with proxy mode support
  - New 'proxy' mode alongside archive/review/queue modes
  - Target printer selection and credential management
- Add proxy configuration endpoints to settings API
- Add permission checks for proxy endpoints

- Add Proxy Mode card to Virtual Printer settings
- Target printer dropdown for proxy destination
- Real-time proxy status display (ports, target, running state)
- Full i18n support (English, German)

- Add network architecture diagram
- Add proxy mode section to README
- Add comprehensive guide to wiki
- Add prominent feature section to website

- Backend unit tests for SlicerProxyManager
- Backend unit tests for proxy mode configuration
- Frontend tests for proxy mode UI components

Closes #207 #170
2026-02-03 11:02:13 +01:00
maziggy 99fa902b64 Allow multiple Home Assistant entities per printer (fixes #214)
Both frontend and backend were blocking printers that already had any
smart plug linked, preventing users from adding multiple HA entities
to the same printer.

Changes:
- Frontend: Only filter out printers with existing Tasmota plugs
- Backend: Only check for duplicate Tasmota plugs on create/update
- HA entities (switches, scripts, lights, etc.) can now be linked
  multiple times to the same printer for different automations
- Tasmota plugs remain limited to one per printer (physical device)
- Restored "Show on Printer Card" toggle for HA entities
- Fixed printer card only showing script.* entities; now shows all
  HA entities with the toggle enabled
- HA entities now default to auto_on=False and auto_off=False
- Printer cards now update immediately when HA entities change

Closes #214
2026-02-03 09:13:13 +01:00
maziggy a82f9278d2 Add authentication to 200+ API endpoints (CVE-2026-25505)
Security fix for critical vulnerability (CVSS 9.8) where API endpoints
were accessible without authentication when auth was enabled.

Changes:
- Add RequirePermissionIfAuthEnabled() to all unprotected route files:
  archives, projects, settings, api_keys, groups, cloud, github_backup,
  support, notifications, notification_templates, maintenance, filaments,
  external_links, smart_plugs, discovery, firmware, kprofiles, camera,
  ams_history, pending_uploads, updates, spoolman, system, print_queue,
  printers
- Keep image-serving endpoints (thumbnails, timelapse, photos, camera
  streams, icons) unauthenticated since <img> tags cannot send headers
- Add backend integration tests for endpoint auth enforcement
- Add frontend tests for ownership-based permissions (canModify)

Fixes: CVE-2026-25505
2026-02-03 09:13:00 +01:00
maziggy 572dbf393e Fix 500 error on GET /archives/{id} endpoint
Load project relationship in ArchiveService.get_archive() alongside
created_by. Async SQLAlchemy doesn't support lazy loading, so project
must be eagerly loaded for archive_to_response() to access project.name.
2026-02-03 09:13:00 +01:00
maziggy 6431a86e2f Fix monthly comparison calculation ignoring quantity multiplier (Issue #229)
The filament statistics were under-reporting totals because the quantity
field was not being multiplied with filament_used_grams. When users
printed multiple items (quantity > 1), only the base filament amount
was counted instead of the total.

Closes #229
2026-02-03 09:12:43 +01:00
maziggy bb61a1dbef Add TOTP authenticator support for Bambu Cloud login (fixes #182)
TOTP (Two-Factor Authentication):
- Detect TOTP vs email verification from Bambu API loginType response
- Use dedicated TFA endpoint on bambulab.com (not api.bambulab.com)
- Include browser-like headers to bypass Cloudflare protection
- Extract token from JSON response or cookies
- Frontend shows appropriate messages for each verification type
- Added i18n translations for TOTP UI (en, de, ja)

Closes #182
2026-02-03 09:12:31 +01:00
maziggy 38d99143c7 Virtual Printer: TLS proxy with real printer serial
Proxy mode changes:
  - Replace transparent TCP proxy with TLS-terminating proxy
  - Slicer connects to Bambuddy cert, Bambuddy connects to printer
  - Use real printer's serial number for SSDP and certificate
  - This ensures MQTT topic subscriptions match the real printer

  The proxy now:
  1. Accepts TLS from slicer using Bambuddy's certificate
  2. Opens TLS connection to real printer
  3. Forwards decrypted data bidirectionally

  Also: Complete i18n localization for VirtualPrinterSettings component
2026-02-02 15:55:55 +01:00
maziggy be18ebb36c Fix P2S printer support - disable vibration_cali and fix FTP SSL
Author: deathly1987 <andre@welker.one>
2026-02-02 14:09:40 +01:00
maziggy 7eb6058928 Spoolman: Show "Open in Spoolman" for linked spools (Issue #210)
When a spool is already linked in Spoolman, the FilamentHoverCard now shows
"Open in Spoolman" button instead of "Link to Spoolman". This allows users
to quickly navigate to the spool's page in Spoolman for editing.

Changes:
- Add GET /api/v1/spoolman/spools/linked endpoint returning tag->spool_id map
- FilamentHoverCard shows "Open in Spoolman" when linkedSpoolId is set
- "Link to Spoolman" only shows when spool is not linked
- Fix unlinked spools detection to strip JSON quotes from empty tags
- Add toast notifications for link success/failure
- Invalidate linked-spools query after linking
- Add backend tests for linked spools endpoint
- Add frontend tests for LinkSpoolModal

Closes #210
2026-02-02 09:23:50 +01:00
maziggy db68dda1f5 Document intentional JWT secret storage (CodeQL Alert #69)
Add explanatory comment for CodeQL alert about clear-text storage
of JWT secret. This is intentional and secure:
- JWT secrets must be readable by the application
- File permissions set to 0600 (owner read/write only)
- Standard practice for self-hosted apps (same as .env files)

The alert should be dismissed in GitHub Security tab as "Won't fix".
2026-02-02 08:19:51 +01:00
maziggy 70f5b6ae98 Bumped version 2026-02-02 08:16:33 +01:00
maziggy 0fa180a5ee Bumped version 2026-02-02 08:04:54 +01:00
maziggy e4e37fb99e Issue #224: File Manager Permissions
The File Manager (Library) backend had no permission enforcement - endpoints were returning data to any authenticated user regardless of their group permissions.

Closes #224
2026-02-02 08:01:42 +01:00
maziggy 018a744475 Location filter for queue and auth fixes (Issue #220)
Features:
- Add location filter for "Any {Model}" queue assignments
- Queue items can target a specific location (e.g., "Any X1C in Workshop")
- Location dropdown filter on Queue page to view jobs by location
- Scheduler considers location when assigning model-based jobs

Closes #220
2026-02-02 07:39:58 +01:00
maziggy c31f296888 Fix critical security vulnerabilities (GHSA-gc24-px2r-5qmf)
## Summary
  Address two critical security issues reported via GitHub Security Advisory:
  1. Hardcoded JWT secret key allowing token forgery
  2. Missing authentication on 77+ API endpoints

  ## Changes

  ### JWT Secret Key (backend/app/core/auth.py)
  - Remove hardcoded secret "bambuddy-secret-key-change-in-production"
  - Load secret from JWT_SECRET_KEY environment variable (recommended)
  - Fall back to .jwt_secret file in data directory (auto-generated)
  - Generate cryptographically secure 64-byte random secret if neither exists
  - File is created with 0600 permissions for security

  ### API Authentication Middleware (backend/app/main.py)
  - Add HTTP middleware that enforces auth on ALL /api/ routes
  - When auth is enabled, every API request requires valid JWT or API key
  - Only exempt routes that must be public:
    - /api/v1/auth/status (check if auth enabled)
    - /api/v1/auth/login (login endpoint)
    - /api/v1/updates/version (version check)
    - /api/v1/ws/* (WebSockets handle own auth)

  ### Test Updates
  - backend/tests/conftest.py: Patch middleware's async_session for tests
  - backend/tests/integration/test_ownership_permissions.py: Add missing
    auth headers to requests that now require authentication

  ## Migration Notes
  - Existing JWT tokens will be invalidated (users must re-login)
  - Set JWT_SECRET_KEY env var in production for token persistence across restarts
  - No database changes required

  Fixes: GHSA-gc24-px2r-5qmf
  Security: CWE-306 (Missing Authentication), CWE-321 (Hardcoded Crypto Key)

Closes GHSA-gc24-px2r-5qmf
2026-02-02 06:51:55 +01:00
maziggy 234693a306 Fix external spool ams_mapping2 slot_id (Issue #213)
The ams_mapping2 format was incorrectly using the tray_id (254/255) as
the slot_id for external spools. The printer expects slot_id to be the
actual slot index (0 for main nozzle, 1 for deputy nozzle), not the
tray_id value.

Before: {"ams_id": 255, "slot_id": 254}  <- invalid slot index
After:  {"ams_id": 255, "slot_id": 0}    <- correct slot index

This caused prints using external spool to fail immediately with error
code 07FF_8007.

Closes #213
2026-02-01 16:29:06 +01:00
maziggy a9bb8ed823 Fix external spool ams_mapping2 slot_id (Issue #213)
The ams_mapping2 format was incorrectly using the tray_id (254/255) as
the slot_id for external spools. The printer expects slot_id to be the
actual slot index (0 for main nozzle, 1 for deputy nozzle), not the
tray_id value.

Before: {"ams_id": 255, "slot_id": 254}  <- invalid slot index
After:  {"ams_id": 255, "slot_id": 0}    <- correct slot index

This caused prints using external spool to fail immediately with error
code 07FF_8007.

Closes #213
2026-02-01 16:26:55 +01:00
maziggy 0f15b2b8c8 Fixed CodeQL Alert #68: Stack trace exposure in archives.py 2026-02-01 16:20:43 +01:00
maziggy 4dad18a331 Fixed CodeQL Alert #68: Stack trace exposure in archives.py 2026-02-01 16:20:07 +01:00