Contents

POST /challenge/$NONCE#

This endpoint is used by the user-agent to submit the address to which a challenge should be sent by the challenger service.

Request:

Body should use the mime-type “application/x-www-form-urlencoded”; multipart/form-data is accepted as well. Alternatively, the address may be uploaded directly as a JSON object using the mime-type application/json. In the form encodings, each field name/value pair becomes one string-valued member of the address object, and each field is limited to 1024 bytes. The total request body is limited to 1024 bytes for the form encodings.

The posted form data must contain an address JSON object that follow the restrictions defined in config. If the address provided in the ChallengeSetupRequest of /setup was set to be read_only and that was subsequently returned in the ChallengeStatusResponse, then the body must not change that address. The read_only field itself is ignored when comparing the addresses and is re-inserted by the service, so the client need not (but may) preserve it.

Response:

200 OK:

The response is ChallengeResponse. Since protocol v2. The created variant carries Cache-Control: no-store,no-cache.

400 Bad Request:

The request does not follow the spec. Since protocol v1. Error codes used are:

  • TALER_EC_GENERIC_PARAMETER_MALFORMED — the $NONCE in the URL is not a valid 52-character Crockford-base32 value (detail is "nonce"), the Content-Length header is not a number (detail is "Content-Length"), an application/json body is valid JSON but not an object (detail is "address"), or a submitted field name or value is not valid UTF-8.

  • TALER_EC_CHALLENGER_ADDRESS_RESTRICTION_VIOLATED — a field is absent or violates the regular expression configured for it in restrictions, see config; detail names the offending field, so the user agent can highlight it and show the corresponding hint/hint_i18n. Since protocol v8.

  • TALER_EC_GENERIC_JSON_INVALID — an application/json body is not well-formed JSON.

403 Forbidden:

The address being submitted differs from the previously submitted address but the validation process was set up as read_only and thus the address cannot be changed. Returned with TALER_EC_CHALLENGER_CLIENT_FORBIDDEN_READ_ONLY. Since protocol v4.

404 Not Found:

The service is unaware of a matching challenge. Since protocol v1. Returned with TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN when the nonce is well-formed but unknown, or the validation has expired. These two cases are not distinguished.

405 Method Not Allowed:

The request used a method other than POST or OPTIONS. Returned by the request router with an Allow header and an empty body; in particular there is no Taler error code.

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-Type is missing or is not one the service can parse. Returned with TALER_EC_GENERIC_PARAMETER_MALFORMED and detail set to "Content-Type". Since protocol v8; previously reported as 400.

429 Too Many Requests:

There have been too many attempts to request challenge transmissions for this $NONCE. The user-agent should wait and (eventually) request a fresh nonce to be set up by the client. Since protocol v2. Two distinct situations are distinguished, since the appropriate recovery differs. Since protocol v8:

  • TALER_EC_CHALLENGER_TOO_MANY_ADDRESS_CHANGES — the number of permitted address changes was exhausted. The user must obtain a fresh nonce from the client.

  • TALER_EC_CHALLENGER_TOO_MANY_PIN_TRANSMISSIONS — the number of permitted TAN transmissions for the current address was exhausted. The user may still try a different address if address changes remain.

Note that merely being within the retransmission cooldown is not an error: it is reported as 200 OK with transmitted set to false.

500 Internal Server Error:

Server is not able to respond due to internal problems. Since protocol v1. Error codes used are:

  • TALER_EC_GENERIC_DB_FETCH_FAILED — reading the previously stored address failed (detail is "get_validation_address").

  • TALER_EC_GENERIC_DB_STORE_FAILED — storing the address or confirming the transmitted TAN failed (detail is "do_challenge_address" or "do_challenge_address_confirm_pin").

  • TALER_EC_GENERIC_FAILED_TO_EXPAND_TEMPLATE — expanding MESSAGE_TEMPLATE_FILE for the challenge message failed.

  • TALER_EC_GENERIC_PARSER_OUT_OF_MEMORY — the service ran out of memory while buffering an application/json body.

  • TALER_EC_CHALLENGER_ADDRESS_RESTRICTION_MALFORMED — the ADDRESS_RESTRICTIONS configuration for the field named in detail has no regular expression, or one that failed to compile. This is an operator error, not a client error; the request is refused because a restriction that cannot be evaluated must not be treated as “no restriction”. Since protocol v8.

502 Bad Gateway:

The challenger service failed to launch or communicate with its helper process for delivering the challenge (SMS, e-mail, postal mail). Returned with TALER_EC_CHALLENGER_HELPER_EXEC_FAILED. The detail distinguishes the failure: "pipe", "exec", "write", or "$EXIT_CODE/$PROCESS_STATUS" when the helper terminated abnormally or with a non-zero exit code.

// Union discriminated by the "type" field.
type ChallengeResponse = ChallengeRedirect | ChallengeCreateResponse
// @since **v2**
interface ChallengeRedirect {
  // Union discriminator field.
  type: "completed";

  // challenge is completed, use should redirect here
  redirect_url: WebURL;
}
interface ChallengeCreateResponse {
   // Union discriminator field.
   type: "created"

   // how many more attempts are allowed, might be shown to the user,
   // highlighting might be appropriate for low values such as 1 or 2 (the
   // form will never be used if the value is zero)
   attempts_left: Integer;

   // the address that is being validated, might be shown or not
   address: Object;

   // true if we just retransmitted the challenge, false if we sent a
   // challenge recently and thus refused to transmit it again this time;
   // might make a useful hint to the user
   transmitted: boolean;

   // when we would re-transmit the challenge the next
   // time (at the earliest) if requested by the user
   // @since **v2**
   retransmission_time: Timestamp;
 }