aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-util
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-06-28 13:12:07 -0300
committerSebastian <sebasjm@gmail.com>2024-06-28 13:12:37 -0300
commit5d8bdc3dd61157c6a2836f9b2651d23e557d9bc5 (patch)
treea42f38935aef9113c22c36c7ed2de2a69c2affa5 /packages/taler-util
parent71f9676fc9d80bccc7353487d8527af74d25a02c (diff)
downloadwallet-core-5d8bdc3dd61157c6a2836f9b2651d23e557d9bc5.tar.xz
update challenger api v2
Diffstat (limited to 'packages/taler-util')
-rw-r--r--packages/taler-util/src/http-client/types.ts27
-rw-r--r--packages/taler-util/src/operation.ts51
2 files changed, 70 insertions, 8 deletions
diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts
index 6e758773c..a91e8cc71 100644
--- a/packages/taler-util/src/http-client/types.ts
+++ b/packages/taler-util/src/http-client/types.ts
@@ -1580,8 +1580,12 @@ export const codecForChallengeStatus =
buildCodecForObject<ChallengerApi.ChallengeStatus>()
.property("restrictions", codecOptional(codecForMap(codecForAny())))
.property("fix_address", codecForBoolean())
+ .property("solved", codecForBoolean())
.property("last_address", codecOptional(codecForMap(codecForAny())))
.property("changes_left", codecForNumber())
+ .property("retransmission_time", codecForTimestamp)
+ .property("pin_transmissions_left", codecForNumber())
+ .property("auth_attempts_left", codecForNumber())
.build("ChallengerApi.ChallengeStatus");
export const codecForChallengeResponse =
@@ -1599,7 +1603,7 @@ export const codecForChallengeCreateResponse =
.property("address", codecForAny())
.property("type", codecForConstString("created"))
.property("transmitted", codecForBoolean())
- .property("next_tx_time", codecForString())
+ .property("next_tx_time", codecForTimestamp)
.build("ChallengerApi.ChallengeCreateResponse");
export const codecForChallengeRedirect =
@@ -5420,6 +5424,25 @@ export namespace ChallengerApi {
// number of times the address can still be changed, may or may not be
// shown to the user
changes_left: Integer;
+
+ // if the challenge has already been solved
+ solved: boolean;
+
+ // when we would re-transmit the challenge the next
+ // time (at the earliest) if requested by the user
+ // only present if challenge already created
+ // @since v2
+ retransmission_time: Timestamp;
+
+ // how many times might the PIN still be retransmitted
+ // only present if challenge already created
+ // @since v2
+ pin_transmissions_left: Integer;
+
+ // how many times might the user still try entering the PIN code
+ // only present if challenge already created
+ // @since v2
+ auth_attempts_left: Integer;
}
export type ChallengeResponse = ChallengeRedirect | ChallengeCreateResponse;
@@ -5447,7 +5470,7 @@ 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: TalerProtocolTimestamp;
}
export type ChallengeSolveResponse = ChallengeRedirect | InvalidPinResponse;
diff --git a/packages/taler-util/src/operation.ts b/packages/taler-util/src/operation.ts
index e2ab9d4e4..2d17238dc 100644
--- a/packages/taler-util/src/operation.ts
+++ b/packages/taler-util/src/operation.ts
@@ -146,7 +146,10 @@ export function opKnownTalerFailure<T extends TalerErrorCode>(
return { type: "fail", case: s, detail };
}
-export function opUnknownFailure(resp: HttpResponse, error: TalerErrorDetail): never {
+export function opUnknownFailure(
+ resp: HttpResponse,
+ error: TalerErrorDetail,
+): never {
throw TalerError.fromDetail(
TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR,
{
@@ -179,15 +182,51 @@ export function narrowOpSuccessOrThrow<Body, ErrorEnum>(
}
}
+export async function succeedOrThrow<R, E>(
+ promise: Promise<OperationResult<R, E>>,
+): Promise<R> {
+ const resp = await promise;
+ if (isOperationOk(resp)) {
+ return resp.body;
+ }
+
+ if (isOperationFail(resp)) {
+ throw TalerError.fromUncheckedDetail({ ...resp, case: resp.case } as any);
+ }
+ throw TalerError.fromException(resp);
+}
+
+export async function failOrThrow<E>(
+ s: E,
+ promise: Promise<OperationResult<unknown, E>>,
+): Promise<TalerErrorDetail | undefined> {
+ const resp = await promise;
+ if (isOperationOk(resp)) {
+ throw TalerError.fromException(
+ new Error(`request succeed but failure "${s}" was expected`),
+ );
+ }
+ if (isOperationFail(resp) && resp.case === s) {
+ return resp.detail;
+ }
+ throw TalerError.fromException(
+ new Error(
+ `request failed with "${JSON.stringify(
+ resp,
+ )}" but case "${s}" was expected`,
+ ),
+ );
+}
+
export type ResultByMethod<
TT extends object,
p extends keyof TT,
> = TT[p] extends (...args: any[]) => infer Ret
? Ret extends Promise<infer Result>
- ? Result extends OperationResult<any, any>
- ? Result
- : never
- : never //api always use Promises
+ ? Result extends OperationResult<any, any>
+ ? Result
+ : never
+ : never //api always use Promises
: never; //error cases just for functions
export type FailCasesByMethod<TT extends object, p extends keyof TT> = Exclude<
@@ -195,4 +234,4 @@ export type FailCasesByMethod<TT extends object, p extends keyof TT> = Exclude<
OperationOk<any>
>;
-export type RedirectResult = { redirectURL: URL }
+export type RedirectResult = { redirectURL: URL };