diff options
author | Sebastian <sebasjm@gmail.com> | 2022-12-21 16:21:25 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-12-21 16:24:18 -0300 |
commit | 7873571d225347aa2174b6d8943d9df820f8817c (patch) | |
tree | 44bea29c1e2d0b270d745e8eaf0247d477d50b8c /packages/taler-wallet-webextension/src/platform | |
parent | 8a98a5f880b9559312779232b6086016c008969b (diff) | |
download | wallet-core-7873571d225347aa2174b6d8943d9df820f8817c.tar.xz |
add typecheck to background operations
Diffstat (limited to 'packages/taler-wallet-webextension/src/platform')
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; |