mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-09 15:35:39 +02:00
Tim (@turulix) is building a fully automated headless slicing pipeline against Bambuddy's API and hit the wall flagged in #665: /cloud/* routes resolve cloud_token per-user from User.cloud_token, but the auth gate returned None for API-keyed requests, so the route fell back to the global Settings-table token, which only carries a value in auth-disabled deployments. Net effect on auth-enabled deployments: API keys reached the gate just fine, then /cloud/filaments always saw user=None and returned 401 / empty results — no path to read slicer presets or the filament catalogue that a CLI workflow needs. Make API keys carry an owner and route /cloud/* lookups through that owner; gate the new capability behind an explicit opt-in scope so existing automation doesn't gain cloud-read access on upgrade. - APIKey gains user_id (FK to users.id, ON DELETE CASCADE) and can_access_cloud (BOOLEAN DEFAULT 0). User-delete route also runs an explicit DELETE FROM api_keys WHERE user_id = ? since SQLite ships FK enforcement off — same pattern as the existing created_by_id cleanup blocks. - New cloud_caller dep on /cloud/* routes resolves to the JWT user OR the API-key owner stashed by a router-level gate. The auth gate itself continues to return None for API keys so #1182's surface stays bounded to /cloud/* — without that bound, any route that fences API keys via `if current_user is None: raise 403` (e.g. long-lived-token management) would silently start accepting them. - The /cloud/* router-level dep enforces three independent fences for API-keyed callers: user_id IS NOT NULL (legacy keys → 401 with recreate copy), can_access_cloud=True (otherwise 403), and owner has cloud_token (existing fence, unchanged). Two extra one-shot fence errors at create/update time refuse can_access_cloud=True when auth is disabled or the key is ownerless. - Frontend: APIKey list shows "Cloud" badge on cloud-enabled keys and "Legacy" badge on ownerless rows; create form gains an "Allow cloud access" toggle, default off. New i18n keys in all 8 locales (en + de fully translated, others seeded with English fallbacks pending native translation — matches the project's flow for newly-added features). Migration: two idempotent ALTER TABLE statements + an index on user_id for the auth gate's owner→keys lookup. Postgres-safe. Tests: 9 backend integration tests in test_api_key_cloud_access.py covering creation flags, the three /cloud/* fences, JWT no-op, and deletion CASCADE; 2 frontend SettingsPage tests pinning the badge matrix and the create-form contract; 5 daemon unit tests for the related SpoolBuddy ssh-key sync work that landed in the same branch. Full backend suite: 3578 passed; full frontend suite: 1597 passed; no regressions. Permission semantics for existing keys: keys created before this release become "legacy" and are rejected at /cloud/* with the recreate message. Every other endpoint they were used against — queue, status, control — is untouched.
41 lines
1.8 KiB
HTML
41 lines
1.8 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
|
<!-- L-4: Restrict Referer header to origin-only on cross-origin navigation so
|
|
sensitive tokens in query parameters are not leaked to third-party servers. -->
|
|
<meta name="referrer" content="strict-origin-when-cross-origin" />
|
|
<title>Bambuddy</title>
|
|
|
|
<!-- PWA Meta Tags -->
|
|
<meta name="description" content="Monitor and manage your Bambu Lab 3D printers" />
|
|
<meta name="theme-color" content="#00ae42" />
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
<meta name="apple-mobile-web-app-title" content="Bambuddy" />
|
|
|
|
<!-- Manifest -->
|
|
<link rel="manifest" href="/manifest.json" />
|
|
|
|
<!-- Favicons -->
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png" />
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png" />
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png" />
|
|
|
|
<!-- Splash screens for iOS -->
|
|
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
|
<script type="module" crossorigin src="/assets/index-BSfASPDE.js"></script>
|
|
<link rel="stylesheet" crossorigin href="/assets/index-7GmlJb0k.css">
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
|
|
<!-- Service Worker Registration (skip on SpoolBuddy kiosk).
|
|
Kept as an external file so the CSP `script-src 'self'` covers it
|
|
without needing 'unsafe-inline' or per-build hashes. -->
|
|
<script src="/sw-register.js"></script>
|
|
</body>
|
|
</html>
|