feat(cropper): save with the session token — no OTP, domain from a2loft
Consumes the a2loft cropper-token-auth change: the save now sends the
session's PocketBase token as a bearer credential and no phone/otp. The
backend authorizes with OpenFGA crop_image (domain:<code> -> domain:idid),
so an operator no longer needs super-user rights in the profile's domain —
which is what made saves fail with a blanket 'Invalid OTP specified.'.
- the save's domain comes from a2loft's own record of the picture
(dims/picture/{uploadId} -> domainCode), falling back to the queue label,
guarded by a path-safety pattern instead of the catalog check
- the 'core' -> 'uc' alias is deleted: 'core' is a2loft's own pseudo-domain
for a profile picture (special-cased there), so rewriting it changed the
attribution and the ID-card notification
- queue loads are enriched with the profile's domainCode; the panel shows
the profile's domain and, when it differs, the picture target
- the cropper's OTP field, state and parameters are gone; the fingerprint
wizard is untouched (its own OTP flow on its own endpoints)
- tests updated: bearer + no query auth, resolved domain wins, unsafe values
refused, no OTP field served (46 pass)
Requires the a2loft change deployed first.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user