From b011c8a32ed478807737b96a9d7fc4e0ff085bdb Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 14 Oct 2022 16:12:24 -0300 Subject: [PATCH] terms and privacy on exchange selection --- .../TermsOfService/index.ts | 14 ++- .../TermsOfService/state.ts | 23 ++--- .../TermsOfService/stories.tsx | 0 .../TermsOfService/test.ts | 0 .../TermsOfService/utils.ts | 2 +- .../TermsOfService/views.tsx | 9 +- .../src/components/index.stories.tsx | 3 +- .../src/cta/Withdraw/views.tsx | 2 +- .../src/cta/index.stories.ts | 3 +- .../src/platform/chrome.ts | 30 ++++-- .../src/wallet/ExchangeAddConfirm.tsx | 4 +- .../src/wallet/ExchangeSelection/index.ts | 19 ++++ .../src/wallet/ExchangeSelection/state.ts | 47 +++++++++ .../src/wallet/ExchangeSelection/stories.tsx | 12 +++ .../src/wallet/ExchangeSelection/views.tsx | 95 +++++++++---------- .../src/wallet/Settings.tsx | 2 +- .../src/wxBackend.ts | 5 +- 17 files changed, 179 insertions(+), 91 deletions(-) rename packages/taler-wallet-webextension/src/{cta => components}/TermsOfService/index.ts (94%) rename packages/taler-wallet-webextension/src/{cta => components}/TermsOfService/state.ts (86%) rename packages/taler-wallet-webextension/src/{cta => components}/TermsOfService/stories.tsx (100%) rename packages/taler-wallet-webextension/src/{cta => components}/TermsOfService/test.ts (100%) rename packages/taler-wallet-webextension/src/{cta => components}/TermsOfService/utils.ts (99%) rename packages/taler-wallet-webextension/src/{cta => components}/TermsOfService/views.tsx (96%) diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/index.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts similarity index 94% rename from packages/taler-wallet-webextension/src/cta/TermsOfService/index.ts rename to packages/taler-wallet-webextension/src/components/TermsOfService/index.ts index 9485f9d0a..2c77e5d3c 100644 --- a/packages/taler-wallet-webextension/src/cta/TermsOfService/index.ts +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts @@ -31,15 +31,13 @@ import { export interface Props { exchangeUrl: string; - onChange: (v: boolean) => void; - readOnly?: boolean; + onChange?: (v: boolean) => void; } export type State = | State.Loading | State.LoadingUriError | State.ErrorAccepting - | State.ShowContent | State.ShowButtonsAccepted | State.ShowButtonsNotAccepted | State.ShowContent; @@ -62,21 +60,21 @@ export namespace State { export interface BaseInfo { error: undefined; - termsAccepted: ToggleHandler; - showingTermsOfService: ToggleHandler; terms: TermsState; } export interface ShowContent extends BaseInfo { status: "show-content"; - error: undefined; + termsAccepted?: ToggleHandler; + showingTermsOfService?: ToggleHandler; } export interface ShowButtonsAccepted extends BaseInfo { status: "show-buttons-accepted"; - error: undefined; + termsAccepted: ToggleHandler; + showingTermsOfService: ToggleHandler; } export interface ShowButtonsNotAccepted extends BaseInfo { status: "show-buttons-not-accepted"; - error: undefined; + showingTermsOfService: ToggleHandler; } } diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/state.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts similarity index 86% rename from packages/taler-wallet-webextension/src/cta/TermsOfService/state.ts rename to packages/taler-wallet-webextension/src/components/TermsOfService/state.ts index 4e89bc243..30322e139 100644 --- a/packages/taler-wallet-webextension/src/cta/TermsOfService/state.ts +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts @@ -21,11 +21,11 @@ import { Props, State } from "./index.js"; import { buildTermsOfServiceState } from "./utils.js"; export function useComponentState( - { exchangeUrl, readOnly, onChange }: Props, + { exchangeUrl, onChange }: Props, api: typeof wxApi, ): State { - const [showContent, setShowContent] = useState(false); - // const [accepted, setAccepted] = useState(false); + const readOnly = !onChange; + const [showContent, setShowContent] = useState(readOnly); const [errorAccepting, setErrorAccepting] = useState( undefined, ); @@ -78,7 +78,7 @@ export function useComponentState( await api.setExchangeTosAccepted(exchangeUrl, undefined); } // setAccepted(accepted); - onChange(accepted); //external update + if (!readOnly) onChange(accepted); //external update } catch (e) { if (e instanceof Error) { //FIXME: uncomment this and display error @@ -90,16 +90,14 @@ export function useComponentState( const accepted = state.status === "accepted"; - const base: State.BaseInfo = { + const base = { error: undefined, showingTermsOfService: { value: showContent, button: { - onClick: readOnly - ? undefined - : async () => { - setShowContent(!showContent); - }, + onClick: async () => { + setShowContent(!showContent); + }, }, }, terms: state, @@ -118,7 +116,10 @@ export function useComponentState( if (showContent) { return { status: "show-content", - ...base, + error: undefined, + terms: state, + showingTermsOfService: readOnly ? undefined : base.showingTermsOfService, + termsAccepted: readOnly ? undefined : base.termsAccepted, }; } //showing buttons diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/stories.tsx b/packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx similarity index 100% rename from packages/taler-wallet-webextension/src/cta/TermsOfService/stories.tsx rename to packages/taler-wallet-webextension/src/components/TermsOfService/stories.tsx diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/test.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/test.ts similarity index 100% rename from packages/taler-wallet-webextension/src/cta/TermsOfService/test.ts rename to packages/taler-wallet-webextension/src/components/TermsOfService/test.ts diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/utils.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts similarity index 99% rename from packages/taler-wallet-webextension/src/cta/TermsOfService/utils.ts rename to packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts index cee6557f7..5766883ae 100644 --- a/packages/taler-wallet-webextension/src/cta/TermsOfService/utils.ts +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts @@ -97,7 +97,7 @@ export type TermsState = { type TermsStatus = "new" | "accepted" | "changed" | "notfound"; -type TermsDocument = +export type TermsDocument = | TermsDocumentXml | TermsDocumentHtml | TermsDocumentPlain diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/views.tsx b/packages/taler-wallet-webextension/src/components/TermsOfService/views.tsx similarity index 96% rename from packages/taler-wallet-webextension/src/cta/TermsOfService/views.tsx rename to packages/taler-wallet-webextension/src/components/TermsOfService/views.tsx index ed6d7dee4..c7f8ccb78 100644 --- a/packages/taler-wallet-webextension/src/cta/TermsOfService/views.tsx +++ b/packages/taler-wallet-webextension/src/components/TermsOfService/views.tsx @@ -17,7 +17,7 @@ import { Fragment, h, VNode } from "preact"; import { LoadingError } from "../../components/LoadingError.js"; import { useTranslationContext } from "../../context/translation.js"; -import { TermsState } from "./utils.js"; +import { TermsDocument, TermsState } from "./utils.js"; import { State } from "./index.js"; import { CheckboxOutlined } from "../../components/CheckboxOutlined.js"; import { @@ -90,7 +90,6 @@ export function ShowButtonsAcceptedTosView({ } export function ShowButtonsNonAcceptedTosView({ - termsAccepted, showingTermsOfService, terms, }: State.ShowButtonsNotAccepted): VNode { @@ -160,7 +159,7 @@ export function ShowTosContentView({ }: State.ShowContent): VNode { const { i18n } = useTranslationContext(); const ableToReviewTermsOfService = - showingTermsOfService.button.onClick !== undefined; + showingTermsOfService?.button.onClick !== undefined; return ( @@ -195,7 +194,7 @@ export function ShowTosContentView({ )} )} - {termsAccepted && ableToReviewTermsOfService && ( + {showingTermsOfService && ableToReviewTermsOfService && (
)} - {terms.status !== "notfound" && ( + {termsAccepted && terms.status !== "notfound" && (
{ return new Promise((resolve, reject) => { logger.trace("send operation to the wallet background", operation); - chrome.runtime.sendMessage({ operation, payload, id: "(none)" }, (resp) => { - if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError.message); - } - resolve(resp); - // return true to keep the channel open - return true; - }); + chrome.runtime.sendMessage( + { operation, payload, id: `id_${i++ % 1000}` }, + (backgroundResponse) => { + console.log("BUG: got response from background", backgroundResponse); + + if (chrome.runtime.lastError) { + reject(chrome.runtime.lastError.message); + } + // const apiResponse = JSON.parse(resp) + resolve(backgroundResponse); + + // return true to keep the channel open + return true; + }, + ); }); } @@ -364,7 +373,10 @@ function listenToAllChannels( ) => void, ): void { chrome.runtime.onMessage.addListener((m, s, c) => { - cb(m, s, c); + cb(m, s, (apiResponse) => { + console.log("BUG: sending response to client", apiResponse); + c(apiResponse); + }); // keep the connection open return true; diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx index b0602d1e6..2118c8984 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx @@ -16,11 +16,9 @@ import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; import { Title } from "../components/styled/index.js"; +import { TermsOfService } from "../components/TermsOfService/index.js"; import { useTranslationContext } from "../context/translation.js"; -import { TermsOfService } from "../cta/TermsOfService/index.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; -import * as wxApi from "../wxApi.js"; export interface Props { url: string; diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts index 06d519268..2ea73d310 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts @@ -21,6 +21,7 @@ import { FeeDescriptionPair, } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; +import { TermsState } from "../../components/TermsOfService/utils.js"; import { HookError } from "../../hooks/useAsyncAsHook.js"; import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js"; import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js"; @@ -31,7 +32,9 @@ import { ComparingView, ErrorLoadingView, NoExchangesView, + PrivacyContentView, ReadyView, + TosContentView, } from "./views.js"; export interface Props { @@ -46,6 +49,8 @@ export type State = | State.LoadingUriError | State.Ready | State.Comparing + | State.ShowingTos + | State.ShowingPrivacy | SelectExchangeState.NoExchange; export namespace State { @@ -63,6 +68,8 @@ export namespace State { exchanges: SelectFieldHandler; selected: ExchangeFullDetails; error: undefined; + onShowTerms: ButtonHandler; + onShowPrivacy: ButtonHandler; } export interface Ready extends BaseInfo { @@ -76,6 +83,16 @@ export namespace State { onReset: ButtonHandler; onSelect: ButtonHandler; } + export interface ShowingTos { + status: "showing-tos"; + exchangeUrl: string; + onClose: ButtonHandler; + } + export interface ShowingPrivacy { + status: "showing-privacy"; + exchangeUrl: string; + onClose: ButtonHandler; + } } const viewMapping: StateViewMap = { @@ -83,6 +100,8 @@ const viewMapping: StateViewMap = { "error-loading": ErrorLoadingView, comparing: ComparingView, "no-exchange": NoExchangesView, + "showing-tos": TosContentView, + "showing-privacy": PrivacyContentView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts index e1b270a42..2450a90ca 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts @@ -50,9 +50,15 @@ export function useComponentState( const original = !initialExchange ? undefined : await api.getExchangeDetailedInfo(initialExchange.exchangeBaseUrl); + return { exchanges, selected, original }; }, [value]); + const [showingTos, setShowingTos] = useState(undefined); + const [showingPrivacy, setShowingPrivacy] = useState( + undefined, + ); + if (!hook) { return { status: "loading", @@ -82,6 +88,27 @@ export function useComponentState( {} as Record, ); + if (showingPrivacy) { + return { + status: "showing-privacy", + error: undefined, + onClose: { + onClick: async () => setShowingPrivacy(undefined), + }, + exchangeUrl: showingPrivacy, + }; + } + if (showingTos) { + return { + status: "showing-tos", + error: undefined, + onClose: { + onClick: async () => setShowingTos(undefined), + }, + exchangeUrl: showingTos, + }; + } + if (!original) { // !original <=> selected == original return { @@ -98,6 +125,16 @@ export function useComponentState( onClick: onCancel, }, selected, + onShowPrivacy: { + onClick: async () => { + setShowingPrivacy(selected.exchangeBaseUrl); + }, + }, + onShowTerms: { + onClick: async () => { + setShowingTos(selected.exchangeBaseUrl); + }, + }, }; } @@ -140,6 +177,16 @@ export function useComponentState( onSelection(selected.exchangeBaseUrl); }, }, + onShowPrivacy: { + onClick: async () => { + setShowingPrivacy(selected.exchangeBaseUrl); + }, + }, + onShowTerms: { + onClick: async () => { + setShowingTos(selected.exchangeBaseUrl); + }, + }, selected, pairTimeline, }; diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx index 38b63e615..dfa8bbd39 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx @@ -39,6 +39,8 @@ export const Bitcoin1 = createExample(ReadyView, { transferFees: {}, globalFees: [], } as any, + onShowPrivacy: {}, + onShowTerms: {}, onClose: {}, }); export const Bitcoin2 = createExample(ReadyView, { @@ -57,6 +59,8 @@ export const Bitcoin2 = createExample(ReadyView, { transferFees: {}, globalFees: [], } as any, + onShowPrivacy: {}, + onShowTerms: {}, onClose: {}, }); @@ -75,6 +79,8 @@ export const Kudos1 = createExample(ReadyView, { transferFees: {}, globalFees: [], } as any, + onShowPrivacy: {}, + onShowTerms: {}, onClose: {}, }); export const Kudos2 = createExample(ReadyView, { @@ -93,6 +99,8 @@ export const Kudos2 = createExample(ReadyView, { transferFees: {}, globalFees: [], } as any, + onShowPrivacy: {}, + onShowTerms: {}, onClose: {}, }); export const ComparingBitcoin = createExample(ComparingView, { @@ -108,6 +116,8 @@ export const ComparingBitcoin = createExample(ComparingView, { globalFees: [], } as any, onReset: {}, + onShowPrivacy: {}, + onShowTerms: {}, onSelect: {}, error: undefined, pairTimeline: { @@ -130,6 +140,8 @@ export const ComparingKudos = createExample(ComparingView, { globalFees: [], } as any, onReset: {}, + onShowPrivacy: {}, + onShowTerms: {}, onSelect: {}, error: undefined, pairTimeline: { diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx index d39aa3878..e89fc8879 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx @@ -22,6 +22,7 @@ import { Amount } from "../../components/Amount.js"; import { LoadingError } from "../../components/LoadingError.js"; import { SelectList } from "../../components/SelectList.js"; import { Input, SvgIcon } from "../../components/styled/index.js"; +import { TermsOfService } from "../../components/TermsOfService/index.js"; import { Time } from "../../components/Time.js"; import { useTranslationContext } from "../../context/translation.js"; import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js"; @@ -119,6 +120,36 @@ export function ErrorLoadingView({ error }: State.LoadingUriError): VNode { ); } +export function PrivacyContentView({ + exchangeUrl, + onClose, +}: State.ShowingPrivacy): VNode { + const { i18n } = useTranslationContext(); + return ( +
+ +
show privacy terms for {exchangeUrl}
+
+ ); +} + +export function TosContentView({ + exchangeUrl, + onClose, +}: State.ShowingTos): VNode { + const { i18n } = useTranslationContext(); + return ( +
+ + +
+ ); +} + export function NoExchangesView({ currency, }: SelectExchangeState.NoExchange): VNode { @@ -145,6 +176,8 @@ export function ComparingView({ onReset, onSelect, pairTimeline, + onShowPrivacy, + onShowTerms, }: State.Comparing): VNode { const { i18n } = useTranslationContext(); return ( @@ -304,54 +337,14 @@ export function ComparingView({ {" "}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Wallet operations - - Fee -
history(i) 0.1
kyc (i) 0.1
account (i) 0.1
purse (i) 0.1
wire SEPA (i) 0.1
closing SEPA(i) 0.1
wad SEPA (i) 0.1
-
- - + +
@@ -362,6 +355,8 @@ export function ReadyView({ exchanges, selected, onClose, + onShowPrivacy, + onShowTerms, }: State.Ready): VNode { const { i18n } = useTranslationContext(); @@ -616,8 +611,12 @@ export function ReadyView({
- - + +
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 56e610e8a..80843ac27 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -36,7 +36,7 @@ import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js"; import { useAutoOpenPermissions } from "../hooks/useAutoOpenPermissions.js"; import { ToggleHandler } from "../mui/handlers.js"; import { Pages } from "../NavigationBar.js"; -import { buildTermsOfServiceStatus } from "../cta/TermsOfService/utils.js"; +import { buildTermsOfServiceStatus } from "../components/TermsOfService/utils.js"; import * as wxApi from "../wxApi.js"; import { platform } from "../platform/api.js"; import { useClipboardPermissions } from "../hooks/useClipboardPermissions.js"; diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts index 1bb8ac332..13cffe747 100644 --- a/packages/taler-wallet-webextension/src/wxBackend.ts +++ b/packages/taler-wallet-webextension/src/wxBackend.ts @@ -182,6 +182,7 @@ async function dispatch( break; } r = await w.handleCoreApiRequest(req.operation, req.id, req.payload); + console.log("response received from wallet", r); break; } } @@ -330,7 +331,9 @@ export async function wxMain(): Promise { // script on the page platform.listenToAllChannels((message, sender, callback) => { afterWalletIsInitialized.then(() => { - dispatch(message, sender, callback); + dispatch(message, sender, (response: CoreApiResponse) => { + callback(response); + }); }); });