feat: mail service
This commit is contained in:
+26
-5
@@ -84,7 +84,8 @@ The service is not responsible for:
|
||||
- downstream business authorization
|
||||
- direct push delivery to clients
|
||||
- long-lived hot-path session caching inside gateway
|
||||
- mail-service implementation details beyond the mail-delivery contract
|
||||
- mail-service implementation details beyond the dedicated login-code delivery
|
||||
REST contract
|
||||
|
||||
## Position in the System
|
||||
|
||||
@@ -140,15 +141,23 @@ The effective DTO contract is:
|
||||
| `POST /api/v1/public/auth/send-email-code` | `{ "email": string }` | `{ "challenge_id": string }` |
|
||||
| `POST /api/v1/public/auth/confirm-email-code` | `{ "challenge_id": string, "code": string, "client_public_key": string, "time_zone": string }` | `{ "device_session_id": string }` |
|
||||
|
||||
`send-email-code` may additionally receive the optional public
|
||||
`Accept-Language` header through gateway. Auth resolves the first supported
|
||||
BCP 47 language tag from that header, falls back to `en` when no supported
|
||||
value is available, uses the resolved value as the auth-mail locale for the
|
||||
dedicated `Mail Service` REST contract, and stores it on the challenge as the
|
||||
create-only preferred-language candidate for a later first-user ensure step.
|
||||
The created `challenge_id` is sent to `Mail Service` as the raw
|
||||
`Idempotency-Key` header value of that dedicated REST call.
|
||||
`client_public_key` is the standard base64-encoded raw 32-byte Ed25519 public
|
||||
key registered for the created device session.
|
||||
`time_zone` is the client-selected IANA time zone name. During the current
|
||||
rollout phase, successful confirms forward create-only user registration
|
||||
context to `User Service` as `preferred_language="en"` and the supplied
|
||||
`time_zone` until gateway geoip-based language derivation is deployed.
|
||||
context to `User Service` as the stored preferred-language candidate from
|
||||
`send-email-code` and the supplied `time_zone`.
|
||||
`User Service` now validates `preferred_language` as BCP 47 and canonicalizes
|
||||
the stored value on creation, so any future derived language must already be a
|
||||
valid BCP 47 tag before auth forwards it.
|
||||
the stored value on creation, so the derived public language value must
|
||||
already be a valid BCP 47 tag before auth forwards it.
|
||||
|
||||
Public boundary rules:
|
||||
|
||||
@@ -162,6 +171,9 @@ Public boundary rules:
|
||||
IANA time zone name
|
||||
- `send-email-code` remains success-shaped for existing, new, blocked, and
|
||||
throttled e-mail paths
|
||||
- `send-email-code` may use optional public `Accept-Language` to derive and
|
||||
store the auth-mail locale plus future create-only `preferred_language`
|
||||
candidate; unsupported or missing values fall back to `en`
|
||||
- `confirm-email-code` returns a ready `device_session_id` synchronously on
|
||||
success
|
||||
|
||||
@@ -236,6 +248,7 @@ Core fields:
|
||||
- creation and expiration timestamps
|
||||
- send and confirm attempt counters
|
||||
- minimal abuse metadata
|
||||
- stored preferred-language candidate derived at send time
|
||||
- optional confirmation metadata used for idempotent retry
|
||||
|
||||
### Challenge States
|
||||
@@ -259,6 +272,14 @@ Supported `challenge.DeliveryState` values:
|
||||
- `throttled`
|
||||
- `failed`
|
||||
|
||||
For the dedicated `Mail Service` REST contract, `delivery_state=sent` means
|
||||
auth successfully handed the request off to
|
||||
`POST /api/v1/internal/login-code-deliveries` and the mail-delivery pipeline.
|
||||
That call uses the created `challenge_id` as the raw `Idempotency-Key` header
|
||||
value.
|
||||
It does not require that the SMTP provider exchange already completed before
|
||||
`challenge_id` was returned to the caller.
|
||||
|
||||
Policy rules:
|
||||
|
||||
- initial challenge TTL is `5m`
|
||||
|
||||
Reference in New Issue
Block a user