summaryrefslogtreecommitdiff
path: root/src/webex/pages
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-05-01 14:16:56 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-05-01 14:16:56 +0530
commit609397d95a73bdae55de41c47b19932e810d0320 (patch)
tree34fb9168eb25567c2d14daa5f69301d6932d58c1 /src/webex/pages
parent3f52d293be88f19e8e68aaa8ee6a80cd6c7cc47a (diff)
downloadwallet-core-609397d95a73bdae55de41c47b19932e810d0320.tar.gz
wallet-core-609397d95a73bdae55de41c47b19932e810d0320.tar.bz2
wallet-core-609397d95a73bdae55de41c47b19932e810d0320.zip
drastically reduce permissions for Web integration
The old web integration with more permissions is still available on an opt-in basis.
Diffstat (limited to 'src/webex/pages')
-rw-r--r--src/webex/pages/pay.tsx2
-rw-r--r--src/webex/pages/popup.tsx111
-rw-r--r--src/webex/pages/welcome.tsx57
-rw-r--r--src/webex/pages/withdraw.tsx7
4 files changed, 166 insertions, 11 deletions
diff --git a/src/webex/pages/pay.tsx b/src/webex/pages/pay.tsx
index 61f287708..a69b6b766 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 0fd2477f6..f6d95e2f9 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 eecbe2be5..5092d2dd8 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 efd0adc86..1647a7065 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"