Files
SlabUploader/PROTOTYPE.md
T
grokbot_ty 2f9b8ebd02 proto(woo): blocking setup gate; require X-Woo-* on Woo HTTP routes
Full-screen WooSetupGate on App mount when this browser lacks device WP
user + app password. Save + Test Woo dismisses only after a successful
test. Publish/test-woo auth failures reopen the gate.

Server: client_for_request requires X-Woo-* on publish, taxonomy sync,
and test-woo (401 woo_device_creds_required); health probe keeps
Settings. Optional SLAB_WOO_ALLOW_SETTINGS_FALLBACK for legacy tests.

See PROTOTYPE.md.
2026-09-26 19:20:16 -07:00

3.4 KiB
Raw Blame History

Prototype: per-user Woo credentials

Branch: proto-per-user-woo-creds (cut from overnight-whole-app).

Goal

2–3 owners can share one SlabUploader install and one Woo store URL, each using their own WordPress user + application password. Inference URL/key stay global. No full auth, ACL, or publish mutex in this prototype.

Credential scheme

Layer What
Browser localStorage keys slabuploader.woo.device.username / …appPassword
Gate Full-screen WooSetupGate on App mount when this browser lacks device creds
HTTP Headers X-Woo-Username + X-Woo-App-Password on Woo-touching calls (required)
Server client_for_request(conn, headers) → override only; no Settings fallback on those routes
Settings Shop-default woo_wp_username / encrypted woo_app_password — used by health probe only; never updated by the device-creds / gate path

Woo-touching calls that require headers (401 woo_device_creds_required if missing):

  • POST /api/v1/slabs/{id}/publish
  • POST /api/v1/admin/taxonomy/sync
  • POST /api/v1/settings/test-woo

Inference / Call 2 / Settings PUT for inference keys are unchanged (shared Settings). Optional test escape hatch: SLAB_WOO_ALLOW_SETTINGS_FALLBACK=1 (prefer sending headers in tests).

Setup gate

  1. On App mount, if this browser has no device username + app password → blocking overlay.
  2. Fields: device WP user + app password (required); Woo base URL display-only from Settings; inference URL/key show configured / not set (masked) and may be entered → PUT Settings for inference only.
  3. Primary CTA: Save device creds & Test Woo. Gate dismisses only after Test Woo succeeds.
  4. Returning browser with device creds → skip gate.
  5. Publish (or Test Woo) Woo auth failure / missing headers → reopen gate.

Flow (request → WooClient)

  1. Frontend reads device creds from localStorage (wooDeviceCreds.ts).
  2. withWooHeaders() merges X-Woo-* onto the fetch.
  3. Backend client_for_request builds a new WooClient for that request only (Basic auth from override plaintext). Missing headers → WooDeviceCredsRequired.
  4. Publish / taxonomy / media use that client instance — no process-global “current user”.

UAT with two browsers

  1. Deploy this branch to the proto stack only (slab-proto-woo-creds on :10892 / :10893). Do not touch overnight :10890; never :10880.
  2. In WordPress, create two application passwords for two WP users on the same store.
  3. Browser A (or profile A): setup gate → enter user A + app password → Save device creds & Test Woo → gate dismisses.
  4. Browser B: same for user B (separate localStorage).
  5. Confirm Test Woo succeeds for both, and that device passwords were not written into shop-default Settings.
  6. Publish different slabs from each browser (do not work the same slab concurrently).
  7. Optional: clear device creds in Settings → reload → gate reappears.

Risks left (prototype)

  • LAN can forge headers — there is no app login; any client on the network can send arbitrary X-Woo-* values. Treat as trusted LAN only.
  • Device passwords sit in localStorage (XSS-readable). Acceptable for this prototype only.
  • No slab ownership ACL / taxonomy mutex / publish CAS — operators must not edit the same slab at once.
  • Taxonomy cache remains shared; a sync from either user refreshes the same rows.