docs: reorder & testing
This commit is contained in:
@@ -18,5 +18,5 @@ Primary references:
|
||||
- [`../openapi.yaml`](../openapi.yaml) — REST contract.
|
||||
- [`../PLAN.md`](../PLAN.md) — historical staged build-up; kept for
|
||||
archaeology, not as a source of truth.
|
||||
- [`../../ARCHITECTURE.md`](../../ARCHITECTURE.md) — workspace-level
|
||||
- [`../../docs/ARCHITECTURE.md`](../../docs/ARCHITECTURE.md) — workspace-level
|
||||
architecture.
|
||||
|
||||
+24
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
This document collects the multi-step interactions inside `backend`
|
||||
that span domain modules. Each section assumes the reader is familiar
|
||||
with `../README.md` and `../../ARCHITECTURE.md`.
|
||||
with `../README.md` and `../../docs/ARCHITECTURE.md`.
|
||||
|
||||
## Registration (send + confirm)
|
||||
|
||||
@@ -39,11 +39,29 @@ sequenceDiagram
|
||||
Gateway-->>Client: 200 {device_session_id}
|
||||
```
|
||||
|
||||
Re-confirming the same `challenge_id` returns the existing session and
|
||||
clears the throttle window (the throttle reuses the latest un-consumed
|
||||
challenge rather than dropping the request). `accounts.user_name` is
|
||||
synthesised once and never overwritten on subsequent sign-ins; the same
|
||||
account always lands the same handle.
|
||||
A `challenge_id` is single-use: confirm consumes the row in the same
|
||||
transaction that inserts the device session, so a second confirm-email-code
|
||||
on the same id returns `400 invalid_request` (`auth.ErrChallengeNotFound`)
|
||||
together with unknown and expired ids. The opaque error code is
|
||||
deliberate — the API never differentiates "consumed", "expired", and
|
||||
"never existed" so an attacker cannot mine challenge_id state.
|
||||
|
||||
Throttle reuses the latest un-consumed challenge rather than dropping
|
||||
the request: send-email-code returns the existing `challenge_id` to a
|
||||
caller hitting the throttle, leaving the wire shape identical to a
|
||||
fresh issue.
|
||||
|
||||
`accounts.permanent_block` is checked twice on the registration path:
|
||||
once in send-email-code (no fresh challenge for an already-blocked
|
||||
address) and once in confirm-email-code after the verification code has
|
||||
matched (catches the case where an admin applied the block in the
|
||||
window between the two calls). Both paths surface
|
||||
`auth.ErrEmailPermanentlyBlocked` and the handler maps it to `400
|
||||
invalid_request` with message `email is not allowed`.
|
||||
|
||||
`accounts.user_name` is synthesised once at first sign-in and never
|
||||
overwritten on subsequent sign-ins; the same account always lands the
|
||||
same handle.
|
||||
|
||||
## Authenticated request lifecycle
|
||||
|
||||
|
||||
Reference in New Issue
Block a user