# Proposal: cropper-token-auth ## Why The cropper's save proves the operator with a phone number and an OTP. a2loft resolves that phone against the domain being saved to, so an operator without super-user rights in that domain is rejected with a blanket `Invalid OTP specified.` — even though they are authorized to crop images for the domain. The a2loft endpoints now accept a PocketBase token (see the a2loft change `cropper-token-auth`), which authorizes with OpenFGA `crop_image` and takes the actor's identity from the token. ## What Changes - The cropper's save posts the **session token** to a2loft instead of `phone` + `otp`; the OTP input is removed from the UI. - The save's domain comes from **a2loft's own picture record** (`dims/picture/{uploadId}` → `domainCode`), falling back to the queue item's label, and the panel shows both (the profile's domain and the picture target). - The `core → uc` alias is deleted: `core` is a2loft's own pseudo-domain for a profile picture, not an alias for `uc`. - The fingerprint wizard's staff lookup and fingerprint save keep their OTP; only the cropper's calls change. ## Capabilities ### New Capabilities (none) ### Modified Capabilities - `image-cropper`: the save is token-authenticated (no OTP), the domain comes from a2loft's record, and the OTP requirement is removed. ## Impact - `tools/cropper.js`: save handler (Bearer token, no `?otp=`), domain resolution via dims with the label as fallback, path-safety check replacing the catalog check, queue loads enriched with the profile's domain. - `tools/public/assets/cropper/`: the OTP field and all `otp` state removed; the panel shows the profile's domain and the picture target. - Requires the a2loft `cropper-token-auth` change to be deployed first.