2f6335ec26
Prototype routing so 2–3 owners can share one store URL with different WP application passwords. Device creds live in localStorage; server uses request override → Settings fallback and never writes overrides into the Settings row. Inference stays on shared Settings. See PROTOTYPE.md for UAT with two browsers and known LAN forge risk.
2.8 KiB
2.8 KiB
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 |
| HTTP | Headers X-Woo-Username + X-Woo-App-Password on Woo-touching calls |
| Server | client_for_request(conn, headers) → override if both headers non-blank, else Settings singleton |
| Settings | Shop-default woo_wp_username / encrypted woo_app_password — never updated by the device-creds path |
Woo-touching calls that attach headers:
POST /api/v1/slabs/{id}/publishPOST /api/v1/admin/taxonomy/syncPOST /api/v1/settings/test-woo
Inference / Call 2 / Settings PUT for inference keys are unchanged (shared Settings).
Flow (request → WooClient)
- Frontend reads device creds from localStorage (
wooDeviceCreds.ts). withWooHeaders()mergesX-Woo-*onto the fetch.- Backend
client_for_requestbuilds a newWooClientfor that request only (Basic auth from override plaintext, or decrypt Settings password). - Publish / taxonomy / media use that client instance — no process-global “current user”.
UAT with two browsers
- Build/run this branch locally (do not deploy over partner UAT :10890; never :10880).
- In WordPress, create two application passwords for two WP users on the same store.
- Browser A (or profile A): Settings → This device’s Woo credentials → enter user A + app password → Save on this device → Test WooCommerce connection.
- Browser B: same for user B (separate localStorage).
- Confirm Test Woo succeeds for both, and that Save Changes on shop-default fields was not used to store the other user’s password.
- Publish different slabs from each browser (do not work the same slab concurrently).
- Optional: clear device creds and confirm fallback to shop-default Settings.
Intentional fallback
- Missing or partial
X-Woo-*headers → shop-default Settings credentials. - Device localStorage empty → same fallback.
- Health probe (
woo_reachable) always uses shop-default Settings (no request).
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.