From fb6aff76d2152d95caa2ba6cb0d91cb01e0687fe Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 6 Jun 2022 00:09:25 -0300 Subject: prettier --- .../taler-wallet-webextension/src/platform/api.ts | 90 +++-- .../src/platform/chrome.ts | 397 ++++++++++++--------- .../taler-wallet-webextension/src/platform/dev.ts | 149 ++++---- .../src/platform/firefox.ts | 30 +- 4 files changed, 375 insertions(+), 291 deletions(-) (limited to 'packages/taler-wallet-webextension/src/platform') diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts index 4713d5d00..e66185b95 100644 --- a/packages/taler-wallet-webextension/src/platform/api.ts +++ b/packages/taler-wallet-webextension/src/platform/api.ts @@ -22,12 +22,11 @@ export interface Permissions { */ permissions?: string[] | undefined; /** - * List of origin permissions. Anything listed here must be a subset of a - * host that appears in the optional_permissions list in the manifest. - * + * List of origin permissions. Anything listed here must be a subset of a + * host that appears in the optional_permissions list in the manifest. + * */ origins?: string[] | undefined; - } /** @@ -38,8 +37,9 @@ export interface CrossBrowserPermissionsApi { requestHostPermissions(): Promise; removeHostPermissions(): Promise; - addPermissionsListener(callback: (p: Permissions, lastError?: string) => void): void; - + addPermissionsListener( + callback: (p: Permissions, lastError?: string) => void, + ): void; } export type MessageFromBackend = { @@ -57,12 +57,12 @@ export interface WalletVersion { */ export interface PlatformAPI { /** - * Garantee that the + * Garantee that the */ keepAlive(cb: VoidFunction): void; /** * FIXME: should not be needed - * + * * check if the platform is firefox */ isFirefox(): boolean; @@ -74,46 +74,46 @@ export interface PlatformAPI { /** * Backend API - * + * * Register a callback to be called when the wallet is ready to start - * @param callback + * @param callback */ notifyWhenAppIsReady(callback: () => void): void; /** * Popup API - * + * * Used when an TalerURI is found and open up from the popup UI. * Closes the popup and open the URI into the wallet UI. - * - * @param talerUri + * + * @param talerUri */ openWalletURIFromPopup(talerUri: string): void; /** * Backend API - * + * * Open a page into the wallet UI - * @param page + * @param page */ openWalletPage(page: string): void; /** * Popup API - * + * * Open a page into the wallet UI and closed the popup - * @param page + * @param page */ openWalletPageFromPopup(page: string): void; /** * Backend API - * + * * When a tab has been detected to have a Taler action the background process * can use this function to redirect the tab to the wallet UI - * - * @param tabId - * @param page + * + * @param tabId + * @param page */ redirectTabToWalletPage(tabId: number, page: string): void; @@ -122,7 +122,6 @@ export interface PlatformAPI { */ getWalletVersion(): WalletVersion; - /** * Backend API */ @@ -134,7 +133,9 @@ export interface PlatformAPI { /** * Backend API */ - registerTalerHeaderListener(onHeader: (tabId: number, url: string) => void): void; + registerTalerHeaderListener( + onHeader: (tabId: number, url: string) => void, + ): void; /** * Frontend API */ @@ -146,49 +147,60 @@ export interface PlatformAPI { /** * Backend API - * - * Check if background process run as service worker. This is used from the + * + * Check if background process run as service worker. This is used from the * wallet use different http api and crypto worker. */ useServiceWorkerAsBackgroundProcess(): boolean; /** * Popup API - * + * * Read the current tab html and try to find any Taler URI or QR code present. - * + * * @return Taler URI if found */ findTalerUriInActiveTab(): Promise; /** * Used from the frontend to send commands to the wallet - * - * @param operation - * @param payload - * + * + * @param operation + * @param payload + * * @return response from the backend */ - sendMessageToWalletBackground(operation: string, payload: any): Promise; + sendMessageToWalletBackground( + operation: string, + payload: any, + ): Promise; /** * Used from the frontend to receive notifications about new information - * @param listener - * @return function to unsubscribe the listener + * @param listener + * @return function to unsubscribe the listener */ - listenToWalletBackground(listener: (message: MessageFromBackend) => void): () => void; + listenToWalletBackground( + listener: (message: MessageFromBackend) => void, + ): () => void; /** * Use by the wallet backend to receive operations from frontend (popup & wallet) * and send a response back. - * - * @param onNewMessage + * + * @param onNewMessage */ - listenToAllChannels(onNewMessage: (message: any, sender: any, sendResponse: (r: CoreApiResponse) => void) => void): void; + listenToAllChannels( + onNewMessage: ( + message: any, + sender: any, + sendResponse: (r: CoreApiResponse) => void, + ) => void, + ): void; /** * Used by the wallet backend to send notification about new information - * @param message + * @param message */ sendMessageToAllChannels(message: MessageFromBackend): void; } diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts index e097baaa1..9caf42a58 100644 --- a/packages/taler-wallet-webextension/src/platform/chrome.ts +++ b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -15,8 +15,18 @@ TALER; see the file COPYING. If not, see */ -import { classifyTalerUri, CoreApiResponse, Logger, TalerUriType } from "@gnu-taler/taler-util"; -import { CrossBrowserPermissionsApi, MessageFromBackend, Permissions, PlatformAPI } from "./api.js"; +import { + classifyTalerUri, + CoreApiResponse, + Logger, + TalerUriType, +} from "@gnu-taler/taler-util"; +import { + CrossBrowserPermissionsApi, + MessageFromBackend, + Permissions, + PlatformAPI, +} from "./api.js"; const api: PlatformAPI = { isFirefox, @@ -39,7 +49,7 @@ const api: PlatformAPI = { useServiceWorkerAsBackgroundProcess, containsTalerHeaderListener, keepAlive, -} +}; export default api; @@ -47,16 +57,15 @@ const logger = new Logger("chrome.ts"); function keepAlive(callback: any): void { if (extensionIsManifestV3()) { - chrome.alarms.create("wallet-worker", { periodInMinutes: 1 }) + chrome.alarms.create("wallet-worker", { periodInMinutes: 1 }); chrome.alarms.onAlarm.addListener((a) => { - logger.trace(`kee p alive alarm: ${a.name}`) + logger.trace(`kee p alive alarm: ${a.name}`); // callback() - }) + }); // } else { } callback(); - } function isFirefox(): boolean { @@ -66,34 +75,35 @@ function isFirefox(): boolean { const hostPermissions = { permissions: ["webRequest"], origins: ["http://*/*", "https://*/*"], -} - +}; export function containsHostPermissions(): Promise { return new Promise((res, rej) => { chrome.permissions.contains(hostPermissions, (resp) => { - const le = chrome.runtime.lastError?.message + const le = chrome.runtime.lastError?.message; if (le) { - rej(le) + rej(le); } - res(resp) - }) - }) + res(resp); + }); + }); } export async function requestHostPermissions(): Promise { return new Promise((res, rej) => { chrome.permissions.request(hostPermissions, (resp) => { - const le = chrome.runtime.lastError?.message + const le = chrome.runtime.lastError?.message; if (le) { - rej(le) + rej(le); } - res(resp) - }) - }) + res(resp); + }); + }); } -type HeaderListenerFunc = (details: chrome.webRequest.WebResponseHeadersDetails) => void +type HeaderListenerFunc = ( + details: chrome.webRequest.WebResponseHeadersDetails, +) => void; let currentHeaderListener: HeaderListenerFunc | undefined = undefined; export function containsTalerHeaderListener(): boolean { @@ -128,57 +138,69 @@ export async function removeHostPermissions(): Promise { } return new Promise((res, rej) => { chrome.permissions.remove(hostPermissions, (resp) => { - const le = chrome.runtime.lastError?.message + const le = chrome.runtime.lastError?.message; if (le) { - rej(le) + rej(le); } - res(resp) - }) - }) + res(resp); + }); + }); } -function addPermissionsListener(callback: (p: Permissions, lastError?: string) => void): void { +function addPermissionsListener( + callback: (p: Permissions, lastError?: string) => void, +): void { chrome.permissions.onAdded.addListener((perm: Permissions) => { const lastError = chrome.runtime.lastError?.message; - callback(perm, lastError) - }) + callback(perm, lastError); + }); } function getPermissionsApi(): CrossBrowserPermissionsApi { return { - addPermissionsListener, containsHostPermissions, requestHostPermissions, removeHostPermissions - } + addPermissionsListener, + containsHostPermissions, + requestHostPermissions, + removeHostPermissions, + }; } /** - * + * * @param callback function to be called */ function notifyWhenAppIsReady(callback: () => void): void { if (extensionIsManifestV3()) { - callback() + callback(); } else { window.addEventListener("load", callback); } } - function openWalletURIFromPopup(talerUri: string): void { const uriType = classifyTalerUri(talerUri); let url: string | undefined = undefined; switch (uriType) { case TalerUriType.TalerWithdraw: - url = chrome.runtime.getURL(`static/wallet.html#/cta/withdraw?talerWithdrawUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/withdraw?talerWithdrawUri=${talerUri}`, + ); break; case TalerUriType.TalerPay: - url = chrome.runtime.getURL(`static/wallet.html#/cta/pay?talerPayUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/pay?talerPayUri=${talerUri}`, + ); break; case TalerUriType.TalerTip: - url = chrome.runtime.getURL(`static/wallet.html#/cta/tip?talerTipUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/tip?talerTipUri=${talerUri}`, + ); break; case TalerUriType.TalerRefund: - url = chrome.runtime.getURL(`static/wallet.html#/cta/refund?talerRefundUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/refund?talerRefundUri=${talerUri}`, + ); break; default: logger.warn( @@ -187,56 +209,54 @@ function openWalletURIFromPopup(talerUri: string): void { return; } - chrome.tabs.create( - { active: true, url, }, - () => { window.close(); }, - ); + chrome.tabs.create({ active: true, url }, () => { + window.close(); + }); } function openWalletPage(page: string): void { - const url = chrome.runtime.getURL(`/static/wallet.html#${page}`) - chrome.tabs.create( - { active: true, url, }, - ); + const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); + chrome.tabs.create({ active: true, url }); } function openWalletPageFromPopup(page: string): void { - const url = chrome.runtime.getURL(`/static/wallet.html#${page}`) - chrome.tabs.create( - { active: true, url, }, - () => { window.close(); }, - ); + const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); + chrome.tabs.create({ active: true, url }, () => { + window.close(); + }); } -async function sendMessageToWalletBackground(operation: string, payload: any): Promise { +async function sendMessageToWalletBackground( + operation: string, + payload: any, +): Promise { return new Promise((resolve, reject) => { - logger.trace("send operation to the wallet background", operation) + logger.trace("send operation to the wallet background", operation); chrome.runtime.sendMessage({ operation, payload, id: "(none)" }, (resp) => { if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError.message) + reject(chrome.runtime.lastError.message); } - resolve(resp) + resolve(resp); // return true to keep the channel open return true; - }) - }) + }); + }); } let notificationPort: chrome.runtime.Port | undefined; function listenToWalletBackground(listener: (m: any) => void): () => void { if (notificationPort === undefined) { - notificationPort = chrome.runtime.connect({ name: "notifications" }) + notificationPort = chrome.runtime.connect({ name: "notifications" }); } - notificationPort.onMessage.addListener(listener) + notificationPort.onMessage.addListener(listener); function removeListener(): void { if (notificationPort !== undefined) { - notificationPort.onMessage.removeListener(listener) + notificationPort.onMessage.removeListener(listener); } } - return removeListener + return removeListener; } - const allPorts: chrome.runtime.Port[] = []; function sendMessageToAllChannels(message: MessageFromBackend): void { @@ -262,9 +282,15 @@ function registerAllIncomingConnections(): void { }); } -function listenToAllChannels(cb: (message: any, sender: any, callback: (r: CoreApiResponse) => void) => void): void { +function listenToAllChannels( + cb: ( + message: any, + sender: any, + callback: (r: CoreApiResponse) => void, + ) => void, +): void { chrome.runtime.onMessage.addListener((m, s, c) => { - cb(m, s, c) + cb(m, s, c); // keep the connection open return true; @@ -278,13 +304,9 @@ function registerReloadOnNewVersion(): void { logger.info("update available:", details); chrome.runtime.reload(); }); - } -function redirectTabToWalletPage( - tabId: number, - page: string, -): void { +function redirectTabToWalletPage(tabId: number, page: string): void { const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); logger.trace("redirecting tabId: ", tabId, " to: ", url); chrome.tabs.update(tabId, { url }); @@ -300,7 +322,9 @@ function getWalletVersion(): WalletVersion { return manifestData; } -function registerTalerHeaderListener(callback: (tabId: number, url: string) => void): void { +function registerTalerHeaderListener( + callback: (tabId: number, url: string) => void, +): void { logger.trace("setting up header listener"); function headerListener( @@ -316,44 +340,45 @@ function registerTalerHeaderListener(callback: (tabId: number, url: string) => v details.statusCode === 200 ) { const values = (details.responseHeaders || []) - .filter(h => h.name.toLowerCase() === 'taler') - .map(h => h.value) - .filter((value): value is string => !!value) + .filter((h) => h.name.toLowerCase() === "taler") + .map((h) => h.value) + .filter((value): value is string => !!value); if (values.length > 0) { - callback(details.tabId, values[0]) + callback(details.tabId, values[0]); } } return; } const prevHeaderListener = currentHeaderListener; - getPermissionsApi().containsHostPermissions().then(result => { - //if there is a handler already, remove it - if ( - prevHeaderListener && - chrome?.webRequest?.onHeadersReceived?.hasListener(prevHeaderListener) - ) { - chrome.webRequest.onHeadersReceived.removeListener(prevHeaderListener); - } - //if the result was positive, add the headerListener - if (result) { - const listener: chrome.webRequest.WebResponseHeadersEvent | undefined = chrome?.webRequest?.onHeadersReceived; - if (listener) { - listener.addListener( - headerListener, - { urls: [""] }, - ["responseHeaders"], - ); - currentHeaderListener = headerListener; + getPermissionsApi() + .containsHostPermissions() + .then((result) => { + //if there is a handler already, remove it + if ( + prevHeaderListener && + chrome?.webRequest?.onHeadersReceived?.hasListener(prevHeaderListener) + ) { + chrome.webRequest.onHeadersReceived.removeListener(prevHeaderListener); } - } - //notify the browser about this change, this operation is expensive - chrome?.webRequest?.handlerBehaviorChanged(() => { - if (chrome.runtime.lastError) { - logger.error(JSON.stringify(chrome.runtime.lastError)); + //if the result was positive, add the headerListener + if (result) { + const listener: chrome.webRequest.WebResponseHeadersEvent | undefined = + chrome?.webRequest?.onHeadersReceived; + if (listener) { + listener.addListener(headerListener, { urls: [""] }, [ + "responseHeaders", + ]); + currentHeaderListener = headerListener; + } } + //notify the browser about this change, this operation is expensive + chrome?.webRequest?.handlerBehaviorChanged(() => { + if (chrome.runtime.lastError) { + logger.error(JSON.stringify(chrome.runtime.lastError)); + } + }); }); - }); } const alertIcons = { @@ -365,8 +390,8 @@ const alertIcons = { "64": "/static/img/taler-alert-64.png", "128": "/static/img/taler-alert-128.png", "256": "/static/img/taler-alert-256.png", - "512": "/static/img/taler-alert-512.png" -} + "512": "/static/img/taler-alert-512.png", +}; const normalIcons = { "16": "/static/img/taler-logo-16.png", "19": "/static/img/taler-logo-19.png", @@ -376,70 +401,99 @@ const normalIcons = { "64": "/static/img/taler-logo-64.png", "128": "/static/img/taler-logo-128.png", "256": "/static/img/taler-logo-256.png", - "512": "/static/img/taler-logo-512.png" -} + "512": "/static/img/taler-logo-512.png", +}; function setNormalIcon(): void { if (extensionIsManifestV3()) { - chrome.action.setIcon({ path: normalIcons }) + chrome.action.setIcon({ path: normalIcons }); } else { - chrome.browserAction.setIcon({ path: normalIcons }) + chrome.browserAction.setIcon({ path: normalIcons }); } } function setAlertedIcon(): void { if (extensionIsManifestV3()) { - chrome.action.setIcon({ path: alertIcons }) + chrome.action.setIcon({ path: alertIcons }); } else { - chrome.browserAction.setIcon({ path: alertIcons }) + chrome.browserAction.setIcon({ path: alertIcons }); } } - -interface OffscreenCanvasRenderingContext2D extends CanvasState, CanvasTransform, CanvasCompositing, CanvasImageSmoothing, CanvasFillStrokeStyles, CanvasShadowStyles, CanvasFilters, CanvasRect, CanvasDrawPath, CanvasUserInterface, CanvasText, CanvasDrawImage, CanvasImageData, CanvasPathDrawingStyles, CanvasTextDrawingStyles, CanvasPath { +interface OffscreenCanvasRenderingContext2D + extends CanvasState, + CanvasTransform, + CanvasCompositing, + CanvasImageSmoothing, + CanvasFillStrokeStyles, + CanvasShadowStyles, + CanvasFilters, + CanvasRect, + CanvasDrawPath, + CanvasUserInterface, + CanvasText, + CanvasDrawImage, + CanvasImageData, + CanvasPathDrawingStyles, + CanvasTextDrawingStyles, + CanvasPath { readonly canvas: OffscreenCanvas; } declare const OffscreenCanvasRenderingContext2D: { prototype: OffscreenCanvasRenderingContext2D; - new(): OffscreenCanvasRenderingContext2D; -} + new (): OffscreenCanvasRenderingContext2D; +}; interface OffscreenCanvas extends EventTarget { width: number; height: number; - getContext(contextId: "2d", contextAttributes?: CanvasRenderingContext2DSettings): OffscreenCanvasRenderingContext2D | null; + getContext( + contextId: "2d", + contextAttributes?: CanvasRenderingContext2DSettings, + ): OffscreenCanvasRenderingContext2D | null; } declare const OffscreenCanvas: { prototype: OffscreenCanvas; - new(width: number, height: number): OffscreenCanvas; -} + new (width: number, height: number): OffscreenCanvas; +}; function createCanvas(size: number): OffscreenCanvas { if (extensionIsManifestV3()) { - return new OffscreenCanvas(size, size) + return new OffscreenCanvas(size, size); } else { - const c = document.createElement("canvas") + const c = document.createElement("canvas"); c.height = size; c.width = size; return c; } } - async function createImage(size: number, file: string): Promise { - const r = await fetch(file) - const b = await r.blob() - const image = await createImageBitmap(b) + const r = await fetch(file); + const b = await r.blob(); + const image = await createImageBitmap(b); const canvas = createCanvas(size); - const canvasContext = canvas.getContext('2d')!; + const canvasContext = canvas.getContext("2d")!; canvasContext.clearRect(0, 0, canvas.width, canvas.height); canvasContext.drawImage(image, 0, 0, canvas.width, canvas.height); - const imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height); + const imageData = canvasContext.getImageData( + 0, + 0, + canvas.width, + canvas.height, + ); return imageData; } async function registerIconChangeOnTalerContent(): Promise { - const imgs = await Promise.all(Object.entries(alertIcons).map(([key, value]) => createImage(parseInt(key, 10), value))) - const imageData = imgs.reduce((prev, cur) => ({ ...prev, [cur.width]: cur }), {} as { [size: string]: ImageData }) + const imgs = await Promise.all( + Object.entries(alertIcons).map(([key, value]) => + createImage(parseInt(key, 10), value), + ), + ); + const imageData = imgs.reduce( + (prev, cur) => ({ ...prev, [cur.width]: cur }), + {} as { [size: string]: ImageData }, + ); if (chrome.declarativeContent) { // using declarative content does not need host permission @@ -447,49 +501,54 @@ async function registerIconChangeOnTalerContent(): Promise { const secureTalerUrlLookup = { conditions: [ new chrome.declarativeContent.PageStateMatcher({ - css: ["a[href^='taler://'"] - }) + css: ["a[href^='taler://'"], + }), ], - actions: [new chrome.declarativeContent.SetIcon({ imageData })] + actions: [new chrome.declarativeContent.SetIcon({ imageData })], }; const inSecureTalerUrlLookup = { conditions: [ new chrome.declarativeContent.PageStateMatcher({ - css: ["a[href^='taler+http://'"] - }) + css: ["a[href^='taler+http://'"], + }), ], - actions: [new chrome.declarativeContent.SetIcon({ imageData })] + actions: [new chrome.declarativeContent.SetIcon({ imageData })], }; chrome.declarativeContent.onPageChanged.removeRules(undefined, function () { - chrome.declarativeContent.onPageChanged.addRules([secureTalerUrlLookup, inSecureTalerUrlLookup]); + chrome.declarativeContent.onPageChanged.addRules([ + secureTalerUrlLookup, + inSecureTalerUrlLookup, + ]); }); return; } //this browser doesn't have declarativeContent //we need host_permission and we will check the content for changing the icon - chrome.tabs.onUpdated.addListener(async (tabId, info: chrome.tabs.TabChangeInfo) => { - if (tabId < 0) return; - logger.info("tab updated", tabId, info); - if (info.status !== "complete") return; - const uri = await findTalerUriInTab(tabId); - if (uri) { - setAlertedIcon() - } else { - setNormalIcon() - } - - }); - chrome.tabs.onActivated.addListener(async ({ tabId }: chrome.tabs.TabActiveInfo) => { - if (tabId < 0) return; - const uri = await findTalerUriInTab(tabId); - if (uri) { - setAlertedIcon() - } else { - setNormalIcon() - } - }) - + chrome.tabs.onUpdated.addListener( + async (tabId, info: chrome.tabs.TabChangeInfo) => { + if (tabId < 0) return; + logger.info("tab updated", tabId, info); + if (info.status !== "complete") return; + const uri = await findTalerUriInTab(tabId); + if (uri) { + setAlertedIcon(); + } else { + setNormalIcon(); + } + }, + ); + chrome.tabs.onActivated.addListener( + async ({ tabId }: chrome.tabs.TabActiveInfo) => { + if (tabId < 0) return; + const uri = await findTalerUriInTab(tabId); + if (uri) { + setAlertedIcon(); + } else { + setNormalIcon(); + } + }, + ); } function registerOnInstalled(callback: () => void): void { @@ -498,27 +557,27 @@ function registerOnInstalled(callback: () => void): void { chrome.runtime.onInstalled.addListener(async (details) => { logger.info(`onInstalled with reason: "${details.reason}"`); if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) { - callback() + callback(); } - registerIconChangeOnTalerContent() + registerIconChangeOnTalerContent(); }); } function extensionIsManifestV3(): boolean { - return chrome.runtime.getManifest().manifest_version === 3 + return chrome.runtime.getManifest().manifest_version === 3; } function useServiceWorkerAsBackgroundProcess(): boolean { - return extensionIsManifestV3() + return extensionIsManifestV3(); } function searchForTalerLinks(): string | undefined { let found; - found = document.querySelector("a[href^='taler://'") - if (found) return found.toString() - found = document.querySelector("a[href^='taler+http://'") - if (found) return found.toString() - return undefined + found = document.querySelector("a[href^='taler://'"); + if (found) return found.toString(); + found = document.querySelector("a[href^='taler+http://'"); + if (found) return found.toString(); + return undefined; } async function getCurrentTab(): Promise { @@ -526,12 +585,12 @@ async function getCurrentTab(): Promise { return new Promise((resolve, reject) => { chrome.tabs.query(queryOptions, (tabs) => { if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError) + reject(chrome.runtime.lastError); return; } - resolve(tabs[0]) + resolve(tabs[0]); }); - }) + }); } async function findTalerUriInTab(tabId: number): Promise { @@ -541,16 +600,17 @@ async function findTalerUriInTab(tabId: number): Promise { const res = await chrome.scripting.executeScript({ target: { tabId, allFrames: true }, func: searchForTalerLinks, - args: [] - }) - return res[0].result + args: [], + }); + return res[0].result; } catch (e) { return; } } else { return new Promise((resolve, reject) => { //manifest v2 - chrome.tabs.executeScript(tabId, + chrome.tabs.executeScript( + tabId, { code: ` (() => { @@ -576,6 +636,5 @@ async function findTalerUriInTab(tabId: number): Promise { async function findTalerUriInActiveTab(): Promise { const tab = await getCurrentTab(); if (!tab || tab.id === undefined) return; - return findTalerUriInTab(tab.id) + return findTalerUriInTab(tab.id); } - diff --git a/packages/taler-wallet-webextension/src/platform/dev.ts b/packages/taler-wallet-webextension/src/platform/dev.ts index 59e6738c5..fbbb4d231 100644 --- a/packages/taler-wallet-webextension/src/platform/dev.ts +++ b/packages/taler-wallet-webextension/src/platform/dev.ts @@ -17,50 +17,55 @@ import { CoreApiResponse } from "@gnu-taler/taler-util"; import { MessageFromBackend, PlatformAPI } from "./api.js"; -const frames = ["popup", "wallet"] +const frames = ["popup", "wallet"]; -const api: PlatformAPI = ({ +const api: PlatformAPI = { isFirefox: () => false, keepAlive: (cb: VoidFunction) => cb(), findTalerUriInActiveTab: async () => undefined, - containsTalerHeaderListener: () => { return true }, + containsTalerHeaderListener: () => { + return true; + }, getPermissionsApi: () => ({ - addPermissionsListener: () => undefined, containsHostPermissions: async () => true, removeHostPermissions: async () => false, requestHostPermissions: async () => false + addPermissionsListener: () => undefined, + containsHostPermissions: async () => true, + removeHostPermissions: async () => false, + requestHostPermissions: async () => false, }), getWalletVersion: () => ({ - version: 'none' + version: "none", }), notifyWhenAppIsReady: (fn: () => void) => { - let total = frames.length + let total = frames.length; function waitAndNotify(): void { - total-- + total--; if (total < 1) { - console.log('done') - fn() + console.log("done"); + fn(); } } - frames.forEach(f => { - const theFrame = window.frames[f as any] - if (theFrame.location.href === 'about:blank') { - waitAndNotify() + frames.forEach((f) => { + const theFrame = window.frames[f as any]; + if (theFrame.location.href === "about:blank") { + waitAndNotify(); } else { - theFrame.addEventListener("load", waitAndNotify) + theFrame.addEventListener("load", waitAndNotify); } - }) + }); }, openWalletPage: (page: string) => { - window.frames['wallet' as any].location = `/wallet.html#${page}` + window.frames["wallet" as any].location = `/wallet.html#${page}`; }, openWalletPageFromPopup: (page: string) => { - window.parent.frames['wallet' as any].location = `/wallet.html#${page}` - window.location.href = "about:blank" + window.parent.frames["wallet" as any].location = `/wallet.html#${page}`; + window.location.href = "about:blank"; }, openWalletURIFromPopup: (page: string) => { - alert('openWalletURIFromPopup not implemented yet') + alert("openWalletURIFromPopup not implemented yet"); }, redirectTabToWalletPage: (tabId: number, page: string) => { - alert('redirectTabToWalletPage not implemented yet') + alert("redirectTabToWalletPage not implemented yet"); }, registerAllIncomingConnections: () => undefined, @@ -70,91 +75,101 @@ const api: PlatformAPI = ({ useServiceWorkerAsBackgroundProcess: () => false, - listenToAllChannels: (fn: (m: any, s: any, c: (r: CoreApiResponse) => void) => void) => { - window.addEventListener("message", (event: MessageEvent) => { - if (event.data.type !== 'command') return - const sender = event.data.header.replyMe - fn(event.data.body, sender, (resp: CoreApiResponse) => { - if (event.source) { - const msg: IframeMessageResponse = { - type: "response", - header: { responseId: sender }, - body: resp + listenToAllChannels: ( + fn: (m: any, s: any, c: (r: CoreApiResponse) => void) => void, + ) => { + window.addEventListener( + "message", + (event: MessageEvent) => { + if (event.data.type !== "command") return; + const sender = event.data.header.replyMe; + fn(event.data.body, sender, (resp: CoreApiResponse) => { + if (event.source) { + const msg: IframeMessageResponse = { + type: "response", + header: { responseId: sender }, + body: resp, + }; + window.parent.postMessage(msg); } - window.parent.postMessage(msg) - } - }) - }) + }); + }, + ); }, sendMessageToAllChannels: (message: MessageFromBackend) => { - Array.from(window.frames).forEach(w => { + Array.from(window.frames).forEach((w) => { try { w.postMessage({ - header: {}, body: message + header: {}, + body: message, }); } catch (e) { - console.error(e) + console.error(e); } - }) + }); }, listenToWalletBackground: (onNewMessage: (m: MessageFromBackend) => void) => { function listener(event: MessageEvent): void { - if (event.data.type !== 'notification') return - onNewMessage(event.data.body) + if (event.data.type !== "notification") return; + onNewMessage(event.data.body); } - window.parent.addEventListener("message", listener) + window.parent.addEventListener("message", listener); return () => { - window.parent.removeEventListener("message", listener) - } + window.parent.removeEventListener("message", listener); + }; }, sendMessageToWalletBackground: async (operation: string, payload: any) => { - const replyMe = `reply-${Math.floor(Math.random() * 100000)}` + const replyMe = `reply-${Math.floor(Math.random() * 100000)}`; const message: IframeMessageCommand = { - type: 'command', + type: "command", header: { replyMe }, - body: { operation, payload, id: "(none)" } - } - window.parent.postMessage(message) + body: { operation, payload, id: "(none)" }, + }; + window.parent.postMessage(message); return new Promise((res, rej) => { function listener(event: MessageEvent): void { - if (event.data.type !== "response" || event.data.header.responseId !== replyMe) { - return + if ( + event.data.type !== "response" || + event.data.header.responseId !== replyMe + ) { + return; } - res(event.data.body) - window.parent.removeEventListener("message", listener) + res(event.data.body); + window.parent.removeEventListener("message", listener); } - window.parent.addEventListener("message", listener, { - - }) - }) - + window.parent.addEventListener("message", listener, {}); + }); }, -}) +}; -type IframeMessageType = IframeMessageNotification | IframeMessageResponse | IframeMessageCommand; +type IframeMessageType = + | IframeMessageNotification + | IframeMessageResponse + | IframeMessageCommand; interface IframeMessageNotification { type: "notification"; - header: Record, - body: MessageFromBackend + header: Record; + body: MessageFromBackend; } interface IframeMessageResponse { type: "response"; header: { responseId: string; - }, - body: CoreApiResponse + }; + body: CoreApiResponse; } interface IframeMessageCommand { type: "command"; header: { replyMe: string; - }, + }; body: { - operation: any, id: string, payload: any - } + operation: any; + id: string; + payload: any; + }; } export default api; - diff --git a/packages/taler-wallet-webextension/src/platform/firefox.ts b/packages/taler-wallet-webextension/src/platform/firefox.ts index d5beda324..32733f6c4 100644 --- a/packages/taler-wallet-webextension/src/platform/firefox.ts +++ b/packages/taler-wallet-webextension/src/platform/firefox.ts @@ -15,7 +15,11 @@ */ import { CrossBrowserPermissionsApi, Permissions, PlatformAPI } from "./api.js"; -import chromePlatform, { containsHostPermissions as chromeContains, removeHostPermissions as chromeRemove, requestHostPermissions as chromeRequest } from "./chrome.js"; +import chromePlatform, { + containsHostPermissions as chromeContains, + removeHostPermissions as chromeRemove, + requestHostPermissions as chromeRequest, +} from "./chrome.js"; const api: PlatformAPI = { ...chromePlatform, @@ -23,18 +27,17 @@ const api: PlatformAPI = { getPermissionsApi, notifyWhenAppIsReady, redirectTabToWalletPage, - useServiceWorkerAsBackgroundProcess + useServiceWorkerAsBackgroundProcess, }; export default api; function isFirefox(): boolean { - return true + return true; } - function addPermissionsListener(callback: (p: Permissions) => void): void { - console.log("addPermissionListener is not supported for Firefox") + console.log("addPermissionListener is not supported for Firefox"); } function getPermissionsApi(): CrossBrowserPermissionsApi { @@ -42,33 +45,28 @@ function getPermissionsApi(): CrossBrowserPermissionsApi { addPermissionsListener, containsHostPermissions: chromeContains, requestHostPermissions: chromeRequest, - removeHostPermissions: chromeRemove - } + removeHostPermissions: chromeRemove, + }; } /** - * + * * @param callback function to be called */ function notifyWhenAppIsReady(callback: () => void): void { if (chrome.runtime && chrome.runtime.getManifest().manifest_version === 3) { - callback() + callback(); } else { window.addEventListener("load", callback); } } - -function redirectTabToWalletPage( - tabId: number, - page: string, -): void { +function redirectTabToWalletPage(tabId: number, page: string): void { const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); console.log("redirecting tabId: ", tabId, " to: ", url); chrome.tabs.update(tabId, { url, loadReplace: true } as any); } - function useServiceWorkerAsBackgroundProcess(): false { - return false + return false; } -- cgit v1.2.3