Contents

GET /authorize/$NONCE#
POST /authorize/$NONCE#

This is the “authorization” endpoint of the OAuth 2.0 protocol. This endpoint is used by the user-agent. It will return data to generate a form to enter the address.

The NONCE is a unique value identifying the challenge, should be shown to the user so that they can recognize it when they receive the TAN code.

Note that both for GET and POST requests the request arguments must be given in the URL and the body should be empty. We currently do NOT support using x-www-form-urlencoded arguments in the body, even for a POST.

Request:

Query Parameters:
  • response_type – Must be code

  • client_id – Identifier of the client.

  • redirect_uri – URI-encoded redirection URI to use upon authorization.

  • state – Arbitrary client state to associate with the request.

  • scope – Not supported, any value is accepted.

  • code_challenge – A string to enhance security using PKCE (available since v3).

  • code_challenge_method – The method used for the code_challenge. Options are S256 (SHA-256) or plain (available since v3).

Response:

200 OK:

The the response is a ChallengeStatusResponse. Since protocol v1. The response carries Cache-Control: no-store,no-cache.

302 Found:

Returned when the client explicitly accepts text/html returning a redirection to the WebUI. Since protocol v1. The Location is the relative URL /webui/ followed by the query string of the request with a nonce=$NONCE argument appended. Note that a request without any Accept header, or with Accept: */*, is answered with 200 OK and JSON instead.

400 Bad Request:

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

  • TALER_EC_GENERIC_PARAMETER_MISSINGresponse_type, client_id or (when a code_challenge_method was given) code_challenge is absent; detail names the argument.

  • TALER_EC_GENERIC_PARAMETER_MALFORMED — the $NONCE in the URL is not a valid 52-character Crockford-base32 value (detail is "nonce"; since protocol v8, previously reported as 404), response_type is not code, client_id is not a number, code_challenge_method is neither plain nor S256, a non-web redirect_uri was combined with a plain/absent code_challenge_method (the PKCE downgrade guard), or one of redirect_uri, state, scope and code_challenge is not valid UTF-8 (since protocol v8; previously such a value reached the database and produced a 500); detail names the argument.

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 no matching validation was updated. This deliberately conflates four causes: the nonce is unknown, it has expired, the client_id does not own it, or the redirect_uri does not match the one registered for the client. Distinguishing them would let an unauthenticated caller enumerate validations.

405 Method Not Allowed:

The request used a method other than GET, HEAD, POST or OPTIONS. Returned by the request router with an Allow header and an empty body; in particular there is no Taler error code. HEAD is accepted on every endpoint that accepts GET, and is handled identically but without a response body (RFC 9110 section 9.3.2); since protocol v8.

500 Internal Server Error:

Server is not able to respond due to internal problems. Since protocol v1. Returned with TALER_EC_GENERIC_DB_STORE_FAILED (detail is "update_validation"), both for a hard database error and for a serialization failure that survived all retries.

Note

Unlike RFC 6749 section 4.1.2.1, errors are never reported by redirecting the user-agent back to the redirect_uri with an error argument; all failures above are returned as a JSON body, even when the request asked for text/html.

interface ChallengeStatusResponse {

  // indicates if the given address cannot be changed anymore, the
  // form should be read-only if set to true.
  fix_address: boolean;

  // form values from the previous submission if available, details depend
  // on the ADDRESS_TYPE, should be used to pre-populate the form
  // May contain a boolean field read_only indicating if
  // the client is not allowed to change the address when posting
  // it to the /challenge endpoint.
  // If read_only is present and true, the service forces
  // fix_address to true and changes_left to 0.
  // Omitted entirely (not null) if no address was submitted yet.
  last_address?: Object;

  // is the challenge already solved?
  solved: boolean;

  // number of times the address can still be changed, may or may not be
  // shown to the user
  changes_left: Integer;

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

  // how many times might the TAN still be retransmitted
  // @since **v2**
  pin_transmissions_left: Integer;

  // how many times might the user still try entering the TAN code
  // @since **v2**
  auth_attempts_left: Integer;
}