gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 03/03: #7120 manifest v3: first iteration working


From: gnunet
Subject: [taler-wallet-core] 03/03: #7120 manifest v3: first iteration working
Date: Sun, 16 Jan 2022 21:55:15 +0100

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

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

commit bc817a638d4ddfff0d5f05b51453c6ca790b24ec
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Sun Jan 16 17:54:48 2022 -0300

    #7120 manifest v3: first iteration working
    
    new permission needed: scripting
    chrome.browserAction -> chrome.action
    webRequestBlocking is not possible anymore
    chrome.extension.getUrl -> chrome.runtime.getUrl
    new serviceWorkerHttpLib: using fetch
    new serviceWorkerCryptoWorkerFactory: using syncCryptoImpl
    few other minor changes
    
    still missing some other changes like migrating setTimeout to chrome.alarms 
api
---
 .../taler-wallet-webextension/manifest-v3.json     |  25 +---
 packages/taler-wallet-webextension/package.json    |   2 +-
 .../taler-wallet-webextension/src/api/browser.ts   |  30 +++++
 .../taler-wallet-webextension/src/background.ts    |  10 +-
 .../taler-wallet-webextension/src/chromeBadge.ts   |   2 +-
 .../taler-wallet-webextension/src/permissions.ts   |   2 +-
 .../src/popup/DeveloperPage.tsx                    |   2 +-
 .../src/popup/Settings.tsx                         |   4 +-
 .../src/popupEntryPoint.tsx                        |   2 +-
 .../taler-wallet-webextension/src/renderHtml.tsx   |   2 +-
 .../src/serviceWorkerCryptoWorkerFactory.ts        |  36 +++++
 .../src/serviceWorkerHttpLib.ts                    | 146 +++++++++++++++++++++
 .../taler-wallet-webextension/src/utils/index.ts   |   2 +-
 .../taler-wallet-webextension/src/wxBackend.ts     |  71 ++++++----
 pnpm-lock.yaml                                     |   8 +-
 15 files changed, 282 insertions(+), 62 deletions(-)

diff --git a/packages/taler-wallet-webextension/manifest-v3.json 
b/packages/taler-wallet-webextension/manifest-v3.json
index b7f7c902..6024b750 100644
--- a/packages/taler-wallet-webextension/manifest-v3.json
+++ b/packages/taler-wallet-webextension/manifest-v3.json
@@ -1,41 +1,28 @@
 {
   "manifest_version": 3,
-
   "name": "GNU Taler Wallet (git)",
   "description": "Privacy preserving and transparent payments",
   "author": "GNU Taler Developers",
   "version": "0.8.1.15",
   "version_name": "0.8.1-dev.15",
-
   "minimum_chrome_version": "88",
-
-  "applications": {
-    "gecko": {
-      "id": "wallet@taler.net",
-      "strict_min_version": "57.0"
-    }
-  },
-
   "icons": {
     "32": "static/img/icon.png",
     "128": "static/img/logo.png"
   },
-
   "permissions": [
     "unlimitedStorage",
-    "activeTab"
+    "activeTab",
+    "scripting"
   ],
-
   "optional_permissions": [
     "webRequest",
     "webRequestBlocking"
   ],
-
-  "host_permissions":[
+  "host_permissions": [
     "http://*/*";,
     "https://*/*";
   ],
-
   "action": {
     "default_icon": {
       "32": "static/img/icon.png"
@@ -43,9 +30,7 @@
     "default_title": "Taler",
     "default_popup": "static/popup.html"
   },
-
   "background": {
-    "page": "static/background.html",
-    "persistent": true
+    "service_worker": "dist/background.js"
   }
-}
+}
\ No newline at end of file
diff --git a/packages/taler-wallet-webextension/package.json 
b/packages/taler-wallet-webextension/package.json
index fd4b0fb4..9b02eee2 100644
--- a/packages/taler-wallet-webextension/package.json
+++ b/packages/taler-wallet-webextension/package.json
@@ -48,7 +48,7 @@
     "@storybook/preact": "6.4.9",
     "@testing-library/preact": "^2.0.1",
     "@testing-library/preact-hooks": "^1.1.0",
-    "@types/chrome": "^0.0.174",
+    "@types/chrome": "0.0.176",
     "@types/history": "^4.7.8",
     "@types/mocha": "^9.0.0",
     "@types/node": "^17.0.8",
diff --git a/packages/taler-wallet-webextension/src/api/browser.ts 
b/packages/taler-wallet-webextension/src/api/browser.ts
index bc50853f..b69a4968 100644
--- a/packages/taler-wallet-webextension/src/api/browser.ts
+++ b/packages/taler-wallet-webextension/src/api/browser.ts
@@ -1,6 +1,36 @@
+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
+}
+
+async function getCurrentTab() {
+  let queryOptions = { active: true, currentWindow: true };
+  let [tab] = await chrome.tabs.query(queryOptions);
+  return tab;
+}
+
+
 
 export async function findTalerUriInActiveTab(): Promise<string | undefined> {
+  if (chrome.runtime.getManifest().manifest_version === 3) {
+    // manifest v3
+    const tab = await getCurrentTab();
+    const res = await chrome.scripting.executeScript({
+      target: {
+        tabId: tab.id!,
+        allFrames: true,
+      } as any,
+      func: searchForTalerLinks,
+      args: []
+    })
+    return res[0].result
+  }
   return new Promise((resolve, reject) => {
+    //manifest v2
     chrome.tabs.executeScript(
       {
         code: `
diff --git a/packages/taler-wallet-webextension/src/background.ts 
b/packages/taler-wallet-webextension/src/background.ts
index dcbf9613..428cd86f 100644
--- a/packages/taler-wallet-webextension/src/background.ts
+++ b/packages/taler-wallet-webextension/src/background.ts
@@ -25,6 +25,12 @@
  */
 import { wxMain } from "./wxBackend";
 
-window.addEventListener("load", () => {
+const loadedFromWebpage = typeof window !== "undefined"
+
+if (chrome.runtime.getManifest().manifest_version === 3) {
   wxMain();
-});
+} else {
+  window.addEventListener("load", () => {
+    wxMain();
+  });
+}
diff --git a/packages/taler-wallet-webextension/src/chromeBadge.ts 
b/packages/taler-wallet-webextension/src/chromeBadge.ts
index 7bc5d368..60585793 100644
--- a/packages/taler-wallet-webextension/src/chromeBadge.ts
+++ b/packages/taler-wallet-webextension/src/chromeBadge.ts
@@ -198,7 +198,7 @@ export class ChromeBadge {
           this.canvas.width,
           this.canvas.height,
         );
-        chrome.browserAction.setIcon({ imageData });
+        chrome.action.setIcon({ imageData });
       } catch (e) {
         // Might fail if browser has over-eager canvas fingerprinting 
countermeasures.
         // There's nothing we can do then ...
diff --git a/packages/taler-wallet-webextension/src/permissions.ts 
b/packages/taler-wallet-webextension/src/permissions.ts
index bcd357fd..909433bb 100644
--- a/packages/taler-wallet-webextension/src/permissions.ts
+++ b/packages/taler-wallet-webextension/src/permissions.ts
@@ -15,6 +15,6 @@
  */
 
 export const extendedPermissions = {
-  permissions: ["webRequest", "webRequestBlocking"],
+  permissions: ["webRequest"],
   origins: ["http://*/*";, "https://*/*";],
 };
diff --git a/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx 
b/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx
index ea87ba01..f4b49c23 100644
--- a/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/DeveloperPage.tsx
@@ -194,7 +194,7 @@ export function openExtensionPage(page: string) {
     // eslint-disable-next-line no-undef
     chrome.tabs.create({
       // eslint-disable-next-line no-undef
-      url: chrome.extension.getURL(page),
+      url: chrome.runtime.getURL(page),
     });
   };
 }
diff --git a/packages/taler-wallet-webextension/src/popup/Settings.tsx 
b/packages/taler-wallet-webextension/src/popup/Settings.tsx
index 3732cf7b..a7cdf9cc 100644
--- a/packages/taler-wallet-webextension/src/popup/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Settings.tsx
@@ -60,9 +60,9 @@ export function SettingsView({
           style={{ color: "darkgreen", textDecoration: "none" }}
           href={
             // eslint-disable-next-line no-undef
-            chrome.extension
+            chrome.runtime
               ? // eslint-disable-next-line no-undef
-                chrome.extension.getURL(`/static/wallet.html#/settings`)
+                chrome.runtime.getURL(`/static/wallet.html#/settings`)
               : "#"
           }
         >
diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx 
b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
index 908349e8..5cd68b9b 100644
--- a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
@@ -173,7 +173,7 @@ function goToWalletPage(page: Pages | string): null {
   chrome.tabs.create({
     active: true,
     // eslint-disable-next-line no-undef
-    url: chrome.extension.getURL(`/static/wallet.html#${page}`),
+    url: chrome.runtime.getURL(`/static/wallet.html#${page}`),
   });
   return null;
 }
diff --git a/packages/taler-wallet-webextension/src/renderHtml.tsx 
b/packages/taler-wallet-webextension/src/renderHtml.tsx
index ba98ae23..1e482cce 100644
--- a/packages/taler-wallet-webextension/src/renderHtml.tsx
+++ b/packages/taler-wallet-webextension/src/renderHtml.tsx
@@ -167,7 +167,7 @@ export function PageLink(props: {
     typeof chrome === "undefined"
       ? undefined
       : // eslint-disable-next-line no-undef
-        chrome.extension?.getURL(`/static/wallet.html#/${props.pageName}`);
+        chrome.runtime?.getURL(`/static/wallet.html#/${props.pageName}`);
   return (
     <a class="actionLink" href={url} target="_blank" rel="noopener noreferrer">
       {props.children}
diff --git 
a/packages/taler-wallet-webextension/src/serviceWorkerCryptoWorkerFactory.ts 
b/packages/taler-wallet-webextension/src/serviceWorkerCryptoWorkerFactory.ts
new file mode 100644
index 00000000..6084ebae
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/serviceWorkerCryptoWorkerFactory.ts
@@ -0,0 +1,36 @@
+/*
+ This file is part of TALER
+ (C) 2016 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * API to access the Taler crypto worker thread.
+ * @author Florian Dold
+ */
+
+import {
+  CryptoWorker,
+  CryptoWorkerFactory,
+  SynchronousCryptoWorker,
+} from "@gnu-taler/taler-wallet-core";
+
+export class SynchronousCryptoWorkerFactory implements CryptoWorkerFactory {
+  startWorker(): CryptoWorker {
+    return new SynchronousCryptoWorker();
+  }
+
+  getConcurrency(): number {
+    return 1;
+  }
+}
diff --git a/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts 
b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts
new file mode 100644
index 00000000..f8953f73
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts
@@ -0,0 +1,146 @@
+/*
+ This file is part of GNU Taler
+ (C) 2020 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Imports.
+ */
+import { Logger, TalerErrorCode } from "@gnu-taler/taler-util";
+import {
+  Headers, HttpRequestLibrary,
+  HttpRequestOptions,
+  HttpResponse,
+  OperationFailedError
+} from "@gnu-taler/taler-wallet-core";
+
+const logger = new Logger("browserHttpLib");
+
+/**
+ * An implementation of the [[HttpRequestLibrary]] using the
+ * browser's XMLHttpRequest.
+ */
+export class ServiceWorkerHttpLib implements HttpRequestLibrary {
+  async fetch(requestUrl: string, options?: HttpRequestOptions): 
Promise<HttpResponse> {
+    const requestMethod = options?.method ?? "GET";
+    const requestBody = options?.body;
+    const requestHeader = options?.headers;
+
+    const response = await fetch(requestUrl, {
+      headers: requestHeader,
+      body: requestBody,
+      method: requestMethod,
+      // timeout: options?.timeout
+    })
+
+    const headerMap = new Headers();
+    response.headers.forEach(addLineToMap(headerMap));
+
+    return {
+      headers: headerMap,
+      status: response.status,
+      requestMethod,
+      requestUrl,
+      json: makeJsonHandler(response, requestUrl),
+      text: makeTextHandler(response, requestUrl),
+      bytes: async () => (await response.blob()).arrayBuffer(),
+    }
+
+  }
+
+
+  get(url: string, opt?: HttpRequestOptions): Promise<HttpResponse> {
+    return this.fetch(url, {
+      method: "GET",
+      ...opt,
+    });
+  }
+
+  postJson(
+    url: string,
+    body: any,
+    opt?: HttpRequestOptions,
+  ): Promise<HttpResponse> {
+    return this.fetch(url, {
+      method: "POST",
+      body: JSON.stringify(body),
+      ...opt,
+    });
+  }
+
+  stop(): void {
+    // Nothing to do
+  }
+}
+
+function makeTextHandler(response: Response, requestUrl: string) {
+  return async function getJsonFromResponse(): Promise<any> {
+    let respText;
+    try {
+      respText = await response.text()
+    } catch (e) {
+      throw OperationFailedError.fromCode(
+        TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+        "Invalid JSON from HTTP response",
+        {
+          requestUrl,
+          httpStatusCode: response.status,
+        },
+      );
+    }
+    return respText
+  }
+}
+
+function makeJsonHandler(response: Response, requestUrl: string) {
+  return async function getJsonFromResponse(): Promise<any> {
+    let responseJson;
+    try {
+      responseJson = await response.json()
+    } catch (e) {
+      throw OperationFailedError.fromCode(
+        TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+        "Invalid JSON from HTTP response",
+        {
+          requestUrl,
+          httpStatusCode: response.status,
+        },
+      );
+    }
+    if (responseJson === null || typeof responseJson !== "object") {
+      throw OperationFailedError.fromCode(
+        TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
+        "Invalid JSON from HTTP response",
+        {
+          requestUrl,
+          httpStatusCode: response.status,
+        },
+      );
+    }
+    return responseJson
+  }
+}
+
+function addLineToMap(map: { set(k: string, v: string): void }) {
+  return (line: string) => {
+    const parts = line.split(": ");
+    const headerName = parts.shift();
+    if (!headerName) {
+      logger.warn("skipping invalid header");
+      return;
+    }
+    const value = parts.join(": ");
+    map.set(headerName, value);
+  }
+}
\ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/utils/index.ts 
b/packages/taler-wallet-webextension/src/utils/index.ts
index 88f9bc4b..55898d18 100644
--- a/packages/taler-wallet-webextension/src/utils/index.ts
+++ b/packages/taler-wallet-webextension/src/utils/index.ts
@@ -225,7 +225,7 @@ function makeExtensionUrlWithParams(
   params?: { [name: string]: string | undefined },
 ): string {
   // eslint-disable-next-line no-undef
-  const innerUrl = new URL(chrome.extension.getURL("/" + url));
+  const innerUrl = new URL(chrome.runtime.getURL("/" + url));
   if (params) {
     const hParams = Object.keys(params)
       .map((k) => `${k}=${params[k]}`)
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts 
b/packages/taler-wallet-webextension/src/wxBackend.ts
index 10889f78..412f33f1 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -23,18 +23,6 @@
 /**
  * Imports.
  */
-import { isFirefox, getPermissionsApi } from "./compat";
-import { extendedPermissions } from "./permissions";
-import {
-  OpenedPromise,
-  openPromise,
-  openTalerDatabase,
-  makeErrorDetails,
-  deleteTalerDatabase,
-  DbAccess,
-  WalletStoresV1,
-  Wallet,
-} from "@gnu-taler/taler-wallet-core";
 import {
   classifyTalerUri,
   CoreApiResponse,
@@ -42,10 +30,19 @@ import {
   NotificationType,
   TalerErrorCode,
   TalerUriType,
-  WalletDiagnostics,
+  WalletDiagnostics
 } from "@gnu-taler/taler-util";
-import { BrowserHttpLib } from "./browserHttpLib";
+import {
+  DbAccess, deleteTalerDatabase, makeErrorDetails, OpenedPromise,
+  openPromise,
+  openTalerDatabase, Wallet, WalletStoresV1
+} from "@gnu-taler/taler-wallet-core";
 import { BrowserCryptoWorkerFactory } from "./browserCryptoWorkerFactory";
+import { BrowserHttpLib } from "./browserHttpLib";
+import { getPermissionsApi, isFirefox } from "./compat";
+import { extendedPermissions } from "./permissions";
+import { SynchronousCryptoWorkerFactory } from 
"./serviceWorkerCryptoWorkerFactory.js";
+import { ServiceWorkerHttpLib } from "./serviceWorkerHttpLib";
 
 /**
  * Currently active wallet instance.  Might be unloaded and
@@ -188,10 +185,10 @@ function getTab(tabId: number): Promise<chrome.tabs.Tab> {
   });
 }
 
-function setBadgeText(options: chrome.browserAction.BadgeTextDetails): void {
+function setBadgeText(options: chrome.action.BadgeTextDetails): void {
   // not supported by all browsers ...
-  if (chrome && chrome.browserAction && chrome.browserAction.setBadgeText) {
-    chrome.browserAction.setBadgeText(options);
+  if (chrome && chrome.action && chrome.action.setBadgeText) {
+    chrome.action.setBadgeText(options);
   } else {
     console.warn("can't set badge text, not supported", options);
   }
@@ -214,7 +211,7 @@ function makeSyncWalletRedirect(
   oldUrl: string,
   params?: { [name: string]: string | undefined },
 ): Record<string, unknown> {
-  const innerUrl = new URL(chrome.extension.getURL(url));
+  const innerUrl = new URL(chrome.runtime.getURL(url));
   if (params) {
     const hParams = Object.keys(params)
       .map((k) => `${k}=${params[k]}`)
@@ -256,12 +253,22 @@ async function reinitWallet(): Promise<void> {
     walletInit.reject(e);
     return;
   }
-  const http = new BrowserHttpLib();
+  let httpLib;
+  let cryptoWorker;
+
+  if (chrome.runtime.getManifest().manifest_version === 3) {
+    httpLib = new ServiceWorkerHttpLib()
+    cryptoWorker = new SynchronousCryptoWorkerFactory();
+  } else {
+    httpLib = new BrowserHttpLib()
+    cryptoWorker = new BrowserCryptoWorkerFactory()
+  }
+
   console.log("setting wallet");
   const wallet = await Wallet.create(
     currentDatabase,
-    http,
-    new BrowserCryptoWorkerFactory(),
+    httpLib,
+    cryptoWorker,
   );
   try {
     await wallet.handleCoreApiRequest("initWallet", "native-init", {});
@@ -284,7 +291,9 @@ async function reinitWallet(): Promise<void> {
     console.log("error during wallet task loop", e);
   });
   // Useful for debugging in the background page.
-  (window as any).talerWallet = wallet;
+  if (typeof window !== "undefined") {
+    (window as any).talerWallet = wallet;
+  }
   currentWallet = wallet;
   walletInit.resolve();
 }
@@ -295,8 +304,8 @@ try {
   chrome.runtime.onInstalled.addListener((details) => {
     console.log("onInstalled with reason", details.reason);
     if (details.reason === "install") {
-      const url = chrome.extension.getURL("/static/wallet.html#/welcome");
-      chrome.tabs.create({ active: true, url: url });
+      const url = chrome.runtime.getURL("/static/wallet.html#/welcome");
+      chrome.tabs.create({ active: true, url });
     }
   });
 } catch (e) {
@@ -387,6 +396,10 @@ function headerListener(
 }
 
 function setupHeaderListener(): void {
+  if (chrome.runtime.getManifest().manifest_version === 3) {
+    console.error("cannot block request on manfest v3")
+    return
+  }
   console.log("setting up header listener");
   // Handlers for catching HTTP requests
   getPermissionsApi().contains(extendedPermissions, (result: boolean) => {
@@ -427,12 +440,14 @@ export async function wxMain(): Promise<void> {
     console.log("update available:", details);
     chrome.runtime.reload();
   });
-  reinitWallet();
+  const afterWalletIsInitialized = reinitWallet();
 
   // Handlers for messages coming directly from the content
   // script on the page
   chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
-    dispatch(req, sender, sendResponse);
+    afterWalletIsInitialized.then(() => {
+      dispatch(req, sender, sendResponse);
+    })
     return true;
   });
 
@@ -447,7 +462,9 @@ export async function wxMain(): Promise<void> {
   });
 
   try {
-    setupHeaderListener();
+    if (chrome.runtime.getManifest().manifest_version === 2) {
+      setupHeaderListener();
+    }
   } catch (e) {
     console.log(e);
   }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 33b57d49..c3931343 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -338,7 +338,7 @@ importers:
       '@storybook/preact': 6.4.9
       '@testing-library/preact': ^2.0.1
       '@testing-library/preact-hooks': ^1.1.0
-      '@types/chrome': ^0.0.174
+      '@types/chrome': 0.0.176
       '@types/history': ^4.7.8
       '@types/mocha': ^9.0.0
       '@types/node': ^17.0.8
@@ -393,7 +393,7 @@ importers:
       '@storybook/preact': 6.4.9_7ac135b2eab8a45315147b85be8cb430
       '@testing-library/preact': 2.0.1_preact@10.5.14
       '@testing-library/preact-hooks': 1.1.0_6273b572ba1ed58b8bbb2ee93959f9e4
-      '@types/chrome': 0.0.174
+      '@types/chrome': 0.0.176
       '@types/history': 4.7.9
       '@types/mocha': 9.0.0
       '@types/node': 17.0.8
@@ -9654,8 +9654,8 @@ packages:
       '@types/node': 17.0.8
     dev: true
 
-  /@types/chrome/0.0.174:
-    resolution: {integrity: 
sha512-x5kjvNdwDtOnT+vbnksj69pDl0u9P/WH9LbQWJawLqGgkBRO3AN/xzTxTPgLpp3IqCbuwfp7bRCHqkkaZguzWw==}
+  /@types/chrome/0.0.176:
+    resolution: {integrity: 
sha512-LOveFOMIUhMJjvRzZv5whGBpncP/gdJ4hcxeAqg94wGi6CyKaCmLgFSofgItf85GuLTl/0BQ6J/Y1e8BqZWfEg==}
     dependencies:
       '@types/filesystem': 0.0.32
       '@types/har-format': 1.2.8

-- 
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]