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:
2026-10-06 19:29:45 +01:00
parent 8a13fb527e
commit 528eaafb18
6 changed files with 18 additions and 9 deletions
+18 -9
View File
@@ -60,24 +60,33 @@ only for permitted operators.
### Requirement: Saving requires a live gate and an OTP
Saving a cropped picture (`/cropper/profile/picture`) SHALL verify the crop
permission live (bypassing the cache) and SHALL require an OTP from the
operator, forwarding the session phone as the validating identity together
with the OTP and the picture's domain to a2loft. A denied or OTP-less save
SHALL not reach a2loft.
permission live (bypassing the cache) and SHALL authenticate the operator with
the session's PocketBase token, sent to a2loft as a bearer credential; no OTP
SHALL be collected or forwarded. The picture's domain SHALL come from a2loft's
own record for the upload (`dims/picture/{uploadId}` → `domainCode`), falling
back to the queue item's label, and SHALL match a path-safe pattern before it
is used in the request. A denied save SHALL not reach a2loft.
#### Scenario: Successful save
- **WHEN** a permitted operator saves with an OTP
- **WHEN** a permitted operator saves
- **THEN** the route verifies the live gate and forwards the picture to
a2loft with the session phone, OTP, and picture domain
a2loft with the session token as a bearer credential and the profile's
resolved domain
#### Scenario: Denied save does not reach a2loft
- **WHEN** the live crop check denies, or the OTP is missing
- **WHEN** the live crop check denies, or the request carries no message body
- **THEN** the route answers 403/400 and makes no a2loft call
#### Scenario: Unsafe domain values are refused
- **WHEN** neither a2loft's record nor the queue label yields a path-safe
domain
- **THEN** the save is refused with 400 and a2loft is not contacted
### Requirement: Unified login — no separate artist login
The cropper SHALL NOT implement its own login. The operator's identity comes
from the YOUreka session (phone prefilled), the picture's metadata carries the
domain, and the only credential the operator supplies is the save-time OTP.
from the YOUreka session and is presented to a2loft as the session's PocketBase
token; the picture's own metadata carries the domain. The cropper collects no
other credential — there is no save-time OTP.
#### Scenario: Phone prefilled from the session
- **WHEN** a signed-in operator opens the cropper