From d483a3f5574355ed9c43eb6ddea59e5734323cf0 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 19 Apr 2023 12:42:47 -0300 Subject: fix #7704 --- packages/taler-wallet-core/src/wallet.ts | 217 ++++++++++++++++++------------- 1 file changed, 124 insertions(+), 93 deletions(-) (limited to 'packages/taler-wallet-core/src/wallet.ts') diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index d6d64b5c9..45b33ce45 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -25,12 +25,38 @@ import { AbsoluteTime, Amounts, + CoinDumpJson, + CoinRefreshRequest, + CoinStatus, + CoreApiResponse, + DenomOperationMap, + DenominationInfo, + Duration, + ExchangeDetailedResponse, + ExchangeListItem, + ExchangeTosStatusDetails, + ExchangesListResponse, + FeeDescription, + GetExchangeTosResult, + InitResponse, + KnownBankAccounts, + KnownBankAccountsInfo, + Logger, + ManualWithdrawalDetails, + MerchantUsingTemplateDetails, + NotificationType, + RefreshReason, + TalerError, + TalerErrorCode, + URL, + ValidateIbanResponse, + WalletCoreVersion, + WalletNotification, codecForAbortTransaction, codecForAcceptBankIntegratedWithdrawalRequest, codecForAcceptExchangeTosRequest, codecForAcceptManualWithdrawalRequet, codecForAcceptPeerPullPaymentRequest, - codecForConfirmPeerPushPaymentRequest, codecForAcceptTipRequest, codecForAddExchangeRequest, codecForAddKnownBankAccounts, @@ -39,8 +65,9 @@ import { codecForApplyRefundFromPurchaseIdRequest, codecForApplyRefundRequest, codecForCheckPeerPullPaymentRequest, - codecForPreparePeerPushCreditRequest, + codecForCheckPeerPushDebitRequest, codecForConfirmPayRequest, + codecForConfirmPeerPushPaymentRequest, codecForCreateDepositGroupRequest, codecForDeleteTransactionRequest, codecForForceRefreshRequest, @@ -54,86 +81,58 @@ import { codecForInitiatePeerPullPaymentRequest, codecForInitiatePeerPushPaymentRequest, codecForIntegrationTestArgs, + codecForIntegrationTestV2Args, codecForListKnownBankAccounts, codecForMerchantPostOrderResponse, codecForPrepareDepositRequest, codecForPreparePayRequest, codecForPreparePayTemplateRequest, codecForPreparePeerPullPaymentRequest, - codecForCheckPeerPushDebitRequest, + codecForPreparePeerPushCreditRequest, codecForPrepareRefundRequest, codecForPrepareTipRequest, + codecForResumeTransaction, codecForRetryTransactionRequest, codecForSetCoinSuspendedRequest, - codecForSetDevModeRequest, codecForSetWalletDeviceIdRequest, + codecForSuspendTransaction, codecForTestPayArgs, codecForTransactionByIdRequest, codecForTransactionsRequest, codecForUserAttentionByIdRequest, codecForUserAttentionsRequest, + codecForValidateIbanRequest, codecForWithdrawFakebankRequest, codecForWithdrawTestBalance, - CoinDumpJson, - CoinRefreshRequest, - CoinStatus, constructPayUri, - CoreApiResponse, - DenominationInfo, - DenomOperationMap, - Duration, durationFromSpec, durationMin, - ExchangeDetailedResponse, - ExchangeListItem, - ExchangesListResponse, - ExchangeTosStatusDetails, - FeeDescription, - GetExchangeTosResult, - InitResponse, + getErrorDetailFromException, j2s, - KnownBankAccounts, - KnownBankAccountsInfo, - Logger, - ManualWithdrawalDetails, - MerchantUsingTemplateDetails, - NotificationType, parsePayTemplateUri, parsePaytoUri, - RefreshReason, - TalerErrorCode, - URL, - WalletCoreVersion, - WalletNotification, - codecForSuspendTransaction, - codecForResumeTransaction, validateIban, - codecForValidateIbanRequest, - ValidateIbanResponse, - codecForIntegrationTestV2Args, } from "@gnu-taler/taler-util"; +import { + HttpRequestLibrary, + readSuccessResponseJsonOrThrow, +} from "@gnu-taler/taler-util/http"; import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; import { CryptoDispatcher, CryptoWorkerFactory, } from "./crypto/workers/crypto-dispatcher.js"; import { - AuditorTrustRecord, - clearDatabase, CoinSourceType, ConfigRecordKey, DenominationRecord, ExchangeDetailsRecord, + WalletStoresV1, + clearDatabase, exportDb, importDb, - WalletStoresV1, } from "./db.js"; -import { - applyDevExperiment, - maybeInitDevMode, - setDevMode, -} from "./dev-experiments.js"; -import { getErrorDetailFromException, TalerError } from "@gnu-taler/taler-util"; +import { DevExperimentHttpLib, applyDevExperiment } from "./dev-experiments.js"; import { ActiveLongpollInfo, ExchangeOperations, @@ -198,18 +197,18 @@ import { processPurchase, } from "./operations/pay-merchant.js"; import { + checkPeerPullPaymentInitiation, + checkPeerPushDebit, confirmPeerPullDebit, confirmPeerPushCredit, - preparePeerPullDebit, - preparePeerPushCredit, initiatePeerPullPayment, initiatePeerPushPayment, - checkPeerPullPaymentInitiation, - checkPeerPushDebit, + preparePeerPullDebit, + preparePeerPushCredit, processPeerPullCredit, - processPeerPushInitiation, processPeerPullDebit, processPeerPushCredit, + processPeerPushInitiation, } from "./operations/pay-peer.js"; import { getPendingOperations } from "./operations/pending.js"; import { @@ -252,10 +251,6 @@ import { selectBestForOverlappingDenominations, selectMinimumFee, } from "./util/denominations.js"; -import { - HttpRequestLibrary, - readSuccessResponseJsonOrThrow, -} from "@gnu-taler/taler-util/http"; import { checkDbInvariant } from "./util/invariants.js"; import { AsyncCondition, @@ -275,22 +270,14 @@ import { WALLET_MERCHANT_PROTOCOL_VERSION, } from "./versions.js"; import { + RecursivePartial, WalletApiOperation, + WalletConfig, + WalletConfigParameter, WalletCoreApiClient, WalletCoreResponseType, } from "./wallet-api-types.js"; -const builtinAuditors: AuditorTrustRecord[] = [ - { - currency: "KUDOS", - auditorPub: "BW9DC48PHQY4NH011SHHX36DZZ3Q22Y6X7FZ1VD1CMZ2PTFZ6PN0", - auditorBaseUrl: "https://auditor.demo.taler.net/", - uids: ["5P25XF8TVQP9AW6VYGY2KV47WT5Y3ZXFSJAA570GJPX5SVJXKBVG"], - }, -]; - -const builtinExchanges: string[] = ["https://exchange.demo.taler.net/"]; - const logger = new Logger("wallet.ts"); /** @@ -495,10 +482,10 @@ async function fillDefaults(ws: InternalWalletState): Promise { return; } logger.info("importing default exchanges and auditors"); - for (const c of builtinAuditors) { + for (const c of ws.config.builtin.auditors) { await tx.auditorTrust.put(c); } - for (const baseUrl of builtinExchanges) { + for (const baseUrl of ws.config.builtin.exchanges) { const now = AbsoluteTime.now(); provideExchangeRecordInTx(ws, tx, baseUrl, now); } @@ -1018,7 +1005,6 @@ async function dispatchRequestInternal( logger.trace("filling defaults"); await fillDefaults(ws); } - await maybeInitDevMode(ws); const resp: InitResponse = { versionInfo: getVersion(ws), }; @@ -1482,15 +1468,10 @@ async function dispatchRequestInternal( await applyDevExperiment(ws, req.devExperimentUri); return {}; } - case WalletApiOperation.SetDevMode: { - const req = codecForSetDevModeRequest().decode(payload); - await setDevMode(ws, req.devModeEnabled); - return {}; - } case WalletApiOperation.GetVersion: { return getVersion(ws); } - //default: + // default: // assertUnreachable(operation); } throw TalerError.fromDetail( @@ -1509,7 +1490,7 @@ export function getVersion(ws: InternalWalletState): WalletCoreVersion { exchange: WALLET_EXCHANGE_PROTOCOL_VERSION, merchant: WALLET_MERCHANT_PROTOCOL_VERSION, bank: WALLET_BANK_INTEGRATION_PROTOCOL_VERSION, - devMode: ws.devModeActive, + devMode: false, }; return version; } @@ -1575,8 +1556,15 @@ export class Wallet { http: HttpRequestLibrary, timer: TimerAPI, cryptoWorkerFactory: CryptoWorkerFactory, + config?: WalletConfigParameter, ) { - this.ws = new InternalWalletStateImpl(db, http, timer, cryptoWorkerFactory); + this.ws = new InternalWalletStateImpl( + db, + http, + timer, + cryptoWorkerFactory, + config ?? {}, + ); } get client(): WalletCoreApiClient { @@ -1586,29 +1574,22 @@ export class Wallet { return this._client; } - /** - * Trust the exchange, do not validate signatures. - * Only used to benchmark the exchange. - */ - setInsecureTrustExchange(): void { - this.ws.insecureTrustExchange = true; - } - - setBatchWithdrawal(enable: boolean): void { - this.ws.batchWithdrawal = enable; - } - static async create( db: DbAccess, http: HttpRequestLibrary, timer: TimerAPI, cryptoWorkerFactory: CryptoWorkerFactory, + config?: WalletConfigParameter, ): Promise { - const w = new Wallet(db, http, timer, cryptoWorkerFactory); + const w = new Wallet(db, http, timer, cryptoWorkerFactory, config); w._client = await getClientFromWalletState(w.ws); return w; } + static getDefaultConfig(): Readonly { + return InternalWalletStateImpl.defaultConfig; + } + addNotificationListener(f: (n: WalletNotification) => void): void { return this.ws.addNotificationListener(f); } @@ -1650,10 +1631,6 @@ class InternalWalletStateImpl implements InternalWalletState { merchantInfoCache: Record = {}; - insecureTrustExchange = false; - - batchWithdrawal = false; - readonly timerGroup: TimerGroup; latch = new AsyncCondition(); stopped = false; @@ -1662,8 +1639,6 @@ class InternalWalletStateImpl implements InternalWalletState { initCalled = false; - devModeActive = false; - exchangeOps: ExchangeOperations = { getExchangeDetails, getExchangeTrust, @@ -1696,6 +1671,31 @@ class InternalWalletStateImpl implements InternalWalletState { */ private resourceLocks: Set = new Set(); + config: Readonly; + + public static defaultConfig: Readonly = { + builtin: { + exchanges: ["https://exchange.demo.taler.net/"], + auditors: [ + { + currency: "KUDOS", + auditorPub: "BW9DC48PHQY4NH011SHHX36DZZ3Q22Y6X7FZ1VD1CMZ2PTFZ6PN0", + auditorBaseUrl: "https://auditor.demo.taler.net/", + uids: ["5P25XF8TVQP9AW6VYGY2KV47WT5Y3ZXFSJAA570GJPX5SVJXKBVG"], + }, + ], + }, + features: { + batchWithdrawal: false, + allowHttp: false, + }, + testing: { + devModeActive: false, + insecureTrustExchange: false, + denomselAllowLate: false, + }, + }; + constructor( // FIXME: Make this a getter and make // the actual value nullable. @@ -1705,10 +1705,15 @@ class InternalWalletStateImpl implements InternalWalletState { public http: HttpRequestLibrary, public timer: TimerAPI, cryptoWorkerFactory: CryptoWorkerFactory, + config: WalletConfigParameter, ) { this.cryptoDispatcher = new CryptoDispatcher(cryptoWorkerFactory); this.cryptoApi = this.cryptoDispatcher.cryptoApi; this.timerGroup = new TimerGroup(timer); + this.config = deepMerge(InternalWalletStateImpl.defaultConfig, config); + if (this.config.testing.devModeActive) { + this.http = new DevExperimentHttpLib(this.http); + } } async getDenomInfo( @@ -1808,3 +1813,29 @@ class InternalWalletStateImpl implements InternalWalletState { } } } + +/** + * Take the full object as template, create a new result with all the values. + * Use the override object to change the values in the result + * return result + * @param full + * @param override + * @returns + */ +function deepMerge( + full: T, + override: RecursivePartial, +): T { + const keys = Object.keys(full); + const result = { ...full }; + for (const k of keys) { + // @ts-ignore + const newVal = override[k]; + if (newVal === undefined) continue; + // @ts-ignore + result[k] = + // @ts-ignore + typeof newVal === "object" ? deepMerge(full[k], newVal) : newVal; + } + return result; +} -- cgit v1.2.3