toggle permission
This commit is contained in:
parent
0b8e0a0806
commit
451dd746da
@ -1,63 +0,0 @@
|
||||
/*
|
||||
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/>
|
||||
*/
|
||||
|
||||
import { h, VNode } from "preact";
|
||||
import { useTranslationContext } from "../context/translation.js";
|
||||
|
||||
export function DebugCheckbox({
|
||||
enabled,
|
||||
onToggle,
|
||||
}: {
|
||||
enabled: boolean;
|
||||
onToggle: () => void;
|
||||
}): VNode {
|
||||
const { i18n } = useTranslationContext();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
checked={enabled}
|
||||
onClick={onToggle}
|
||||
type="checkbox"
|
||||
id="checkbox-perm"
|
||||
style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }}
|
||||
/>
|
||||
<label
|
||||
htmlFor="checkbox-perm"
|
||||
style={{ marginLeft: "0.5em", fontWeight: "bold" }}
|
||||
>
|
||||
<i18n.Translate>
|
||||
Automatically open wallet based on page content
|
||||
</i18n.Translate>
|
||||
</label>
|
||||
<span
|
||||
style={{
|
||||
color: "#383838",
|
||||
fontSize: "smaller",
|
||||
display: "block",
|
||||
marginLeft: "2em",
|
||||
}}
|
||||
>
|
||||
(
|
||||
<i18n.Translate>
|
||||
Enabling this option below will make using the wallet faster, but
|
||||
requires more permissions from your browser.
|
||||
</i18n.Translate>
|
||||
)
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -229,3 +229,10 @@ export const EditExchangeModified = createExample(TestedComponent, {
|
||||
tosProps: normalTosState,
|
||||
},
|
||||
});
|
||||
|
||||
export const CompletedWithoutBankURL = createExample(TestedComponent, {
|
||||
state: {
|
||||
status: "completed",
|
||||
hook: undefined,
|
||||
},
|
||||
});
|
||||
|
@ -37,6 +37,7 @@ import {
|
||||
ButtonWarning,
|
||||
LinkSuccess,
|
||||
SubTitle,
|
||||
SuccessBox,
|
||||
WalletAction,
|
||||
} from "../components/styled/index.js";
|
||||
import { useTranslationContext } from "../context/translation.js";
|
||||
@ -53,7 +54,12 @@ interface Props {
|
||||
talerWithdrawUri?: string;
|
||||
}
|
||||
|
||||
type State = LoadingUri | LoadingExchange | LoadingInfoError | Success;
|
||||
type State =
|
||||
| LoadingUri
|
||||
| LoadingExchange
|
||||
| LoadingInfoError
|
||||
| Success
|
||||
| Completed;
|
||||
|
||||
interface LoadingUri {
|
||||
status: "loading-uri";
|
||||
@ -68,6 +74,11 @@ interface LoadingInfoError {
|
||||
hook: HookError | undefined;
|
||||
}
|
||||
|
||||
type Completed = {
|
||||
status: "completed";
|
||||
hook: undefined;
|
||||
};
|
||||
|
||||
type Success = {
|
||||
status: "success";
|
||||
hook: undefined;
|
||||
@ -185,6 +196,7 @@ export function useComponentState(
|
||||
undefined,
|
||||
);
|
||||
const [doingWithdraw, setDoingWithdraw] = useState<boolean>(false);
|
||||
const [withdrawCompleted, setWithdrawCompleted] = useState<boolean>(false);
|
||||
|
||||
const [showExchangeSelection, setShowExchangeSelection] = useState(false);
|
||||
const [nextExchange, setNextExchange] = useState<string | undefined>();
|
||||
@ -220,6 +232,7 @@ export function useComponentState(
|
||||
if (res.confirmTransferUrl) {
|
||||
document.location.href = res.confirmTransferUrl;
|
||||
}
|
||||
setWithdrawCompleted(true);
|
||||
} catch (e) {
|
||||
if (e instanceof TalerError) {
|
||||
setWithdrawError(e);
|
||||
@ -245,6 +258,12 @@ export function useComponentState(
|
||||
hook: undefined,
|
||||
};
|
||||
}
|
||||
if (withdrawCompleted) {
|
||||
return {
|
||||
status: "completed",
|
||||
hook: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const exchangeHandler: SelectFieldHandler = {
|
||||
onChange: async (e) => setNextExchange(e),
|
||||
@ -332,8 +351,64 @@ export function useComponentState(
|
||||
};
|
||||
}
|
||||
|
||||
export function View({ state }: { state: Success }): VNode {
|
||||
export function View({ state }: { state: State }): VNode {
|
||||
const { i18n } = useTranslationContext();
|
||||
if (state.status === "loading-uri") {
|
||||
if (!state.hook) return <Loading />;
|
||||
|
||||
return (
|
||||
<LoadingError
|
||||
title={
|
||||
<i18n.Translate>Could not get the info from the URI</i18n.Translate>
|
||||
}
|
||||
error={state.hook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (state.status === "loading-exchange") {
|
||||
if (!state.hook) return <Loading />;
|
||||
|
||||
return (
|
||||
<LoadingError
|
||||
title={<i18n.Translate>Could not get exchange</i18n.Translate>}
|
||||
error={state.hook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (state.status === "loading-info") {
|
||||
if (!state.hook) return <Loading />;
|
||||
return (
|
||||
<LoadingError
|
||||
title={
|
||||
<i18n.Translate>Could not get info of withdrawal</i18n.Translate>
|
||||
}
|
||||
error={state.hook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (state.status === "completed") {
|
||||
return (
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
<SubTitle>
|
||||
<i18n.Translate>Digital cash withdrawal</i18n.Translate>
|
||||
</SubTitle>
|
||||
<SuccessBox>
|
||||
<h3>
|
||||
<i18n.Translate>Withdrawal in process...</i18n.Translate>
|
||||
</h3>
|
||||
<p>
|
||||
<i18n.Translate>
|
||||
You can close the page now. Check your bank if the transaction
|
||||
need a confirmation step to be completed
|
||||
</i18n.Translate>
|
||||
</p>
|
||||
</SuccessBox>
|
||||
</WalletAction>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
@ -460,39 +535,5 @@ export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (state.status === "loading-uri") {
|
||||
if (!state.hook) return <Loading />;
|
||||
|
||||
return (
|
||||
<LoadingError
|
||||
title={
|
||||
<i18n.Translate>Could not get the info from the URI</i18n.Translate>
|
||||
}
|
||||
error={state.hook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (state.status === "loading-exchange") {
|
||||
if (!state.hook) return <Loading />;
|
||||
|
||||
return (
|
||||
<LoadingError
|
||||
title={<i18n.Translate>Could not get exchange</i18n.Translate>}
|
||||
error={state.hook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (state.status === "loading-info") {
|
||||
if (!state.hook) return <Loading />;
|
||||
return (
|
||||
<LoadingError
|
||||
title={
|
||||
<i18n.Translate>Could not get info of withdrawal</i18n.Translate>
|
||||
}
|
||||
error={state.hook}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <View state={state} />;
|
||||
}
|
||||
|
@ -17,23 +17,32 @@
|
||||
import { useState, useEffect } from "preact/hooks";
|
||||
import * as wxApi from "../wxApi.js";
|
||||
import { platform } from "../platform/api.js";
|
||||
import { getReadRequestPermissions } from "../permissions.js";
|
||||
import { ToggleHandler } from "../mui/handlers.js";
|
||||
import { TalerError } from "@gnu-taler/taler-wallet-core";
|
||||
|
||||
export function useExtendedPermissions(): [boolean, () => Promise<void>] {
|
||||
export function useExtendedPermissions(): ToggleHandler {
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
|
||||
const [error, setError] = useState<TalerError | undefined>();
|
||||
const toggle = async (): Promise<void> => {
|
||||
return handleExtendedPerm(enabled, setEnabled)
|
||||
return handleExtendedPerm(enabled, setEnabled).catch(e => {
|
||||
setError(TalerError.fromException(e))
|
||||
})
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
async function getExtendedPermValue(): Promise<void> {
|
||||
const res = await wxApi.getExtendedPermissions();
|
||||
const res = await wxApi.containsHeaderListener();
|
||||
setEnabled(res.newValue);
|
||||
}
|
||||
getExtendedPermValue();
|
||||
}, []);
|
||||
return [enabled, toggle];
|
||||
return {
|
||||
value: enabled,
|
||||
button: {
|
||||
onClick: toggle,
|
||||
error
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function handleExtendedPerm(isEnabled: boolean, onChange: (value: boolean) => void): Promise<void> {
|
||||
@ -42,18 +51,20 @@ async function handleExtendedPerm(isEnabled: boolean, onChange: (value: boolean)
|
||||
// as the result of an input event ...
|
||||
let granted: boolean;
|
||||
try {
|
||||
granted = await platform.getPermissionsApi().request(getReadRequestPermissions());
|
||||
granted = await platform.getPermissionsApi().requestHostPermissions();
|
||||
} catch (lastError) {
|
||||
console.error("error requesting permissions");
|
||||
console.error(lastError);
|
||||
onChange(false);
|
||||
return
|
||||
throw lastError;
|
||||
}
|
||||
console.log("permissions granted:", granted);
|
||||
const res = await wxApi.setExtendedPermissions(granted);
|
||||
const res = await wxApi.toggleHeaderListener(granted);
|
||||
onChange(res.newValue);
|
||||
} else {
|
||||
await wxApi.setExtendedPermissions(false).then(r => onChange(r.newValue));
|
||||
try {
|
||||
await wxApi.toggleHeaderListener(false).then(r => onChange(r.newValue));
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -11,6 +11,11 @@ export interface ButtonHandler {
|
||||
error?: TalerError;
|
||||
}
|
||||
|
||||
export interface ToggleHandler {
|
||||
value?: boolean;
|
||||
button: ButtonHandler;
|
||||
}
|
||||
|
||||
export interface SelectFieldHandler {
|
||||
onChange: (value: string) => Promise<void>;
|
||||
error?: string;
|
||||
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
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/>
|
||||
*/
|
||||
|
||||
const perms = {
|
||||
permissions: ["webRequest"],
|
||||
origins: ["http://*/*", "https://*/*"],
|
||||
}
|
||||
export const getReadRequestPermissions = (): typeof perms => perms
|
@ -34,9 +34,9 @@ export interface Permissions {
|
||||
* Compatibility API that works on multiple browsers.
|
||||
*/
|
||||
export interface CrossBrowserPermissionsApi {
|
||||
contains(p: Permissions): Promise<boolean>;
|
||||
request(p: Permissions): Promise<boolean>;
|
||||
remove(p: Permissions): Promise<boolean>;
|
||||
containsHostPermissions(): Promise<boolean>;
|
||||
requestHostPermissions(): Promise<boolean>;
|
||||
removeHostPermissions(): Promise<boolean>;
|
||||
|
||||
addPermissionsListener(callback: (p: Permissions, lastError?: string) => void): void;
|
||||
|
||||
@ -131,6 +131,10 @@ export interface PlatformAPI {
|
||||
* Backend API
|
||||
*/
|
||||
registerTalerHeaderListener(onHeader: (tabId: number, url: string) => void): void;
|
||||
/**
|
||||
* Frontend API
|
||||
*/
|
||||
containsTalerHeaderListener(): boolean;
|
||||
/**
|
||||
* Backend API
|
||||
*/
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
import { classifyTalerUri, CoreApiResponse, TalerUriType } from "@gnu-taler/taler-util";
|
||||
import { getReadRequestPermissions } from "../permissions.js";
|
||||
import { CrossBrowserPermissionsApi, MessageFromBackend, Permissions, PlatformAPI } from "./api.js";
|
||||
|
||||
const api: PlatformAPI = {
|
||||
@ -37,7 +36,8 @@ const api: PlatformAPI = {
|
||||
registerTalerHeaderListener,
|
||||
sendMessageToAllChannels,
|
||||
sendMessageToWalletBackground,
|
||||
useServiceWorkerAsBackgroundProcess
|
||||
useServiceWorkerAsBackgroundProcess,
|
||||
containsTalerHeaderListener,
|
||||
}
|
||||
|
||||
export default api;
|
||||
@ -46,9 +46,15 @@ function isFirefox(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function contains(p: Permissions): Promise<boolean> {
|
||||
const hostPermissions = {
|
||||
permissions: ["webRequest"],
|
||||
origins: ["http://*/*", "https://*/*"],
|
||||
}
|
||||
|
||||
|
||||
export function containsHostPermissions(): Promise<boolean> {
|
||||
return new Promise((res, rej) => {
|
||||
chrome.permissions.contains(p, (resp) => {
|
||||
chrome.permissions.contains(hostPermissions, (resp) => {
|
||||
const le = chrome.runtime.lastError?.message
|
||||
if (le) {
|
||||
rej(le)
|
||||
@ -58,9 +64,9 @@ export function contains(p: Permissions): Promise<boolean> {
|
||||
})
|
||||
}
|
||||
|
||||
export async function request(p: Permissions): Promise<boolean> {
|
||||
export async function requestHostPermissions(): Promise<boolean> {
|
||||
return new Promise((res, rej) => {
|
||||
chrome.permissions.request(p, (resp) => {
|
||||
chrome.permissions.request(hostPermissions, (resp) => {
|
||||
const le = chrome.runtime.lastError?.message
|
||||
if (le) {
|
||||
rej(le)
|
||||
@ -70,9 +76,41 @@ export async function request(p: Permissions): Promise<boolean> {
|
||||
})
|
||||
}
|
||||
|
||||
export async function remove(p: Permissions): Promise<boolean> {
|
||||
type HeaderListenerFunc = (details: chrome.webRequest.WebResponseHeadersDetails) => void
|
||||
let currentHeaderListener: HeaderListenerFunc | undefined = undefined;
|
||||
|
||||
export function containsTalerHeaderListener(): boolean {
|
||||
return currentHeaderListener !== undefined;
|
||||
}
|
||||
|
||||
export async function removeHostPermissions(): Promise<boolean> {
|
||||
//if there is a handler already, remove it
|
||||
if (
|
||||
"webRequest" in chrome &&
|
||||
"onHeadersReceived" in chrome.webRequest &&
|
||||
currentHeaderListener &&
|
||||
chrome.webRequest.onHeadersReceived.hasListener(currentHeaderListener)
|
||||
) {
|
||||
chrome.webRequest.onHeadersReceived.removeListener(currentHeaderListener);
|
||||
}
|
||||
|
||||
currentHeaderListener = undefined;
|
||||
|
||||
//notify the browser about this change, this operation is expensive
|
||||
if ("webRequest" in chrome) {
|
||||
chrome.webRequest.handlerBehaviorChanged(() => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error(JSON.stringify(chrome.runtime.lastError));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (chrome.runtime && chrome.runtime.getManifest().manifest_version === 3) {
|
||||
// Trying to remove host permissions with manifest >= v3 throws an error
|
||||
return true;
|
||||
}
|
||||
return new Promise((res, rej) => {
|
||||
chrome.permissions.remove(p, (resp) => {
|
||||
chrome.permissions.remove(hostPermissions, (resp) => {
|
||||
const le = chrome.runtime.lastError?.message
|
||||
if (le) {
|
||||
rej(le)
|
||||
@ -92,7 +130,7 @@ function addPermissionsListener(callback: (p: Permissions, lastError?: string) =
|
||||
|
||||
function getPermissionsApi(): CrossBrowserPermissionsApi {
|
||||
return {
|
||||
addPermissionsListener, contains, request, remove
|
||||
addPermissionsListener, containsHostPermissions, requestHostPermissions, removeHostPermissions
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,7 +283,6 @@ function getWalletVersion(): WalletVersion {
|
||||
return manifestData;
|
||||
}
|
||||
|
||||
|
||||
function registerTalerHeaderListener(callback: (tabId: number, url: string) => void): void {
|
||||
console.log("setting up header listener");
|
||||
|
||||
@ -271,15 +308,18 @@ function registerTalerHeaderListener(callback: (tabId: number, url: string) => v
|
||||
}
|
||||
return;
|
||||
}
|
||||
const prevHeaderListener = currentHeaderListener;
|
||||
currentHeaderListener = headerListener;
|
||||
|
||||
getPermissionsApi().contains(getReadRequestPermissions()).then(result => {
|
||||
getPermissionsApi().containsHostPermissions().then(result => {
|
||||
//if there is a handler already, remove it
|
||||
if (
|
||||
"webRequest" in chrome &&
|
||||
"onHeadersReceived" in chrome.webRequest &&
|
||||
chrome.webRequest.onHeadersReceived.hasListener(headerListener)
|
||||
prevHeaderListener &&
|
||||
chrome.webRequest.onHeadersReceived.hasListener(prevHeaderListener)
|
||||
) {
|
||||
chrome.webRequest.onHeadersReceived.removeListener(headerListener);
|
||||
chrome.webRequest.onHeadersReceived.removeListener(prevHeaderListener);
|
||||
}
|
||||
//if the result was positive, add the headerListener
|
||||
if (result) {
|
||||
|
@ -22,8 +22,9 @@ const frames = ["popup", "wallet"]
|
||||
const api: PlatformAPI = ({
|
||||
isFirefox: () => false,
|
||||
findTalerUriInActiveTab: async () => undefined,
|
||||
containsTalerHeaderListener: () => { return true },
|
||||
getPermissionsApi: () => ({
|
||||
addPermissionsListener: () => undefined, contains: async () => true, remove: async () => false, request: async () => false
|
||||
addPermissionsListener: () => undefined, containsHostPermissions: async () => true, removeHostPermissions: async () => false, requestHostPermissions: async () => false
|
||||
}),
|
||||
getWalletVersion: () => ({
|
||||
version: 'none'
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { CrossBrowserPermissionsApi, Permissions, PlatformAPI } from "./api.js";
|
||||
import chromePlatform, { contains as chromeContains, remove as chromeRemove, request as chromeRequest } from "./chrome.js";
|
||||
import chromePlatform, { containsHostPermissions as chromeContains, removeHostPermissions as chromeRemove, requestHostPermissions as chromeRequest } from "./chrome.js";
|
||||
|
||||
const api: PlatformAPI = {
|
||||
...chromePlatform,
|
||||
@ -40,9 +40,9 @@ function addPermissionsListener(callback: (p: Permissions) => void): void {
|
||||
function getPermissionsApi(): CrossBrowserPermissionsApi {
|
||||
return {
|
||||
addPermissionsListener,
|
||||
contains: chromeContains,
|
||||
request: chromeRequest,
|
||||
remove: chromeRemove
|
||||
containsHostPermissions: chromeContains,
|
||||
requestHostPermissions: chromeRequest,
|
||||
removeHostPermissions: chromeRemove
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,18 +32,19 @@ export default {
|
||||
|
||||
export const AllOff = createExample(TestedComponent, {
|
||||
deviceName: "this-is-the-device-name",
|
||||
permissionToggle: { value: false, button: {} },
|
||||
setDeviceName: () => Promise.resolve(),
|
||||
});
|
||||
|
||||
export const OneChecked = createExample(TestedComponent, {
|
||||
deviceName: "this-is-the-device-name",
|
||||
permissionsEnabled: true,
|
||||
permissionToggle: { value: false, button: {} },
|
||||
setDeviceName: () => Promise.resolve(),
|
||||
});
|
||||
|
||||
export const WithOneExchange = createExample(TestedComponent, {
|
||||
deviceName: "this-is-the-device-name",
|
||||
permissionsEnabled: true,
|
||||
permissionToggle: { value: false, button: {} },
|
||||
setDeviceName: () => Promise.resolve(),
|
||||
knownExchanges: [
|
||||
{
|
||||
@ -62,7 +63,7 @@ export const WithOneExchange = createExample(TestedComponent, {
|
||||
|
||||
export const WithExchangeInDifferentState = createExample(TestedComponent, {
|
||||
deviceName: "this-is-the-device-name",
|
||||
permissionsEnabled: true,
|
||||
permissionToggle: { value: false, button: {} },
|
||||
setDeviceName: () => Promise.resolve(),
|
||||
knownExchanges: [
|
||||
{
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { ExchangeListItem } from "@gnu-taler/taler-util";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { Checkbox } from "../components/Checkbox.js";
|
||||
import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js";
|
||||
import { JustInDevMode } from "../components/JustInDevMode.js";
|
||||
import { SelectList } from "../components/SelectList.js";
|
||||
import {
|
||||
@ -32,12 +33,13 @@ import { useTranslationContext } from "../context/translation.js";
|
||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||
import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js";
|
||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions.js";
|
||||
import { ToggleHandler } from "../mui/handlers.js";
|
||||
import { Pages } from "../NavigationBar.js";
|
||||
import { buildTermsOfServiceStatus } from "../utils/index.js";
|
||||
import * as wxApi from "../wxApi.js";
|
||||
|
||||
export function SettingsPage(): VNode {
|
||||
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
||||
const permissionToggle = useExtendedPermissions();
|
||||
const { devMode, toggleDevMode } = useDevContext();
|
||||
const { name, update } = useBackupDeviceName();
|
||||
|
||||
@ -52,8 +54,7 @@ export function SettingsPage(): VNode {
|
||||
}
|
||||
deviceName={name}
|
||||
setDeviceName={update}
|
||||
permissionsEnabled={permissionsEnabled}
|
||||
togglePermissions={togglePermissions}
|
||||
permissionToggle={permissionToggle}
|
||||
developerMode={devMode}
|
||||
toggleDeveloperMode={toggleDevMode}
|
||||
/>
|
||||
@ -63,8 +64,7 @@ export function SettingsPage(): VNode {
|
||||
export interface ViewProps {
|
||||
deviceName: string;
|
||||
setDeviceName: (s: string) => Promise<void>;
|
||||
permissionsEnabled: boolean;
|
||||
togglePermissions: () => void;
|
||||
permissionToggle: ToggleHandler;
|
||||
developerMode: boolean;
|
||||
toggleDeveloperMode: () => void;
|
||||
knownExchanges: Array<ExchangeListItem>;
|
||||
@ -72,8 +72,7 @@ export interface ViewProps {
|
||||
|
||||
export function SettingsView({
|
||||
knownExchanges,
|
||||
permissionsEnabled,
|
||||
togglePermissions,
|
||||
permissionToggle,
|
||||
developerMode,
|
||||
toggleDeveloperMode,
|
||||
}: ViewProps): VNode {
|
||||
@ -82,6 +81,12 @@ export function SettingsView({
|
||||
return (
|
||||
<Fragment>
|
||||
<section>
|
||||
{permissionToggle.button.error && (
|
||||
<ErrorTalerOperation
|
||||
title={<i18n.Translate>Could not toggle auto-open</i18n.Translate>}
|
||||
error={permissionToggle.button.error.errorDetail}
|
||||
/>
|
||||
)}
|
||||
<SubTitle>
|
||||
<i18n.Translate>Navigator</i18n.Translate>
|
||||
</SubTitle>
|
||||
@ -98,8 +103,8 @@ export function SettingsView({
|
||||
requires more permissions from your browser.
|
||||
</i18n.Translate>
|
||||
}
|
||||
enabled={permissionsEnabled}
|
||||
onToggle={togglePermissions}
|
||||
enabled={permissionToggle.value!}
|
||||
onToggle={permissionToggle.button.onClick!}
|
||||
/>
|
||||
|
||||
<SubTitle>
|
||||
|
@ -28,7 +28,7 @@ export default {
|
||||
};
|
||||
|
||||
export const Normal = createExample(TestedComponent, {
|
||||
permissionsEnabled: true,
|
||||
permissionToggle: { value: true, button: {} },
|
||||
diagnostics: {
|
||||
errors: [],
|
||||
walletManifestVersion: "1.0",
|
||||
@ -40,9 +40,9 @@ export const Normal = createExample(TestedComponent, {
|
||||
|
||||
export const TimedoutDiagnostics = createExample(TestedComponent, {
|
||||
timedOut: true,
|
||||
permissionsEnabled: false,
|
||||
permissionToggle: { value: true, button: {} },
|
||||
});
|
||||
|
||||
export const RunningDiagnostics = createExample(TestedComponent, {
|
||||
permissionsEnabled: false,
|
||||
permissionToggle: { value: true, button: {} },
|
||||
});
|
||||
|
@ -27,15 +27,15 @@ import { SubTitle, Title } from "../components/styled/index.js";
|
||||
import { useTranslationContext } from "../context/translation.js";
|
||||
import { useDiagnostics } from "../hooks/useDiagnostics.js";
|
||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions.js";
|
||||
import { ToggleHandler } from "../mui/handlers.js";
|
||||
import { platform } from "../platform/api.js";
|
||||
|
||||
export function WelcomePage(): VNode {
|
||||
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
||||
const permissionToggle = useExtendedPermissions();
|
||||
const [diagnostics, timedOut] = useDiagnostics();
|
||||
return (
|
||||
<View
|
||||
permissionsEnabled={permissionsEnabled}
|
||||
togglePermissions={togglePermissions}
|
||||
permissionToggle={permissionToggle}
|
||||
diagnostics={diagnostics}
|
||||
timedOut={timedOut}
|
||||
/>
|
||||
@ -43,14 +43,12 @@ export function WelcomePage(): VNode {
|
||||
}
|
||||
|
||||
export interface ViewProps {
|
||||
permissionsEnabled: boolean;
|
||||
togglePermissions: () => void;
|
||||
permissionToggle: ToggleHandler;
|
||||
diagnostics: WalletDiagnostics | undefined;
|
||||
timedOut: boolean;
|
||||
}
|
||||
export function View({
|
||||
permissionsEnabled,
|
||||
togglePermissions,
|
||||
permissionToggle,
|
||||
diagnostics,
|
||||
timedOut,
|
||||
}: ViewProps): VNode {
|
||||
@ -105,8 +103,8 @@ export function View({
|
||||
requires more permissions from your browser.)
|
||||
</i18n.Translate>
|
||||
}
|
||||
enabled={permissionsEnabled}
|
||||
onToggle={togglePermissions}
|
||||
enabled={permissionToggle.value!}
|
||||
onToggle={permissionToggle.button.onClick!}
|
||||
/>
|
||||
<SubTitle>
|
||||
<i18n.Translate>Next Steps</i18n.Translate>
|
||||
|
@ -345,17 +345,17 @@ export function getDiagnostics(): Promise<WalletDiagnostics> {
|
||||
/**
|
||||
* Get diagnostics information
|
||||
*/
|
||||
export function setExtendedPermissions(
|
||||
export function toggleHeaderListener(
|
||||
value: boolean,
|
||||
): Promise<ExtendedPermissionsResponse> {
|
||||
return callBackend("wxSetExtendedPermissions", { value });
|
||||
return callBackend("toggleHeaderListener", { value });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get diagnostics information
|
||||
*/
|
||||
export function getExtendedPermissions(): Promise<ExtendedPermissionsResponse> {
|
||||
return callBackend("wxGetExtendedPermissions", {});
|
||||
export function containsHeaderListener(): Promise<ExtendedPermissionsResponse> {
|
||||
return callBackend("containsHeaderListener", {});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,6 @@ import {
|
||||
import { SetTimeoutTimerAPI } from "@gnu-taler/taler-wallet-core";
|
||||
import { BrowserCryptoWorkerFactory } from "./browserCryptoWorkerFactory.js";
|
||||
import { BrowserHttpLib } from "./browserHttpLib.js";
|
||||
import { getReadRequestPermissions } from "./permissions.js";
|
||||
import { MessageFromBackend, platform } from "./platform/api.js";
|
||||
import { SynchronousCryptoWorkerFactory } from "./serviceWorkerCryptoWorkerFactory.js";
|
||||
import { ServiceWorkerHttpLib } from "./serviceWorkerHttpLib.js";
|
||||
@ -131,19 +130,19 @@ async function dispatch(
|
||||
r = wrapResponse(await reinitWallet());
|
||||
break;
|
||||
}
|
||||
case "wxGetExtendedPermissions": {
|
||||
const res = await platform.getPermissionsApi().contains(getReadRequestPermissions());
|
||||
case "containsHeaderListener": {
|
||||
const res = await platform.containsTalerHeaderListener();
|
||||
r = wrapResponse({ newValue: res });
|
||||
break;
|
||||
}
|
||||
case "wxSetExtendedPermissions": {
|
||||
case "toggleHeaderListener": {
|
||||
const newVal = req.payload.value;
|
||||
logger.trace("new extended permissions value", newVal);
|
||||
if (newVal) {
|
||||
platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
|
||||
r = wrapResponse({ newValue: true });
|
||||
} else {
|
||||
const rem = await platform.getPermissionsApi().remove(getReadRequestPermissions());
|
||||
const rem = await platform.getPermissionsApi().removeHostPermissions();
|
||||
logger.trace("permissions removed:", rem);
|
||||
r = wrapResponse({ newVal: false });
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user