feat(orca-cloud): integrate Orca Cloud profile sync across UI, slicer and SpoolBuddy

Reads, lists, and slices with profiles from a user's Orca Cloud account
  (OrcaSlicer 2.4.0-alpha's Supabase-backed sync) alongside the existing
  Bambu Cloud integration. Four sign-in providers (Google / Apple / GitHub /
  email+password); password defaults. Paste-flow PKCE because Orca's
  Supabase project only allowlists localhost redirect_to — open feature
  request at OrcaSlicer/OrcaSlicer#14028.

  Surfaces:
  - Profiles tab: new "Orca Cloud" tab next to "Bambu Cloud" with the same
    rich layout (search + 5 filter dropdowns + 3-column grouped grid +
    read-only detail modal)
  - SliceModal: 4-tier preset picker (orca_cloud > local > bambu cloud >
    standard); separate status banner per cloud; metadata-aware pre-pick
    scores Orca filaments above local (Orca's sync_pull returns full
    content inline so filament_type / filament_colour come for free, no
    per-setting fetch rate-limit dance)
  - ConfigureAmsSlotModal: orca_cloud as a new preset source (prefixed
    orca_<UUID> to match local_/builtin_); generic Bambu filament-ID
    derivation from parsed material (printer firmware can't grok Orca
    UUIDs); slot mapping persists preset_source='orca_cloud'
  - SpoolForm / SpoolBuddyWriteTagPage: Orca filaments merge into the
    cloud preset list via Promise.allSettled (OrcaProfileMeta is
    structurally identical to SlicerSetting)

  Backend:
  - services/orca_cloud.py: OrcaCloudService with PKCE / token exchange /
    single-use refresh rotation / get_user_info / list_profiles via the
    bare /sync/pull bootstrap path
  - routes/orca_cloud.py: 7 endpoints (auth/start, auth/finish,
    auth/password, status, logout, profiles, profiles/{id}); router-level
    _cloud_api_key_gate + per-route cloud_caller() so API-keyed callers
    (SpoolBuddy kiosk) properly resolve their owner User; just-in-time
    refresh with atomic persist-before-API-call
  - routes/slicer_presets.py: _fetch_orca_cloud_presets mirrors the Bambu
    Cloud fetcher (status vocabulary, 5min cache, permission shortcut);
    _dedupe_by_name extended to 4 tiers; UnifiedPresetsResponse gains
    orca_cloud + orca_cloud_status
  - services/preset_resolver.py: PresetRef.source extended with
    "orca_cloud"; _resolve_orca_cloud walks list + filters
  - 8 columns on users table for tokens (5 persistent) + transient PKCE
    handshake state with 10-min TTL (3); dialect-branched DATETIME /
    TIMESTAMP; auth-disabled mode falls back to Settings table
  - orca_cloud:auth permission folded into can_access_cloud API-key scope
    (same trust dimension)
This commit is contained in:
maziggy
2026-06-04 15:50:44 +02:00
parent 764eb58540
commit 18d534c945
45 changed files with 4891 additions and 630 deletions
+11
View File
@@ -142,6 +142,7 @@ function isAlwaysAllowedIdentical(value) {
const DE_COGNATES = [
'Name', 'Status', 'Tag', 'Tags', 'Online', 'Offline', 'Standard', 'Modus',
'Stop', 'Reset', 'Test', 'Code', 'Token', 'Server', 'Port', 'Bug', 'Job',
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'Pause', 'Power', 'System', 'Problem', 'Designer', 'Extruder', 'Firmware',
'Material', 'Original', 'Position', 'Webhook', 'Workflow', 'Slicer',
'Region', 'Normal', 'Orange', 'Branch', 'Budget', 'Commit', 'Global',
@@ -169,6 +170,7 @@ const DE_COGNATES = [
// French cognates — many UI labels overlap with English exactly.
const FR_COGNATES = [
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'Status', 'Tag', 'Tags', 'Online', 'Offline', 'Standard', 'Filament',
'Filaments', 'Software', 'Hardware', 'Stop', 'Reset', 'Test', 'Code',
'Token', 'Server', 'Port', 'Plate', 'Layer', 'Active', 'Total', 'Avatar',
@@ -205,6 +207,8 @@ const FR_COGNATES = [
// Italian cognates.
const IT_COGNATES = [
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'Email', // common loanword in Italian, used verbatim in UI labels
'Status', 'Tag', 'Tags', 'Online', 'Offline', 'Standard', 'Filament',
'Filaments', 'Software', 'Hardware', 'Stop', 'Reset', 'Test', 'Code',
'Token', 'Server', 'Port', 'Plate', 'Layer', 'Modal', 'Pin', 'Pro', 'Mini',
@@ -232,6 +236,7 @@ const IT_COGNATES = [
// everything needs translation. Only true loanwords / proper nouns stay.
const JA_COGNATES = [
'OK', 'Bambu', 'Code',
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'EU (DD/MM/YYYY)', 'US (MM/DD/YYYY)', 'ON, true, 1',
'({{count}}/8)', 'Custom Headers (JSON)',
'Box label (62 × 29 mm)',
@@ -242,6 +247,7 @@ const JA_COGNATES = [
// Portuguese (BR) cognates.
const PT_BR_COGNATES = [
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'Status', 'Tag', 'Tags', 'Online', 'Offline', 'Standard', 'Filament',
'Software', 'Hardware', 'Stop', 'Reset', 'Test', 'Code', 'Token', 'Server',
'Port', 'Plate', 'Layer', 'Modal', 'Pin', 'Pro', 'Mini', 'Studio', 'Cache',
@@ -269,6 +275,7 @@ const PT_BR_COGNATES = [
// Chinese (Simplified): very few cognates beyond brand names.
const ZH_CN_COGNATES = [
'OK', 'Bambu',
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'({{count}}/8)', 'Custom Headers (JSON)',
'Box label (62 × 29 mm)',
'Avery L7160 — A4 sheet (38.1 × 63.5 mm × 21)',
@@ -278,6 +285,7 @@ const ZH_CN_COGNATES = [
const ZH_TW_COGNATES = [
'OK', 'Bambu',
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'({{count}}/8)', 'Custom Headers (JSON)',
'Box label (62 × 29 mm)',
'Avery L7160 — A4 sheet (38.1 × 63.5 mm × 21)',
@@ -289,6 +297,7 @@ const ZH_TW_COGNATES = [
// Allow loanwords/acronyms, format strings, and proper nouns that stay verbatim.
const KO_COGNATES = [
'OK', 'Bambu', 'N/A',
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'({{count}}/8)', '(25%, 50%, 75%)',
'Custom Headers (JSON)',
'Box label (62 × 29 mm)',
@@ -305,6 +314,7 @@ const KO_COGNATES = [
// Spanish cognates — words/phrases that are genuinely identical in Spanish.
const ES_COGNATES = [
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'Error', 'Firmware', 'General', 'Control', 'Total', 'total', 'Material',
'Material:', 'Color', 'Hex', 'Local', 'Global', 'China', 'Editable',
'Normal', 'Metal', 'Multicolor', 'Proxy', 'Host', 'Factor', 'Original',
@@ -323,6 +333,7 @@ const ES_COGNATES = [
// from English (loanwords + acronyms + format strings). Curated, not a shortcut.
const TR_COGNATES = [
'Filament', 'Firmware', 'Disk', 'Hex', 'Test', 'Port', 'Model', 'Metal',
'Bambu Cloud', 'Orca Cloud', // brand names — same in every locale
'Min', 'Normal', 'Platform', 'Net', 'Trend', 'Commit', 'Global', 'Proxy',
'N/A', 'email',
'STARTTLS (Port 587)', 'SSL/TLS (Port 465)',