summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/wxBackend.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-12-21 16:21:25 -0300
committerSebastian <sebasjm@gmail.com>2022-12-21 16:24:18 -0300
commit7873571d225347aa2174b6d8943d9df820f8817c (patch)
tree44bea29c1e2d0b270d745e8eaf0247d477d50b8c /packages/taler-wallet-webextension/src/wxBackend.ts
parent8a98a5f880b9559312779232b6086016c008969b (diff)
downloadwallet-core-7873571d225347aa2174b6d8943d9df820f8817c.tar.gz
wallet-core-7873571d225347aa2174b6d8943d9df820f8817c.tar.bz2
wallet-core-7873571d225347aa2174b6d8943d9df820f8817c.zip
add typecheck to background operations
Diffstat (limited to 'packages/taler-wallet-webextension/src/wxBackend.ts')
-rw-r--r--packages/taler-wallet-webextension/src/wxBackend.ts201
1 files changed, 114 insertions, 87 deletions
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts
index 28adfa037..c94b390ff 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -25,8 +25,6 @@
*/
import {
classifyTalerUri,
- CoreApiResponse,
- CoreApiResponseSuccess,
Logger,
TalerErrorCode,
TalerUriType,
@@ -36,20 +34,27 @@ import {
DbAccess,
deleteTalerDatabase,
exportDb,
+ getErrorDetailFromException,
importDb,
makeErrorDetail,
OpenedPromise,
openPromise,
openTalerDatabase,
+ SetTimeoutTimerAPI,
Wallet,
+ WalletOperations,
WalletStoresV1,
} from "@gnu-taler/taler-wallet-core";
-import { SetTimeoutTimerAPI } from "@gnu-taler/taler-wallet-core";
-import { BrowserCryptoWorkerFactory } from "./browserCryptoWorkerFactory.js";
import { BrowserHttpLib } from "./browserHttpLib.js";
-import { MessageFromBackend, platform } from "./platform/api.js";
+import {
+ MessageFromBackend,
+ MessageFromFrontend,
+ MessageResponse,
+ platform,
+} from "./platform/api.js";
import { SynchronousCryptoWorkerFactory } from "./serviceWorkerCryptoWorkerFactory.js";
import { ServiceWorkerHttpLib } from "./serviceWorkerHttpLib.js";
+import { BackgroundOperations, ExtendedPermissionsResponse } from "./wxApi.js";
/**
* Currently active wallet instance. Might be unloaded and
@@ -107,92 +112,115 @@ async function getDiagnostics(): Promise<WalletDiagnostics> {
return diagnostics;
}
-async function dispatch(
- req: any,
- sender: any,
- sendResponse: any,
-): Promise<void> {
- let r: CoreApiResponse;
+type BackendHandlerType = {
+ [Op in keyof BackgroundOperations]: (
+ req: BackgroundOperations[Op]["request"],
+ ) => Promise<BackgroundOperations[Op]["response"]>;
+};
+
+async function containsHeaderListener(): Promise<ExtendedPermissionsResponse> {
+ const result = await platform.containsTalerHeaderListener();
+ return { newValue: result };
+}
+
+async function resetDb(): Promise<void> {
+ await deleteTalerDatabase(indexedDB as any);
+ await reinitWallet();
+}
+
+async function runGarbageCollector(): Promise<void> {
+ const dbBeforeGc = currentDatabase;
+ if (!dbBeforeGc) {
+ throw Error("no current db before running gc");
+ }
+ const dump = await exportDb(dbBeforeGc.idbHandle());
+
+ await deleteTalerDatabase(indexedDB as any);
+ logger.info("cleaned");
+ await reinitWallet();
+ logger.info("init");
+
+ const dbAfterGc = currentDatabase;
+ if (!dbAfterGc) {
+ throw Error("no current db before running gc");
+ }
+ await importDb(dbAfterGc.idbHandle(), dump);
+ logger.info("imported");
+}
+
+async function toggleHeaderListener(
+ newVal: boolean,
+): Promise<ExtendedPermissionsResponse> {
+ logger.trace("new extended permissions value", newVal);
+ if (newVal) {
+ platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
+ return { newValue: true };
+ }
+
+ const rem = await platform.getPermissionsApi().removeHostPermissions();
+ logger.trace("permissions removed:", rem);
+ return { newValue: false };
+}
- const wrapResponse = (result: unknown): CoreApiResponseSuccess => {
+const backendHandlers: BackendHandlerType = {
+ containsHeaderListener,
+ getDiagnostics,
+ resetDb,
+ runGarbageCollector,
+ toggleHeaderListener,
+};
+
+async function dispatch<Op extends WalletOperations | BackgroundOperations>(
+ req: MessageFromFrontend<Op> & { id: string },
+): Promise<MessageResponse> {
+ if (req.channel === "background") {
+ const handler = backendHandlers[req.operation] as (req: any) => any;
+ if (!handler) {
+ return {
+ type: "error",
+ id: req.id,
+ operation: String(req.operation),
+ error: getErrorDetailFromException(
+ Error(`unknown background operation`),
+ ),
+ };
+ }
+ const result = await handler(req.payload);
return {
type: "response",
id: req.id,
- operation: req.operation,
+ operation: String(req.operation),
result,
};
- };
+ }
- try {
- switch (req.operation) {
- case "wxGetDiagnostics": {
- r = wrapResponse(await getDiagnostics());
- break;
- }
- case "reset-db": {
- await deleteTalerDatabase(indexedDB as any);
- r = wrapResponse(await reinitWallet());
- break;
- }
- case "run-gc": {
- logger.info("gc");
- const dump = await exportDb(currentDatabase!.idbHandle());
- await deleteTalerDatabase(indexedDB as any);
- logger.info("cleaned");
- await reinitWallet();
- logger.info("init");
- await importDb(currentDatabase!.idbHandle(), dump);
- logger.info("imported");
- r = wrapResponse({ result: true });
- break;
- }
- case "containsHeaderListener": {
- const res = await platform.containsTalerHeaderListener();
- r = wrapResponse({ newValue: res });
- break;
- }
- //FIXME: implement type checked api like WalletCoreApi
- case "toggleHeaderListener": {
- const newVal = req.payload.value;
- logger.trace("new extended permissions value", newVal);
- if (newVal) {
- platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
- r = wrapResponse({ newValue: true });
- } else {
- const rem = await platform
- .getPermissionsApi()
- .removeHostPermissions();
- logger.trace("permissions removed:", rem);
- r = wrapResponse({ newVal: false });
- }
- break;
- }
- default: {
- const w = currentWallet;
- if (!w) {
- r = {
- type: "error",
- id: req.id,
- operation: req.operation,
- error: makeErrorDetail(
- TalerErrorCode.WALLET_CORE_NOT_AVAILABLE,
- {},
- "wallet core not available",
- ),
- };
- break;
- }
- r = await w.handleCoreApiRequest(req.operation, req.id, req.payload);
- console.log("response received from wallet", r);
- break;
- }
+ if (req.channel === "wallet") {
+ const w = currentWallet;
+ if (!w) {
+ return {
+ type: "error",
+ id: req.id,
+ operation: req.operation,
+ error: makeErrorDetail(
+ TalerErrorCode.WALLET_CORE_NOT_AVAILABLE,
+ {},
+ "wallet core not available",
+ ),
+ };
}
- sendResponse(r);
- } catch (e) {
- logger.error(`Error sending operation: ${req.operation}`, e);
- // might fail if tab disconnected
+ return await w.handleCoreApiRequest(req.operation, req.id, req.payload);
}
+
+ const anyReq = req as any;
+ return {
+ type: "error",
+ id: anyReq.id,
+ operation: String(anyReq.operation),
+ error: getErrorDetailFromException(
+ Error(`unknown channel ${anyReq.channel}`),
+ ),
+ };
}
async function reinitWallet(): Promise<void> {
@@ -328,12 +356,11 @@ export async function wxMain(): Promise<void> {
// Handlers for messages coming directly from the content
// script on the page
- platform.listenToAllChannels((message, sender, callback) => {
- afterWalletIsInitialized.then(() => {
- dispatch(message, sender, (response: CoreApiResponse) => {
- callback(response);
- });
- });
+ platform.listenToAllChannels(async (message) => {
+ //wait until wallet is initialized
+ await afterWalletIsInitialized;
+ const result = await dispatch(message);
+ return result;
});
platform.registerAllIncomingConnections();