From 3db00d9d73c7fcd88f8450330c01639a6b171df9 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 31 Jul 2020 20:13:59 +0530 Subject: fix concurrency bug in bank-integrated withdrawal, better response parsing --- src/operations/reserves.ts | 25 ++++++++++++++----------- src/types/talerTypes.ts | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/operations/reserves.ts b/src/operations/reserves.ts index fdc35bb14..405a02f9e 100644 --- a/src/operations/reserves.ts +++ b/src/operations/reserves.ts @@ -43,7 +43,10 @@ import { getExchangeTrust, getExchangePaytoUri, } from "./exchanges"; -import { codecForWithdrawOperationStatusResponse } from "../types/talerTypes"; +import { + codecForWithdrawOperationStatusResponse, + codecForBankWithdrawalOperationPostResponse, +} from "../types/talerTypes"; import { assertUnreachable } from "../util/assertUnreachable"; import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto"; import { randomBytes } from "../crypto/primitives/nacl-fast"; @@ -71,7 +74,9 @@ import { TalerErrorCode } from "../TalerErrorCode"; import { readSuccessResponseJsonOrErrorCode, throwUnexpectedRequestError, + readSuccessResponseJsonOrThrow, } from "../util/http"; +import { codecForAny } from "../util/codec"; const logger = new Logger("reserves.ts"); @@ -324,14 +329,14 @@ async function registerReserveWithBank( return; } const bankStatusUrl = bankInfo.statusUrl; - if (reserve.timestampReserveInfoPosted) { - throw Error("bank claims that reserve info selection is not done"); - } - // FIXME: parse bank response - await ws.http.postJson(bankStatusUrl, { + const httpResp = await ws.http.postJson(bankStatusUrl, { reserve_pub: reservePub, selected_exchange: bankInfo.exchangePaytoUri, }); + await readSuccessResponseJsonOrThrow( + httpResp, + codecForBankWithdrawalOperationPostResponse(), + ); await ws.db.mutate(Stores.reserves, reservePub, (r) => { switch (r.reserveStatus) { case ReserveRecordStatus.REGISTERING_BANK: @@ -382,11 +387,9 @@ async function processReserveBankStatusImpl( } const statusResp = await ws.http.get(bankStatusUrl); - if (statusResp.status !== 200) { - throw Error(`unexpected status ${statusResp.status} for bank status query`); - } - const status = codecForWithdrawOperationStatusResponse().decode( - await statusResp.json(), + const status = await readSuccessResponseJsonOrThrow( + statusResp, + codecForWithdrawOperationStatusResponse(), ); if (status.selection_done) { diff --git a/src/types/talerTypes.ts b/src/types/talerTypes.ts index 823f437b5..95c1a711c 100644 --- a/src/types/talerTypes.ts +++ b/src/types/talerTypes.ts @@ -940,6 +940,20 @@ export interface WithdrawUriInfoResponse { possibleExchanges: ExchangeListItem[]; } +/** + * Response body for the following endpoint: + * + * POST {talerBankIntegrationApi}/withdrawal-operation/{wopid} + */ +export interface BankWithdrawalOperationPostResponse { + transfer_done: boolean; +} + +export const codecForBankWithdrawalOperationPostResponse = (): Codec => + makeCodecForObject() + .property("transfer_done", codecForBoolean) + .build("BankWithdrawalOperationPostResponse"); + export type AmountString = string; export type Base32String = string; export type EddsaSignatureString = string; -- cgit v1.2.3