summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-10-14 16:12:24 -0300
committerSebastian <sebasjm@gmail.com>2022-10-14 16:12:49 -0300
commitb011c8a32ed478807737b96a9d7fc4e0ff085bdb (patch)
treef9961a73888b83743431acf134da7f3da22fa4e9 /packages/taler-wallet-webextension/src/cta
parent6acddd6d70abc568e4b3740f56662691278aa645 (diff)
downloadwallet-core-b011c8a32ed478807737b96a9d7fc4e0ff085bdb.tar.gz
wallet-core-b011c8a32ed478807737b96a9d7fc4e0ff085bdb.tar.bz2
wallet-core-b011c8a32ed478807737b96a9d7fc4e0ff085bdb.zip
terms and privacy on exchange selection
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta')
-rw-r--r--packages/taler-wallet-webextension/src/cta/TermsOfService/index.ts96
-rw-r--r--packages/taler-wallet-webextension/src/cta/TermsOfService/state.ts136
-rw-r--r--packages/taler-wallet-webextension/src/cta/TermsOfService/stories.tsx29
-rw-r--r--packages/taler-wallet-webextension/src/cta/TermsOfService/test.ts28
-rw-r--r--packages/taler-wallet-webextension/src/cta/TermsOfService/utils.ts130
-rw-r--r--packages/taler-wallet-webextension/src/cta/TermsOfService/views.tsx224
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/cta/index.stories.ts3
8 files changed, 2 insertions, 646 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/index.ts b/packages/taler-wallet-webextension/src/cta/TermsOfService/index.ts
deleted file mode 100644
index 9485f9d0a..000000000
--- a/packages/taler-wallet-webextension/src/cta/TermsOfService/index.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
-import { ToggleHandler } from "../../mui/handlers.js";
-import { compose, StateViewMap } from "../../utils/index.js";
-import * as wxApi from "../../wxApi.js";
-import { useComponentState } from "./state.js";
-import { TermsState } from "./utils.js";
-import {
- ErrorAcceptingView,
- LoadingUriView,
- ShowButtonsAcceptedTosView,
- ShowButtonsNonAcceptedTosView,
- ShowTosContentView,
-} from "./views.js";
-
-export interface Props {
- exchangeUrl: string;
- onChange: (v: boolean) => void;
- readOnly?: boolean;
-}
-
-export type State =
- | State.Loading
- | State.LoadingUriError
- | State.ErrorAccepting
- | State.ShowContent
- | State.ShowButtonsAccepted
- | State.ShowButtonsNotAccepted
- | State.ShowContent;
-
-export namespace State {
- export interface Loading {
- status: "loading";
- error: undefined;
- }
-
- export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
- }
-
- export interface ErrorAccepting {
- status: "error-accepting";
- error: HookError;
- }
-
- export interface BaseInfo {
- error: undefined;
- termsAccepted: ToggleHandler;
- showingTermsOfService: ToggleHandler;
- terms: TermsState;
- }
- export interface ShowContent extends BaseInfo {
- status: "show-content";
- error: undefined;
- }
- export interface ShowButtonsAccepted extends BaseInfo {
- status: "show-buttons-accepted";
- error: undefined;
- }
- export interface ShowButtonsNotAccepted extends BaseInfo {
- status: "show-buttons-not-accepted";
- error: undefined;
- }
-}
-
-const viewMapping: StateViewMap<State> = {
- loading: Loading,
- "loading-error": LoadingUriView,
- "show-content": ShowTosContentView,
- "show-buttons-accepted": ShowButtonsAcceptedTosView,
- "show-buttons-not-accepted": ShowButtonsNonAcceptedTosView,
- "error-accepting": ErrorAcceptingView,
-};
-
-export const TermsOfService = compose(
- "TermsOfService",
- (p: Props) => useComponentState(p, wxApi),
- viewMapping,
-);
diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/state.ts b/packages/taler-wallet-webextension/src/cta/TermsOfService/state.ts
deleted file mode 100644
index 4e89bc243..000000000
--- a/packages/taler-wallet-webextension/src/cta/TermsOfService/state.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-import { useState } from "preact/hooks";
-import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
-import * as wxApi from "../../wxApi.js";
-import { Props, State } from "./index.js";
-import { buildTermsOfServiceState } from "./utils.js";
-
-export function useComponentState(
- { exchangeUrl, readOnly, onChange }: Props,
- api: typeof wxApi,
-): State {
- const [showContent, setShowContent] = useState<boolean>(false);
- // const [accepted, setAccepted] = useState<boolean>(false);
- const [errorAccepting, setErrorAccepting] = useState<Error | undefined>(
- undefined,
- );
-
- /**
- * For the exchange selected, bring the status of the terms of service
- */
- const terms = useAsyncAsHook(async () => {
- const exchangeTos = await api.getExchangeTos(exchangeUrl, ["text/xml"]);
-
- const state = buildTermsOfServiceState(exchangeTos);
-
- return { state };
- }, []);
-
- if (!terms) {
- return {
- status: "loading",
- error: undefined,
- };
- }
- if (terms.hasError) {
- return {
- status: "loading-error",
- error: terms,
- };
- }
-
- if (errorAccepting) {
- return {
- status: "error-accepting",
- error: {
- hasError: true,
- operational: false,
- message: errorAccepting.message,
- },
- };
- }
-
- const { state } = terms.response;
-
- async function onUpdate(accepted: boolean): Promise<void> {
- if (!state) return;
-
- try {
- if (accepted) {
- await api.setExchangeTosAccepted(exchangeUrl, state.version);
- } else {
- // mark as not accepted
- await api.setExchangeTosAccepted(exchangeUrl, undefined);
- }
- // setAccepted(accepted);
- onChange(accepted); //external update
- } catch (e) {
- if (e instanceof Error) {
- //FIXME: uncomment this and display error
- // setErrorAccepting(e.message);
- setErrorAccepting(e);
- }
- }
- }
-
- const accepted = state.status === "accepted";
-
- const base: State.BaseInfo = {
- error: undefined,
- showingTermsOfService: {
- value: showContent,
- button: {
- onClick: readOnly
- ? undefined
- : async () => {
- setShowContent(!showContent);
- },
- },
- },
- terms: state,
- termsAccepted: {
- value: accepted,
- button: {
- onClick: async () => {
- const newValue = !accepted; //toggle
- onUpdate(newValue);
- setShowContent(false);
- },
- },
- },
- };
-
- if (showContent) {
- return {
- status: "show-content",
- ...base,
- };
- }
- //showing buttons
- if (accepted) {
- return {
- status: "show-buttons-accepted",
- ...base,
- };
- } else {
- return {
- status: "show-buttons-not-accepted",
- ...base,
- };
- }
-}
diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/stories.tsx b/packages/taler-wallet-webextension/src/cta/TermsOfService/stories.tsx
deleted file mode 100644
index 2479274cb..000000000
--- a/packages/taler-wallet-webextension/src/cta/TermsOfService/stories.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { createExample } from "../../test-utils.js";
-// import { ReadyView } from "./views.js";
-
-export default {
- title: "TermsOfService",
-};
-
-// export const Ready = createExample(ReadyView, {});
diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/test.ts b/packages/taler-wallet-webextension/src/cta/TermsOfService/test.ts
deleted file mode 100644
index eae4d4ca2..000000000
--- a/packages/taler-wallet-webextension/src/cta/TermsOfService/test.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { expect } from "chai";
-
-describe("test description", () => {
- it("should assert", () => {
- expect([]).deep.equals([]);
- });
-});
diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/utils.ts b/packages/taler-wallet-webextension/src/cta/TermsOfService/utils.ts
deleted file mode 100644
index cee6557f7..000000000
--- a/packages/taler-wallet-webextension/src/cta/TermsOfService/utils.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-import { GetExchangeTosResult } from "@gnu-taler/taler-util";
-
-export function buildTermsOfServiceState(
- tos: GetExchangeTosResult,
-): TermsState {
- const content: TermsDocument | undefined = parseTermsOfServiceContent(
- tos.contentType,
- tos.content,
- );
-
- const status: TermsStatus = buildTermsOfServiceStatus(
- tos.content,
- tos.acceptedEtag,
- tos.currentEtag,
- );
-
- return { content, status, version: tos.currentEtag };
-}
-export function buildTermsOfServiceStatus(
- content: string | undefined,
- acceptedVersion: string | undefined,
- currentVersion: string | undefined,
-): TermsStatus {
- return !content
- ? "notfound"
- : !acceptedVersion
- ? "new"
- : acceptedVersion !== currentVersion
- ? "changed"
- : "accepted";
-}
-
-function parseTermsOfServiceContent(
- type: string,
- text: string,
-): TermsDocument | undefined {
- if (type === "text/xml") {
- try {
- const document = new DOMParser().parseFromString(text, "text/xml");
- return { type: "xml", document };
- } catch (e) {
- console.log(e);
- }
- } else if (type === "text/html") {
- try {
- const href = new URL(text);
- return { type: "html", href };
- } catch (e) {
- console.log(e);
- }
- } else if (type === "text/json") {
- try {
- const data = JSON.parse(text);
- return { type: "json", data };
- } catch (e) {
- console.log(e);
- }
- } else if (type === "text/pdf") {
- try {
- const location = new URL(text);
- return { type: "pdf", location };
- } catch (e) {
- console.log(e);
- }
- } else if (type === "text/plain") {
- try {
- const content = text;
- return { type: "plain", content };
- } catch (e) {
- console.log(e);
- }
- }
- return undefined;
-}
-
-export type TermsState = {
- content: TermsDocument | undefined;
- status: TermsStatus;
- version: string;
-};
-
-type TermsStatus = "new" | "accepted" | "changed" | "notfound";
-
-type TermsDocument =
- | TermsDocumentXml
- | TermsDocumentHtml
- | TermsDocumentPlain
- | TermsDocumentJson
- | TermsDocumentPdf;
-
-export interface TermsDocumentXml {
- type: "xml";
- document: Document;
-}
-
-export interface TermsDocumentHtml {
- type: "html";
- href: URL;
-}
-
-export interface TermsDocumentPlain {
- type: "plain";
- content: string;
-}
-
-export interface TermsDocumentJson {
- type: "json";
- data: any;
-}
-
-export interface TermsDocumentPdf {
- type: "pdf";
- location: URL;
-}
diff --git a/packages/taler-wallet-webextension/src/cta/TermsOfService/views.tsx b/packages/taler-wallet-webextension/src/cta/TermsOfService/views.tsx
deleted file mode 100644
index ed6d7dee4..000000000
--- a/packages/taler-wallet-webextension/src/cta/TermsOfService/views.tsx
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 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/>
- */
-
-import { Fragment, h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
-import { useTranslationContext } from "../../context/translation.js";
-import { TermsState } from "./utils.js";
-import { State } from "./index.js";
-import { CheckboxOutlined } from "../../components/CheckboxOutlined.js";
-import {
- LinkSuccess,
- TermsOfService,
- WarningBox,
- WarningText,
-} from "../../components/styled/index.js";
-import { ExchangeXmlTos } from "../../components/ExchangeToS.js";
-import { ToggleHandler } from "../../mui/handlers.js";
-import { Button } from "../../mui/Button.js";
-
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- <LoadingError
- title={<i18n.Translate>Could not load</i18n.Translate>}
- error={error}
- />
- );
-}
-
-export function ErrorAcceptingView({ error }: State.ErrorAccepting): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- <LoadingError
- title={<i18n.Translate>Could not load</i18n.Translate>}
- error={error}
- />
- );
-}
-
-export function ShowButtonsAcceptedTosView({
- termsAccepted,
- showingTermsOfService,
- terms,
-}: State.ShowButtonsAccepted): VNode {
- const { i18n } = useTranslationContext();
- const ableToReviewTermsOfService =
- showingTermsOfService.button.onClick !== undefined;
-
- return (
- <Fragment>
- {ableToReviewTermsOfService && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <LinkSuccess
- upperCased
- onClick={showingTermsOfService.button.onClick}
- >
- <i18n.Translate>Show terms of service</i18n.Translate>
- </LinkSuccess>
- </section>
- )}
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <CheckboxOutlined
- name="terms"
- enabled={termsAccepted.value}
- label={
- <i18n.Translate>
- I accept the exchange terms of service
- </i18n.Translate>
- }
- onToggle={termsAccepted.button.onClick}
- />
- </section>
- </Fragment>
- );
-}
-
-export function ShowButtonsNonAcceptedTosView({
- termsAccepted,
- showingTermsOfService,
- terms,
-}: State.ShowButtonsNotAccepted): VNode {
- const { i18n } = useTranslationContext();
- const ableToReviewTermsOfService =
- showingTermsOfService.button.onClick !== undefined;
-
- if (!ableToReviewTermsOfService) {
- return (
- <Fragment>
- {terms.status === "notfound" && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <WarningText>
- <i18n.Translate>
- Exchange doesn&apos;t have terms of service
- </i18n.Translate>
- </WarningText>
- </section>
- )}
- </Fragment>
- );
- }
-
- return (
- <Fragment>
- {terms.status === "notfound" && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <WarningText>
- <i18n.Translate>
- Exchange doesn&apos;t have terms of service
- </i18n.Translate>
- </WarningText>
- </section>
- )}
- {terms.status === "new" && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <Button
- variant="contained"
- color="success"
- onClick={showingTermsOfService.button.onClick}
- >
- <i18n.Translate>Review exchange terms of service</i18n.Translate>
- </Button>
- </section>
- )}
- {terms.status === "changed" && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <Button
- variant="contained"
- color="success"
- onClick={showingTermsOfService.button.onClick}
- >
- <i18n.Translate>
- Review new version of terms of service
- </i18n.Translate>
- </Button>
- </section>
- )}
- </Fragment>
- );
-}
-
-export function ShowTosContentView({
- termsAccepted,
- showingTermsOfService,
- terms,
-}: State.ShowContent): VNode {
- const { i18n } = useTranslationContext();
- const ableToReviewTermsOfService =
- showingTermsOfService.button.onClick !== undefined;
-
- return (
- <Fragment>
- {terms.status !== "notfound" && !terms.content && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <WarningBox>
- <i18n.Translate>
- The exchange reply with a empty terms of service
- </i18n.Translate>
- </WarningBox>
- </section>
- )}
- {terms.content && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- {terms.content.type === "xml" && (
- <TermsOfService>
- <ExchangeXmlTos doc={terms.content.document} />
- </TermsOfService>
- )}
- {terms.content.type === "plain" && (
- <div style={{ textAlign: "left" }}>
- <pre>{terms.content.content}</pre>
- </div>
- )}
- {terms.content.type === "html" && (
- <iframe src={terms.content.href.toString()} />
- )}
- {terms.content.type === "pdf" && (
- <a href={terms.content.location.toString()} download="tos.pdf">
- <i18n.Translate>Download Terms of Service</i18n.Translate>
- </a>
- )}
- </section>
- )}
- {termsAccepted && ableToReviewTermsOfService && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <LinkSuccess
- upperCased
- onClick={showingTermsOfService.button.onClick}
- >
- <i18n.Translate>Hide terms of service</i18n.Translate>
- </LinkSuccess>
- </section>
- )}
- {terms.status !== "notfound" && (
- <section style={{ justifyContent: "space-around", display: "flex" }}>
- <CheckboxOutlined
- name="terms"
- enabled={termsAccepted.value}
- label={
- <i18n.Translate>
- I accept the exchange terms of service
- </i18n.Translate>
- }
- onToggle={termsAccepted.button.onClick}
- />
- </section>
- )}
- </Fragment>
- );
-}
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
index 44c7db83f..468d22d54 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
@@ -35,7 +35,7 @@ import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
import editIcon from "../../svg/edit_24px.svg";
import { ExchangeDetails, WithdrawDetails } from "../../wallet/Transaction.js";
-import { TermsOfService } from "../TermsOfService/index.js";
+import { TermsOfService } from "../../components/TermsOfService/index.js";
import { State } from "./index.js";
export function LoadingUriView({ error }: State.LoadingUriError): VNode {
diff --git a/packages/taler-wallet-webextension/src/cta/index.stories.ts b/packages/taler-wallet-webextension/src/cta/index.stories.ts
index c54defccf..d920ff854 100644
--- a/packages/taler-wallet-webextension/src/cta/index.stories.ts
+++ b/packages/taler-wallet-webextension/src/cta/index.stories.ts
@@ -24,10 +24,9 @@ import * as a3 from "./Payment/stories.jsx";
import * as a4 from "./Refund/stories.jsx";
import * as a5 from "./Tip/stories.jsx";
import * as a6 from "./Withdraw/stories.jsx";
-import * as a7 from "./TermsOfService/stories.js";
import * as a8 from "./InvoiceCreate/stories.js";
import * as a9 from "./InvoicePay/stories.js";
import * as a10 from "./TransferCreate/stories.js";
import * as a11 from "./TransferPickup/stories.js";
-export default [a1, a3, a4, a5, a6, a7, a8, a9, a10, a11];
+export default [a1, a3, a4, a5, a6, a8, a9, a10, a11];