# Module: Azaion.Common.Requests.LoginResponse + RefreshTokenRequest ## Purpose Response DTO for `/login`, `/login/mfa`, and `/token/refresh` (dual-token shape), plus the request DTO for `/token/refresh`. > Added in cycle 2 (2026-05-14) by AZ-531 (Epic AZ-529, Refresh-token Flow). The pre-AZ-531 single-token `{ token }` shape is preserved via the `Token` accessor for backward compatibility — pre-AZ-531 clients see the same value via `Token` even though new clients consume `AccessToken` / `RefreshToken`. ## Public Interface ### LoginResponse | Property | Type | Description | |----------|------|-------------| | `AccessToken` | `string` | The 15-min ES256 JWT to be sent as `Authorization: Bearer <…>` on subsequent requests. | | `AccessExp` | `DateTime` | Absolute expiry of `AccessToken` (UTC). | | `RefreshToken` | `string` | Opaque base64url string (43 chars). Send to `/token/refresh` to rotate. NEVER decode — it is not a JWT. | | `RefreshExp` | `DateTime` | Sliding expiry of the refresh token (UTC). | | `Token` (read-only) | `string` | Backward-compat accessor returning `AccessToken`. Pre-AZ-531 clients that read `Token` keep working. | ### RefreshTokenRequest | Property | Type | Description | |----------|------|-------------| | `RefreshToken` | `string` | The opaque token returned in the previous `LoginResponse.RefreshToken` (or in the previous successful `/token/refresh` response). | ## Internal Logic None — pure data classes. The `Token` getter is a read-only alias. ## Dependencies None. ## Consumers - `Program.cs` `/login` — returns `LoginResponse` (when MFA is not required) via the shared `IssueDualTokens` helper. - `Program.cs` `/login/mfa` — returns `LoginResponse` via `IssueDualTokens` after second-factor success. - `Program.cs` `/token/refresh` — accepts `RefreshTokenRequest`, returns `LoginResponse`. - `RefreshTokenService.IssueForNewLogin` / `Rotate` — supplies the values that populate `LoginResponse`. ## Data Models None. ## Configuration None. ## External Integrations None. ## Security - `RefreshToken` is high-entropy (256 bits) and opaque. It is never logged and only ever returned in this response shape (HTTPS is mandatory in Production — see AZ-538 HSTS / HTTPS-redirect). - `AccessToken` is a JWT carrying `sid`, `jti`, `amr`, role and email claims. Validation is configured in `Program.cs` (`ValidateIssuer`, `ValidateAudience`, `ValidateLifetime`, `ValidateIssuerSigningKey`, `ValidAlgorithms = [ES256]`). - Backward-compat note — the `Token` accessor exists so pre-AZ-531 UI builds keep working during the transition. New clients should use `AccessToken` so they can also pick up `AccessExp` for proactive refresh scheduling. ## Tests - `e2e/Azaion.E2E/Tests/RefreshTokenTests.cs` — assertions on the shape (AC-1) and on rotation behaviour (AC-2..AC-5).