aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx50
-rw-r--r--packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx101
-rw-r--r--packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx89
-rw-r--r--packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx5
-rw-r--r--packages/anastasis-webui/src/pages/home/authMethod/index.tsx5
5 files changed, 209 insertions, 41 deletions
diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
new file mode 100644
index 000000000..43807fefe
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
@@ -0,0 +1,50 @@
+/* eslint-disable @typescript-eslint/camelcase */
+/*
+ This file is part of GNU Taler
+ (C) 2021 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 { ReducerState } from 'anastasis-core';
+import { createExample, reducerStatesExample } from '../../utils';
+import { AddingProviderScreen as TestedComponent } from './AddingProviderScreen';
+
+
+export default {
+ title: 'Pages/backup/AddingProviderScreen',
+ component: TestedComponent,
+ args: {
+ order: 4,
+ },
+ argTypes: {
+ onUpdate: { action: 'onUpdate' },
+ onBack: { action: 'onBack' },
+ },
+};
+
+export const NewProvider = createExample(TestedComponent, {
+ ...reducerStatesExample.authEditing,
+} as ReducerState);
+
+export const NewSMSProvider = createExample(TestedComponent, {
+ ...reducerStatesExample.authEditing,
+} as ReducerState, { providerType: 'sms'});
+
+export const NewIBANProvider = createExample(TestedComponent, {
+ ...reducerStatesExample.authEditing,
+} as ReducerState, { providerType: 'iban' });
diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx
new file mode 100644
index 000000000..9c83da49e
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.tsx
@@ -0,0 +1,101 @@
+/* eslint-disable @typescript-eslint/camelcase */
+import {
+ encodeCrock,
+ stringToBytes
+} from "@gnu-taler/taler-util";
+import { h, VNode } from "preact";
+import { useLayoutEffect, useRef, useState } from "preact/hooks";
+import { TextInput } from "../../components/fields/TextInput";
+import { authMethods, KnownAuthMethods } from "./authMethod";
+import { AnastasisClientFrame } from "./index";
+
+interface Props {
+ providerType?: KnownAuthMethods;
+ cancel: () => void;
+}
+export function AddingProviderScreen({ providerType, cancel }: Props): VNode {
+ const [providerURL, setProviderURL] = useState("");
+ const [error, setError] = useState<string | undefined>()
+ const providerLabel = providerType ? authMethods[providerType].label : undefined
+
+ function testProvider(): void {
+ setError(undefined)
+
+ fetch(`${providerURL}/config`)
+ .then(r => r.json().catch(d => ({})))
+ .then(r => {
+ if (!("methods" in r) || !Array.isArray(r.methods)) {
+ setError("This provider doesn't have authentication method. Check the provider URL")
+ return;
+ }
+ if (!providerLabel) {
+ setError("")
+ return
+ }
+ let found = false
+ for (let i = 0; i < r.methods.length && !found; i++) {
+ found = r.methods[i].type !== providerType
+ }
+ if (!found) {
+ setError(`This provider does not support authentication method ${providerLabel}`)
+ }
+ })
+ .catch(e => {
+ setError(`There was an error testing this provider, try another one. ${e.message}`)
+ })
+
+ }
+ function addProvider(): void {
+ // addAuthMethod({
+ // authentication_method: {
+ // type: "sms",
+ // instructions: `SMS to ${providerURL}`,
+ // challenge: encodeCrock(stringToBytes(providerURL)),
+ // },
+ // });
+ }
+ const inputRef = useRef<HTMLInputElement>(null);
+ useLayoutEffect(() => {
+ inputRef.current?.focus();
+ }, []);
+
+ let errors = !providerURL ? 'Add provider URL' : undefined
+ try {
+ new URL(providerURL)
+ } catch {
+ errors = 'Check the URL'
+ }
+ if (!!error && !errors) {
+ errors = error
+ }
+
+ return (
+ <AnastasisClientFrame hideNav
+ title={!providerLabel ? `Backup: Adding a provider` : `Backup: Adding a ${providerLabel} provider`}
+ hideNext={errors}>
+ <div>
+ <p>
+ Add a provider url {errors}
+ </p>
+ <div class="container">
+ <TextInput
+ label="Provider URL"
+ placeholder="https://provider.com"
+ grabFocus
+ bind={[providerURL, setProviderURL]} />
+ </div>
+ {!!error && <p class="block has-text-danger">{error}</p>}
+ {error === "" && <p class="block has-text-success">This provider worked!</p>}
+ <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
+ <button class="button" onClick={testProvider}>TEST</button>
+ </div>
+ <div style={{ marginTop: '2em', display: 'flex', justifyContent: 'space-between' }}>
+ <button class="button" onClick={cancel}>Cancel</button>
+ <span data-tooltip={errors}>
+ <button class="button is-info" disabled={errors !== undefined} onClick={addProvider}>Add</button>
+ </span>
+ </div>
+ </div>
+ </AnastasisClientFrame>
+ );
+}
diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
index ab482044f..b95d3f1e3 100644
--- a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/camelcase */
import { AuthMethod } from "anastasis-core";
-import { ComponentChildren, h, VNode } from "preact";
+import { ComponentChildren, Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { TextInput } from "../../components/fields/TextInput";
import { useAnastasisContext } from "../../context/anastasis";
import { authMethods, KnownAuthMethods } from "./authMethod";
import { AnastasisClientFrame } from "./index";
@@ -13,6 +14,7 @@ const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>
export function AuthenticationEditorScreen(): VNode {
const [noProvidersAck, setNoProvidersAck] = useState(false)
const [selectedMethod, setSelectedMethod] = useState<KnownAuthMethods | undefined>(undefined);
+ const [addingProvider, setAddingProvider] = useState<string | undefined>(undefined)
const reducer = useAnastasisContext()
if (!reducer) {
@@ -62,36 +64,58 @@ export function AuthenticationEditorScreen(): VNode {
};
const AuthSetup = authMethods[selectedMethod].screen ?? AuthMethodNotImplemented;
- return (
+ return (<Fragment>
<AuthSetup
cancel={cancel}
configured={camByType[selectedMethod] || []}
addAuthMethod={addMethod}
method={selectedMethod} />
+
+ {!authAvailableSet.has(selectedMethod) && <ConfirmModal active
+ onCancel={cancel} description="No providers founds" label="Add a provider manually"
+ onConfirm={() => {
+ null
+ }}
+ >
+ We have found no trusted cloud providers for your recovery secret. You can add a provider manually.
+ To add a provider you must know the provider URL (e.g. https://provider.com)
+ <p>
+ <a>More about cloud providers</a>
+ </p>
+ </ConfirmModal>}
+
+ </Fragment>
);
}
+
+ if (addingProvider !== undefined) {
+ return <div />
+ }
+
function MethodButton(props: { method: KnownAuthMethods }): VNode {
+ if (authMethods[props.method].skip) return <div />
+
return (
<div class="block">
<button
style={{ justifyContent: 'space-between' }}
class="button is-fullwidth"
onClick={() => {
- if (!authAvailableSet.has(props.method)) {
- //open add sms dialog
- } else {
- setSelectedMethod(props.method);
- }
- if (reducer) reducer.dismissError();
+ setSelectedMethod(props.method);
}}
>
<div style={{ display: 'flex' }}>
<span class="icon ">
{authMethods[props.method].icon}
</span>
- <span>
- {authMethods[props.method].label}
- </span>
+ {authAvailableSet.has(props.method) ?
+ <span>
+ Add a {authMethods[props.method].label} challenge
+ </span> :
+ <span>
+ Add a {authMethods[props.method].label} provider
+ </span>
+ }
</div>
{!authAvailableSet.has(props.method) &&
<span class="icon has-text-danger" >
@@ -111,41 +135,34 @@ export function AuthenticationEditorScreen(): VNode {
return (
<AnastasisClientFrame title="Backup: Configure Authentication Methods" hideNext={errors}>
<div class="columns">
- <div class="column is-half">
+ <div class="column one-third">
<div>
{getKeys(authMethods).map(method => <MethodButton key={method} method={method} />)}
</div>
- {authAvailableSet.size === 0 && <ConfirmModal active={!noProvidersAck} onCancel={() => setNoProvidersAck(true)} description="No providers founds" label="Add a provider manually">
+ {authAvailableSet.size === 0 && <ConfirmModal active={!noProvidersAck}
+ onCancel={() => setNoProvidersAck(true)} description="No providers founds" label="Add a provider manually"
+ onConfirm={() => {
+ null
+ }}
+ >
We have found no trusted cloud providers for your recovery secret. You can add a provider manually.
To add a provider you must know the provider URL (e.g. https://provider.com)
<p>
<a>More about cloud providers</a>
</p>
</ConfirmModal>}
-
- {/* {haveMethodsConfigured && (
- configuredAuthMethods.map((x, i) => {
- return (
- <p key={i}>
- {x.type} ({x.instructions}){" "}
- <button class="button is-danger is-small"
- onClick={() => reducer.transition("delete_authentication", {
- authentication_method: i,
- })}
- >
- Remove
- </button>
- </p>
- );
- })
- )} */}
</div>
- <div class="column is-half">
- When recovering your wallet, you will be asked to verify your identity via the methods you configure here.
-
- <b>Explain the exclamation marks</b>
-
- <a>Explain how to add providers</a>
+ <div class="column two-third">
+ <p class="block">
+ When recovering your wallet, you will be asked to verify your identity via the methods you configure here.
+ The list of authentication method is defined by the backup provider list.
+ </p>
+ <p class="block">
+ <button class="button is-info">Manage the backup provider's list</button>
+ </p>
+ {authAvailableSet.size > 0 && <p class="block">
+ We couldn't find provider for some of the authentication methods.
+ </p>}
</div>
</div>
</AnastasisClientFrame>
diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
index b8beb7b47..9441022b8 100644
--- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx
@@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/camelcase */
-import { AuthMethod } from "anastasis-core";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import { useAnastasisContext } from "../../context/anastasis";
@@ -51,8 +50,8 @@ export function ReviewPoliciesScreen(): VNode {
{policies.length < 1 && <p class="block">
No policies had been created. Go back and add more authentication methods.
</p>}
- <div class="block" onClick={() => setEditingPolicy(policies.length + 1)}>
- <button class="button is-success">Add new policy</button>
+ <div class="block" style={{justifyContent:'flex-end'}} >
+ <button class="button is-success" onClick={() => setEditingPolicy(policies.length + 1)}>Add new policy</button>
</div>
{policies.map((p, policy_index) => {
const methods = p.methods
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
index 1e1d7bc03..7b0cce883 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
@@ -17,6 +17,7 @@ interface AuthMethodConfiguration {
icon: VNode;
label: string;
screen: (props: AuthMethodSetupProps) => VNode;
+ skip?: boolean;
}
export type KnownAuthMethods = "sms" | "email" | "post" | "question" | "video" | "totp" | "iban";
@@ -62,7 +63,7 @@ export const authMethods: KnowMethodConfig = {
video: {
icon: <img src={videoIcon} />,
label: "Video",
- screen: VideScreen
-
+ screen: VideScreen,
+ skip: true,
}
} \ No newline at end of file