aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-06-03 16:21:09 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-06-03 16:21:21 +0530
commite15e56c65a07b5b39c9f781099909469d65eefba (patch)
tree8559db0839b0f5c881da08d9501f63c8c7eee38c
parenta3354306c629ab3ab5f45617f31b90976416105a (diff)
make permissions work for firefox
-rw-r--r--src/webex/compat.ts50
-rw-r--r--src/webex/pages/welcome.tsx43
-rw-r--r--src/webex/permissions.ts20
-rw-r--r--src/webex/wxBackend.ts45
4 files changed, 124 insertions, 34 deletions
diff --git a/src/webex/compat.ts b/src/webex/compat.ts
index 1cbf34a2c..4635abd80 100644
--- a/src/webex/compat.ts
+++ b/src/webex/compat.ts
@@ -33,3 +33,53 @@ export function isFirefox(): boolean {
export function isNode(): boolean {
return typeof process !== "undefined" && process.release.name === "node";
}
+
+/**
+ * Compatibility API that works on multiple browsers.
+ */
+export interface CrossBrowserPermissionsApi {
+ contains(
+ permissions: chrome.permissions.Permissions,
+ callback: (result: boolean) => void,
+ ): void;
+
+ addPermissionsListener(
+ callback: (permissions: chrome.permissions.Permissions) => void,
+ ): void;
+
+ request(
+ permissions: chrome.permissions.Permissions,
+ callback?: (granted: boolean) => void,
+ ): void;
+
+ remove(
+ permissions: chrome.permissions.Permissions,
+ callback?: (removed: boolean) => void,
+ ): void;
+}
+
+export function getPermissionsApi(): CrossBrowserPermissionsApi {
+ const myBrowser = (globalThis as any).browser;
+ if (
+ typeof myBrowser === "object" &&
+ typeof myBrowser.permissions === "object"
+ ) {
+ return {
+ addPermissionsListener: () => {
+ // Not supported yet.
+ },
+ contains: myBrowser.permissions.contains,
+ request: myBrowser.permissions.request,
+ remove: myBrowser.permissions.remove,
+ };
+ } else {
+ return {
+ addPermissionsListener: chrome.permissions.onAdded.addListener.bind(
+ chrome.permissions.onAdded,
+ ),
+ contains: chrome.permissions.contains,
+ request: chrome.permissions.request,
+ remove: chrome.permissions.remove,
+ };
+ }
+}
diff --git a/src/webex/pages/welcome.tsx b/src/webex/pages/welcome.tsx
index 6e445e431..8d4920cac 100644
--- a/src/webex/pages/welcome.tsx
+++ b/src/webex/pages/welcome.tsx
@@ -25,6 +25,8 @@ import { getDiagnostics } from "../wxApi";
import { PageLink } from "../renderHtml";
import { WalletDiagnostics } from "../../types/walletTypes";
import * as wxApi from "../wxApi";
+import { getPermissionsApi } from "../compat";
+import { extendedPermissions } from "../permissions";
function Diagnostics(): JSX.Element | null {
const [timedOut, setTimedOut] = useState(false);
@@ -97,22 +99,51 @@ function Diagnostics(): JSX.Element | null {
}
export function PermissionsCheckbox(): JSX.Element {
- const [extendedPermissions, setExtendedPermissions] = useState(false);
- async function handleExtendedPerm(newVal: boolean): Promise<void> {
- const res = await wxApi.setExtendedPermissions(newVal);
- setExtendedPermissions(res.newValue);
+ const [extendedPermissionsEnabled, setExtendedPermissionsEnabled] = useState(
+ false,
+ );
+ async function handleExtendedPerm(requestedVal: boolean): Promise<void> {
+ let nextVal: boolean | undefined;
+ if (requestedVal) {
+ const granted = await new Promise<boolean>((resolve, reject) => {
+ // We set permissions here, since apparently FF wants this to be done
+ // as the result of an input event ...
+ getPermissionsApi().request(
+ extendedPermissions,
+ (granted: boolean) => {
+ if (chrome.runtime.lastError) {
+ console.error("error requesting permissions");
+ console.error(chrome.runtime.lastError);
+ reject(chrome.runtime.lastError);
+ return;
+ }
+ console.log("permissions granted:", granted);
+ resolve(granted);
+ },
+ );
+ });
+ const res = await wxApi.setExtendedPermissions(granted);
+ console.log(res);
+ nextVal = res.newValue;
+ } else {
+ const res = await wxApi.setExtendedPermissions(false);
+ console.log(res);
+ nextVal = res.newValue;
+ }
+ console.log("new permissions applied:", nextVal);
+ setExtendedPermissionsEnabled(nextVal ?? false);
}
useEffect(() => {
async function getExtendedPermValue(): Promise<void> {
const res = await wxApi.getExtendedPermissions();
- setExtendedPermissions(res.newValue);
+ setExtendedPermissionsEnabled(res.newValue);
}
getExtendedPermValue();
});
return (
<div>
<input
- checked={extendedPermissions}
+ checked={extendedPermissionsEnabled}
onChange={(x) => handleExtendedPerm(x.target.checked)}
type="checkbox"
id="checkbox-perm"
diff --git a/src/webex/permissions.ts b/src/webex/permissions.ts
new file mode 100644
index 000000000..57ca6dc66
--- /dev/null
+++ b/src/webex/permissions.ts
@@ -0,0 +1,20 @@
+/*
+ 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/>
+ */
+
+export const extendedPermissions = {
+ permissions: ["webRequest", "webRequestBlocking"],
+ origins: ["http://*/*", "https://*/*"],
+}; \ No newline at end of file
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 0e8b53070..54486c356 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -40,11 +40,12 @@ import { BrowserHttpLib } from "../util/http";
import { OpenedPromise, openPromise } from "../util/promiseUtils";
import { classifyTalerUri, TalerUriType } from "../util/taleruri";
import { Wallet } from "../wallet";
-import { isFirefox } from "./compat";
+import { isFirefox, getPermissionsApi } from "./compat";
import { MessageType } from "./messages";
import * as wxApi from "./wxApi";
import MessageSender = chrome.runtime.MessageSender;
import { Database } from "../util/query";
+import { extendedPermissions } from "./permissions";
const NeedsWallet = Symbol("NeedsWallet");
@@ -63,11 +64,6 @@ let outdatedDbVersion: number | undefined;
const walletInit: OpenedPromise<void> = openPromise<void>();
-const extendedPermissions = {
- permissions: ["webRequest", "webRequestBlocking"],
- origins: ["http://*/*", "https://*/*"],
-};
-
const notificationPorts: chrome.runtime.Port[] = [];
async function handleMessage(
@@ -216,7 +212,7 @@ async function handleMessage(
if (!proposalId) {
throw Error("proposalId missing");
}
- if (typeof proposalId !== "string") {
+ if (typeof proposalId !== "string") {
throw Error("proposalId must be a string");
}
return needsWallet().getPurchaseDetails(proposalId);
@@ -294,26 +290,13 @@ async function handleMessage(
return needsWallet().preparePayForUri(detail.talerPayUri);
case "set-extended-permissions": {
const newVal = detail.value;
+ console.log("new extended permissions value", newVal);
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 };
+ setupHeaderListener();
+ return { newValue: true };
} else {
await new Promise((resolve, reject) => {
- chrome.permissions.remove(extendedPermissions, (rem) => {
+ getPermissionsApi().remove(extendedPermissions, (rem) => {
console.log("permissions removed:", rem);
resolve();
});
@@ -323,7 +306,7 @@ async function handleMessage(
}
case "get-extended-permissions": {
const res = await new Promise((resolve, reject) => {
- chrome.permissions.contains(extendedPermissions, (result: boolean) => {
+ getPermissionsApi().contains(extendedPermissions, (result: boolean) => {
resolve(result);
});
});
@@ -590,7 +573,7 @@ function headerListener(
function setupHeaderListener(): void {
console.log("setting up header listener");
// Handlers for catching HTTP requests
- chrome.permissions.contains(extendedPermissions, (result: boolean) => {
+ getPermissionsApi().contains(extendedPermissions, (result: boolean) => {
if (
chrome.webRequest.onHeadersReceived &&
chrome.webRequest.onHeadersReceived.hasListener(headerListener)
@@ -644,9 +627,15 @@ export async function wxMain(): Promise<void> {
});
});
- setupHeaderListener();
+ try {
+ setupHeaderListener();
+ } catch (e) {
+ console.log(e);
+ }
- chrome.permissions.onAdded.addListener((perm) => {
+ // On platforms that support it, also listen to external
+ // modification of permissions.
+ getPermissionsApi().addPermissionsListener((perm) => {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
return;