From 4a83e9639d59d4a3116d17d8633ea0d8c69aaa62 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 11 Nov 2021 13:22:14 -0300 Subject: changes from feedback better backup and recovery ending screen async button on modal and solve challenges use providers name when possible --- .../src/pages/home/AttributeEntryScreen.tsx | 6 +-- .../pages/home/BackupFinishedScreen.stories.tsx | 4 +- .../src/pages/home/BackupFinishedScreen.tsx | 37 ++++++------------ .../src/pages/home/ChallengeOverviewScreen.tsx | 23 ++++++----- .../src/pages/home/ConfirmModal.tsx | 7 ++-- .../src/pages/home/RecoveryFinishedScreen.tsx | 45 ++++++++++++++++------ .../src/pages/home/SecretSelectionScreen.tsx | 42 +++++++++++--------- .../pages/home/authMethod/AuthMethodEmailSolve.tsx | 27 ++++++++++--- .../pages/home/authMethod/AuthMethodIbanSolve.tsx | 2 +- .../pages/home/authMethod/AuthMethodPostSolve.tsx | 2 +- .../home/authMethod/AuthMethodQuestionSolve.tsx | 10 ++++- .../pages/home/authMethod/AuthMethodSmsSolve.tsx | 26 +++++++++++-- .../pages/home/authMethod/AuthMethodTotpSolve.tsx | 3 +- packages/anastasis-webui/src/utils/index.tsx | 9 ++--- 14 files changed, 150 insertions(+), 93 deletions(-) diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx index 4b26c38b7..4a937d855 100644 --- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.tsx @@ -59,16 +59,16 @@ export function AttributeEntryScreen(): VNode { setAskUserIfSure(false)} - description="You can not forget what you had entered" + description="The values in the form must be correct" label="I am sure" cancelLabel="Wait, I want to check" onConfirm={() => reducer.transition("enter_user_attributes", { identity_attributes: attrs, - })} + }).then(() => setAskUserIfSure(false) )} > You personal information is used to define the location where your secret will be safely stored. If you forget what you have entered or - if there is a misspell you will be unable to recover your secret again. + if there is a misspell you will be unable to recover your secret. ) : null} diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx index 0789ee6ad..c3ff7e746 100644 --- a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx @@ -49,13 +49,13 @@ export const WithDetails = createExample(TestedComponent, { ...reducerStatesExample.backupFinished, secret_name: "super_secret", success_details: { - "http://anastasis.net": { + "https://anastasis.demo.taler.net/": { policy_expiration: { t_ms: "never", }, policy_version: 0, }, - "http://taler.net": { + "https://kudos.demo.anastasis.lu/": { policy_expiration: { t_ms: new Date().getTime() + 60 * 60 * 24 * 1000, }, diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx index 825ec5dc0..129f1e9e4 100644 --- a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.tsx @@ -1,3 +1,4 @@ +import { AuthenticationProviderStatusOk } from "anastasis-core"; import { format } from "date-fns"; import { h, VNode } from "preact"; import { useAnastasisContext } from "../../context/anastasis"; @@ -15,33 +16,28 @@ export function BackupFinishedScreen(): VNode { return
invalid state
; } const details = reducer.currentReducerState.success_details; + const providers = reducer.currentReducerState.authentication_providers ?? {} return ( - - {reducer.currentReducerState.secret_name ? ( -

- Your backup of secret{" "} - "{reducer.currentReducerState.secret_name}" was successful. -

- ) : ( -

Your secret was successfully backed up.

- )} + +

Your backup is complete.

{details && (

The backup is stored by the following providers:

- {Object.keys(details).map((x, i) => { - const sd = details[x]; + {Object.keys(details).map((url, i) => { + const sd = details[url]; + const p = providers[url] as AuthenticationProviderStatusOk return (
- {x} + {p.business_name}

version {sd.policy_version} {sd.policy_expiration.t_ms !== "never" ? ` expires at: ${format( - sd.policy_expiration.t_ms, - "dd-MM-yyyy", - )}` + new Date(sd.policy_expiration.t_ms), + "dd-MM-yyyy", + )}` : " without expiration date"}

@@ -49,17 +45,6 @@ export function BackupFinishedScreen(): VNode { })}
)} -
- -
); } diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx index c6de00e98..d0c9b2f5d 100644 --- a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx @@ -3,6 +3,7 @@ import { h, VNode } from "preact"; import { useAnastasisContext } from "../../context/anastasis"; import { AnastasisClientFrame } from "./index"; import { authMethods, KnownAuthMethods } from "./authMethod"; +import { AsyncButton } from "../../components/AsyncButton"; function OverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }) { const { feedback } = props; @@ -150,13 +151,15 @@ export function ChallengeOverviewScreen(): VNode { id: string; feedback?: ChallengeFeedback; }): VNode { - function selectChallenge(): void { - if (reducer) reducer.transition("select_challenge", { uuid: id }); + async function selectChallenge(): Promise { + if (reducer) { + return reducer.transition("select_challenge", { uuid: id }); + } } if (!feedback) { return (
- +
); } @@ -178,7 +181,7 @@ export function ChallengeOverviewScreen(): VNode { case ChallengeFeedbackStatus.Payment: return (
- +
); case ChallengeFeedbackStatus.Redirect: return (
- +
); case ChallengeFeedbackStatus.Solved: @@ -212,7 +215,7 @@ export function ChallengeOverviewScreen(): VNode { default: return (
- +
); } diff --git a/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx b/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx index cab70de63..e3561d892 100644 --- a/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx +++ b/packages/anastasis-webui/src/pages/home/ConfirmModal.tsx @@ -1,10 +1,11 @@ import { ComponentChildren, h, VNode } from "preact"; +import { AsyncButton } from "../../components/AsyncButton"; export interface ConfirmModelProps { active?: boolean; description?: string; onCancel?: () => void; - onConfirm?: () => void; + onConfirm?: () => Promise; label?: string; cancelLabel?: string; children?: ComponentChildren; @@ -33,13 +34,13 @@ export function ConfirmModal({ {cancelLabel}
- +
diff --git a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx index 11ae09d4f..dba2aa446 100644 --- a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.tsx @@ -1,10 +1,18 @@ import { bytesToString, decodeCrock } from "@gnu-taler/taler-util"; import { h, VNode } from "preact"; +import { useEffect, useState } from "preact/hooks"; +import { QR } from "../../components/QR"; import { useAnastasisContext } from "../../context/anastasis"; import { AnastasisClientFrame } from "./index"; export function RecoveryFinishedScreen(): VNode { const reducer = useAnastasisContext(); + const [copied, setCopied] = useState(false) + useEffect(() => { + setTimeout(() => { + setCopied(false) + },1000) + }, [copied]) if (!reducer) { return
no reducer in context
; @@ -15,6 +23,7 @@ export function RecoveryFinishedScreen(): VNode { ) { return
invalid state
; } + const secretName = reducer.currentReducerState.recovery_document?.secret_name; const encodedSecret = reducer.currentReducerState.core_secret; if (!encodedSecret) { return ( @@ -35,19 +44,33 @@ export function RecoveryFinishedScreen(): VNode { ); } const secret = bytesToString(decodeCrock(encodedSecret.value)); + const contentURI = `data:${encodedSecret.mime},${secret}` + // const fileName = encodedSecret['filename'] + // data:plain/text;base64,asdasd return ( - -

Your secret: {secret}

-
- + +
+ +
+ + Save as + +
+
+
+
); diff --git a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx index 4000f9bfe..7e517abfe 100644 --- a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.tsx @@ -1,3 +1,4 @@ +import { AuthenticationProviderStatus, AuthenticationProviderStatusOk } from "anastasis-core"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import { AsyncButton } from "../../components/AsyncButton"; @@ -38,15 +39,13 @@ export function SecretSelectionScreen(): VNode { }); } - const providerList = Object.keys( - reducer.currentReducerState.authentication_providers ?? {}, - ); + const provs = reducer.currentReducerState.authentication_providers ?? {}; const recoveryDocument = reducer.currentReducerState.recovery_document; if (!recoveryDocument) { return ( doSelectVersion(newProv, 0)} /> @@ -56,7 +55,7 @@ export function SecretSelectionScreen(): VNode { if (selectingVersion) { return ( setSelectingVersion(false)} @@ -69,12 +68,15 @@ export function SecretSelectionScreen(): VNode { return setManageProvider(false)} />; } + const provierInfo = provs[recoveryDocument.provider_url] as AuthenticationProviderStatusOk return (
-

{recoveryDocument.provider_url}

+

+ {provierInfo.business_name} +

{currentVersion === 0 ? (

Set to recover the latest version

@@ -111,7 +113,7 @@ function ChooseAnotherProviderScreen({ onChange, }: { selected: string; - providers: string[]; + providers: { [url: string]: AuthenticationProviderStatus }; onChange: (prov: string) => void; }): VNode { return ( @@ -132,11 +134,13 @@ function ChooseAnotherProviderScreen({ {" "} Choose a provider{" "} - {providers.map((prov) => ( - - ))} + })}
@@ -158,20 +162,21 @@ function SelectOtherVersionProviderScreen({ onCancel: () => void; provider: string; version: number; - providers: string[]; + providers: { [url: string]: AuthenticationProviderStatus }; onConfirm: (prov: string, v: number) => Promise; }): VNode { const [otherProvider, setOtherProvider] = useState(provider); const [otherVersion, setOtherVersion] = useState( version > 0 ? String(version) : "", ); + const otherProviderInfo = providers[otherProvider] as AuthenticationProviderStatusOk return (
-

Provider {otherProvider}

+

Provider {otherProviderInfo.business_name}

{version === 0 ? (

Set to recover the latest version

@@ -193,11 +198,13 @@ function SelectOtherVersionProviderScreen({ {" "} Choose a provider{" "} - {providers.map((prov) => ( - - ))} + })}
@@ -242,7 +249,6 @@ function SelectOtherVersionProviderScreen({
-
.
); diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx index ff6c51d1c..1e0b6f18a 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx @@ -10,6 +10,7 @@ import { AuthMethodSolveProps } from "./index"; export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode { const [answer, setAnswer] = useState(""); + const [expanded, setExpanded] = useState(false) const reducer = useAnastasisContext(); if (!reducer) { @@ -86,14 +87,30 @@ export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode { feedback?.state === ChallengeFeedbackStatus.TruthUnknown; return ( - +

- An email has been sent to "{selectedChallenge.instructions}". - Type the code below. - Here we need to add the code "{selectedUuid}" + An email has been sent to "{selectedChallenge.instructions}". The + message has and identification code and recovery code that starts with "A-". + Wait the message to arrive and the enter the recovery code below.

- + {!expanded ?

+ The identification code in the email should start with "{selectedUuid.substring(0, 10)}" + setExpanded(e => !e)}> + + +

+ :

+ The identification code in the email is "{selectedUuid}" + setExpanded(e => !e)}> + + +

} +
+

Send a wire transfer to the address,

diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx index ee001ebe9..97e768cbe 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx @@ -86,7 +86,7 @@ export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode { feedback?.state === ChallengeFeedbackStatus.TruthUnknown; return ( - +

Wait for the answer

diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx index 222789507..b4896eac8 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx @@ -86,9 +86,15 @@ export function AuthMethodQuestionSolve({ id }: AuthMethodSolveProps): VNode { feedback?.state === ChallengeFeedbackStatus.TruthUnknown; return ( - + -

Answer the question please

+

+ In this challenge you need to provide the answer for the next question: +

+
+        {selectedChallenge.instructions}
+      
+

Type the answer below

+

- An sms has been sent to "{selectedChallenge.instructions}". Type - the code below + An sms has been sent to "{selectedChallenge.instructions}". The + message has and identification code and recovery code that starts with "A-". + Wait the message to arrive and the enter the recovery code below.

- + {!expanded ?

+ The identification code in the SMS should start with "{selectedUuid.substring(0, 10)}" + setExpanded(e => !e)}> + + +

+ :

+ The identification code in the SMS is "{selectedUuid}" + setExpanded(e => !e)}> + + +

} +
+

enter the totp solution

@@ -110,3 +110,4 @@ export function AuthMethodTotpSolve({ id }: AuthMethodSolveProps): VNode {
); } +// NKE8 VD857T X033X6RG WEGPYP6D70 Q7YE XN8D2 ZN79SCN 231B4QK0 diff --git a/packages/anastasis-webui/src/utils/index.tsx b/packages/anastasis-webui/src/utils/index.tsx index 04cc8c921..a8f6c3101 100644 --- a/packages/anastasis-webui/src/utils/index.tsx +++ b/packages/anastasis-webui/src/utils/index.tsx @@ -101,7 +101,7 @@ const base = { "http://localhost:8086/": { http_status: 200, annual_fee: "COL:0", - business_name: "ana", + business_name: "Anastasis Local", currency: "COL", liability_limit: "COL:10", methods: [ @@ -125,7 +125,7 @@ const base = { "https://kudos.demo.anastasis.lu/": { http_status: 200, annual_fee: "COL:0", - business_name: "ana", + business_name: "Anastasis Kudo", currency: "COL", liability_limit: "COL:10", methods: [ @@ -145,7 +145,7 @@ const base = { "https://anastasis.demo.taler.net/": { http_status: 200, annual_fee: "COL:0", - business_name: "ana", + business_name: "Anastasis Demo", currency: "COL", liability_limit: "COL:10", methods: [ @@ -180,9 +180,6 @@ const base = { hint: "request to provider failed", }, }, - // expiration: { - // d_ms: 1792525051855 // check t_ms - // }, } as Partial; export const reducerStatesExample = { -- cgit v1.2.3