aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/platform
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/platform
parent8a98a5f880b9559312779232b6086016c008969b (diff)
downloadwallet-core-7873571d225347aa2174b6d8943d9df820f8817c.tar.xz
add typecheck to background operations
Diffstat (limited to 'packages/taler-wallet-webextension/src/platform')
-rw-r--r--packages/taler-wallet-webextension/src/platform/api.ts41
-rw-r--r--packages/taler-wallet-webextension/src/platform/chrome.ts80
-rw-r--r--packages/taler-wallet-webextension/src/platform/dev.ts27
3 files changed, 91 insertions, 57 deletions
diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts
index 37546d2df..7df190303 100644
--- a/packages/taler-wallet-webextension/src/platform/api.ts
+++ b/packages/taler-wallet-webextension/src/platform/api.ts
@@ -15,6 +15,8 @@
*/
import { CoreApiResponse, NotificationType } from "@gnu-taler/taler-util";
+import { WalletOperations } from "@gnu-taler/taler-wallet-core";
+import { BackgroundOperations } from "../wxApi.js";
export interface Permissions {
/**
@@ -50,6 +52,30 @@ export type MessageFromBackend = {
type: NotificationType;
};
+export type MessageFromFrontend<
+ Op extends BackgroundOperations | WalletOperations,
+> = Op extends BackgroundOperations
+ ? MessageFromFrontendBackground<keyof BackgroundOperations>
+ : Op extends WalletOperations
+ ? MessageFromFrontendWallet<keyof WalletOperations>
+ : never;
+
+export type MessageFromFrontendBackground<
+ Op extends keyof BackgroundOperations,
+> = {
+ channel: "background";
+ operation: Op;
+ payload: BackgroundOperations[Op]["request"];
+};
+
+export type MessageFromFrontendWallet<Op extends keyof WalletOperations> = {
+ channel: "wallet";
+ operation: Op;
+ payload: WalletOperations[Op]["request"];
+};
+
+export type MessageResponse = CoreApiResponse;
+
export interface WalletWebExVersion {
version_name?: string | undefined;
version: string;
@@ -183,10 +209,9 @@ export interface PlatformAPI {
*
* @return response from the backend
*/
- sendMessageToWalletBackground(
- operation: string,
- payload: any,
- ): Promise<CoreApiResponse>;
+ sendMessageToBackground<Op extends WalletOperations | BackgroundOperations>(
+ message: MessageFromFrontend<Op>,
+ ): Promise<MessageResponse>;
/**
* Used from the frontend to receive notifications about new information
@@ -204,11 +229,9 @@ export interface PlatformAPI {
* @param onNewMessage
*/
listenToAllChannels(
- onNewMessage: (
- message: any,
- sender: any,
- sendResponse: (r: CoreApiResponse) => void,
- ) => void,
+ notifyNewMessage: <Op extends WalletOperations | BackgroundOperations>(
+ message: MessageFromFrontend<Op> & { id: string },
+ ) => Promise<MessageResponse>,
): void;
/**
diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts
index 7785e19ef..f951685d2 100644
--- a/packages/taler-wallet-webextension/src/platform/chrome.ts
+++ b/packages/taler-wallet-webextension/src/platform/chrome.ts
@@ -20,9 +20,13 @@ import {
Logger,
TalerUriType,
} from "@gnu-taler/taler-util";
+import { WalletOperations } from "@gnu-taler/taler-wallet-core";
+import { BackgroundOperations } from "../wxApi.js";
import {
CrossBrowserPermissionsApi,
MessageFromBackend,
+ MessageFromFrontend,
+ MessageResponse,
Permissions,
PlatformAPI,
} from "./api.js";
@@ -41,11 +45,11 @@ const api: PlatformAPI = {
redirectTabToWalletPage,
registerAllIncomingConnections,
registerOnInstalled,
- listenToAllChannels,
+ listenToAllChannels: listenToAllChannels as any,
registerReloadOnNewVersion,
registerTalerHeaderListener,
sendMessageToAllChannels,
- sendMessageToWalletBackground,
+ sendMessageToBackground,
useServiceWorkerAsBackgroundProcess,
containsTalerHeaderListener,
keepAlive,
@@ -302,30 +306,22 @@ function openWalletPageFromPopup(page: string): void {
let i = 0;
-async function sendMessageToWalletBackground(
- operation: string,
- payload: any,
-): Promise<any> {
- return new Promise<any>((resolve, reject) => {
- logger.trace("send operation to the wallet background", operation);
- chrome.runtime.sendMessage(
- { operation, payload, id: `id_${i++ % 1000}` },
- (backgroundResponse) => {
- logger.trace(
- "BUG: got response from background",
- backgroundResponse,
- chrome.runtime.lastError,
- );
+async function sendMessageToBackground<
+ Op extends WalletOperations | BackgroundOperations,
+>(message: MessageFromFrontend<Op>): Promise<MessageResponse> {
+ const messageWithId = { ...message, id: `id_${i++ % 1000}` };
- if (chrome.runtime.lastError) {
- reject(chrome.runtime.lastError.message);
- } else {
- resolve(backgroundResponse);
- }
- // return true to keep the channel open
- return true;
- },
- );
+ return new Promise<any>((resolve, reject) => {
+ logger.trace("send operation to the wallet background", message);
+ chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => {
+ if (chrome.runtime.lastError) {
+ reject(chrome.runtime.lastError.message);
+ } else {
+ resolve(backgroundResponse);
+ }
+ // return true to keep the channel open
+ return true;
+ });
});
}
@@ -377,21 +373,27 @@ function registerAllIncomingConnections(): void {
}
function listenToAllChannels(
- cb: (
- message: any,
- sender: any,
- callback: (r: CoreApiResponse) => void,
- ) => void,
+ notifyNewMessage: <Op extends WalletOperations | BackgroundOperations>(
+ message: MessageFromFrontend<Op> & { id: string },
+ ) => Promise<MessageResponse>,
): void {
- chrome.runtime.onMessage.addListener((m, s, c) => {
- cb(m, s, (apiResponse) => {
- logger.trace("BUG: sending response to client", apiResponse);
- try {
- c(apiResponse);
- } catch (e) {
- logger.error("wallet operation ended with error", e);
- }
- });
+ chrome.runtime.onMessage.addListener((message, sender, reply) => {
+ notifyNewMessage(message)
+ .then((apiResponse) => {
+ try {
+ reply(apiResponse);
+ } catch (e) {
+ logger.error(
+ "sending response to frontend failed",
+ message,
+ apiResponse,
+ e,
+ );
+ }
+ })
+ .catch((e) => {
+ logger.error("notify to background failed", e);
+ });
// keep the connection open
return true;
diff --git a/packages/taler-wallet-webextension/src/platform/dev.ts b/packages/taler-wallet-webextension/src/platform/dev.ts
index 8a410b062..df40b29e7 100644
--- a/packages/taler-wallet-webextension/src/platform/dev.ts
+++ b/packages/taler-wallet-webextension/src/platform/dev.ts
@@ -15,7 +15,14 @@
*/
import { CoreApiResponse } from "@gnu-taler/taler-util";
-import { MessageFromBackend, PlatformAPI } from "./api.js";
+import { WalletOperations } from "@gnu-taler/taler-wallet-core";
+import { BackgroundOperations } from "../wxApi.js";
+import {
+ MessageFromBackend,
+ MessageFromFrontend,
+ MessageResponse,
+ PlatformAPI,
+} from "./api.js";
const frames = ["popup", "wallet"];
@@ -121,12 +128,17 @@ const api: PlatformAPI = {
window.parent.removeEventListener("message", listener);
};
},
- sendMessageToWalletBackground: async (operation: string, payload: any) => {
+
+ sendMessageToBackground: async <
+ Op extends WalletOperations | BackgroundOperations,
+ >(
+ payload: MessageFromFrontend<Op>,
+ ): Promise<MessageResponse> => {
const replyMe = `reply-${Math.floor(Math.random() * 100000)}`;
const message: IframeMessageCommand = {
type: "command",
header: { replyMe },
- body: { operation, payload, id: "(none)" },
+ body: payload,
};
window.parent.postMessage(message);
@@ -150,6 +162,7 @@ type IframeMessageType =
| IframeMessageNotification
| IframeMessageResponse
| IframeMessageCommand;
+
interface IframeMessageNotification {
type: "notification";
header: Record<string, never>;
@@ -160,7 +173,7 @@ interface IframeMessageResponse {
header: {
responseId: string;
};
- body: CoreApiResponse;
+ body: MessageResponse;
}
interface IframeMessageCommand {
@@ -168,11 +181,7 @@ interface IframeMessageCommand {
header: {
replyMe: string;
};
- body: {
- operation: any;
- id: string;
- payload: any;
- };
+ body: MessageFromFrontend<any>;
}
export default api;