[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-core] 02/06: fix challenger api
From: |
gnunet |
Subject: |
[taler-wallet-core] 02/06: fix challenger api |
Date: |
Mon, 22 Apr 2024 13:55:31 +0200 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository wallet-core.
commit eada01727571fe0aae632696baa97bc4ab6be521
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Sun Apr 21 14:55:26 2024 -0300
fix challenger api
---
packages/taler-util/src/http-client/challenger.ts | 67 +++++++++++++++--------
packages/taler-util/src/http-client/types.ts | 8 +--
packages/taler-util/src/http-common.ts | 41 ++++++++++++++
packages/taler-util/src/operation.ts | 5 +-
4 files changed, 92 insertions(+), 29 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
diff --git a/packages/taler-util/src/http-common.ts
b/packages/taler-util/src/http-common.ts
index cc75debd5..d8cd36287 100644
--- a/packages/taler-util/src/http-common.ts
+++ b/packages/taler-util/src/http-common.ts
@@ -268,6 +268,47 @@ export async function
readSuccessResponseJsonOrErrorCode<T>(
};
}
+export async function readResponseJsonOrErrorCode<T>(
+ httpResponse: HttpResponse,
+ codec: Codec<T>,
+): Promise<{ isError: boolean; response: T }> {
+ let respJson;
+ try {
+ respJson = await httpResponse.json();
+ } catch (e: any) {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+ {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ validationError: e.toString(),
+ },
+ "Couldn't parse JSON format from response",
+ );
+ }
+ let parsedResponse: T;
+ try {
+ parsedResponse = codec.decode(respJson);
+ } catch (e: any) {
+ throw TalerError.fromDetail(
+ TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+ {
+ requestUrl: httpResponse.requestUrl,
+ requestMethod: httpResponse.requestMethod,
+ httpStatusCode: httpResponse.status,
+ validationError: e.toString(),
+ },
+ "Response invalid",
+ );
+ }
+ return {
+ isError: !(httpResponse.status >= 200 && httpResponse.status < 300),
+ response: parsedResponse,
+ };
+}
+
+
type HttpErrorDetails = {
requestUrl: string;
requestMethod: string;
diff --git a/packages/taler-util/src/operation.ts
b/packages/taler-util/src/operation.ts
index 771f5860b..e2ab9d4e4 100644
--- a/packages/taler-util/src/operation.ts
+++ b/packages/taler-util/src/operation.ts
@@ -19,6 +19,7 @@
*/
import {
HttpResponse,
+ readResponseJsonOrErrorCode,
readSuccessResponseJsonOrThrow,
readTalerErrorResponse,
} from "./http-common.js";
@@ -126,7 +127,7 @@ export async function opKnownAlternativeFailure<T extends
HttpStatusCode, B>(
s: T,
codec: Codec<B>,
): Promise<OperationAlternative<T, B>> {
- const body = await readSuccessResponseJsonOrThrow(resp, codec);
+ const body = (await readResponseJsonOrErrorCode(resp, codec)).response;
return { type: "fail", case: s, body };
}
@@ -193,3 +194,5 @@ export type FailCasesByMethod<TT extends object, p extends
keyof TT> = Exclude<
ResultByMethod<TT, p>,
OperationOk<any>
>;
+
+export type RedirectResult = { redirectURL: URL }
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-wallet-core] branch master updated (288dae0c7 -> 56c2e76a3), gnunet, 2024/04/22
- [taler-wallet-core] 03/06: challenger preact api, gnunet, 2024/04/22
- [taler-wallet-core] 04/06: challenger spa, gnunet, 2024/04/22
- [taler-wallet-core] 02/06: fix challenger api,
gnunet <=
- [taler-wallet-core] 01/06: remove unused, gnunet, 2024/04/22
- [taler-wallet-core] 05/06: fix pogen link, gnunet, 2024/04/22
- [taler-wallet-core] 06/06: challenger ui i18n, gnunet, 2024/04/22