summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-10-07 12:01:40 +0200
committerFlorian Dold <florian@dold.me>2021-10-07 12:01:40 +0200
commite2fe2d6db16b422ee6d69ef03f1393e1f0f42749 (patch)
tree7016f657b08b284afd62a55752baeab69d7be946 /packages/taler-wallet-webextension
parent2c3456608e8e87a86a5b2f62301b4ea78a2cb00d (diff)
downloadwallet-core-e2fe2d6db16b422ee6d69ef03f1393e1f0f42749.tar.gz
wallet-core-e2fe2d6db16b422ee6d69ef03f1393e1f0f42749.tar.bz2
wallet-core-e2fe2d6db16b422ee6d69ef03f1393e1f0f42749.zip
add anastasis skeleton, put crypto in taler-util
Diffstat (limited to 'packages/taler-wallet-webextension')
-rw-r--r--packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx280
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx280
2 files changed, 358 insertions, 202 deletions
diff --git a/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx
index 6b6e8f5c2..55686ee97 100644
--- a/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/ProviderAddPage.tsx
@@ -14,13 +14,24 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { Amounts, BackupBackupProviderTerms, canonicalizeBaseUrl, i18n } from "@gnu-taler/taler-util";
-import { verify } from "@gnu-taler/taler-wallet-core/src/crypto/primitives/nacl-fast";
+import {
+ Amounts,
+ BackupBackupProviderTerms,
+ canonicalizeBaseUrl,
+ i18n,
+} from "@gnu-taler/taler-util";
import { VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { Checkbox } from "../components/Checkbox";
import { ErrorMessage } from "../components/ErrorMessage";
-import { Button, ButtonPrimary, Input, LightText, PopupBox, SmallLightText } from "../components/styled/index";
+import {
+ Button,
+ ButtonPrimary,
+ Input,
+ LightText,
+ PopupBox,
+ SmallLightText,
+} from "../components/styled/index";
import * as wxApi from "../wxApi";
interface Props {
@@ -30,52 +41,65 @@ interface Props {
function getJsonIfOk(r: Response) {
if (r.ok) {
- return r.json()
+ return r.json();
} else {
if (r.status >= 400 && r.status < 500) {
- throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`)
+ throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`);
} else {
- throw new Error(`Try another server: (${r.status}) ${r.statusText || 'internal server error'}`)
+ throw new Error(
+ `Try another server: (${r.status}) ${
+ r.statusText || "internal server error"
+ }`,
+ );
}
}
}
-
export function ProviderAddPage({ onBack }: Props): VNode {
- const [verifying, setVerifying] = useState<{ url: string, name: string, provider: BackupBackupProviderTerms } | undefined>(undefined)
-
- async function getProviderInfo(url: string): Promise<BackupBackupProviderTerms> {
+ const [verifying, setVerifying] = useState<
+ | { url: string; name: string; provider: BackupBackupProviderTerms }
+ | undefined
+ >(undefined);
+
+ async function getProviderInfo(
+ url: string,
+ ): Promise<BackupBackupProviderTerms> {
return fetch(`${url}config`)
- .catch(e => { throw new Error(`Network error`) })
- .then(getJsonIfOk)
+ .catch((e) => {
+ throw new Error(`Network error`);
+ })
+ .then(getJsonIfOk);
}
if (!verifying) {
- return <SetUrlView
- onCancel={onBack}
- onVerify={(url) => getProviderInfo(url)}
- onConfirm={(url, name) => getProviderInfo(url)
- .then((provider) => {
- setVerifying({ url, name, provider });
- })
- .catch(e => e.message)
- }
- />
+ return (
+ <SetUrlView
+ onCancel={onBack}
+ onVerify={(url) => getProviderInfo(url)}
+ onConfirm={(url, name) =>
+ getProviderInfo(url)
+ .then((provider) => {
+ setVerifying({ url, name, provider });
+ })
+ .catch((e) => e.message)
+ }
+ />
+ );
}
- return <ConfirmProviderView
- provider={verifying.provider}
- url={verifying.url}
- onCancel={() => {
- setVerifying(undefined);
- }}
- onConfirm={() => {
- wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack)
- }}
-
- />
+ return (
+ <ConfirmProviderView
+ provider={verifying.provider}
+ url={verifying.url}
+ onCancel={() => {
+ setVerifying(undefined);
+ }}
+ onConfirm={() => {
+ wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack);
+ }}
+ />
+ );
}
-
export interface SetUrlViewProps {
initialValue?: string;
onCancel: () => void;
@@ -84,83 +108,137 @@ export interface SetUrlViewProps {
withError?: string;
}
-export function SetUrlView({ initialValue, onCancel, onVerify, onConfirm, withError }: SetUrlViewProps) {
- const [value, setValue] = useState<string>(initialValue || "")
- const [urlError, setUrlError] = useState(false)
- const [name, setName] = useState<string|undefined>(undefined)
- const [error, setError] = useState<string | undefined>(withError)
+export function SetUrlView({
+ initialValue,
+ onCancel,
+ onVerify,
+ onConfirm,
+ withError,
+}: SetUrlViewProps) {
+ const [value, setValue] = useState<string>(initialValue || "");
+ const [urlError, setUrlError] = useState(false);
+ const [name, setName] = useState<string | undefined>(undefined);
+ const [error, setError] = useState<string | undefined>(withError);
useEffect(() => {
try {
- const url = canonicalizeBaseUrl(value)
- onVerify(url).then(r => {
- setUrlError(false)
- setName(new URL(url).hostname)
- }).catch(() => {
- setUrlError(true)
- setName(undefined)
- })
+ const url = canonicalizeBaseUrl(value);
+ onVerify(url)
+ .then((r) => {
+ setUrlError(false);
+ setName(new URL(url).hostname);
+ })
+ .catch(() => {
+ setUrlError(true);
+ setName(undefined);
+ });
} catch {
- setUrlError(true)
- setName(undefined)
+ setUrlError(true);
+ setName(undefined);
}
- }, [value])
- return <PopupBox>
- <section>
- <h1> Add backup provider</h1>
- <ErrorMessage title={error && "Could not get provider information"} description={error} />
- <LightText> Backup providers may charge for their service</LightText>
- <p>
- <Input invalid={urlError}>
- <label>URL</label>
- <input type="text" placeholder="https://" value={value} onChange={(e) => setValue(e.currentTarget.value)} />
- </Input>
- <Input>
- <label>Name</label>
- <input type="text" disabled={name === undefined} value={name} onChange={e => setName(e.currentTarget.value)}/>
- </Input>
- </p>
- </section>
- <footer>
- <Button onClick={onCancel}><i18n.Translate> &lt; Back</i18n.Translate></Button>
- <ButtonPrimary
- disabled={!value && !urlError}
- onClick={() => {
- const url = canonicalizeBaseUrl(value)
- return onConfirm(url, name!).then(r => r ? setError(r) : undefined)
- }}><i18n.Translate>Next</i18n.Translate></ButtonPrimary>
- </footer>
- </PopupBox>
+ }, [value]);
+ return (
+ <PopupBox>
+ <section>
+ <h1> Add backup provider</h1>
+ <ErrorMessage
+ title={error && "Could not get provider information"}
+ description={error}
+ />
+ <LightText> Backup providers may charge for their service</LightText>
+ <p>
+ <Input invalid={urlError}>
+ <label>URL</label>
+ <input
+ type="text"
+ placeholder="https://"
+ value={value}
+ onChange={(e) => setValue(e.currentTarget.value)}
+ />
+ </Input>
+ <Input>
+ <label>Name</label>
+ <input
+ type="text"
+ disabled={name === undefined}
+ value={name}
+ onChange={(e) => setName(e.currentTarget.value)}
+ />
+ </Input>
+ </p>
+ </section>
+ <footer>
+ <Button onClick={onCancel}>
+ <i18n.Translate> &lt; Back</i18n.Translate>
+ </Button>
+ <ButtonPrimary
+ disabled={!value && !urlError}
+ onClick={() => {
+ const url = canonicalizeBaseUrl(value);
+ return onConfirm(url, name!).then((r) =>
+ r ? setError(r) : undefined,
+ );
+ }}
+ >
+ <i18n.Translate>Next</i18n.Translate>
+ </ButtonPrimary>
+ </footer>
+ </PopupBox>
+ );
}
export interface ConfirmProviderViewProps {
- provider: BackupBackupProviderTerms,
- url: string,
+ provider: BackupBackupProviderTerms;
+ url: string;
onCancel: () => void;
onConfirm: () => void;
}
-export function ConfirmProviderView({ url, provider, onCancel, onConfirm }: ConfirmProviderViewProps) {
+export function ConfirmProviderView({
+ url,
+ provider,
+ onCancel,
+ onConfirm,
+}: ConfirmProviderViewProps) {
const [accepted, setAccepted] = useState(false);
- return <PopupBox>
- <section>
- <h1>Review terms of service</h1>
- <div>Provider URL: <a href={url} target="_blank">{url}</a></div>
- <SmallLightText>Please review and accept this provider's terms of service</SmallLightText>
- <h2>1. Pricing</h2>
- <p>
- {Amounts.isZero(provider.annual_fee) ? 'free of charge' : `${provider.annual_fee} per year of service`}
- </p>
- <h2>2. Storage</h2>
- <p>
- {provider.storage_limit_in_megabytes} megabytes of storage per year of service
- </p>
- <Checkbox label="Accept terms of service" name="terms" onToggle={() => setAccepted(old => !old)} enabled={accepted} />
- </section>
- <footer>
- <Button onClick={onCancel}><i18n.Translate> &lt; Back</i18n.Translate></Button>
- <ButtonPrimary
- disabled={!accepted}
- onClick={onConfirm}><i18n.Translate>Add provider</i18n.Translate></ButtonPrimary>
- </footer>
- </PopupBox>
+ return (
+ <PopupBox>
+ <section>
+ <h1>Review terms of service</h1>
+ <div>
+ Provider URL:{" "}
+ <a href={url} target="_blank">
+ {url}
+ </a>
+ </div>
+ <SmallLightText>
+ Please review and accept this provider's terms of service
+ </SmallLightText>
+ <h2>1. Pricing</h2>
+ <p>
+ {Amounts.isZero(provider.annual_fee)
+ ? "free of charge"
+ : `${provider.annual_fee} per year of service`}
+ </p>
+ <h2>2. Storage</h2>
+ <p>
+ {provider.storage_limit_in_megabytes} megabytes of storage per year of
+ service
+ </p>
+ <Checkbox
+ label="Accept terms of service"
+ name="terms"
+ onToggle={() => setAccepted((old) => !old)}
+ enabled={accepted}
+ />
+ </section>
+ <footer>
+ <Button onClick={onCancel}>
+ <i18n.Translate> &lt; Back</i18n.Translate>
+ </Button>
+ <ButtonPrimary disabled={!accepted} onClick={onConfirm}>
+ <i18n.Translate>Add provider</i18n.Translate>
+ </ButtonPrimary>
+ </footer>
+ </PopupBox>
+ );
}
diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx
index 14384f23f..1c7fdc829 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx
@@ -14,13 +14,24 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { Amounts, BackupBackupProviderTerms, canonicalizeBaseUrl, i18n } from "@gnu-taler/taler-util";
-import { verify } from "@gnu-taler/taler-wallet-core/src/crypto/primitives/nacl-fast";
+import {
+ Amounts,
+ BackupBackupProviderTerms,
+ canonicalizeBaseUrl,
+ i18n,
+} from "@gnu-taler/taler-util";
import { VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { Checkbox } from "../components/Checkbox";
import { ErrorMessage } from "../components/ErrorMessage";
-import { Button, ButtonPrimary, Input, LightText, WalletBox, SmallLightText } from "../components/styled/index";
+import {
+ Button,
+ ButtonPrimary,
+ Input,
+ LightText,
+ WalletBox,
+ SmallLightText,
+} from "../components/styled/index";
import * as wxApi from "../wxApi";
interface Props {
@@ -30,52 +41,65 @@ interface Props {
function getJsonIfOk(r: Response) {
if (r.ok) {
- return r.json()
+ return r.json();
} else {
if (r.status >= 400 && r.status < 500) {
- throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`)
+ throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`);
} else {
- throw new Error(`Try another server: (${r.status}) ${r.statusText || 'internal server error'}`)
+ throw new Error(
+ `Try another server: (${r.status}) ${
+ r.statusText || "internal server error"
+ }`,
+ );
}
}
}
-
export function ProviderAddPage({ onBack }: Props): VNode {
- const [verifying, setVerifying] = useState<{ url: string, name: string, provider: BackupBackupProviderTerms } | undefined>(undefined)
-
- async function getProviderInfo(url: string): Promise<BackupBackupProviderTerms> {
+ const [verifying, setVerifying] = useState<
+ | { url: string; name: string; provider: BackupBackupProviderTerms }
+ | undefined
+ >(undefined);
+
+ async function getProviderInfo(
+ url: string,
+ ): Promise<BackupBackupProviderTerms> {
return fetch(`${url}config`)
- .catch(e => { throw new Error(`Network error`) })
- .then(getJsonIfOk)
+ .catch((e) => {
+ throw new Error(`Network error`);
+ })
+ .then(getJsonIfOk);
}
if (!verifying) {
- return <SetUrlView
- onCancel={onBack}
- onVerify={(url) => getProviderInfo(url)}
- onConfirm={(url, name) => getProviderInfo(url)
- .then((provider) => {
- setVerifying({ url, name, provider });
- })
- .catch(e => e.message)
- }
- />
+ return (
+ <SetUrlView
+ onCancel={onBack}
+ onVerify={(url) => getProviderInfo(url)}
+ onConfirm={(url, name) =>
+ getProviderInfo(url)
+ .then((provider) => {
+ setVerifying({ url, name, provider });
+ })
+ .catch((e) => e.message)
+ }
+ />
+ );
}
- return <ConfirmProviderView
- provider={verifying.provider}
- url={verifying.url}
- onCancel={() => {
- setVerifying(undefined);
- }}
- onConfirm={() => {
- wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack)
- }}
-
- />
+ return (
+ <ConfirmProviderView
+ provider={verifying.provider}
+ url={verifying.url}
+ onCancel={() => {
+ setVerifying(undefined);
+ }}
+ onConfirm={() => {
+ wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack);
+ }}
+ />
+ );
}
-
export interface SetUrlViewProps {
initialValue?: string;
onCancel: () => void;
@@ -84,83 +108,137 @@ export interface SetUrlViewProps {
withError?: string;
}
-export function SetUrlView({ initialValue, onCancel, onVerify, onConfirm, withError }: SetUrlViewProps) {
- const [value, setValue] = useState<string>(initialValue || "")
- const [urlError, setUrlError] = useState(false)
- const [name, setName] = useState<string|undefined>(undefined)
- const [error, setError] = useState<string | undefined>(withError)
+export function SetUrlView({
+ initialValue,
+ onCancel,
+ onVerify,
+ onConfirm,
+ withError,
+}: SetUrlViewProps) {
+ const [value, setValue] = useState<string>(initialValue || "");
+ const [urlError, setUrlError] = useState(false);
+ const [name, setName] = useState<string | undefined>(undefined);
+ const [error, setError] = useState<string | undefined>(withError);
useEffect(() => {
try {
- const url = canonicalizeBaseUrl(value)
- onVerify(url).then(r => {
- setUrlError(false)
- setName(new URL(url).hostname)
- }).catch(() => {
- setUrlError(true)
- setName(undefined)
- })
+ const url = canonicalizeBaseUrl(value);
+ onVerify(url)
+ .then((r) => {
+ setUrlError(false);
+ setName(new URL(url).hostname);
+ })
+ .catch(() => {
+ setUrlError(true);
+ setName(undefined);
+ });
} catch {
- setUrlError(true)
- setName(undefined)
+ setUrlError(true);
+ setName(undefined);
}
- }, [value])
- return <WalletBox>
- <section>
- <h1> Add backup provider</h1>
- <ErrorMessage title={error && "Could not get provider information"} description={error} />
- <LightText> Backup providers may charge for their service</LightText>
- <p>
- <Input invalid={urlError}>
- <label>URL</label>
- <input type="text" placeholder="https://" value={value} onChange={(e) => setValue(e.currentTarget.value)} />
- </Input>
- <Input>
- <label>Name</label>
- <input type="text" disabled={name === undefined} value={name} onChange={e => setName(e.currentTarget.value)}/>
- </Input>
- </p>
- </section>
- <footer>
- <Button onClick={onCancel}><i18n.Translate> &lt; Back</i18n.Translate></Button>
- <ButtonPrimary
- disabled={!value && !urlError}
- onClick={() => {
- const url = canonicalizeBaseUrl(value)
- return onConfirm(url, name!).then(r => r ? setError(r) : undefined)
- }}><i18n.Translate>Next</i18n.Translate></ButtonPrimary>
- </footer>
- </WalletBox>
+ }, [value]);
+ return (
+ <WalletBox>
+ <section>
+ <h1> Add backup provider</h1>
+ <ErrorMessage
+ title={error && "Could not get provider information"}
+ description={error}
+ />
+ <LightText> Backup providers may charge for their service</LightText>
+ <p>
+ <Input invalid={urlError}>
+ <label>URL</label>
+ <input
+ type="text"
+ placeholder="https://"
+ value={value}
+ onChange={(e) => setValue(e.currentTarget.value)}
+ />
+ </Input>
+ <Input>
+ <label>Name</label>
+ <input
+ type="text"
+ disabled={name === undefined}
+ value={name}
+ onChange={(e) => setName(e.currentTarget.value)}
+ />
+ </Input>
+ </p>
+ </section>
+ <footer>
+ <Button onClick={onCancel}>
+ <i18n.Translate> &lt; Back</i18n.Translate>
+ </Button>
+ <ButtonPrimary
+ disabled={!value && !urlError}
+ onClick={() => {
+ const url = canonicalizeBaseUrl(value);
+ return onConfirm(url, name!).then((r) =>
+ r ? setError(r) : undefined,
+ );
+ }}
+ >
+ <i18n.Translate>Next</i18n.Translate>
+ </ButtonPrimary>
+ </footer>
+ </WalletBox>
+ );
}
export interface ConfirmProviderViewProps {
- provider: BackupBackupProviderTerms,
- url: string,
+ provider: BackupBackupProviderTerms;
+ url: string;
onCancel: () => void;
onConfirm: () => void;
}
-export function ConfirmProviderView({ url, provider, onCancel, onConfirm }: ConfirmProviderViewProps) {
+export function ConfirmProviderView({
+ url,
+ provider,
+ onCancel,
+ onConfirm,
+}: ConfirmProviderViewProps) {
const [accepted, setAccepted] = useState(false);
- return <WalletBox>
- <section>
- <h1>Review terms of service</h1>
- <div>Provider URL: <a href={url} target="_blank">{url}</a></div>
- <SmallLightText>Please review and accept this provider's terms of service</SmallLightText>
- <h2>1. Pricing</h2>
- <p>
- {Amounts.isZero(provider.annual_fee) ? 'free of charge' : `${provider.annual_fee} per year of service`}
- </p>
- <h2>2. Storage</h2>
- <p>
- {provider.storage_limit_in_megabytes} megabytes of storage per year of service
- </p>
- <Checkbox label="Accept terms of service" name="terms" onToggle={() => setAccepted(old => !old)} enabled={accepted} />
- </section>
- <footer>
- <Button onClick={onCancel}><i18n.Translate> &lt; Back</i18n.Translate></Button>
- <ButtonPrimary
- disabled={!accepted}
- onClick={onConfirm}><i18n.Translate>Add provider</i18n.Translate></ButtonPrimary>
- </footer>
- </WalletBox>
+ return (
+ <WalletBox>
+ <section>
+ <h1>Review terms of service</h1>
+ <div>
+ Provider URL:{" "}
+ <a href={url} target="_blank">
+ {url}
+ </a>
+ </div>
+ <SmallLightText>
+ Please review and accept this provider's terms of service
+ </SmallLightText>
+ <h2>1. Pricing</h2>
+ <p>
+ {Amounts.isZero(provider.annual_fee)
+ ? "free of charge"
+ : `${provider.annual_fee} per year of service`}
+ </p>
+ <h2>2. Storage</h2>
+ <p>
+ {provider.storage_limit_in_megabytes} megabytes of storage per year of
+ service
+ </p>
+ <Checkbox
+ label="Accept terms of service"
+ name="terms"
+ onToggle={() => setAccepted((old) => !old)}
+ enabled={accepted}
+ />
+ </section>
+ <footer>
+ <Button onClick={onCancel}>
+ <i18n.Translate> &lt; Back</i18n.Translate>
+ </Button>
+ <ButtonPrimary disabled={!accepted} onClick={onConfirm}>
+ <i18n.Translate>Add provider</i18n.Translate>
+ </ButtonPrimary>
+ </footer>
+ </WalletBox>
+ );
}