From ded00b680a776d03cd8c928354c87c0be8690f56 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 12 Oct 2022 22:27:50 +0200 Subject: wallet-core: implement enabling/disabling dev mode --- packages/taler-wallet-core/src/dev-experiments.ts | 118 +++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) (limited to 'packages/taler-wallet-core/src/dev-experiments.ts') diff --git a/packages/taler-wallet-core/src/dev-experiments.ts b/packages/taler-wallet-core/src/dev-experiments.ts index 8e2ce5882..c3167b3e4 100644 --- a/packages/taler-wallet-core/src/dev-experiments.ts +++ b/packages/taler-wallet-core/src/dev-experiments.ts @@ -25,14 +25,130 @@ * Imports. */ -import { Logger } from "@gnu-taler/taler-util"; +import { Logger, parseDevExperimentUri } from "@gnu-taler/taler-util"; +import { ConfigRecordKey } from "./db.js"; import { InternalWalletState } from "./internal-wallet-state.js"; +import { + HttpRequestLibrary, + HttpRequestOptions, + HttpResponse, +} from "./util/http.js"; const logger = new Logger("dev-experiments.ts"); +/** + * Apply a dev experiment to the wallet database / state. + */ export async function applyDevExperiment( ws: InternalWalletState, 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 (parsedUri.devExperimentId == "enable-devmode") { + logger.info("enabling devmode"); + await ws.db + .mktx((x) => [x.config]) + .runReadWrite(async (tx) => { + tx.config.put({ + key: ConfigRecordKey.DevMode, + value: true, + }); + }); + await maybeInitDevMode(ws); + return; + } + if (parsedUri.devExperimentId === "disable-devmode") { + logger.info("disabling devmode"); + await ws.db + .mktx((x) => [x.config]) + .runReadWrite(async (tx) => { + tx.config.put({ + key: ConfigRecordKey.DevMode, + value: false, + }); + }); + await leaveDevMode(ws); + return; + } + if (!ws.devModeActive) { + throw Error( + "can't handle devmode URI (other than enable-devmode) unless devmode is active", + ); + } + throw Error(`dev-experiment id not understood ${parsedUri.devExperimentId}`); +} + +/** + * Enter dev mode, if the wallet's config entry in the DB demands it. + */ +export async function maybeInitDevMode(ws: InternalWalletState): Promise { + const devMode = await ws.db + .mktx((x) => [x.config]) + .runReadOnly(async (tx) => { + const rec = await tx.config.get(ConfigRecordKey.DevMode); + if (!rec || rec.key !== ConfigRecordKey.DevMode) { + return false; + } + return rec.value; + }); + if (!devMode) { + ws.devModeActive = false; + return; + } + ws.devModeActive = true; + if (ws.http instanceof DevExperimentHttpLib) { + return; + } + ws.http = new DevExperimentHttpLib(ws.http); +} + +export async function leaveDevMode(ws: InternalWalletState): Promise { + if (ws.http instanceof DevExperimentHttpLib) { + ws.http = ws.http.underlyingLib; + } + ws.devModeActive = false; +} + +export class DevExperimentHttpLib implements HttpRequestLibrary { + _isDevExperimentLib = true; + underlyingLib: HttpRequestLibrary; + + constructor(lib: HttpRequestLibrary) { + this.underlyingLib = lib; + } + + get( + url: string, + opt?: HttpRequestOptions | undefined, + ): Promise { + return this.fetch(url, { + method: "GET", + ...opt, + }); + } + + postJson( + url: string, + body: any, + opt?: HttpRequestOptions | undefined, + ): Promise { + return this.fetch(url, { + method: "POST", + body, + ...opt, + }); + } + + fetch( + url: string, + opt?: HttpRequestOptions | undefined, + ): Promise { + logger.info(`devexperiment httplib ${url}`); + return this.underlyingLib.fetch(url, opt); + } } -- cgit v1.2.3