make permissions work for firefox
This commit is contained in:
parent
a3354306c6
commit
e15e56c65a
@ -33,3 +33,53 @@ export function isFirefox(): boolean {
|
|||||||
export function isNode(): boolean {
|
export function isNode(): boolean {
|
||||||
return typeof process !== "undefined" && process.release.name === "node";
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -25,6 +25,8 @@ import { getDiagnostics } from "../wxApi";
|
|||||||
import { PageLink } from "../renderHtml";
|
import { PageLink } from "../renderHtml";
|
||||||
import { WalletDiagnostics } from "../../types/walletTypes";
|
import { WalletDiagnostics } from "../../types/walletTypes";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
import { getPermissionsApi } from "../compat";
|
||||||
|
import { extendedPermissions } from "../permissions";
|
||||||
|
|
||||||
function Diagnostics(): JSX.Element | null {
|
function Diagnostics(): JSX.Element | null {
|
||||||
const [timedOut, setTimedOut] = useState(false);
|
const [timedOut, setTimedOut] = useState(false);
|
||||||
@ -97,22 +99,51 @@ function Diagnostics(): JSX.Element | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function PermissionsCheckbox(): JSX.Element {
|
export function PermissionsCheckbox(): JSX.Element {
|
||||||
const [extendedPermissions, setExtendedPermissions] = useState(false);
|
const [extendedPermissionsEnabled, setExtendedPermissionsEnabled] = useState(
|
||||||
async function handleExtendedPerm(newVal: boolean): Promise<void> {
|
false,
|
||||||
const res = await wxApi.setExtendedPermissions(newVal);
|
);
|
||||||
setExtendedPermissions(res.newValue);
|
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(() => {
|
useEffect(() => {
|
||||||
async function getExtendedPermValue(): Promise<void> {
|
async function getExtendedPermValue(): Promise<void> {
|
||||||
const res = await wxApi.getExtendedPermissions();
|
const res = await wxApi.getExtendedPermissions();
|
||||||
setExtendedPermissions(res.newValue);
|
setExtendedPermissionsEnabled(res.newValue);
|
||||||
}
|
}
|
||||||
getExtendedPermValue();
|
getExtendedPermValue();
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
checked={extendedPermissions}
|
checked={extendedPermissionsEnabled}
|
||||||
onChange={(x) => handleExtendedPerm(x.target.checked)}
|
onChange={(x) => handleExtendedPerm(x.target.checked)}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id="checkbox-perm"
|
id="checkbox-perm"
|
||||||
|
20
src/webex/permissions.ts
Normal file
20
src/webex/permissions.ts
Normal file
@ -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://*/*"],
|
||||||
|
};
|
@ -40,11 +40,12 @@ import { BrowserHttpLib } from "../util/http";
|
|||||||
import { OpenedPromise, openPromise } from "../util/promiseUtils";
|
import { OpenedPromise, openPromise } from "../util/promiseUtils";
|
||||||
import { classifyTalerUri, TalerUriType } from "../util/taleruri";
|
import { classifyTalerUri, TalerUriType } from "../util/taleruri";
|
||||||
import { Wallet } from "../wallet";
|
import { Wallet } from "../wallet";
|
||||||
import { isFirefox } from "./compat";
|
import { isFirefox, getPermissionsApi } from "./compat";
|
||||||
import { MessageType } from "./messages";
|
import { MessageType } from "./messages";
|
||||||
import * as wxApi from "./wxApi";
|
import * as wxApi from "./wxApi";
|
||||||
import MessageSender = chrome.runtime.MessageSender;
|
import MessageSender = chrome.runtime.MessageSender;
|
||||||
import { Database } from "../util/query";
|
import { Database } from "../util/query";
|
||||||
|
import { extendedPermissions } from "./permissions";
|
||||||
|
|
||||||
const NeedsWallet = Symbol("NeedsWallet");
|
const NeedsWallet = Symbol("NeedsWallet");
|
||||||
|
|
||||||
@ -63,11 +64,6 @@ let outdatedDbVersion: number | undefined;
|
|||||||
|
|
||||||
const walletInit: OpenedPromise<void> = openPromise<void>();
|
const walletInit: OpenedPromise<void> = openPromise<void>();
|
||||||
|
|
||||||
const extendedPermissions = {
|
|
||||||
permissions: ["webRequest", "webRequestBlocking"],
|
|
||||||
origins: ["http://*/*", "https://*/*"],
|
|
||||||
};
|
|
||||||
|
|
||||||
const notificationPorts: chrome.runtime.Port[] = [];
|
const notificationPorts: chrome.runtime.Port[] = [];
|
||||||
|
|
||||||
async function handleMessage(
|
async function handleMessage(
|
||||||
@ -216,7 +212,7 @@ async function handleMessage(
|
|||||||
if (!proposalId) {
|
if (!proposalId) {
|
||||||
throw Error("proposalId missing");
|
throw Error("proposalId missing");
|
||||||
}
|
}
|
||||||
if (typeof proposalId !== "string") {
|
if (typeof proposalId !== "string") {
|
||||||
throw Error("proposalId must be a string");
|
throw Error("proposalId must be a string");
|
||||||
}
|
}
|
||||||
return needsWallet().getPurchaseDetails(proposalId);
|
return needsWallet().getPurchaseDetails(proposalId);
|
||||||
@ -294,26 +290,13 @@ async function handleMessage(
|
|||||||
return needsWallet().preparePayForUri(detail.talerPayUri);
|
return needsWallet().preparePayForUri(detail.talerPayUri);
|
||||||
case "set-extended-permissions": {
|
case "set-extended-permissions": {
|
||||||
const newVal = detail.value;
|
const newVal = detail.value;
|
||||||
|
console.log("new extended permissions value", newVal);
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
const res = await new Promise((resolve, reject) => {
|
setupHeaderListener();
|
||||||
chrome.permissions.request(
|
return { newValue: true };
|
||||||
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 {
|
} else {
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
chrome.permissions.remove(extendedPermissions, (rem) => {
|
getPermissionsApi().remove(extendedPermissions, (rem) => {
|
||||||
console.log("permissions removed:", rem);
|
console.log("permissions removed:", rem);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
@ -323,7 +306,7 @@ async function handleMessage(
|
|||||||
}
|
}
|
||||||
case "get-extended-permissions": {
|
case "get-extended-permissions": {
|
||||||
const res = await new Promise((resolve, reject) => {
|
const res = await new Promise((resolve, reject) => {
|
||||||
chrome.permissions.contains(extendedPermissions, (result: boolean) => {
|
getPermissionsApi().contains(extendedPermissions, (result: boolean) => {
|
||||||
resolve(result);
|
resolve(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -590,7 +573,7 @@ function headerListener(
|
|||||||
function setupHeaderListener(): void {
|
function setupHeaderListener(): void {
|
||||||
console.log("setting up header listener");
|
console.log("setting up header listener");
|
||||||
// Handlers for catching HTTP requests
|
// Handlers for catching HTTP requests
|
||||||
chrome.permissions.contains(extendedPermissions, (result: boolean) => {
|
getPermissionsApi().contains(extendedPermissions, (result: boolean) => {
|
||||||
if (
|
if (
|
||||||
chrome.webRequest.onHeadersReceived &&
|
chrome.webRequest.onHeadersReceived &&
|
||||||
chrome.webRequest.onHeadersReceived.hasListener(headerListener)
|
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) {
|
if (chrome.runtime.lastError) {
|
||||||
console.error(chrome.runtime.lastError);
|
console.error(chrome.runtime.lastError);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user