diff options
Diffstat (limited to 'packages/taler-util/src/http-client')
-rw-r--r-- | packages/taler-util/src/http-client/challenger.ts | 67 | ||||
-rw-r--r-- | packages/taler-util/src/http-client/types.ts | 8 |
2 files changed, 47 insertions, 28 deletions
diff --git a/packages/taler-util/src/http-client/challenger.ts b/packages/taler-util/src/http-client/challenger.ts index fa4214aa6..8d23ed273 100644 --- a/packages/taler-util/src/http-client/challenger.ts +++ b/packages/taler-util/src/http-client/challenger.ts @@ -4,10 +4,13 @@ import { createPlatformHttpLib } from "../http.js"; import { LibtoolVersion } from "../libtool-version.js"; import { FailCasesByMethod, + RedirectResult, ResultByMethod, + opFixedSuccess, + opKnownAlternativeFailure, opKnownHttpFailure, opSuccessFromHttp, - opUnknownFailure + opUnknownFailure, } from "../operation.js"; import { AccessToken, @@ -16,7 +19,8 @@ import { codecForChallengeStatus, codecForChallengerAuthResponse, codecForChallengerInfoResponse, - codecForChallengerTermsOfServiceResponse + codecForChallengerTermsOfServiceResponse, + codecForInvalidPinResponse, } from "./types.js"; import { makeBearerTokenAuthHeader } from "./utils.js"; @@ -91,7 +95,12 @@ export class ChallengerHttpClient { * https://docs.taler.net/core/api-challenger.html#post--authorize-$NONCE * */ - async login(nonce: string, clientId: string, redirectUri: string, state: string | undefined) { + async login( + nonce: string, + clientId: string, + redirectUri: string, + state: string | undefined, + ) { const url = new URL(`authorize/${nonce}`, this.baseUrl); url.searchParams.set("response_type", "code"); url.searchParams.set("client_id", clientId); @@ -127,17 +136,23 @@ export class ChallengerHttpClient { */ async challenge(nonce: string, body: Record<"email", string>) { const url = new URL(`challenge/${nonce}`, this.baseUrl); - + const resp = await this.httpLib.fetch(url.href, { method: "POST", body: new URLSearchParams(Object.entries(body)).toString(), headers: { - "Content-Type": "application/x-www-form-urlencoded" - } + "Content-Type": "application/x-www-form-urlencoded", + }, + redirect: "manual", }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccessFromHttp(resp, codecForChallengeCreateResponse()); + case HttpStatusCode.Found: + const redirect = resp.headers.get("Location")!; + return opFixedSuccess<RedirectResult>({ + redirectURL: new URL(redirect), + }); case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -165,23 +180,25 @@ export class ChallengerHttpClient { method: "POST", body: new URLSearchParams(Object.entries(body)).toString(), headers: { - "Content-Type": "application/x-www-form-urlencoded" + "Content-Type": "application/x-www-form-urlencoded", }, redirect: "manual", }); switch (resp.status) { case HttpStatusCode.Found: - const redirect = resp.headers.get("Location")! - const uri = new URL(redirect) - const code = uri.searchParams.get("code")! - return { - type: "ok" as const, - body: { code } - } - // return opSuccessFromHttp(resp, codecForChallengeCreateResponse()); + const redirect = resp.headers.get("Location")!; + return opFixedSuccess<RedirectResult>({ + redirectURL: new URL(redirect), + }); case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); - case HttpStatusCode.NotFound: + case HttpStatusCode.Forbidden: + return opKnownAlternativeFailure( + resp, + resp.status, + codecForInvalidPinResponse(), + ); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotAcceptable: return opKnownHttpFailure(resp.status, resp); @@ -210,15 +227,17 @@ export class ChallengerHttpClient { const resp = await this.httpLib.fetch(url.href, { method: "POST", headers: { - "Content-Type": "application/x-www-form-urlencoded" + "Content-Type": "application/x-www-form-urlencoded", }, - body: new URLSearchParams(Object.entries({ - client_id, - redirect_uri, - client_secret, - code, - grant_type: "authorization_code", - })).toString(), + body: new URLSearchParams( + Object.entries({ + client_id, + redirect_uri, + client_secret, + code, + grant_type: "authorization_code", + }), + ).toString(), }); switch (resp.status) { case HttpStatusCode.Ok: diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts index e12c2ed6b..13ef9a3e6 100644 --- a/packages/taler-util/src/http-client/types.ts +++ b/packages/taler-util/src/http-client/types.ts @@ -1533,7 +1533,7 @@ export const codecForChallengeCreateResponse = export const codecForInvalidPinResponse = (): Codec<ChallengerApi.InvalidPinResponse> => buildCodecForObject<ChallengerApi.InvalidPinResponse>() - .property("ec", codecForNumber()) + .property("ec", codecOptional(codecForNumber())) .property("hint", codecForAny()) .property("addresses_left", codecForNumber()) .property("pin_transmissions_left", codecForNumber()) @@ -5319,17 +5319,17 @@ export namespace ChallengerApi { // timestamp explaining when we would re-transmit the challenge the next // time (at the earliest) if requested by the user - next_tx_time: String; + next_tx_time: string; } export interface InvalidPinResponse { // numeric Taler error code, should be shown to indicate the error // compactly for reporting to developers - ec: Integer; + ec?: number; // human-readable Taler error code, should be shown for the user to // understand the error - hint: String; + 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 |