docs(openspec): archive cropper-token-auth and sync specs
The cropper upload POSTs with the session token and no OTP query auth, and the panel shows the profile's domain and picture target. Field pass was verified earlier (upload 0b90075b, saved with no OTP). Merged the image-cropper delta into the main spec and archived the change.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# Design
|
||||
|
||||
## Context
|
||||
|
||||
See proposal.md. The a2loft `cropper-token-auth` change adds token mode to the
|
||||
profile-picture endpoints: `Authorization: Bearer <pb token>`, identity from
|
||||
the token's phone, authorized with OpenFGA `crop_image` on `domain:<code>` then
|
||||
`domain:idid`. This change consumes it.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:** the cropper saves with the session token and no OTP; the save's
|
||||
domain is a2loft's own record of the picture; the panel is truthful about the
|
||||
profile's domain.
|
||||
|
||||
**Non-Goals:** the fingerprint wizard's OTP flow; the cropper's lookup (there
|
||||
is none — pictures come from the queue); removing OTP support in a2loft.
|
||||
|
||||
## Decisions
|
||||
|
||||
1. **Token sent from the server**, never exposed to the browser beyond the
|
||||
page's existing injected session: the proxy attaches
|
||||
`Authorization: Bearer ${req.session.token}`.
|
||||
2. **Domain from a2loft, not the client**: `dims/picture/{uploadId}` is the
|
||||
record of the picture; its `domainCode` is the profile's identity domain and
|
||||
its `domain` is the picture target (`core`). Sent as `domainCode`, displayed
|
||||
as both. Falls back to the queue item's label when a2loft has no record
|
||||
(custom ids), guarded by a path-safety pattern.
|
||||
3. **The `core → uc` alias is deleted**: `core` is a2loft's own pseudo-domain
|
||||
(special-cased in `getUserByPhoneAsync`/`updatePicture`), so rewriting it —
|
||||
as the old bot did for its own calls — changed attribution and the
|
||||
notification. Authorization no longer depends on the domain, so no alias is
|
||||
needed.
|
||||
4. **Queue loads are enriched** with `domainCode` for display (one extra
|
||||
read-only a2loft call per picture).
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [a2loft record unavailable for an upload] → falls back to the queue label
|
||||
under the path-safety check; the save still carries the token for authz.
|
||||
- [Operators outside the domain's super-users] → irrelevant now: the OpenFGA
|
||||
check with the `domain:idid` fallback authorizes them.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
Deploy a2loft first (dual-mode, no client change), then this change; the
|
||||
cropper saves without an OTP. Rollback = revert the proxy and re-add the field.
|
||||
|
||||
## Open Questions
|
||||
|
||||
None.
|
||||
Reference in New Issue
Block a user