/* This file is part of GNU Taler (C) 2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see */ /** * Implementation of dev experiments, i.e. scenarios * triggered by taler://dev-experiment URIs. * * @author Florian Dold */ /** * Imports. */ import { Logger, RefreshReason, TalerPreciseTimestamp, encodeCrock, getRandomBytes, parseDevExperimentUri, } from "@gnu-taler/taler-util"; import { HttpRequestLibrary, HttpRequestOptions, HttpResponse, } from "@gnu-taler/taler-util/http"; import { RefreshGroupRecord, RefreshOperationStatus, timestampPreciseToDb, } from "./db.js"; import { WalletExecutionContext } from "./wallet.js"; const logger = new Logger("dev-experiments.ts"); /** * Apply a dev experiment to the wallet database / state. */ export async function applyDevExperiment( wex: WalletExecutionContext, uri: string, ): Promise { logger.info(`applying dev experiment ${uri}`); const parsedUri = parseDevExperimentUri(uri); if (!parsedUri) { logger.info("unable to parse dev experiment URI"); return; } if (!wex.ws.config.testing.devModeActive) { throw Error( "can't handle devmode URI (other than enable-devmode) unless devmode is active", ); } if (parsedUri.devExperimentId == "insert-pending-refresh") { await wex.db.runReadWriteTx(["refreshGroups"], async (tx) => { const refreshGroupId = encodeCrock(getRandomBytes(32)); const newRg: RefreshGroupRecord = { currency: "TESTKUDOS", expectedOutputPerCoin: [], inputPerCoin: [], oldCoinPubs: [], operationStatus: RefreshOperationStatus.Pending, reason: RefreshReason.Manual, refreshGroupId, statusPerCoin: [], timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()), timestampFinished: undefined, originatingTransactionId: undefined, infoPerExchange: {}, }; await tx.refreshGroups.put(newRg); }); return; } throw Error(`dev-experiment id not understood ${parsedUri.devExperimentId}`); } export class DevExperimentHttpLib implements HttpRequestLibrary { _isDevExperimentLib = true; underlyingLib: HttpRequestLibrary; constructor(lib: HttpRequestLibrary) { this.underlyingLib = lib; } fetch( url: string, opt?: HttpRequestOptions | undefined, ): Promise { logger.trace(`devexperiment httplib ${url}`); return this.underlyingLib.fetch(url, opt); } }