Validates an authorization response (the query parameters delivered to the
redirect URI) against its ConduitMcp.Client.OAuth.Pending, before the
code goes anywhere near a token endpoint.
validate/3 runs these checks in order and stops at the first failure:
stateequals the pending state, compared in constant time withPlug.Crypto.secure_compare/2; missing or different ⇒:invalid_state.Principal - the
:principalthe callback is completed under equals (===) the one the flow was started with ⇒ else:principal_mismatch.Expiry -
nowis beforeexpires_at⇒ else:state_expired.iss(RFC 9207 §2.4, OA-3), by exact string comparison with the recorded issuer and no normalization of case, slashes or ports:issin the responseAS advertises isssupportResult present, equal either continue present, different either :iss_mismatchabsent true:iss_missingabsent false/ not advertisedcontinue A present
issis compared even when the authorization server never advertised the parameter. A key with anilvalue counts as absent.error- an error response becomes the matching typed reason (:access_denied, ... or:authorization_errorfor an unknown code), with the server'serror,error_descriptionanderror_uristrings in:data.code- returned wrapped inConduitMcp.Client.Secret; absent ⇒:missing_code.
Steps 1-4 come first so that a response from the wrong party, or for the
wrong flow, surfaces nothing it carries: on any of those failures the
error's :data is nil, and in particular a mismatched response's
error_description is never passed through.
Replay
validate/3 is pure, so it accepts the same Pending and parameters as
often as it is called. Single use of state is enforced by the host's
store, which must delete the pending entry when it is looked up (see
ConduitMcp.Client.OAuth.Pending).
Summary
Functions
Validates params (string-keyed, as decoded from the redirect query) for
pending. See the moduledoc for the order of checks.
Functions
@spec validate(ConduitMcp.Client.OAuth.Pending.t(), map(), keyword()) :: {:ok, ConduitMcp.Client.Secret.t()} | {:error, ConduitMcp.Client.OAuth.Error.t()}
Validates params (string-keyed, as decoded from the redirect query) for
pending. See the moduledoc for the order of checks.
Options
:principal- the host identity completing the flow (defaultnil; must equal the pending principal).:now- current Unix time in seconds (default: the system clock).