diff options
author | Sebastian <sebasjm@gmail.com> | 2024-01-09 18:51:49 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2024-01-09 18:51:49 -0300 |
commit | f5771cc7b99dc938fd606dcbee350b66ec8027c9 (patch) | |
tree | 95c1aa5b8a5e6067c7689b0caf161c50d1f694ed /packages/taler-util | |
parent | 1826b9121a0308aa0a7ac39a89ad7dc8ea2ae965 (diff) | |
download | wallet-core-f5771cc7b99dc938fd606dcbee350b66ec8027c9.tar.xz |
prepare for 2fa impl
Diffstat (limited to 'packages/taler-util')
-rw-r--r-- | packages/taler-util/src/http-client/bank-core.ts | 182 | ||||
-rw-r--r-- | packages/taler-util/src/operation.ts | 10 |
2 files changed, 109 insertions, 83 deletions
diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts index b7e0292bd..dd0948250 100644 --- a/packages/taler-util/src/http-client/bank-core.ts +++ b/packages/taler-util/src/http-client/bank-core.ts @@ -20,7 +20,9 @@ import { TalerErrorCode, codecForChallenge, codecForTalerErrorDetail, - codecForTanTransmission + codecForTanTransmission, + opKnownHttpFailure, + opKnownTalerFailure } from "@gnu-taler/taler-util"; import { HttpRequestLibrary, @@ -45,7 +47,7 @@ export type TalerCoreBankErrorsByMethod<prop extends keyof TalerCoreBankHttpClie * Uses libtool's current:revision:age versioning. */ export class TalerCoreBankHttpClient { - public readonly PROTOCOL_VERSION = "0:0:0"; + public readonly PROTOCOL_VERSION = "4:0:0"; httpLib: HttpRequestLibrary; @@ -95,17 +97,17 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForRegisterAccountResponse()) - case HttpStatusCode.BadRequest: return opKnownFailure("invalid-phone-or-email", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_REGISTER_USERNAME_REUSE: return opKnownFailure("username-already-exists", resp); - case TalerErrorCode.BANK_REGISTER_PAYTO_URI_REUSE: return opKnownFailure("payto-already-exists", resp); - case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("insufficient-funds", resp); - case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT: return opKnownFailure("username-reserved", resp); - case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT: return opKnownFailure("user-cant-set-debt", resp); + case TalerErrorCode.BANK_REGISTER_USERNAME_REUSE: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_REGISTER_PAYTO_URI_REUSE: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } @@ -127,14 +129,14 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Accepted: return opSuccess(resp, codecForChallenge()) case HttpStatusCode.NoContent: return opEmptySuccess() - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT: return opKnownFailure("username-reserved", resp); - case TalerErrorCode.BANK_ACCOUNT_BALANCE_NOT_ZERO: return opKnownFailure("balance-not-zero", resp); + case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_ACCOUNT_BALANCE_NOT_ZERO: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } @@ -158,16 +160,16 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Accepted: return opSuccess(resp, codecForChallenge()) case HttpStatusCode.NoContent: return opEmptySuccess() - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_NON_ADMIN_PATCH_LEGAL_NAME: return opKnownFailure("user-cant-change-name", resp); - case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT: return opKnownFailure("user-cant-change-debt", resp); - case TalerErrorCode.BANK_NON_ADMIN_PATCH_CASHOUT: return opKnownFailure("user-cant-change-cashout", resp); - case TalerErrorCode.BANK_MISSING_TAN_INFO: return opKnownFailure("missing-contact-data", resp); + case TalerErrorCode.BANK_NON_ADMIN_PATCH_LEGAL_NAME: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_NON_ADMIN_PATCH_CASHOUT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_NON_ADMIN_PATCH_CONTACT: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } @@ -191,14 +193,14 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Accepted: return opSuccess(resp, codecForChallenge()) case HttpStatusCode.NoContent: return opEmptySuccess() - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_NON_ADMIN_PATCH_MISSING_OLD_PASSWORD: return opKnownFailure("user-require-old-password", resp); - case TalerErrorCode.BANK_PATCH_BAD_OLD_PASSWORD: return opKnownFailure("wrong-old-password", resp); + case TalerErrorCode.BANK_NON_ADMIN_PATCH_MISSING_OLD_PASSWORD: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_PATCH_BAD_OLD_PASSWORD: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } @@ -246,7 +248,7 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForListBankAccountsResponse()) case HttpStatusCode.NoContent: return opFixedSuccess({ accounts: [] }) - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -265,8 +267,8 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForAccountData()) - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -291,8 +293,8 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForBankAccountTransactionsResponse()) case HttpStatusCode.NoContent: return opFixedSuccess({ transactions: [] }) - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -311,8 +313,8 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForBankAccountTransactionInfo()) - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -333,16 +335,16 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Accepted: return opSuccess(resp, codecForChallenge()) case HttpStatusCode.Ok: return opSuccess(resp, codecForCreateTransactionResponse()) - case HttpStatusCode.BadRequest: return opKnownFailure("invalid-input", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); + case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_SAME_ACCOUNT: return opKnownFailure("creditor-same", resp); - case TalerErrorCode.BANK_UNKNOWN_CREDITOR: return opKnownFailure("creditor-not-found", resp); - case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("insufficient-funds", resp); + case TalerErrorCode.BANK_SAME_ACCOUNT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_UNKNOWN_CREDITOR: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } @@ -369,9 +371,9 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForBankAccountCreateWithdrawalResponse()) - case HttpStatusCode.NotFound: return opKnownFailure("account-not-found", resp); - case HttpStatusCode.Conflict: return opKnownFailure("insufficient-funds", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Conflict: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -391,9 +393,9 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.NoContent: return opEmptySuccess() //FIXME: missing in docs - case HttpStatusCode.BadRequest: return opKnownFailure("invalid-id", resp) - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp) - case HttpStatusCode.Conflict: return opKnownFailure("previously-confirmed", resp); + case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp) + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp) + case HttpStatusCode.Conflict: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -414,15 +416,15 @@ export class TalerCoreBankHttpClient { case HttpStatusCode.Accepted: return opSuccess(resp, codecForChallenge()) case HttpStatusCode.NoContent: return opEmptySuccess() //FIXME: missing in docs - case HttpStatusCode.BadRequest: return opKnownFailure("invalid-id", resp) - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp) + case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp) + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp) case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: return opKnownFailure("previously-aborted", resp); - case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownFailure("no-exchange-or-reserve-selected", resp); - case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("insufficient-funds", resp); + case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } @@ -449,8 +451,8 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForWithdrawalPublicInfo()) //FIXME: missing in docs - case HttpStatusCode.BadRequest: return opKnownFailure("invalid-id", resp) - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp) + case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp) + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp) default: return opUnknownFailure(resp, await resp.text()) } } @@ -475,19 +477,27 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Accepted: return opSuccess(resp, codecForChallenge()) case HttpStatusCode.Ok: return opSuccess(resp, codecForCashoutPending()) - case HttpStatusCode.NotFound: return opKnownFailure("account-not-found", resp) + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp) case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_TRANSFER_REQUEST_UID_REUSED: return opKnownFailure("request-already-used", resp); - case TalerErrorCode.BANK_BAD_CONVERSION: return opKnownFailure("incorrect-exchange-rate", resp); - case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("no-enough-balance", resp); - case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownFailure("no-cashout-uri", resp); + case TalerErrorCode.BANK_TRANSFER_REQUEST_UID_REUSED: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_BAD_CONVERSION: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } - case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp); + case HttpStatusCode.BadGateway: { + const body = await resp.json() + const details = codecForTalerErrorDetail().decode(body) + switch (details.code) { + case TalerErrorCode.BANK_TAN_CHANNEL_SCRIPT_FAILED: return opKnownTalerFailure(details.code, resp); + default: return opUnknownFailure(resp, body) + } + } + case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -506,9 +516,9 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.NoContent: return opEmptySuccess() - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); - case HttpStatusCode.Conflict: return opKnownFailure("already-confirmed", resp); - case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Conflict: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -528,21 +538,21 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.NoContent: return opEmptySuccess() - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Conflict: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: return opKnownFailure("already-aborted", resp); - case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownFailure("no-cashout-payto", resp); - case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownFailure("no-enough-balance", resp); - case TalerErrorCode.BANK_BAD_CONVERSION: return opKnownFailure("incorrect-exchange-rate", resp); - case TalerErrorCode.BANK_TAN_CHALLENGE_FAILED: return opKnownFailure("invalid-code", resp); + case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_UNALLOWED_DEBIT: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_BAD_CONVERSION: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_TAN_CHALLENGE_FAILED: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } - case HttpStatusCode.TooManyRequests: return opKnownFailure("too-many-attempts", resp); - case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp); + case HttpStatusCode.TooManyRequests: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -561,8 +571,8 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForCashoutStatusResponse()) - case HttpStatusCode.NotFound: return opKnownFailure("not-found", resp); - case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -583,8 +593,8 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForCashouts()) case HttpStatusCode.NoContent: return opFixedSuccess({ cashouts: [] }); - case HttpStatusCode.NotFound: return opKnownFailure("account-not-found", resp);; - case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp);; + case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -605,7 +615,7 @@ export class TalerCoreBankHttpClient { switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForGlobalCashouts()) case HttpStatusCode.NoContent: return opFixedSuccess({ cashouts: [] }); - case HttpStatusCode.NotImplemented: return opKnownFailure("cashout-not-supported", resp); + case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -634,11 +644,11 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForMonitorResponse()) - case HttpStatusCode.BadRequest: return opKnownFailure("invalid-input", resp); - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); + case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); //FIXME remove when server is updated //FIXME: should be 404 ? - case HttpStatusCode.ServiceUnavailable: return opKnownFailure("monitor-not-supported", resp); + case HttpStatusCode.ServiceUnavailable: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } @@ -656,13 +666,13 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.Ok: return opSuccess(resp, codecForTanTransmission()) - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); - case HttpStatusCode.NotFound: return opKnownFailure("invalid-challenge", resp); + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.BadGateway: { const body = await resp.json() const details = codecForTalerErrorDetail().decode(body) switch (details.code) { - case TalerErrorCode.BANK_TAN_CHANNEL_SCRIPT_FAILED: return opKnownFailure("tan-failed", resp); + case TalerErrorCode.BANK_TAN_CHANNEL_SCRIPT_FAILED: return opKnownTalerFailure(details.code, resp); default: return opUnknownFailure(resp, body) } } @@ -679,11 +689,19 @@ export class TalerCoreBankHttpClient { }, }); switch (resp.status) { - case HttpStatusCode.Ok: return opEmptySuccess() - case HttpStatusCode.Unauthorized: return opKnownFailure("unauthorized", resp); - case HttpStatusCode.NotFound: return opKnownFailure("invalid-challenge", resp); - case HttpStatusCode.Conflict: return opKnownFailure("wrong-code", resp); - case HttpStatusCode.TooManyRequests: return opKnownFailure("too-many-errors", resp); + case HttpStatusCode.NoContent: return opEmptySuccess() + case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Conflict: { + const body = await resp.json() + const details = codecForTalerErrorDetail().decode(body) + switch (details.code) { + case TalerErrorCode.BANK_TAN_CHALLENGE_EXPIRED: return opKnownTalerFailure(details.code, resp); + case TalerErrorCode.BANK_TAN_CHALLENGE_FAILED: return opKnownTalerFailure(details.code, resp); + default: return opUnknownFailure(resp, body) + } + } + case HttpStatusCode.TooManyRequests: return opKnownHttpFailure(resp.status, resp); default: return opUnknownFailure(resp, await resp.text()) } } diff --git a/packages/taler-util/src/operation.ts b/packages/taler-util/src/operation.ts index 06bfe26bd..8b264d905 100644 --- a/packages/taler-util/src/operation.ts +++ b/packages/taler-util/src/operation.ts @@ -1,5 +1,5 @@ import { HttpResponse, readSuccessResponseJsonOrThrow, readTalerErrorResponse } from "./http-common.js"; -import { Codec, TalerError, TalerErrorCode, TalerErrorDetail } from "./index.js"; +import { Codec, HttpStatusCode, TalerError, TalerErrorCode, TalerErrorDetail } from "./index.js"; export type OperationResult<Body, ErrorEnum> = | OperationOk<Body> @@ -31,6 +31,14 @@ export function opFixedSuccess<T>(body: T): OperationOk<T> { export function opEmptySuccess(): OperationOk<void> { return { type: "ok" as const, body: void 0 } } +export async function opKnownHttpFailure<T extends HttpStatusCode>(s: T, resp: HttpResponse): Promise<OperationFail<T>> { + const detail = await readTalerErrorResponse(resp) + return { type: "fail", case: s, detail } +} +export async function opKnownTalerFailure<T extends TalerErrorCode>(s: T, resp: HttpResponse): Promise<OperationFail<T>> { + const detail = await readTalerErrorResponse(resp) + return { type: "fail", case: s, detail } +} export async function opKnownFailure<T extends string>(s: T, resp: HttpResponse): Promise<OperationFail<T>> { const detail = await readTalerErrorResponse(resp) return { type: "fail", case: s, detail } |