gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: check if the script should be


From: gnunet
Subject: [taler-wallet-core] branch master updated: check if the script should be injected remove header listener
Date: Tue, 18 Apr 2023 15:48:02 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new b34f3568e check if the script should be injected remove header listener
b34f3568e is described below

commit b34f3568e8c9dde73f11583a6b46ef1509990397
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue Apr 18 10:47:53 2023 -0300

    check if the script should be injected
    remove header listener
---
 .../taler-wallet-webextension/manifest-v2.json     |  25 +-
 .../taler-wallet-webextension/manifest-v3.json     |   8 +-
 .../src/background.dev.ts                          |  14 +-
 .../taler-wallet-webextension/src/background.ts    |   9 +-
 .../src/hooks/useClipboardPermissions.ts           |  40 +--
 .../src/hooks/useSettings.ts                       |  10 +-
 .../taler-wallet-webextension/src/platform/api.ts  |  38 +--
 .../src/platform/chrome.ts                         | 295 ++++++++-------------
 .../taler-wallet-webextension/src/platform/dev.ts  |  36 +--
 .../src/platform/firefox.ts                        |  42 ++-
 .../src/taler-wallet-interaction-loader.ts         |  76 +++++-
 .../src/taler-wallet-interaction-support.ts        |   2 +-
 .../src/wallet/Settings.tsx                        |   2 +-
 .../src/wallet/Welcome.tsx                         |   2 +-
 packages/taler-wallet-webextension/src/wxApi.ts    |   8 -
 .../taler-wallet-webextension/src/wxBackend.ts     | 222 +++++++---------
 16 files changed, 408 insertions(+), 421 deletions(-)

diff --git a/packages/taler-wallet-webextension/manifest-v2.json 
b/packages/taler-wallet-webextension/manifest-v2.json
index bcce56e71..e83a16f56 100644
--- a/packages/taler-wallet-webextension/manifest-v2.json
+++ b/packages/taler-wallet-webextension/manifest-v2.json
@@ -17,8 +17,7 @@
   },
   "permissions": [
     "unlimitedStorage",
-    "http://*/*";,
-    "https://*/*";,
+    "storage",
     "activeTab"
   ],
   "web_accessible_resources": [
@@ -28,21 +27,31 @@
     "dist/taler-wallet-interaction-support.js.map",
     "dist/taler-wallet-interaction-support.js"
   ],
-  "optional_permissions": [
-    "http://*/*";,
-    "https://*/*";,
-    "webRequest"
-  ],
   "content_scripts": [{
     "id": "taler-wallet-interaction-support",
     "matches": ["file://*/*", "http://*/*";, "https://*/*";],
     "js": ["dist/taler-wallet-interaction-loader.js"]
   }],
   "protocol_handlers": [
+    {
+      "protocol": "ext+taler+http",
+      "name": "Taler Wallet WebExtension",
+      "uriTemplate": "/static/wallet.html#/cta/taler-uri/%s"
+    },
+    {
+      "protocol": "web+taler+http",
+      "name": "Taler Wallet WebExtension",
+      "uriTemplate": "/static/wallet.html#/cta/taler-uri/%s"
+    },
     {
       "protocol": "ext+taler",
       "name": "Taler Wallet WebExtension",
-      "uriTemplate": 
"/static/wallet.html#/cta/withdraw?d=1&talerWithdrawUri=%s"
+      "uriTemplate": "/static/wallet.html#/cta/taler-uri/%s"
+    },
+    {
+      "protocol": "web+taler",
+      "name": "Taler Wallet WebExtension",
+      "uriTemplate": "/static/wallet.html#/cta/taler-uri/%s"
     }
   ],
   "browser_action": {
diff --git a/packages/taler-wallet-webextension/manifest-v3.json 
b/packages/taler-wallet-webextension/manifest-v3.json
index 72c8d8cd8..93a1a7fc8 100644
--- a/packages/taler-wallet-webextension/manifest-v3.json
+++ b/packages/taler-wallet-webextension/manifest-v3.json
@@ -14,6 +14,7 @@
   },
   "permissions": [
     "unlimitedStorage",
+    "storage",
     "activeTab",
     "scripting",
     "declarativeContent",
@@ -26,9 +27,6 @@
       }
     }
   },
-  "optional_permissions": [
-    "webRequest"
-  ],
   "content_scripts": [{
     "id": "taler-wallet-interaction",
     "matches": ["file://*/*", "http://*/*";, "https://*/*";],
@@ -50,10 +48,6 @@
       ]
     }
   ],
-  "host_permissions": [
-    "http://*/*";,
-    "https://*/*";
-  ],
   "action": {
     "default_icon": {
       "16": "static/img/taler-logo-16.png",
diff --git a/packages/taler-wallet-webextension/src/background.dev.ts 
b/packages/taler-wallet-webextension/src/background.dev.ts
index cac62c44d..9ed0e1b8f 100644
--- a/packages/taler-wallet-webextension/src/background.dev.ts
+++ b/packages/taler-wallet-webextension/src/background.dev.ts
@@ -30,14 +30,8 @@ import { wxMain } from "./wxBackend.js";
 console.log("Wallet setup for Dev API");
 setupPlatform(devAPI);
 
-try {
-  platform.registerOnInstalled(() => {
-    platform.openWalletPage("/welcome");
-  });
-} catch (e) {
-  console.error(e);
+async function start() {
+  await platform.notifyWhenAppIsReady();
+  await wxMain();
 }
-
-platform.notifyWhenAppIsReady(() => {
-  wxMain();
-});
+start();
diff --git a/packages/taler-wallet-webextension/src/background.ts 
b/packages/taler-wallet-webextension/src/background.ts
index 7382120aa..0d5a186d2 100644
--- a/packages/taler-wallet-webextension/src/background.ts
+++ b/packages/taler-wallet-webextension/src/background.ts
@@ -43,6 +43,9 @@ if (isFirefox) {
 }
 
 // setGlobalLogLevelFromString("trace")
-platform.notifyWhenAppIsReady(() => {
-  wxMain();
-});
+
+async function start() {
+  await platform.notifyWhenAppIsReady();
+  await wxMain();
+}
+start();
diff --git 
a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts 
b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts
index 25757f473..3255c90e5 100644
--- a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts
@@ -20,6 +20,12 @@ import { useBackendContext } from "../context/backend.js";
 import { ToggleHandler } from "../mui/handlers.js";
 import { platform } from "../platform/foreground.js";
 
+/**
+ * This is not implemented.
+ * Clipboard permission need to get ask the permission to the user
+ * based on user-intention
+ * @returns
+ */
 export function useClipboardPermissions(): ToggleHandler {
   const [enabled, setEnabled] = useState(false);
   const api = useBackendContext();
@@ -40,27 +46,27 @@ export function useClipboardPermissions(): ToggleHandler {
       }
       setEnabled(granted);
     } else {
-      try {
-        await api.background
-          .call("toggleHeaderListener", false)
-          .then((r) => setEnabled(r.newValue));
-      } catch (e) {
-        console.log(e);
-      }
+      // try {
+      //   await api.background
+      //     .call("toggleHeaderListener", false)
+      //     .then((r) => setEnabled(r.newValue));
+      // } catch (e) {
+      //   console.log(e);
+      // }
     }
     return;
   }
 
-  useEffect(() => {
-    async function getValue(): Promise<void> {
-      const res = await api.background.call(
-        "containsHeaderListener",
-        undefined,
-      );
-      setEnabled(res.newValue);
-    }
-    getValue();
-  }, []);
+  // useEffect(() => {
+  //   async function getValue(): Promise<void> {
+  //     const res = await api.background.call(
+  //       "containsHeaderListener",
+  //       undefined,
+  //     );
+  //     setEnabled(res.newValue);
+  //   }
+  //   getValue();
+  // }, []);
 
   return {
     value: enabled,
diff --git a/packages/taler-wallet-webextension/src/hooks/useSettings.ts 
b/packages/taler-wallet-webextension/src/hooks/useSettings.ts
index 04bce236a..040fee424 100644
--- a/packages/taler-wallet-webextension/src/hooks/useSettings.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useSettings.ts
@@ -15,14 +15,7 @@
  */
 
 import { useLocalStorage } from "@gnu-taler/web-util/lib/index.browser";
-
-interface Settings {
-  injectTalerSupport: boolean;
-}
-
-const defaultSettings: Settings = {
-  injectTalerSupport: false,
-};
+import { Settings, defaultSettings } from "../platform/api.js";
 
 function parse_json_or_undefined<T>(str: string | undefined): T | undefined {
   if (str === undefined) return undefined;
@@ -42,7 +35,6 @@ export function useSettings(): [
   const parsed: Settings = parse_json_or_undefined(value) ?? defaultSettings;
   function updateField<T extends keyof Settings>(k: T, v: Settings[T]) {
     const newValue = { ...parsed, [k]: v };
-    console.log("should update", k, v, parsed, newValue);
     const json = JSON.stringify(newValue);
     console.log(json);
     update(json);
diff --git a/packages/taler-wallet-webextension/src/platform/api.ts 
b/packages/taler-wallet-webextension/src/platform/api.ts
index 40993477b..f87500c4f 100644
--- a/packages/taler-wallet-webextension/src/platform/api.ts
+++ b/packages/taler-wallet-webextension/src/platform/api.ts
@@ -17,6 +17,10 @@
 import { CoreApiResponse, NotificationType } from "@gnu-taler/taler-util";
 import { WalletOperations } from "@gnu-taler/taler-wallet-core";
 import { BackgroundOperations } from "../wxApi.js";
+import {
+  ExtensionOperations,
+  MessageFromExtension,
+} from "../taler-wallet-interaction-loader.js";
 
 export interface Permissions {
   /**
@@ -35,9 +39,9 @@ export interface Permissions {
  * Compatibility API that works on multiple browsers.
  */
 export interface CrossBrowserPermissionsApi {
-  containsHostPermissions(): Promise<boolean>;
-  requestHostPermissions(): Promise<boolean>;
-  removeHostPermissions(): Promise<boolean>;
+  // containsHostPermissions(): Promise<boolean>;
+  // requestHostPermissions(): Promise<boolean>;
+  // removeHostPermissions(): Promise<boolean>;
 
   containsClipboardPermissions(): Promise<boolean>;
   requestClipboardPermissions(): Promise<boolean>;
@@ -53,9 +57,11 @@ export type MessageFromBackend = {
 };
 
 export type MessageFromFrontend<
-  Op extends BackgroundOperations | WalletOperations,
+  Op extends BackgroundOperations | WalletOperations | ExtensionOperations,
 > = Op extends BackgroundOperations
   ? MessageFromFrontendBackground<keyof BackgroundOperations>
+  : Op extends ExtensionOperations
+  ? MessageFromExtension<keyof ExtensionOperations>
   : Op extends WalletOperations
   ? MessageFromFrontendWallet<keyof WalletOperations>
   : never;
@@ -81,11 +87,23 @@ export interface WalletWebExVersion {
   version: string;
 }
 
+export interface Settings {
+  injectTalerSupport: boolean;
+}
+
+export const defaultSettings: Settings = {
+  injectTalerSupport: false,
+};
+
 /**
  * Compatibility helpers needed for browsers that don't implement
  * WebExtension APIs consistently.
  */
 export interface BackgroundPlatformAPI {
+  /**
+   *
+   */
+  getSettingsFromStorage(): Promise<Settings>;
   /**
    * Guarantee that the service workers don't die
    */
@@ -116,16 +134,12 @@ export interface BackgroundPlatformAPI {
    * Register a callback to be called when the wallet is ready to start
    * @param callback
    */
-  notifyWhenAppIsReady(callback: () => void): void;
+  notifyWhenAppIsReady(): Promise<void>;
 
   /**
    * Get the wallet version from manifest
    */
   getWalletWebExVersion(): WalletWebExVersion;
-  /**
-   * Frontend API
-   */
-  containsTalerHeaderListener(): boolean;
   /**
    * Backend API
    */
@@ -134,12 +148,6 @@ export interface BackgroundPlatformAPI {
    * Backend API
    */
   registerReloadOnNewVersion(): void;
-  /**
-   * Backend API
-   */
-  registerTalerHeaderListener(
-    onHeader: (tabId: number, url: string) => void,
-  ): void;
 
   /**
    * Permission API for checking and add a listener
diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts 
b/packages/taler-wallet-webextension/src/platform/chrome.ts
index 03259314e..51cf2f64e 100644
--- a/packages/taler-wallet-webextension/src/platform/chrome.ts
+++ b/packages/taler-wallet-webextension/src/platform/chrome.ts
@@ -31,10 +31,13 @@ import {
   MessageFromFrontend,
   MessageResponse,
   Permissions,
+  Settings,
+  defaultSettings,
 } from "./api.js";
 
 const api: BackgroundPlatformAPI & ForegroundPlatformAPI = {
   isFirefox,
+  getSettingsFromStorage,
   findTalerUriInActiveTab,
   findTalerUriInClipboard,
   getPermissionsApi,
@@ -49,11 +52,9 @@ const api: BackgroundPlatformAPI & ForegroundPlatformAPI = {
   registerOnInstalled,
   listenToAllChannels: listenToAllChannels as any,
   registerReloadOnNewVersion,
-  registerTalerHeaderListener,
   sendMessageToAllChannels,
   sendMessageToBackground,
   useServiceWorkerAsBackgroundProcess,
-  containsTalerHeaderListener,
   keepAlive,
 };
 
@@ -61,6 +62,19 @@ export default api;
 
 const logger = new Logger("chrome.ts");
 
+async function getSettingsFromStorage(): Promise<Settings> {
+  const data = await chrome.storage.local.get("wallet-settings");
+  if (!data) return defaultSettings;
+  const settings = data["wallet-settings"];
+  if (!settings) return defaultSettings;
+  try {
+    const parsed = JSON.parse(settings);
+    return parsed;
+  } catch (e) {
+    return defaultSettings;
+  }
+}
+
 function keepAlive(callback: any): void {
   if (extensionIsManifestV3()) {
     chrome.alarms.create("wallet-worker", { periodInMinutes: 1 });
@@ -78,10 +92,10 @@ function isFirefox(): boolean {
   return false;
 }
 
-const hostPermissions = {
-  permissions: ["webRequest"],
-  origins: ["http://*/*";, "https://*/*";],
-};
+// const hostPermissions = {
+//   permissions: ["webRequest"],
+//   origins: ["http://*/*";, "https://*/*";],
+// };
 
 export function containsClipboardPermissions(): Promise<boolean> {
   return new Promise((res, rej) => {
@@ -96,17 +110,17 @@ export function containsClipboardPermissions(): 
Promise<boolean> {
   });
 }
 
-export function containsHostPermissions(): Promise<boolean> {
-  return new Promise((res, rej) => {
-    chrome.permissions.contains(hostPermissions, (resp) => {
-      const le = chrome.runtime.lastError?.message;
-      if (le) {
-        rej(le);
-      }
-      res(resp);
-    });
-  });
-}
+// export function containsHostPermissions(): Promise<boolean> {
+//   return new Promise((res, rej) => {
+//     chrome.permissions.contains(hostPermissions, (resp) => {
+//       const le = chrome.runtime.lastError?.message;
+//       if (le) {
+//         rej(le);
+//       }
+//       res(resp);
+//     });
+//   });
+// }
 
 export async function requestClipboardPermissions(): Promise<boolean> {
   return new Promise((res, rej) => {
@@ -121,73 +135,67 @@ export async function requestClipboardPermissions(): 
Promise<boolean> {
   });
 }
 
-export async function requestHostPermissions(): Promise<boolean> {
-  return new Promise((res, rej) => {
-    chrome.permissions.request(hostPermissions, (resp) => {
-      const le = chrome.runtime.lastError?.message;
-      if (le) {
-        rej(le);
-      }
-      res(resp);
-    });
-  });
-}
-
-type HeaderListenerFunc = (
-  details: chrome.webRequest.WebResponseHeadersDetails,
-) => void;
-let currentHeaderListener: HeaderListenerFunc | undefined = undefined;
-
-type TabListenerFunc = (tabId: number, info: chrome.tabs.TabChangeInfo) => 
void;
-let currentTabListener: TabListenerFunc | undefined = undefined;
-
-export function containsTalerHeaderListener(): boolean {
-  return (
-    currentHeaderListener !== undefined || currentTabListener !== undefined
-  );
-}
-
-export async function removeHostPermissions(): Promise<boolean> {
-  //if there is a handler already, remove it
-  if (
-    currentHeaderListener &&
-    chrome?.webRequest?.onHeadersReceived?.hasListener(currentHeaderListener)
-  ) {
-    chrome.webRequest.onHeadersReceived.removeListener(currentHeaderListener);
-  }
-  if (
-    currentTabListener &&
-    chrome?.tabs?.onUpdated?.hasListener(currentTabListener)
-  ) {
-    chrome.tabs.onUpdated.removeListener(currentTabListener);
-  }
-
-  currentHeaderListener = undefined;
-  currentTabListener = undefined;
-
-  //notify the browser about this change, this operation is expensive
-  if ("webRequest" in chrome) {
-    chrome.webRequest.handlerBehaviorChanged(() => {
-      if (chrome.runtime.lastError) {
-        logger.error(JSON.stringify(chrome.runtime.lastError));
-      }
-    });
-  }
-
-  if (extensionIsManifestV3()) {
-    // Trying to remove host permissions with manifest >= v3 throws an error
-    return true;
-  }
-  return new Promise((res, rej) => {
-    chrome.permissions.remove(hostPermissions, (resp) => {
-      const le = chrome.runtime.lastError?.message;
-      if (le) {
-        rej(le);
-      }
-      res(resp);
-    });
-  });
-}
+// export async function requestHostPermissions(): Promise<boolean> {
+//   return new Promise((res, rej) => {
+//     chrome.permissions.request(hostPermissions, (resp) => {
+//       const le = chrome.runtime.lastError?.message;
+//       if (le) {
+//         rej(le);
+//       }
+//       res(resp);
+//     });
+//   });
+// }
+
+// type HeaderListenerFunc = (
+//   details: chrome.webRequest.WebResponseHeadersDetails,
+// ) => void;
+// let currentHeaderListener: HeaderListenerFunc | undefined = undefined;
+
+// type TabListenerFunc = (tabId: number, info: chrome.tabs.TabChangeInfo) => 
void;
+// let currentTabListener: TabListenerFunc | undefined = undefined;
+
+// export async function removeHostPermissions(): Promise<boolean> {
+//   //if there is a handler already, remove it
+//   if (
+//     currentHeaderListener &&
+//     
chrome?.webRequest?.onHeadersReceived?.hasListener(currentHeaderListener)
+//   ) {
+//     
chrome.webRequest.onHeadersReceived.removeListener(currentHeaderListener);
+//   }
+//   if (
+//     currentTabListener &&
+//     chrome?.tabs?.onUpdated?.hasListener(currentTabListener)
+//   ) {
+//     chrome.tabs.onUpdated.removeListener(currentTabListener);
+//   }
+
+//   currentHeaderListener = undefined;
+//   currentTabListener = undefined;
+
+//   //notify the browser about this change, this operation is expensive
+//   if ("webRequest" in chrome) {
+//     chrome.webRequest.handlerBehaviorChanged(() => {
+//       if (chrome.runtime.lastError) {
+//         logger.error(JSON.stringify(chrome.runtime.lastError));
+//       }
+//     });
+//   }
+
+//   if (extensionIsManifestV3()) {
+//     // Trying to remove host permissions with manifest >= v3 throws an error
+//     return true;
+//   }
+//   return new Promise((res, rej) => {
+//     chrome.permissions.remove(hostPermissions, (resp) => {
+//       const le = chrome.runtime.lastError?.message;
+//       if (le) {
+//         rej(le);
+//       }
+//       res(resp);
+//     });
+//   });
+// }
 
 export function removeClipboardPermissions(): Promise<boolean> {
   return new Promise((res, rej) => {
@@ -214,9 +222,9 @@ function addPermissionsListener(
 function getPermissionsApi(): CrossBrowserPermissionsApi {
   return {
     addPermissionsListener,
-    containsHostPermissions,
-    requestHostPermissions,
-    removeHostPermissions,
+    // containsHostPermissions,
+    // requestHostPermissions,
+    // removeHostPermissions,
     requestClipboardPermissions,
     removeClipboardPermissions,
     containsClipboardPermissions,
@@ -227,12 +235,16 @@ function getPermissionsApi(): CrossBrowserPermissionsApi {
  *
  * @param callback function to be called
  */
-function notifyWhenAppIsReady(callback: () => void): void {
-  if (extensionIsManifestV3()) {
-    callback();
-  } else {
-    window.addEventListener("load", callback);
-  }
+function notifyWhenAppIsReady(): Promise<void> {
+  return new Promise((resolve, reject) => {
+    if (extensionIsManifestV3()) {
+      resolve();
+    } else {
+      window.addEventListener("load", () => {
+        resolve();
+      });
+    }
+  });
 }
 
 function openWalletURIFromPopup(maybeTalerUri: string): void {
@@ -478,101 +490,6 @@ function getWalletWebExVersion(): WalletVersion {
   return manifestData;
 }
 
-function registerTalerHeaderListener(
-  callback: (tabId: number, url: string) => void,
-): void {
-  logger.trace("setting up header listener");
-
-  function headerListener(
-    details: chrome.webRequest.WebResponseHeadersDetails,
-  ): void {
-    if (chrome.runtime.lastError) {
-      logger.error(JSON.stringify(chrome.runtime.lastError));
-      return;
-    }
-    if (
-      details.statusCode === 402 ||
-      details.statusCode === 202 ||
-      details.statusCode === 200
-    ) {
-      const values = (details.responseHeaders || [])
-        .filter((h) => h.name.toLowerCase() === "taler")
-        .map((h) => h.value)
-        .filter((value): value is string => !!value);
-      if (values.length > 0) {
-        logger.info(
-          `Found a Taler URI in a response header for the request 
${details.url} from tab ${details.tabId}`,
-        );
-        callback(details.tabId, values[0]);
-      }
-    }
-    return;
-  }
-
-  async function tabListener(
-    tabId: number,
-    info: chrome.tabs.TabChangeInfo,
-  ): Promise<void> {
-    if (tabId < 0) return;
-    const tabLocationHasBeenUpdated = info.status === "complete";
-    const tabTitleHasBeenUpdated = info.title !== undefined;
-    if (tabLocationHasBeenUpdated || tabTitleHasBeenUpdated) {
-      const uri = await findTalerUriInTab(tabId);
-      if (!uri) return;
-      logger.info(`Found a Taler URI in the tab ${tabId}`);
-      callback(tabId, uri);
-    }
-  }
-
-  const prevHeaderListener = currentHeaderListener;
-  const prevTabListener = currentTabListener;
-
-  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 (
-        prevTabListener &&
-        chrome?.tabs?.onUpdated?.hasListener(prevTabListener)
-      ) {
-        chrome.tabs.onUpdated.removeListener(prevTabListener);
-      }
-
-      //if the result was positive, add the headerListener
-      if (result) {
-        const headersEvent:
-          | chrome.webRequest.WebResponseHeadersEvent
-          | undefined = chrome?.webRequest?.onHeadersReceived;
-        if (headersEvent) {
-          headersEvent.addListener(headerListener, { urls: ["<all_urls>"] }, [
-            "responseHeaders",
-          ]);
-          currentHeaderListener = headerListener;
-        }
-
-        const tabsEvent: chrome.tabs.TabUpdatedEvent | undefined =
-          chrome?.tabs?.onUpdated;
-        if (tabsEvent) {
-          tabsEvent.addListener(tabListener);
-          currentTabListener = tabListener;
-        }
-      }
-
-      //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 = {
   "16": "/static/img/taler-alert-16.png",
   "19": "/static/img/taler-alert-19.png",
@@ -750,7 +667,7 @@ function registerOnInstalled(callback: () => void): void {
     if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) {
       callback();
     }
-    registerIconChangeOnTalerContent();
+    await registerIconChangeOnTalerContent();
   });
 }
 
diff --git a/packages/taler-wallet-webextension/src/platform/dev.ts 
b/packages/taler-wallet-webextension/src/platform/dev.ts
index d57072c80..1a4183bec 100644
--- a/packages/taler-wallet-webextension/src/platform/dev.ts
+++ b/packages/taler-wallet-webextension/src/platform/dev.ts
@@ -23,18 +23,17 @@ import {
   MessageFromBackend,
   MessageFromFrontend,
   MessageResponse,
+  defaultSettings,
 } from "./api.js";
 
 const frames = ["popup", "wallet"];
 
 const api: BackgroundPlatformAPI & ForegroundPlatformAPI = {
   isFirefox: () => false,
+  getSettingsFromStorage: () => Promise.resolve(defaultSettings),
   keepAlive: (cb: VoidFunction) => cb(),
   findTalerUriInActiveTab: async () => undefined,
   findTalerUriInClipboard: async () => undefined,
-  containsTalerHeaderListener: () => {
-    return true;
-  },
   getPermissionsApi: () => ({
     addPermissionsListener: () => undefined,
     containsHostPermissions: async () => true,
@@ -47,21 +46,23 @@ const api: BackgroundPlatformAPI & ForegroundPlatformAPI = {
   getWalletWebExVersion: () => ({
     version: "none",
   }),
-  notifyWhenAppIsReady: (fn: () => void) => {
+  notifyWhenAppIsReady: () => {
     let total = frames.length;
-    function waitAndNotify(): void {
-      total--;
-      if (total < 1) {
-        fn();
-      }
-    }
-    frames.forEach((f) => {
-      const theFrame = window.frames[f as any];
-      if (theFrame.location.href === "about:blank") {
-        waitAndNotify();
-      } else {
-        theFrame.addEventListener("load", waitAndNotify);
+    return new Promise((fn) => {
+      function waitAndNotify(): void {
+        total--;
+        if (total < 1) {
+          fn();
+        }
       }
+      frames.forEach((f) => {
+        const theFrame = window.frames[f as any];
+        if (theFrame.location.href === "about:blank") {
+          waitAndNotify();
+        } else {
+          theFrame.addEventListener("load", waitAndNotify);
+        }
+      });
     });
   },
 
@@ -80,9 +81,8 @@ const api: BackgroundPlatformAPI & ForegroundPlatformAPI = {
   },
 
   registerAllIncomingConnections: () => undefined,
-  registerOnInstalled: (fn: () => void) => undefined,
+  registerOnInstalled: () => Promise.resolve(),
   registerReloadOnNewVersion: () => undefined,
-  registerTalerHeaderListener: () => undefined,
 
   useServiceWorkerAsBackgroundProcess: () => false,
 
diff --git a/packages/taler-wallet-webextension/src/platform/firefox.ts 
b/packages/taler-wallet-webextension/src/platform/firefox.ts
index 7f6980be7..01848e1ab 100644
--- a/packages/taler-wallet-webextension/src/platform/firefox.ts
+++ b/packages/taler-wallet-webextension/src/platform/firefox.ts
@@ -19,11 +19,10 @@ import {
   CrossBrowserPermissionsApi,
   ForegroundPlatformAPI,
   Permissions,
+  Settings,
+  defaultSettings,
 } from "./api.js";
 import chromePlatform, {
-  containsHostPermissions as chromeHostContains,
-  removeHostPermissions as chromeHostRemove,
-  requestHostPermissions as chromeHostRequest,
   containsClipboardPermissions as chromeClipContains,
   removeClipboardPermissions as chromeClipRemove,
   requestClipboardPermissions as chromeClipRequest,
@@ -32,6 +31,7 @@ import chromePlatform, {
 const api: BackgroundPlatformAPI & ForegroundPlatformAPI = {
   ...chromePlatform,
   isFirefox,
+  getSettingsFromStorage,
   getPermissionsApi,
   notifyWhenAppIsReady,
   redirectTabToWalletPage,
@@ -51,25 +51,43 @@ function addPermissionsListener(callback: (p: Permissions) 
=> void): void {
 function getPermissionsApi(): CrossBrowserPermissionsApi {
   return {
     addPermissionsListener,
-    containsHostPermissions: chromeHostContains,
-    requestHostPermissions: chromeHostRequest,
-    removeHostPermissions: chromeHostRemove,
+    // containsHostPermissions: chromeHostContains,
+    // requestHostPermissions: chromeHostRequest,
+    // removeHostPermissions: chromeHostRemove,
     containsClipboardPermissions: chromeClipContains,
     removeClipboardPermissions: chromeClipRemove,
     requestClipboardPermissions: chromeClipRequest,
   };
 }
 
+async function getSettingsFromStorage(): Promise<Settings> {
+  //@ts-ignore
+  const data = await browser.storage.local.get("wallet-settings");
+  if (!data) return defaultSettings;
+  const settings = data["wallet-settings"];
+  if (!settings) return defaultSettings;
+  try {
+    const parsed = JSON.parse(settings);
+    return parsed;
+  } catch (e) {
+    return defaultSettings;
+  }
+}
+
 /**
  *
  * @param callback function to be called
  */
-function notifyWhenAppIsReady(callback: () => void): void {
-  if (chrome.runtime && chrome.runtime.getManifest().manifest_version === 3) {
-    callback();
-  } else {
-    window.addEventListener("load", callback);
-  }
+function notifyWhenAppIsReady(): Promise<void> {
+  return new Promise((resolve) => {
+    if (chrome.runtime && chrome.runtime.getManifest().manifest_version === 3) 
{
+      resolve();
+    } else {
+      window.addEventListener("load", () => {
+        resolve();
+      });
+    }
+  });
 }
 
 function redirectTabToWalletPage(tabId: number, page: string): void {
diff --git 
a/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts 
b/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
index 838b47397..cc5a02260 100644
--- a/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
+++ b/packages/taler-wallet-webextension/src/taler-wallet-interaction-loader.ts
@@ -14,6 +14,8 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+import { CoreApiResponse } from "@gnu-taler/taler-util";
+
 /**
  * This will modify all the pages that the user load when navigating with Web 
Extension enabled
  *
@@ -62,7 +64,7 @@ const logger = {
     console.error(`${new Date().toISOString()} TALER`, ...msg),
 };
 
-function start() {
+async function start() {
   if (shouldNotInject) {
     return;
   }
@@ -73,8 +75,15 @@ function start() {
   }
   createBridgeWithExtension();
   logger.debug("bridged created");
-  injectTalerSupportScript(debugEnabled);
-  logger.debug("done");
+
+  const shouldInject = await callBackground("isInjectionEnabled", undefined);
+
+  if (shouldInject) {
+    injectTalerSupportScript(debugEnabled);
+    logger.debug("injection completed");
+  } else {
+    logger.debug("injection is not enabled");
+  }
 }
 
 /**
@@ -132,4 +141,65 @@ function createBridgeWithExtension() {
   );
 }
 
+export interface ExtensionOperations {
+  isInjectionEnabled: {
+    request: void;
+    response: boolean;
+  };
+}
+
+export type MessageFromExtension<Op extends keyof ExtensionOperations> = {
+  channel: "extension";
+  operation: Op;
+  payload: ExtensionOperations[Op]["request"];
+};
+
+export type MessageResponse = CoreApiResponse;
+
+async function callBackground<Op extends keyof ExtensionOperations>(
+  operation: Op,
+  payload: ExtensionOperations[Op]["request"],
+): Promise<ExtensionOperations[Op]["response"]> {
+  const message: MessageFromExtension<Op> = {
+    channel: "extension",
+    operation,
+    payload,
+  };
+
+  const response = await sendMessageToBackground(message);
+  if (response.type === "error") {
+    throw new Error(`Background operation "${operation}" failed`);
+  }
+  return response.result as any;
+}
+let nextMessageIndex = 0;
+async function sendMessageToBackground<Op extends keyof ExtensionOperations>(
+  message: MessageFromExtension<Op>,
+): Promise<MessageResponse> {
+  const messageWithId = { ...message, id: `id_${nextMessageIndex++ % 1000}` };
+
+  return new Promise<any>((resolve, reject) => {
+    // logger.trace("send operation to the wallet background", message);
+    let timedout = false;
+    const timerId = setTimeout(() => {
+      timedout = true;
+      throw new Error("timeout");
+      // throw TalerError.fromDetail(TalerErrorCode.GENERIC_TIMEOUT, {});
+    }, 5 * 1000); //five seconds
+    chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => {
+      if (timedout) {
+        return false; //already rejected
+      }
+      clearTimeout(timerId);
+      if (chrome.runtime.lastError) {
+        reject(chrome.runtime.lastError.message);
+      } else {
+        resolve(backgroundResponse);
+      }
+      // return true to keep the channel open
+      return true;
+    });
+  });
+}
+
 start();
diff --git 
a/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts 
b/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
index 00f774cc6..34687306b 100644
--- a/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
+++ b/packages/taler-wallet-webextension/src/taler-wallet-interaction-support.ts
@@ -92,7 +92,7 @@ function buildApi(config: Readonly<Info>): API {
     }
     const targetAttr = ev.currentTarget.attributes.getNamedItem("target");
     const windowTarget =
-      targetAttr && targetAttr.value ? targetAttr.value : "taler-wallet";
+      targetAttr && targetAttr.value ? targetAttr.value : "_self";
     const page = convertURIToWebExtensionPath(hrefAttr.value);
     if (!page) {
       logger.debug(`onclick: could not convert "${hrefAttr.value}" into path`);
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx 
b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
index eea1ffb49..ae3a6e688 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
@@ -271,7 +271,7 @@ export function SettingsView({
           <i18n.Translate>Navigator</i18n.Translate>
         </SubTitle>
         <Checkbox
-          label={i18n.str`Automatically inject Taler API in all pages`}
+          label={i18n.str`Inject Taler support in all pages`}
           name="inject"
           description={
             <i18n.Translate>
diff --git a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx 
b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx
index 1893c4161..0ddcdb0ac 100644
--- a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx
@@ -100,7 +100,7 @@ export function View({
           <i18n.Translate>Navigator</i18n.Translate>
         </SubTitle>
         <Checkbox
-          label={i18n.str`Automatically inject Taler API in all pages`}
+          label={i18n.str`Inject Taler support in all pages`}
           name="inject"
           description={
             <i18n.Translate>
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts 
b/packages/taler-wallet-webextension/src/wxApi.ts
index 98ed72f50..d15528699 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -68,18 +68,10 @@ export interface BackgroundOperations {
     request: void;
     response: void;
   };
-  containsHeaderListener: {
-    request: void;
-    response: ExtendedPermissionsResponse;
-  };
   getDiagnostics: {
     request: void;
     response: WalletDiagnostics;
   };
-  toggleHeaderListener: {
-    request: boolean;
-    response: ExtendedPermissionsResponse;
-  };
   runGarbageCollector: {
     request: void;
     response: void;
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts 
b/packages/taler-wallet-webextension/src/wxBackend.ts
index c50412053..bf91e8521 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -24,42 +24,39 @@
  * Imports.
  */
 import {
-  classifyTalerUri,
-  Logger,
   LogLevel,
-  setGlobalLogLevelFromString,
-  setLogLevelFromString,
+  Logger,
   TalerErrorCode,
-  TalerUriType,
   WalletDiagnostics,
-  makeErrorDetail,
   getErrorDetailFromException,
-  parseTalerUri,
-  TalerUriAction,
+  makeErrorDetail,
+  setGlobalLogLevelFromString,
+  setLogLevelFromString,
 } from "@gnu-taler/taler-util";
 import {
   DbAccess,
-  deleteTalerDatabase,
-  exportDb,
-  importDb,
   OpenedPromise,
-  openPromise,
-  openTalerDatabase,
   SetTimeoutTimerAPI,
   Wallet,
   WalletOperations,
   WalletStoresV1,
+  deleteTalerDatabase,
+  exportDb,
+  importDb,
+  openPromise,
+  openTalerDatabase,
 } from "@gnu-taler/taler-wallet-core";
 import { BrowserHttpLib } from "./browserHttpLib.js";
-import { platform } from "./platform/background.js";
 import {
   MessageFromBackend,
   MessageFromFrontend,
   MessageResponse,
 } from "./platform/api.js";
+import { platform } from "./platform/background.js";
 import { SynchronousCryptoWorkerFactory } from 
"./serviceWorkerCryptoWorkerFactory.js";
 import { ServiceWorkerHttpLib } from "./serviceWorkerHttpLib.js";
-import { BackgroundOperations, ExtendedPermissionsResponse } from "./wxApi.js";
+import { ExtensionOperations } from "./taler-wallet-interaction-loader.js";
+import { BackgroundOperations } from "./wxApi.js";
 
 /**
  * Currently active wallet instance.  Might be unloaded and
@@ -123,10 +120,11 @@ type BackendHandlerType = {
   ) => Promise<BackgroundOperations[Op]["response"]>;
 };
 
-async function containsHeaderListener(): Promise<ExtendedPermissionsResponse> {
-  const result = await platform.containsTalerHeaderListener();
-  return { newValue: result };
-}
+type ExtensionHandlerType = {
+  [Op in keyof ExtensionOperations]: (
+    req: ExtensionOperations[Op]["request"],
+  ) => Promise<ExtensionOperations[Op]["response"]>;
+};
 
 async function resetDb(): Promise<void> {
   await deleteTalerDatabase(indexedDB as any);
@@ -153,20 +151,6 @@ async function runGarbageCollector(): Promise<void> {
   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 };
-}
-
 function freeze(time: number): Promise<void> {
   return new Promise((res, rej) => {
     setTimeout(res, time);
@@ -177,14 +161,21 @@ async function sum(ns: Array<number>): Promise<number> {
   return ns.reduce((prev, cur) => prev + cur, 0);
 }
 
+const extensionHandlers: ExtensionHandlerType = {
+  isInjectionEnabled,
+};
+
+async function isInjectionEnabled(): Promise<boolean> {
+  const settings = await platform.getSettingsFromStorage();
+  return settings.injectTalerSupport === true;
+}
+
 const backendHandlers: BackendHandlerType = {
   freeze,
   sum,
-  containsHeaderListener,
   getDiagnostics,
   resetDb,
   runGarbageCollector,
-  toggleHeaderListener,
   setLoggingLevel,
 };
 
@@ -203,55 +194,85 @@ async function setLoggingLevel({
   }
 }
 
-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`),
-        ),
-      };
+async function dispatch<
+  Op extends WalletOperations | BackgroundOperations | ExtensionOperations,
+>(req: MessageFromFrontend<Op> & { id: string }): Promise<MessageResponse> {
+  switch (req.channel) {
+    case "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`),
+          ),
+        };
+      }
+      try {
+        const result = await handler(req.payload);
+        return {
+          type: "response",
+          id: req.id,
+          operation: String(req.operation),
+          result,
+        };
+      } catch (er) {
+        return {
+          type: "error",
+          id: req.id,
+          error: getErrorDetailFromException(er),
+          operation: String(req.operation),
+        };
+      }
     }
-    try {
-      const result = await handler(req.payload);
-      return {
-        type: "response",
-        id: req.id,
-        operation: String(req.operation),
-        result,
-      };
-    } catch (er) {
-      return {
-        type: "error",
-        id: req.id,
-        error: getErrorDetailFromException(er),
-        operation: String(req.operation),
-      };
+    case "extension": {
+      const handler = extensionHandlers[req.operation] as (req: any) => any;
+      if (!handler) {
+        return {
+          type: "error",
+          id: req.id,
+          operation: String(req.operation),
+          error: getErrorDetailFromException(
+            Error(`unknown extension operation`),
+          ),
+        };
+      }
+      try {
+        const result = await handler(req.payload);
+        return {
+          type: "response",
+          id: req.id,
+          operation: String(req.operation),
+          result,
+        };
+      } catch (er) {
+        return {
+          type: "error",
+          id: req.id,
+          error: getErrorDetailFromException(er),
+          operation: String(req.operation),
+        };
+      }
     }
-  }
+    case "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",
+          ),
+        };
+      }
 
-  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",
-        ),
-      };
+      return await w.handleCoreApiRequest(req.operation, req.id, req.payload);
     }
-
-    return await w.handleCoreApiRequest(req.operation, req.id, req.payload);
   }
 
   const anyReq = req as any;
@@ -261,7 +282,7 @@ async function dispatch<Op extends WalletOperations | 
BackgroundOperations>(
     operation: String(anyReq.operation),
     error: getErrorDetailFromException(
       Error(
-        `unknown channel ${anyReq.channel}, should be "background" or 
"wallet"`,
+        `unknown channel ${anyReq.channel}, should be "background", 
"extension" or "wallet"`,
       ),
     ),
   };
@@ -330,23 +351,6 @@ async function reinitWallet(): Promise<void> {
   return walletInit.resolve();
 }
 
-function parseTalerUriAndRedirect(tabId: number, maybeTalerUri: string): void {
-  const talerUri = maybeTalerUri.startsWith("ext+")
-    ? maybeTalerUri.substring(4)
-    : maybeTalerUri;
-  const uri = parseTalerUri(talerUri);
-  if (!uri) {
-    logger.warn(
-      `Response with HTTP 402 the Taler header but could not classify 
${talerUri}`,
-    );
-    return;
-  }
-  return platform.redirectTabToWalletPage(
-    tabId,
-    `/taler-uri/${encodeURIComponent(talerUri)}`,
-  );
-}
-
 /**
  * Main function to run for the WebExtension backend.
  *
@@ -370,30 +374,10 @@ export async function wxMain(): Promise<void> {
   platform.registerAllIncomingConnections();
 
   try {
-    platform.registerOnInstalled(() => {
+    await platform.registerOnInstalled(() => {
       platform.openWalletPage("/welcome");
-
-      //
-      try {
-        platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
-      } catch (e) {
-        logger.error("could not register header listener", e);
-      }
     });
   } catch (e) {
     console.error(e);
   }
-
-  // On platforms that support it, also listen to external
-  // modification of permissions.
-  platform.getPermissionsApi().addPermissionsListener((perm, lastError) => {
-    if (lastError) {
-      logger.error(
-        `there was a problem trying to get permission ${perm}`,
-        lastError,
-      );
-      return;
-    }
-    platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
-  });
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]