commit 8988dc7d187973c97e3d74983136e24c47c913c8
parent 351693ff63564039d19efb21ca846403eaced576
Author: Florian Dold <dold@taler.net>
Date: Sat, 29 Aug 2026 16:57:22 +0200
merchant API: document reset tokens and MFA challenge binding
Diffstat:
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/core/api-merchant.rst b/core/api-merchant.rst
@@ -496,6 +496,19 @@ request, they must include a list of comma-separated challenge IDs of the
solved challenges in a ``Taler-Challenge-Ids`` HTTP header. The body must
remain absolutely unchanged.
+Challenge IDs are bound to the merchant instance, the critical operation,
+the required authentication factor, and the exact request body for which
+they were issued. A solved challenge is therefore authorization to retry
+that particular transaction. It is not proof of a generic privilege
+elevation or merely of an MFA authentication performed recently, and it
+MUST NOT authorize an operation for another instance. Binding challenges
+to their merchant instance is required since protocol **v39**.
+
+Clients should retain challenge IDs only while transmitting or confirming
+the challenges and completing or retrying the protected request. They must
+not attach challenge IDs to unrelated requests or reuse them for another
+instance, operation, or request body.
+
.. note::
If all allowed attempts to solve the MFA challenge(s) fail, the endpoint
diff --git a/core/merchant/post-instances-INSTANCE-forgot-password.rst b/core/merchant/post-instances-INSTANCE-forgot-password.rst
@@ -12,15 +12,20 @@
Since protocol **v21**.
- **Request** the request must be an `InstanceAuthConfigurationMessage`.
+ **Request** the request must be a `ForgotPasswordRequest`.
**Response:**
+ :http:statuscode:`200 Ok`:
+ The backend has successfully changed the credentials and returns a
+ refreshable ``spa`` access token in a `LoginTokenSuccessResponse`, as
+ requested with ``token_duration``. @since **v39**
:http:statuscode:`202 Accepted`:
2FA is required for this operation. This returns
the `ChallengeResponse`. @since **v21**
:http:statuscode:`204 No content`:
The backend has successfully changed the credentials for the instance.
+ No login token was requested.
:http:statuscode:`403 Forbidden`:
MFA channels are not available for this instance.
Returned with ``TALER_EC_MERCHANT_GENERIC_MFA_MISSING``.
@@ -33,3 +38,16 @@
:http:statuscode:`500 Internal Server Error`:
The server experienced an internal failure.
Returned with ``TALER_EC_GENERIC_DB_STORE_FAILED``.
+
+ **Details:**
+
+ .. ts:def:: ForgotPasswordRequest
+
+ // @since v39
+ type ForgotPasswordRequest = InstanceAuthConfigurationMessage & {
+ // If present and non-zero, issue a refreshable login token with
+ // "spa" scope after the password reset. "forever" requests a token
+ // without a finite expiration. Missing or zero preserves the 204
+ // response without a token.
+ token_duration?: RelativeTime;
+ };