- POST /solve/$NONCE#
Used by the user-agent to submit an answer to the challenge. If the answer is correct, the user will be redirected to the client’s redirect URI, otherwise the user may be given another chance to complete the process.
Request:
Body should use the mime-type “application/x-www-form-urlencoded”;
multipart/form-datais accepted as well. The posted form data must contain a “pin” field, whose value must be a decimal unsigned integer. The request body is limited to 1024 bytes.Response:
- 200 OK:
If the request ask for application/json the response is a ChallengeSolveResponse. Since protocol v2. Note that this status is only used for the successful outcome; an incorrect or unusable TAN is reported with 403, 409, 410 or 429 (see below).
- 302 Found:
Only possible if request didn’t ask for application/json. Since protocol v2. Since protocol v10, also returned for a validation that failed permanently, see
410 Gonebelow. The user is redirected to the redirect URI of the client to pass the grant to the client. The target will be the redirect URI specified by the client (during registration and again upon/authorize), plus acodeargument with the authorization code, and thestateargument from the/authorizeendpoint. Thestateargument is omitted entirely if the client did not supply one. The response body is the plain textOk!.- 400 Bad Request:
The request does not follow the spec. Since protocol v1. Error codes used are:
TALER_EC_GENERIC_PARAMETER_MALFORMED— the$NONCEin the URL is not a valid 52-character Crockford-base32 value (detailis"nonce"), theContent-Lengthheader is not a number (detailis"Content-Length"), or thepinfield is not a decimal number (detailis"pin").TALER_EC_GENERIC_PARAMETER_MISSING— there is nopinfield in the body (detailis"pin").
- 403 Forbidden:
The TAN was checked and did not match. The response is InvalidPinResponse. Since protocol v1. Returned with
TALER_EC_CHALLENGER_INVALID_PIN.- 404 Not found:
The service is unaware of a matching challenge, or the validation has expired. Since protocol v1. Returned with
TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN.- 405 Method Not Allowed:
The request used a method other than
POSTorOPTIONS. Returned by the request router with anAllowheader and an empty body; in particular there is no Taler error code.- 409 Conflict:
The service had never actually transmitted a TAN, so solving is naturally impossible. Since protocol v8. The response is an InvalidPinResponse with
no_challengeset to true. Returned withTALER_EC_CHALLENGER_NO_CHALLENGE_TRANSMITTED.- 410 Gone:
The validation failed permanently: the user exhausted every address change, TAN transmission and TAN attempt (an address the client set as
read_onlycounts as one that cannot be changed), so it can never succeed. Returned withTALER_EC_CHALLENGER_VALIDATION_FAILED; the response is a ValidationFailedResponse. The user-agent must send the user to itsredirect_urlso that the client learns about the failure. If the request asked fortext/html, the service instead redirects to that URL with a302 Foundright away. Since protocol v10. Note that the response consuming the very last guess already reports this, rather thanTALER_EC_CHALLENGER_INVALID_PINwith a403: at that point nothing is left to try. Before protocol v10, this situation was reported as429withTALER_EC_CHALLENGER_TOO_MANY_ATTEMPTSand the client was never told.- 413 Request entity too large:
The request body exceeds the 1024 byte limit. Returned with
TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT.- 415 Unsupported Media Type:
The
Content-Typeis missing or is not one the service can parse. Returned withTALER_EC_GENERIC_PARAMETER_MALFORMEDanddetailset to"Content-Type". Since protocol v8; previously reported as400.- 429 Too Many Requests:
The user has run out of TAN guesses for the current TAN, but may still request a retransmission or change the address. Since protocol v2. The body is an InvalidPinResponse with
exhaustedset to true, returned withTALER_EC_CHALLENGER_NO_PIN_ATTEMPTS_LEFT(since protocol v8). Once nothing is left to try, the service answers410instead (since protocol v10).- 500 Internal Server Error:
Server is not able to respond due to internal problems. Since protocol v1. Returned with
TALER_EC_GENERIC_DB_FETCH_FAILED;detailis"do_solve_challenge"when solving failed and"get_validation"when the subsequent construction of the redirect URL failed.
Note
Error responses are always JSON, even when the request asked for
text/html; only the success case and a permanently failed validation honour theAcceptheader by returning a 302 redirect.Note
Once a challenge has been solved, repeating the request for the same (unexpired)
$NONCEsucceeds again regardless of thepinsubmitted, re-issuing the redirect and authorization code.// Only the "completed" variant occurs with a 200 status; the // "pending" variant (InvalidPinResponse) is returned with a 403, // 409 or 429 status, and a failed validation with a 410 // (ValidationFailedResponse). Since **v8** every unsuccessful /solve uses // that one shape, so a client need only parse InvalidPinResponse. type ChallengeSolveResponse = ChallengeRedirect;
// Since protocol **v10**. interface ValidationFailedResponse { // TALER_EC_CHALLENGER_VALIDATION_FAILED code: Integer; // human-readable description of the error hint: string; // Where the user-agent must send the user: the client's redirect // URI with the RFC 6749 section 4.1.2.1 error response arguments // error=access_denied, an error_description and the // state given to /authorize (omitted if there was none). // Absent if the service does not know a redirect URI for the // validation, which cannot happen once /authorize succeeded. redirect_url?: string; }
interface InvalidPinResponse { // Union discriminator field. type: "pending"; // numeric Taler error code, should be shown to indicate the error // compactly for reporting to developers code: Integer; // human-readable Taler error code, should be shown for the user to // understand the error hint: string; // how many times is the user still allowed to change the address; // if 0, the user should not be shown a link to jump to the // address entry form addresses_left: Integer; // how many times might the TAN still be retransmitted pin_transmissions_left: Integer; // how many times might the user still try entering the TAN code auth_attempts_left: Integer; // if true, the TAN was not even evaluated as the user previously // exhausted the number of attempts exhausted: boolean; // if true, the TAN was not even evaluated as no challenge was ever // issued (the user must have skipped the step of providing their // address first!) no_challenge: boolean; }