aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-util/src/http-client/bank-core.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-util/src/http-client/bank-core.ts')
-rw-r--r--packages/taler-util/src/http-client/bank-core.ts204
1 files changed, 80 insertions, 124 deletions
diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts
index dbb6c7112..8a3283d0f 100644
--- a/packages/taler-util/src/http-client/bank-core.ts
+++ b/packages/taler-util/src/http-client/bank-core.ts
@@ -17,6 +17,7 @@
import {
HttpStatusCode,
LibtoolVersion,
+ LongPollParams,
TalerErrorCode,
codecForChallenge,
codecForTalerErrorDetail,
@@ -29,22 +30,26 @@ import {
HttpRequestLibrary,
createPlatformHttpLib
} from "@gnu-taler/taler-util/http";
-import { FailCasesByMethod, ResultByMethod, opEmptySuccess, opFixedSuccess, opKnownFailure, opSuccess, opUnknownFailure } from "../operation.js";
+import { FailCasesByMethod, ResultByMethod, opEmptySuccess, opFixedSuccess, opSuccess, opUnknownFailure } from "../operation.js";
import { TalerAuthenticationHttpClient } from "./authentication.js";
import { TalerBankConversionHttpClient } from "./bank-conversion.js";
import { TalerBankIntegrationHttpClient } from "./bank-integration.js";
import { TalerRevenueHttpClient } from "./bank-revenue.js";
import { TalerWireGatewayHttpClient } from "./bank-wire.js";
import { AccessToken, PaginationParams, TalerCorebankApi, UserAndToken, WithdrawalOperationStatus, codecForAccountData, codecForBankAccountCreateWithdrawalResponse, codecForBankAccountTransactionInfo, codecForBankAccountTransactionsResponse, codecForCashoutPending, codecForCashoutStatusResponse, codecForCashouts, codecForCoreBankConfig, codecForCreateTransactionResponse, codecForGlobalCashouts, codecForListBankAccountsResponse, codecForMonitorResponse, codecForPublicAccountsResponse, codecForRegisterAccountResponse, codecForWithdrawalPublicInfo } from "./types.js";
-import { addPaginationParams, makeBearerTokenAuthHeader } from "./utils.js";
+import { addLongPollingParam, addPaginationParams, makeBearerTokenAuthHeader } from "./utils.js";
export type TalerCoreBankResultByMethod<prop extends keyof TalerCoreBankHttpClient> = ResultByMethod<TalerCoreBankHttpClient, prop>
export type TalerCoreBankErrorsByMethod<prop extends keyof TalerCoreBankHttpClient> = FailCasesByMethod<TalerCoreBankHttpClient, prop>
/**
- * Protocol version spoken with the bank.
+ * Protocol version spoken with the core bank.
*
+ * Endpoint must be ordered in the same way that in the docs
+ * Response code (http and taler) must have the same order that in the docs
+ * That way is easier to see changes
+ *
* Uses libtool's current:revision:age versioning.
*/
export class TalerCoreBankHttpClient {
@@ -134,8 +139,8 @@ export class TalerCoreBankHttpClient {
switch (resp.status) {
case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.NoContent: return opEmptySuccess()
- case HttpStatusCode.NotFound: 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)
@@ -166,17 +171,17 @@ export class TalerCoreBankHttpClient {
switch (resp.status) {
case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.NoContent: return opEmptySuccess()
- case HttpStatusCode.NotFound: 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_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);
+ case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT: return opKnownTalerFailure(details.code, resp);
case TalerErrorCode.BANK_TAN_CHANNEL_NOT_SUPPORTED: return opKnownTalerFailure(details.code, resp);
+ case TalerErrorCode.BANK_MISSING_TAN_INFO: return opKnownTalerFailure(details.code, resp);
default: return opUnknownFailure(resp, body)
}
}
@@ -289,9 +294,10 @@ export class TalerCoreBankHttpClient {
* https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-transactions
*
*/
- async getTransactions(auth: UserAndToken, pagination?: PaginationParams) {
+ async getTransactions(auth: UserAndToken, params?: PaginationParams & LongPollParams) {
const url = new URL(`accounts/${auth.username}/transactions`, this.baseUrl);
- addPaginationParams(url, pagination)
+ addPaginationParams(url, params)
+ addLongPollingParam(url, params)
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
headers: {
@@ -342,8 +348,8 @@ export class TalerCoreBankHttpClient {
body,
});
switch (resp.status) {
- case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.Ok: return opSuccess(resp, codecForCreateTransactionResponse())
+ case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp);
@@ -382,62 +388,63 @@ export class TalerCoreBankHttpClient {
case HttpStatusCode.Ok: return opSuccess(resp, codecForBankAccountCreateWithdrawalResponse())
case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict: return opKnownHttpFailure(resp.status, resp);
+ //FIXME: missing in docs
case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-withdrawals-$WITHDRAWAL_ID-abort
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-withdrawals-$WITHDRAWAL_ID-confirm
*
*/
- async abortWithdrawalById(auth: UserAndToken, wid: string) {
- const url = new URL(`accounts/${auth.username}/withdrawals/${wid}/abort`, this.baseUrl);
+ async confirmWithdrawalById(auth: UserAndToken, wid: string, cid?: string) {
+ const url = new URL(`accounts/${auth.username}/withdrawals/${wid}/confirm`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
+ Authorization: makeBearerTokenAuthHeader(auth.token),
+ "X-Challenge-Id": cid,
},
});
switch (resp.status) {
+ case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.NoContent: return opEmptySuccess()
//FIXME: missing in docs
case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp)
case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp)
- case HttpStatusCode.Conflict: 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 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)
+ }
+ }
default: return opUnknownFailure(resp, await resp.text())
}
}
/**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-withdrawals-$WITHDRAWAL_ID-confirm
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-withdrawals-$WITHDRAWAL_ID-abort
*
*/
- async confirmWithdrawalById(auth: UserAndToken, wid: string, cid?: string) {
- const url = new URL(`accounts/${auth.username}/withdrawals/${wid}/confirm`, this.baseUrl);
+ async abortWithdrawalById(auth: UserAndToken, wid: string) {
+ const url = new URL(`accounts/${auth.username}/withdrawals/${wid}/abort`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token),
- "X-Challenge-Id": cid,
+ Authorization: makeBearerTokenAuthHeader(auth.token)
},
});
switch (resp.status) {
- case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.NoContent: return opEmptySuccess()
//FIXME: missing in docs
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 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)
- }
- }
+ case HttpStatusCode.Conflict: return opKnownHttpFailure(resp.status, resp);
default: return opUnknownFailure(resp, await resp.text())
}
}
@@ -446,14 +453,13 @@ export class TalerCoreBankHttpClient {
* https://docs.taler.net/core/api-corebank.html#get--withdrawals-$WITHDRAWAL_ID
*
*/
- async getWithdrawalById(wid: string, wait?: {
+ async getWithdrawalById(wid: string, params?: {
old_state?: WithdrawalOperationStatus,
- timeoutMs: number
- }) {
+ } & LongPollParams) {
const url = new URL(`withdrawals/${wid}`, this.baseUrl);
- if (wait) {
- url.searchParams.set("long_poll_ms", String(wait.timeoutMs))
- url.searchParams.set("old_state", !wait.old_state ? "pending" : wait.old_state)
+ addLongPollingParam(url, params)
+ if (params) {
+ url.searchParams.set("old_state", !params.old_state ? "pending" : params.old_state)
}
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
@@ -486,8 +492,8 @@ export class TalerCoreBankHttpClient {
body,
});
switch (resp.status) {
- case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.Ok: return opSuccess(resp, codecForCashoutPending())
+ case HttpStatusCode.Accepted: return opKnownAlternativeFailure(resp, resp.status, codecForChallenge())
case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp)
case HttpStatusCode.Conflict: {
const body = await resp.json()
@@ -514,61 +520,6 @@ export class TalerCoreBankHttpClient {
}
/**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-abort
- * @deprecated since 4
- */
- async abortCashoutById(auth: UserAndToken, cid: number) {
- const url = new URL(`accounts/${auth.username}/cashouts/${cid}/abort`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- });
- switch (resp.status) {
- case HttpStatusCode.NoContent: return opEmptySuccess()
- 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())
- }
- }
-
- /**
- * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-cashouts-$CASHOUT_ID-confirm
- * @deprecated since 4
- */
- async confirmCashoutById(auth: UserAndToken, cid: number, body: TalerCorebankApi.CashoutConfirmRequest) {
- const url = new URL(`accounts/${auth.username}/cashouts/${cid}/confirm`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "POST",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth.token)
- },
- body,
- });
- switch (resp.status) {
- case HttpStatusCode.NoContent: return opEmptySuccess()
- 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 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 opKnownHttpFailure(resp.status, resp);
- case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp);
- default: return opUnknownFailure(resp, await resp.text())
- }
- }
-
- /**
* https://docs.taler.net/core/api-corebank.html#get--accounts-$USERNAME-cashouts-$CASHOUT_ID
*
*/
@@ -604,7 +555,6 @@ export class TalerCoreBankHttpClient {
switch (resp.status) {
case HttpStatusCode.Ok: return opSuccess(resp, codecForCashouts())
case HttpStatusCode.NoContent: return opFixedSuccess({ cashouts: [] });
- case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp);;
case HttpStatusCode.NotImplemented: return opKnownHttpFailure(resp.status, resp);
default: return opUnknownFailure(resp, await resp.text())
}
@@ -632,41 +582,13 @@ export class TalerCoreBankHttpClient {
}
//
- // MONITOR
+ // 2FA
//
/**
- * https://docs.taler.net/core/api-corebank.html#get--monitor
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-challenge-$CHALLENGE_ID
*
*/
- async getMonitor(auth: AccessToken, params: { timeframe?: TalerCorebankApi.MonitorTimeframeParam, which?: number } = {}) {
- const url = new URL(`monitor`, this.baseUrl);
- if (params.timeframe) {
- url.searchParams.set("timeframe", TalerCorebankApi.MonitorTimeframeParam[params.timeframe])
- }
- if (params.which) {
- url.searchParams.set("which", String(params.which))
- }
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- headers: {
- Authorization: makeBearerTokenAuthHeader(auth)
- },
- });
- switch (resp.status) {
- case HttpStatusCode.Ok: return opSuccess(resp, codecForMonitorResponse())
- 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 opKnownHttpFailure(resp.status, resp);
- default: return opUnknownFailure(resp, await resp.text())
- }
- }
-
- //
- // 2FA
- //
async sendChallenge(auth: UserAndToken, cid: string) {
const url = new URL(`accounts/${auth.username}/challenge/${cid}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -691,6 +613,10 @@ export class TalerCoreBankHttpClient {
}
}
+ /**
+ * https://docs.taler.net/core/api-corebank.html#post--accounts-$USERNAME-challenge-$CHALLENGE_ID-confirm
+ *
+ */
async confirmChallenge(auth: UserAndToken, cid: string, body: TalerCorebankApi.ChallengeSolve) {
const url = new URL(`accounts/${auth.username}/challenge/${cid}/confirm`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -718,6 +644,36 @@ export class TalerCoreBankHttpClient {
}
}
+ //
+ // MONITOR
+ //
+
+ /**
+ * https://docs.taler.net/core/api-corebank.html#get--monitor
+ *
+ */
+ async getMonitor(auth: AccessToken, params: { timeframe?: TalerCorebankApi.MonitorTimeframeParam, which?: number } = {}) {
+ const url = new URL(`monitor`, this.baseUrl);
+ if (params.timeframe) {
+ url.searchParams.set("timeframe", TalerCorebankApi.MonitorTimeframeParam[params.timeframe])
+ }
+ if (params.which) {
+ url.searchParams.set("which", String(params.which))
+ }
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ headers: {
+ Authorization: makeBearerTokenAuthHeader(auth)
+ },
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok: return opSuccess(resp, codecForMonitorResponse())
+ case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp);
+ default: return opUnknownFailure(resp, await resp.text())
+ }
+ }
+
//
// Others API