gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated (5be0708a -> 609397d9)


From: gnunet
Subject: [taler-wallet-core] branch master updated (5be0708a -> 609397d9)
Date: Fri, 01 May 2020 10:47:45 +0200

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

dold pushed a change to branch master
in repository wallet-core.

    from 5be0708a adopt new merchant refund API
     new 9798bf51 fix path
     new e52e1fab fix redirection
     new 3f52d293 error message
     new 609397d9 drastically reduce permissions for Web integration

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/crypto/workers/cryptoApi.ts      |   2 +-
 src/operations/errors.ts             |   2 +-
 src/types/walletTypes.ts             |   5 +
 src/webex/messages.ts                |   8 +
 src/webex/pageEntryPoint.ts          |   4 +
 src/webex/pages/pay.tsx              |   2 +-
 src/webex/pages/popup.tsx            | 111 ++++++++++++-
 src/webex/pages/welcome.tsx          |  57 ++++++-
 src/webex/pages/withdraw.tsx         |   7 +
 src/webex/renderHtml.tsx             |   4 +-
 src/webex/wxApi.ts                   |  15 ++
 src/webex/wxBackend.ts               | 299 +++++++++++++++--------------------
 webextension/manifest.json           |  14 +-
 webextension/static/style/wallet.css |  35 ++--
 webextension/static/welcome.html     |   9 +-
 webextension/static/withdraw.html    |   6 +-
 16 files changed, 369 insertions(+), 211 deletions(-)

diff --git a/src/crypto/workers/cryptoApi.ts b/src/crypto/workers/cryptoApi.ts
index 456bf309..a6f9d162 100644
--- a/src/crypto/workers/cryptoApi.ts
+++ b/src/crypto/workers/cryptoApi.ts
@@ -104,7 +104,7 @@ export interface CryptoWorkerFactory {
 export class BrowserCryptoWorkerFactory implements CryptoWorkerFactory {
   startWorker(): CryptoWorker {
     const workerCtor = Worker;
-    const workerPath = "/dist/webextension/browserWorkerEntry.js";
+    const workerPath = "/browserWorkerEntry.js";
     return new workerCtor(workerPath) as CryptoWorker;
   }
 
diff --git a/src/operations/errors.ts b/src/operations/errors.ts
index 50e68993..0d180a46 100644
--- a/src/operations/errors.ts
+++ b/src/operations/errors.ts
@@ -144,7 +144,7 @@ export async function guardOperationException<T>(
     console.log("guard: caught something else");
     const opErr = {
       type: "exception",
-      message: "non-error exception thrown",
+      message: "unexpected exception thrown",
       details: {
         value: e.toString(),
       },
diff --git a/src/types/walletTypes.ts b/src/types/walletTypes.ts
index 113a137c..ed334bc4 100644
--- a/src/types/walletTypes.ts
+++ b/src/types/walletTypes.ts
@@ -475,3 +475,8 @@ export interface DepositInfo {
   denomPub: string;
   denomSig: string;
 }
+
+
+export interface ExtendedPermissionsResponse {
+  newValue: boolean;
+}
\ No newline at end of file
diff --git a/src/webex/messages.ts b/src/webex/messages.ts
index 745e309c..179eec88 100644
--- a/src/webex/messages.ts
+++ b/src/webex/messages.ts
@@ -164,6 +164,14 @@ export interface MessageMap {
     request: {};
     response: walletTypes.WalletDiagnostics;
   };
+  "set-extended-permissions": {
+    request: { value: boolean };
+    response: walletTypes.ExtendedPermissionsResponse;
+  };
+  "get-extended-permissions": {
+    request: { };
+    response: walletTypes.ExtendedPermissionsResponse;
+  };
 }
 
 /**
diff --git a/src/webex/pageEntryPoint.ts b/src/webex/pageEntryPoint.ts
index dd9c1303..b9bdba06 100644
--- a/src/webex/pageEntryPoint.ts
+++ b/src/webex/pageEntryPoint.ts
@@ -24,6 +24,7 @@ import ReactDOM from "react-dom";
 import { createPopup } from "./pages/popup";
 import { createWithdrawPage } from "./pages/withdraw";
 import { createWelcomePage } from "./pages/welcome";
+import { createPayPage } from "./pages/pay";
 
 function main(): void {
   try {
@@ -43,6 +44,9 @@ function main(): void {
       case "welcome.html":
         mainElement = createWelcomePage();
         break;
+      case "pay.html":
+        mainElement = createPayPage();
+        break;
       default:
         throw Error(`page '${page}' not implemented`);
     }
diff --git a/src/webex/pages/pay.tsx b/src/webex/pages/pay.tsx
index 61f28770..a69b6b76 100644
--- a/src/webex/pages/pay.tsx
+++ b/src/webex/pages/pay.tsx
@@ -178,7 +178,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: 
string }): JSX.Element {
   );
 }
 
-export function makePayPage(): JSX.Element {
+export function createPayPage(): JSX.Element {
   const url = new URL(document.location.href);
   const talerPayUri = url.searchParams.get("talerPayUri");
   if (!talerPayUri) {
diff --git a/src/webex/pages/popup.tsx b/src/webex/pages/popup.tsx
index 0fd2477f..f6d95e2f 100644
--- a/src/webex/pages/popup.tsx
+++ b/src/webex/pages/popup.tsx
@@ -34,11 +34,12 @@ import { WalletBalance, WalletBalanceEntry } from 
"../../types/walletTypes";
 import { abbrev, renderAmount, PageLink } from "../renderHtml";
 import * as wxApi from "../wxApi";
 
-import React, { Fragment } from "react";
+import React, { Fragment, useState, useEffect } from "react";
 import { HistoryEvent } from "../../types/history";
 
 import moment from "moment";
 import { Timestamp } from "../../util/time";
+import { classifyTalerUri, TalerUriType } from "../../util/taleruri";
 
 // FIXME: move to newer react functions
 /* eslint-disable react/no-deprecated */
@@ -761,7 +762,113 @@ function openTab(page: string) {
   };
 }
 
+function makeExtensionUrlWithParams(
+  url: string,
+  params?: { [name: string]: string | undefined },
+): string {
+  const innerUrl = new URL(chrome.extension.getURL("/" + url));
+  if (params) {
+    for (const key in params) {
+      const p = params[key];
+      if (p) {
+        innerUrl.searchParams.set(key, p);
+      }
+    }
+  }
+  return innerUrl.href;
+}
+
+function actionForTalerUri(talerUri: string): string | undefined {
+  const uriType = classifyTalerUri(talerUri);
+  switch (uriType) {
+    case TalerUriType.TalerWithdraw:
+      return makeExtensionUrlWithParams("withdraw.html", {
+        talerWithdrawUri: talerUri,
+      });
+    case TalerUriType.TalerPay:
+      return makeExtensionUrlWithParams("pay.html", {
+        talerPayUri: talerUri,
+      });
+    case TalerUriType.TalerTip:
+      return makeExtensionUrlWithParams("tip.html", {
+        talerTipUri: talerUri,
+      });
+    case TalerUriType.TalerRefund:
+      return makeExtensionUrlWithParams("refund.html", {
+        talerRefundUri: talerUri,
+      });
+    case TalerUriType.TalerNotifyReserve:
+      // FIXME: implement
+      break;
+    default:
+      console.warn(
+        "Response with HTTP 402 has Taler header, but header value is not a 
taler:// URI.",
+      );
+      break;
+  }
+  return undefined;
+}
+
+async function findTalerUriInActiveTab(): Promise<string | undefined> {
+  return new Promise((resolve, reject) => {
+    chrome.tabs.executeScript(
+      {
+        code: `
+        (() => {
+          let x = document.querySelector("a[href^='taler://'");
+          return x ? x.href.toString() : null;
+        })();
+      `,
+        allFrames: false,
+      },
+      (result) => {
+        if (chrome.runtime.lastError) {
+          console.error(chrome.runtime.lastError);
+          resolve(undefined);
+          return;
+        }
+        console.log("got result", result);
+        resolve(result[0]);
+      },
+    );
+  });
+}
+
 function WalletPopup(): JSX.Element {
+  const [talerActionUrl, setTalerActionUrl] = useState<string | undefined>(
+    undefined,
+  );
+  const [dismissed, setDismissed] = useState(false);
+  useEffect(() => {
+    async function check(): Promise<void> {
+      const talerUri = await findTalerUriInActiveTab();
+      if (talerUri) {
+        const actionUrl = actionForTalerUri(talerUri);
+        setTalerActionUrl(actionUrl);
+      }
+    }
+    check();
+  });
+  if (talerActionUrl && !dismissed) {
+    return (
+      <div style={{ padding: "1em" }}>
+        <h1>Taler Action</h1>
+        <p>This page has a Taler action. </p>
+        <p>
+          <button
+            onClick={() => {
+              window.open(talerActionUrl, "_blank");
+            }}
+          >
+            Open
+          </button>
+        </p>
+        <p>
+          <button onClick={() => setDismissed(true)}>Dismiss</button>
+        </p>
+      </div>
+    );
+  }
   return (
     <div>
       <WalletNavBar />
@@ -777,6 +884,6 @@ function WalletPopup(): JSX.Element {
 }
 
 export function createPopup(): JSX.Element {
-  chrome.runtime.connect({ name: "popup" });
+  //chrome.runtime.connect({ name: "popup" });
   return <WalletPopup />;
 }
diff --git a/src/webex/pages/welcome.tsx b/src/webex/pages/welcome.tsx
index eecbe2be..5092d2dd 100644
--- a/src/webex/pages/welcome.tsx
+++ b/src/webex/pages/welcome.tsx
@@ -24,8 +24,9 @@ import React, { useState, useEffect } from "react";
 import { getDiagnostics } from "../wxApi";
 import { PageLink } from "../renderHtml";
 import { WalletDiagnostics } from "../../types/walletTypes";
+import * as wxApi from "../wxApi";
 
-function Diagnostics(): JSX.Element {
+function Diagnostics(): JSX.Element | null {
   const [timedOut, setTimedOut] = useState(false);
   const [diagnostics, setDiagnostics] = useState<WalletDiagnostics | 
undefined>(
     undefined,
@@ -55,7 +56,7 @@ function Diagnostics(): JSX.Element {
 
   if (diagnostics) {
     if (diagnostics.errors.length === 0) {
-      return <p>Running diagnostics ... everything looks fine.</p>;
+      return null;
     } else {
       return (
         <div
@@ -96,16 +97,56 @@ function Diagnostics(): JSX.Element {
 }
 
 function Welcome(): JSX.Element {
+  const [extendedPermissions, setExtendedPermissions] = useState(false);
+  async function handleExtendedPerm(newVal: boolean): Promise<void> {
+    const res = await wxApi.setExtendedPermissions(newVal);
+    setExtendedPermissions(res.newValue);
+  }
+  useEffect(() => {
+    async function getExtendedPermValue(): Promise<void> {
+      const res = await wxApi.getExtendedPermissions()
+      setExtendedPermissions(res.newValue);
+    }
+    getExtendedPermValue();
+  });
   return (
     <>
       <p>Thank you for installing the wallet.</p>
-      <h2>First Steps</h2>
-      <p>
-        Check out <a href="https://demo.taler.net/";>demo.taler.net</a> for a
-        demo.
-      </p>
-      <h2>Troubleshooting</h2>
       <Diagnostics />
+      <h2>Permissions</h2>
+      <div>
+        <input
+          checked={extendedPermissions}
+          onChange={(x) => handleExtendedPerm(x.target.checked)}
+          type="checkbox"
+          id="checkbox-perm"
+          style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }}
+        />
+        <label
+          htmlFor="checkbox-perm"
+          style={{ marginLeft: "0.5em", fontWeight: "bold" }}
+        >
+          Automatically open wallet based on page content
+        </label>
+        <span
+          style={{
+            color: "#383838",
+            fontSize: "smaller",
+            display: "block",
+            marginLeft: "2em",
+          }}
+        >
+          (Enabling this option below will make using the wallet faster, but
+          requires more permissions from your browser.)
+        </span>
+      </div>
+      <h2>Next Steps</h2>
+      <a href="https://demo.taler.net/"; style={{ display: "block" }}>
+        Try the demo »
+      </a>
+      <a href="https://demo.taler.net/"; style={{ display: "block" }}>
+        Learn how to top up your wallet balance »
+      </a>
     </>
   );
 }
diff --git a/src/webex/pages/withdraw.tsx b/src/webex/pages/withdraw.tsx
index efd0adc8..1647a706 100644
--- a/src/webex/pages/withdraw.tsx
+++ b/src/webex/pages/withdraw.tsx
@@ -160,11 +160,18 @@ function NewExchangeSelection(props: {
 
   return (
     <div>
+      <h1>Digital Cash Withdrawal</h1>
       <i18n.Translate wrap="p">
         You are about to withdraw{" "}
         <strong>{renderAmount(details.bankWithdrawDetails.amount)}</strong> 
from
         your bank account into your wallet.
       </i18n.Translate>
+      { selectedExchange ?
+        <p>
+          The exchange <strong>{selectedExchange}</strong> will be used as the 
Taler payment service provider.
+        </p> : null
+      }
+
       <div>
         <button
           className="pure-button button-success"
diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx
index b1363abf..a56af37f 100644
--- a/src/webex/renderHtml.tsx
+++ b/src/webex/renderHtml.tsx
@@ -109,6 +109,7 @@ export class Collapsible extends React.Component<
       return (
         <h2>
           <a className="opener opener-collapsed" href="#" onClick={doOpen}>
+            {" "}
             {this.props.title}
           </a>
         </h2>
@@ -118,6 +119,7 @@ export class Collapsible extends React.Component<
       <div>
         <h2>
           <a className="opener opener-open" href="#" onClick={doClose}>
+            {" "}
             {this.props.title}
           </a>
         </h2>
@@ -143,7 +145,6 @@ function WireFee(props: {
           <th>Closing Fee</th>
         </tr>
       </thead>
-      ,
       <tbody>
         {props.rci.wireFees.feesForType[props.s].map((f) => (
           <tr key={f.sig}>
@@ -153,7 +154,6 @@ function WireFee(props: {
           </tr>
         ))}
       </tbody>
-      ,
     </>
   );
 }
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index 07b223c8..128041e5 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -41,6 +41,7 @@ import {
   WithdrawDetails,
   PreparePayResult,
   AcceptWithdrawalResponse,
+  ExtendedPermissionsResponse,
 } from "../types/walletTypes";
 
 import { MessageMap, MessageType } from "./messages";
@@ -324,3 +325,17 @@ export function acceptWithdrawal(
 export function getDiagnostics(): Promise<WalletDiagnostics> {
   return callBackend("get-diagnostics", {});
 }
+
+/**
+ * Get diagnostics information
+ */
+export function setExtendedPermissions(value: boolean): 
Promise<ExtendedPermissionsResponse> {
+  return callBackend("set-extended-permissions", { value });
+}
+
+/**
+ * Get diagnostics information
+ */
+export function getExtendedPermissions(): Promise<ExtendedPermissionsResponse> 
{
+  return callBackend("get-extended-permissions", {});
+}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 8fbb1431..17e5215f 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -63,6 +63,11 @@ let outdatedDbVersion: number | undefined;
 
 const walletInit: OpenedPromise<void> = openPromise<void>();
 
+const extendedPermissions = {
+  permissions: ["webRequest", "webRequestBlocking", "tabs"],
+  origins: ["http://*/*";, "https://*/*";],
+};
+
 async function handleMessage(
   sender: MessageSender,
   type: MessageType,
@@ -282,6 +287,43 @@ async function handleMessage(
     }
     case "prepare-pay":
       return needsWallet().preparePayForUri(detail.talerPayUri);
+    case "set-extended-permissions": {
+      const newVal = detail.value;
+      if (newVal) {
+        const res = await new Promise((resolve, reject) => {
+          chrome.permissions.request(
+            extendedPermissions,
+            (granted: boolean) => {
+              console.log("permissions granted:", granted);
+              if (chrome.runtime.lastError) {
+                console.error(chrome.runtime.lastError);
+              }
+              resolve(granted);
+            },
+          );
+        });
+        if (res) {
+          setupHeaderListener();
+        }
+        return { newValue: res };
+      } else {
+        await new Promise((resolve, reject) => {
+          chrome.permissions.remove(extendedPermissions, (rem) => {
+            console.log("permissions removed:", rem);
+            resolve();
+          });
+        });
+        return { newVal: false };
+      }
+    }
+    case "get-extended-permissions": {
+      const res = await new Promise((resolve, reject) => {
+        chrome.permissions.contains(extendedPermissions, (result: boolean) => {
+          resolve(result);
+        });
+      });
+      return { newValue: res };
+    }
     default:
       // Exhaustiveness check.
       // See https://www.typescriptlang.org/docs/handbook/advanced-types.html
@@ -379,6 +421,8 @@ function makeSyncWalletRedirect(
     };
     doit();
   }
+  console.log("redirecting to", innerUrl.href);
+  chrome.tabs.update(tabId, { url: innerUrl.href });
   return { redirectUrl: innerUrl.href };
 }
 
@@ -451,6 +495,91 @@ try {
   console.error(e);
 }
 
+function headerListener(
+  details: chrome.webRequest.WebResponseHeadersDetails,
+): chrome.webRequest.BlockingResponse | undefined {
+  if (chrome.runtime.lastError) {
+    console.error(chrome.runtime.lastError);
+    return;
+  }
+  const wallet = currentWallet;
+  if (!wallet) {
+    console.warn("wallet not available while handling header");
+    return;
+  }
+  if (details.statusCode === 402 || details.statusCode === 202) {
+    console.log(`got 402/202 from ${details.url}`);
+    for (const header of details.responseHeaders || []) {
+      if (header.name.toLowerCase() === "taler") {
+        const talerUri = header.value || "";
+        const uriType = classifyTalerUri(talerUri);
+        switch (uriType) {
+          case TalerUriType.TalerWithdraw:
+            return makeSyncWalletRedirect(
+              "withdraw.html",
+              details.tabId,
+              details.url,
+              {
+                talerWithdrawUri: talerUri,
+              },
+            );
+          case TalerUriType.TalerPay:
+            return makeSyncWalletRedirect(
+              "pay.html",
+              details.tabId,
+              details.url,
+              {
+                talerPayUri: talerUri,
+              },
+            );
+          case TalerUriType.TalerTip:
+            return makeSyncWalletRedirect(
+              "tip.html",
+              details.tabId,
+              details.url,
+              {
+                talerTipUri: talerUri,
+              },
+            );
+          case TalerUriType.TalerRefund:
+            return makeSyncWalletRedirect(
+              "refund.html",
+              details.tabId,
+              details.url,
+              {
+                talerRefundUri: talerUri,
+              },
+            );
+          case TalerUriType.TalerNotifyReserve:
+            Promise.resolve().then(() => {
+              const w = currentWallet;
+              if (!w) {
+                return;
+              }
+              w.handleNotifyReserve();
+            });
+            break;
+          default:
+            console.warn(
+              "Response with HTTP 402 has Taler header, but header value is 
not a taler:// URI.",
+            );
+            break;
+        }
+      }
+    }
+  }
+  return;
+}
+
+function setupHeaderListener(): void {
+  // Handlers for catching HTTP requests
+  chrome.webRequest.onHeadersReceived.addListener(
+    headerListener,
+    { urls: ["https://*/*";, "http://*/*";] },
+    ["responseHeaders", "blocking"],
+  );
+}
+
 /**
  * Main function to run for the WebExtension backend.
  *
@@ -463,101 +592,6 @@ export async function wxMain(): Promise<void> {
     console.log("update available:", details);
     chrome.runtime.reload();
   });
-
-  chrome.tabs.query({}, (tabs) => {
-    console.log("got tabs", tabs);
-    for (const tab of tabs) {
-      if (!tab.url || !tab.id) {
-        continue;
-      }
-      const uri = new URL(tab.url);
-      if (uri.protocol !== "http:" && uri.protocol !== "https:") {
-        continue;
-      }
-      console.log(
-        "injecting into existing tab",
-        tab.id,
-        "with url",
-        uri.href,
-        "protocol",
-        uri.protocol,
-      );
-      injectScript(
-        tab.id,
-        { file: "/dist/contentScript-bundle.js", runAt: "document_start" },
-        uri.href,
-      );
-      const code = `
-        if (("taler" in window) || 
document.documentElement.getAttribute("data-taler-nojs")) {
-          document.dispatchEvent(new Event("taler-probe-result"));
-        }
-      `;
-      injectScript(tab.id, { code, runAt: "document_start" }, uri.href);
-    }
-  });
-
-  const tabTimers: { [n: number]: number[] } = {};
-
-  chrome.tabs.onRemoved.addListener((tabId, changeInfo) => {
-    const tt = tabTimers[tabId] || [];
-    const bgPage = chrome.extension.getBackgroundPage();
-    if (!bgPage) {
-      console.error("background page unavailable");
-      return;
-    }
-    for (const t of tt) {
-      bgPage.clearTimeout(t);
-    }
-  });
-  chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
-    if (changeInfo.status !== "complete") {
-      return;
-    }
-    const timers: number[] = [];
-
-    const run = (): void => {
-      timers.shift();
-      chrome.tabs.get(tabId, (tab) => {
-        if (chrome.runtime.lastError) {
-          return;
-        }
-        if (!tab.url || !tab.id) {
-          return;
-        }
-        const uri = new URL(tab.url);
-        if (!(uri.protocol === "http:" || uri.protocol === "https:")) {
-          return;
-        }
-        const code = `
-          if (("taler" in window) || 
document.documentElement.getAttribute("data-taler-nojs")) {
-            document.dispatchEvent(new Event("taler-probe-result"));
-          }
-        `;
-        injectScript(tab.id, { code, runAt: "document_start" }, uri.href);
-      });
-    };
-
-    const addRun = (dt: number): void => {
-      const bgPage = chrome.extension.getBackgroundPage();
-      if (!bgPage) {
-        console.error("no background page");
-        return;
-      }
-      const id = bgPage.setTimeout(run, dt);
-      timers.push(id);
-    };
-
-    addRun(0);
-    addRun(50);
-    addRun(300);
-    addRun(1000);
-    addRun(2000);
-    addRun(4000);
-    addRun(8000);
-    addRun(16000);
-    tabTimers[tabId] = timers;
-  });
-
   reinitWallet();
 
   // Handlers for messages coming directly from the content
@@ -567,78 +601,5 @@ export async function wxMain(): Promise<void> {
     return true;
   });
 
-  // Handlers for catching HTTP requests
-  chrome.webRequest.onHeadersReceived.addListener(
-    (details) => {
-      const wallet = currentWallet;
-      if (!wallet) {
-        console.warn("wallet not available while handling header");
-      }
-      if (details.statusCode === 402 || details.statusCode === 202) {
-        console.log(`got 402/202 from ${details.url}`);
-        for (const header of details.responseHeaders || []) {
-          if (header.name.toLowerCase() === "taler") {
-            const talerUri = header.value || "";
-            const uriType = classifyTalerUri(talerUri);
-            switch (uriType) {
-              case TalerUriType.TalerWithdraw:
-                return makeSyncWalletRedirect(
-                  "withdraw.html",
-                  details.tabId,
-                  details.url,
-                  {
-                    talerWithdrawUri: talerUri,
-                  },
-                );
-              case TalerUriType.TalerPay:
-                return makeSyncWalletRedirect(
-                  "pay.html",
-                  details.tabId,
-                  details.url,
-                  {
-                    talerPayUri: talerUri,
-                  },
-                );
-              case TalerUriType.TalerTip:
-                return makeSyncWalletRedirect(
-                  "tip.html",
-                  details.tabId,
-                  details.url,
-                  {
-                    talerTipUri: talerUri,
-                  },
-                );
-              case TalerUriType.TalerRefund:
-                return makeSyncWalletRedirect(
-                  "refund.html",
-                  details.tabId,
-                  details.url,
-                  {
-                    talerRefundUri: talerUri,
-                  },
-                );
-              case TalerUriType.TalerNotifyReserve:
-                Promise.resolve().then(() => {
-                  const w = currentWallet;
-                  if (!w) {
-                    return;
-                  }
-                  w.handleNotifyReserve();
-                });
-                break;
-
-              default:
-                console.warn(
-                  "Response with HTTP 402 has Taler header, but header value 
is not a taler:// URI.",
-                );
-                break;
-            }
-          }
-        }
-      }
-      return {};
-    },
-    { urls: ["<all_urls>"] },
-    ["responseHeaders", "blocking"],
-  );
+  setupHeaderListener();
 }
diff --git a/webextension/manifest.json b/webextension/manifest.json
index 5bcb8c06..7592b350 100644
--- a/webextension/manifest.json
+++ b/webextension/manifest.json
@@ -24,6 +24,10 @@
 
   "permissions": [
     "storage",
+    "activeTab"
+  ],
+
+  "optional_permissions": [
     "tabs",
     "webRequest",
     "webRequestBlocking",
@@ -39,16 +43,6 @@
     "default_popup": "popup.html"
   },
 
-  "content_scripts": [
-    {
-      "matches": ["*://*/*"],
-      "js": [
-        "contentScript.js"
-      ],
-      "run_at": "document_start"
-    }
-  ],
-
   "background": {
     "page": "background.html",
     "persistent": true
diff --git a/webextension/static/style/wallet.css 
b/webextension/static/style/wallet.css
index 16a414b3..7c06f238 100644
--- a/webextension/static/style/wallet.css
+++ b/webextension/static/style/wallet.css
@@ -1,14 +1,15 @@
 body {
   font-size: 100%;
   overflow-y: scroll;
+  margin-top: 2em;
 }
 
 #main {
-  border: solid 1px black;
+  border: solid 5px black;
   border-radius: 10px;
   margin-left: auto;
   margin-right: auto;
-  margin-top: 2em;
+  padding-top: 2em;
   max-width: 50%;
   padding: 2em;
 }
@@ -18,16 +19,6 @@ header {
   height: 100px;
   margin: 0;
   padding: 0;
-  border-bottom: 1px solid black;
-}
-
-header h1 {
-  font-size: 200%;
-  margin: 0;
-  padding: 0 0 0 120px;
-  position: relative;
-  top: 50%;
-  transform: translateY(-50%);
 }
 
 header #logo {
@@ -37,7 +28,6 @@ header #logo {
   padding: 0;
   margin: 0;
   text-align: center;
-  border-right: 1px solid black;
   background-image: url(/img/logo.png);
   background-size: 100px;
 }
@@ -50,7 +40,6 @@ aside {
 section#main {
   margin: auto;
   padding: 20px;
-  border-left: 1px solid black;
   height: 100%;
   max-width: 50%;
 }
@@ -61,19 +50,23 @@ section#main h1:first-child {
 
 h1 {
   font-size: 160%;
+  font-family: "monospace";
 }
 
 h2 {
   font-size: 140%;
+  font-family: "monospace";
 }
 
 h3 {
   font-size: 120%;
+  font-family: "monospace";
 }
 
 h4,
 h5,
 h6 {
+  font-family: "monospace";
   font-size: 100%;
 }
 
@@ -281,3 +274,17 @@ a.opener {
 object.svg-icon.svg-baseline {
   transform: translate(0, 0.125em);
 }
+
+.switch {
+  position: relative;
+  display: inline-block;
+  width: 60px;
+  height: 34px;
+}
+
+/* Hide default HTML checkbox */
+.switch input {
+  opacity: 0;
+  width: 0;
+  height: 0;
+}
\ No newline at end of file
diff --git a/webextension/static/welcome.html b/webextension/static/welcome.html
index dc893211..07ecac70 100644
--- a/webextension/static/welcome.html
+++ b/webextension/static/welcome.html
@@ -2,7 +2,7 @@
 <html>
   <head>
     <meta charset="UTF-8" />
-    <title>Taler Wallet: Withdraw</title>
+    <title>Taler Wallet Installed</title>
 
     <link rel="icon" href="/img/icon.png" />
     <link rel="stylesheet" type="text/css" href="/style/pure.css" />
@@ -12,7 +12,12 @@
 
   <body>
     <section id="main">
-      <h1>GNU Taler Wallet Installed!</h1>
+      <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;">
+        <h1 style="font-family: monospace; font-size: 250%;">
+          <span style="color: #aa3939;">❰</span>Taler Wallet<span 
style="color: #aa3939;">❱</span>
+        </h1>
+      </div>
+      <h1>Browser Extension Installed!</h1>
       <div id="container">Loading...</div>
     </section>
   </body>
diff --git a/webextension/static/withdraw.html 
b/webextension/static/withdraw.html
index d2aab1b6..5137204b 100644
--- a/webextension/static/withdraw.html
+++ b/webextension/static/withdraw.html
@@ -11,7 +11,11 @@
 
   <body>
     <section id="main">
-      <h1>GNU Taler Wallet</h1>
+      <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;">
+        <h1 style="font-family: monospace; font-size: 250%;">
+          <span style="color: #aa3939;">❰</span>Taler Wallet<span 
style="color: #aa3939;">❱</span>
+        </h1>
+      </div>
       <div class="fade" id="container"></div>
     </section>
   </body>

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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