diff options
Diffstat (limited to 'packages/taler-wallet-core/src')
-rw-r--r-- | packages/taler-wallet-core/src/bank-api-client.ts | 151 |
1 files changed, 134 insertions, 17 deletions
diff --git a/packages/taler-wallet-core/src/bank-api-client.ts b/packages/taler-wallet-core/src/bank-api-client.ts index 01c28e8e8..8e351cb48 100644 --- a/packages/taler-wallet-core/src/bank-api-client.ts +++ b/packages/taler-wallet-core/src/bank-api-client.ts @@ -267,8 +267,7 @@ export namespace BankAccessApi { export interface BankAccessApiClientArgs { baseUrl: string; - username: string; - password: string; + auth?: { username: string; password: string }; enableThrottling?: boolean; allowHttp?: boolean; } @@ -339,19 +338,33 @@ export class BankAccessApiClient { }); } - async getTransactions(): Promise<void> { + setAuth(auth: { username: string; password: string }) { + this.args.auth = auth; + } + + private makeAuthHeader(): Record<string, string> { + if (!this.args.auth) { + return {}; + } + const authHeaderValue = makeBasicAuthHeader( + this.args.auth.username, + this.args.auth.password, + ); + return { + Authorization: authHeaderValue, + }; + } + + async getTransactions(username: string): Promise<void> { + const auth = this.args.auth; const reqUrl = new URL( - `accounts/${this.args.username}/transactions`, + `accounts/${username}/transactions`, this.args.baseUrl, ); - const authHeaderValue = makeBasicAuthHeader( - this.args.username, - this.args.password, - ); const resp = await this.httpLib.fetch(reqUrl.href, { method: "GET", headers: { - Authorization: authHeaderValue, + ...this.makeAuthHeader(), }, }); @@ -360,24 +373,128 @@ export class BankAccessApiClient { } async createTransaction( + username: string, req: BankAccessApiCreateTransactionRequest, ): Promise<any> { const reqUrl = new URL( - `accounts/${this.args.username}/transactions`, + `accounts/${username}/transactions`, this.args.baseUrl, ); - const authHeaderValue = makeBasicAuthHeader( - this.args.username, - this.args.password, - ); + const resp = await this.httpLib.fetch(reqUrl.href, { method: "POST", body: req, - headers: { - Authorization: authHeaderValue, - }, + headers: this.makeAuthHeader(), }); return await readSuccessResponseJsonOrThrow(resp, codecForAny()); } + + async registerAccount( + username: string, + password: string, + options: { + iban?: string; + }, + ): Promise<BankUser> { + const url = new URL("testing/register", this.args.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: { + username, + password, + iban: options?.iban, + }, + }); + let paytoUri = `payto://x-taler-bank/localhost/${username}`; + if (resp.status !== 200 && resp.status !== 202 && resp.status !== 204) { + logger.error(`${j2s(await resp.json())}`); + throw TalerError.fromDetail( + TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR, + { + httpStatusCode: resp.status, + }, + ); + } + try { + // Pybank has no body, thus this might throw. + const respJson = await resp.json(); + // LibEuFin demobank returns payto URI in response + if (respJson.paytoUri) { + paytoUri = respJson.paytoUri; + } + } catch (e) { + // Do nothing + } + return { + password, + username, + accountPaytoUri: paytoUri, + }; + } + + async createRandomBankUser(): Promise<BankUser> { + const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase(); + const password = "pw-" + encodeCrock(getRandomBytes(10)).toLowerCase(); + // FIXME: This is just a temporary workaround, because demobank is running out of short IBANs + const iban = generateIban("DE", 15); + return await this.registerAccount(username, password, { + iban, + }); + } + + async createWithdrawalOperation( + user: string, + amount: string, + ): Promise<WithdrawalOperationInfo> { + const url = new URL(`accounts/${user}/withdrawals`, this.args.baseUrl); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: { + amount, + }, + headers: this.makeAuthHeader(), + }); + return readSuccessResponseJsonOrThrow( + resp, + codecForWithdrawalOperationInfo(), + ); + } + + async confirmWithdrawalOperation( + username: string, + wopi: WithdrawalOperationInfo, + ): Promise<void> { + const url = new URL( + `accounts/${username}/withdrawals/${wopi.withdrawal_id}/confirm`, + this.args.baseUrl, + ); + logger.info(`confirming withdrawal operation via ${url.href}`); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: {}, + headers: this.makeAuthHeader(), + }); + + logger.info(`response status ${resp.status}`); + const respJson = await readSuccessResponseJsonOrThrow(resp, codecForAny()); + + // FIXME: We don't check the status here! + } + + async abortWithdrawalOperation( + accountName: string, + wopi: WithdrawalOperationInfo, + ): Promise<void> { + const url = new URL( + `accounts/${accountName}/withdrawals/${wopi.withdrawal_id}/abort`, + this.args.baseUrl, + ); + const resp = await this.httpLib.fetch(url.href, { + method: "POST", + body: {}, + headers: this.makeAuthHeader(), + }); + await readSuccessResponseJsonOrThrow(resp, codecForAny()); + } } |