From 6ef5fd21fc365d780da42170ce85042f874ed1dc Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 8 Nov 2021 09:56:06 -0300 Subject: some solve challenge examples, WIP --- .../pages/home/AddingProviderScreen.stories.tsx | 3 +- .../pages/home/AttributeEntryScreen.stories.tsx | 5 +- .../home/AuthenticationEditorScreen.stories.tsx | 12 +- .../src/pages/home/AuthenticationEditorScreen.tsx | 20 +-- .../pages/home/BackupFinishedScreen.stories.tsx | 5 +- .../pages/home/ChallengeOverviewScreen.stories.tsx | 2 +- .../pages/home/ChallengePayingScreen.stories.tsx | 2 +- .../src/pages/home/EditPoliciesScreen.stories.tsx | 2 +- .../pages/home/PoliciesPayingScreen.stories.tsx | 5 +- .../pages/home/RecoveryFinishedScreen.stories.tsx | 2 +- .../pages/home/ReviewPoliciesScreen.stories.tsx | 3 +- .../src/pages/home/SecretEditorScreen.stories.tsx | 3 +- .../pages/home/SecretSelectionScreen.stories.tsx | 2 +- .../src/pages/home/SolveScreen.stories.tsx | 2 +- .../anastasis-webui/src/pages/home/SolveScreen.tsx | 184 +++------------------ .../src/pages/home/StartScreen.stories.tsx | 2 +- .../src/pages/home/TruthsPayingScreen.stories.tsx | 2 +- .../authMethod/AuthMethodEmailSetup.stories.tsx | 9 +- .../pages/home/authMethod/AuthMethodEmailSetup.tsx | 8 +- .../authMethod/AuthMethodEmailSolve.stories.tsx | 80 +++++++++ .../pages/home/authMethod/AuthMethodEmailSolve.tsx | 106 ++++++++++++ .../authMethod/AuthMethodIbanSetup.stories.tsx | 9 +- .../pages/home/authMethod/AuthMethodIbanSetup.tsx | 3 +- .../authMethod/AuthMethodIbanSolve.stories.tsx | 56 +++++++ .../pages/home/authMethod/AuthMethodIbanSolve.tsx | 105 ++++++++++++ .../authMethod/AuthMethodPostSetup.stories.tsx | 8 +- .../pages/home/authMethod/AuthMethodPostSetup.tsx | 7 +- .../authMethod/AuthMethodPostSolve.stories.tsx | 56 +++++++ .../pages/home/authMethod/AuthMethodPostSolve.tsx | 105 ++++++++++++ .../authMethod/AuthMethodQuestionSetup.stories.tsx | 8 +- .../home/authMethod/AuthMethodQuestionSetup.tsx | 3 +- .../authMethod/AuthMethodQuestionSolve.stories.tsx | 56 +++++++ .../home/authMethod/AuthMethodQuestionSolve.tsx | 105 ++++++++++++ .../home/authMethod/AuthMethodSmsSetup.stories.tsx | 8 +- .../pages/home/authMethod/AuthMethodSmsSetup.tsx | 3 +- .../home/authMethod/AuthMethodSmsSolve.stories.tsx | 56 +++++++ .../pages/home/authMethod/AuthMethodSmsSolve.tsx | 106 ++++++++++++ .../authMethod/AuthMethodTotpSetup.stories.tsx | 8 +- .../pages/home/authMethod/AuthMethodTotpSetup.tsx | 3 +- .../authMethod/AuthMethodTotpSolve.stories.tsx | 56 +++++++ .../pages/home/authMethod/AuthMethodTotpSolve.tsx | 105 ++++++++++++ .../authMethod/AuthMethodVideoSetup.stories.tsx | 8 +- .../pages/home/authMethod/AuthMethodVideoSetup.tsx | 3 +- .../authMethod/AuthMethodVideoSolve.stories.tsx | 56 +++++++ .../pages/home/authMethod/AuthMethodVideoSolve.tsx | 105 ++++++++++++ .../src/pages/home/authMethod/index.tsx | 69 +++++--- packages/anastasis-webui/src/pages/home/index.tsx | 4 +- 47 files changed, 1287 insertions(+), 283 deletions(-) create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx create mode 100644 packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx (limited to 'packages') diff --git a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx index 43807fefe..d290a6602 100644 --- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -26,7 +25,7 @@ import { AddingProviderScreen as TestedComponent } from './AddingProviderScreen' export default { - title: 'Pages/backup/AddingProviderScreen', + title: 'Pages/backup/AuthorizationMethod/AddingProvider', component: TestedComponent, args: { order: 4, diff --git a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx index 549686616..9cdd132ef 100644 --- a/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/AttributeEntryScreen.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -26,10 +25,10 @@ import { AttributeEntryScreen as TestedComponent } from './AttributeEntryScreen' export default { - title: 'Pages/AttributeEntryScreen', + title: 'Pages/PersonalInformation', component: TestedComponent, args: { - order: 4, + order: 3, }, argTypes: { onUpdate: { action: 'onUpdate' }, diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx index 5077c3eb0..2712522ce 100644 --- a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -26,10 +25,10 @@ import { AuthenticationEditorScreen as TestedComponent } from './AuthenticationE export default { - title: 'Pages/backup/AuthenticationEditorScreen', + title: 'Pages/backup/AuthorizationMethod', component: TestedComponent, args: { - order: 5, + order: 4, }, argTypes: { onUpdate: { action: 'onUpdate' }, @@ -37,7 +36,7 @@ export default { }, }; -export const Example = createExample(TestedComponent, reducerStatesExample.authEditing); +export const InitialState = createExample(TestedComponent, reducerStatesExample.authEditing); export const OneAuthMethodConfigured = createExample(TestedComponent, { ...reducerStatesExample.authEditing, authentication_methods: [{ @@ -86,8 +85,3 @@ export const NoAuthMethodProvided = createExample(TestedComponent, { authentication_providers: {}, authentication_methods: [] } as ReducerState); - - // type: string; - // instructions: string; - // challenge: string; - // mime_type?: string; diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx index 93ca81194..a71220c55 100644 --- a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx @@ -1,10 +1,8 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { AuthMethod } from "anastasis-core"; 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 { authMethods, AuthMethodSetupProps, AuthMethodWithRemove, KnownAuthMethods } from "./authMethod"; import { AnastasisClientFrame } from "./index"; @@ -14,7 +12,7 @@ const getKeys = Object.keys as (obj: T) => Array export function AuthenticationEditorScreen(): VNode { const [noProvidersAck, setNoProvidersAck] = useState(false) const [selectedMethod, setSelectedMethod] = useState(undefined); - const [addingProvider, setAddingProvider] = useState(undefined) + // const [addingProvider, setAddingProvider] = useState(undefined) const reducer = useAnastasisContext() if (!reducer) { @@ -63,7 +61,7 @@ export function AuthenticationEditorScreen(): VNode { setSelectedMethod(undefined); }; - const AuthSetup = authMethods[selectedMethod].screen ?? AuthMethodNotImplemented; + const AuthSetup = authMethods[selectedMethod].setup ?? AuthMethodNotImplemented; return ( - } - function MethodButton(props: { method: KnownAuthMethods }): VNode { if (authMethods[props.method].skip) return
@@ -169,14 +163,6 @@ export function AuthenticationEditorScreen(): VNode { ); } -type AuthMethodWithRemove = AuthMethod & { remove: () => void } -export interface AuthMethodSetupProps { - method: string; - addAuthMethod: (x: any) => void; - configured: AuthMethodWithRemove[]; - cancel: () => void; -} - function AuthMethodNotImplemented(props: AuthMethodSetupProps): VNode { return ( diff --git a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx index b71a79727..306adacbb 100644 --- a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -26,10 +25,10 @@ import { BackupFinishedScreen as TestedComponent } from './BackupFinishedScreen' export default { - title: 'Pages/backup/FinishedScreen', + title: 'Pages/backup/Finished', component: TestedComponent, args: { - order: 9, + order: 8, }, argTypes: { onUpdate: { action: 'onUpdate' }, diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx index e001ed157..46c574cf2 100644 --- a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx @@ -24,7 +24,7 @@ import { createExample, reducerStatesExample } from "../../utils"; import { ChallengeOverviewScreen as TestedComponent } from "./ChallengeOverviewScreen"; export default { - title: "Pages/recovery/ChallengeOverviewScreen", + title: "Pages/recovery/SolveChallenge/Overview", component: TestedComponent, args: { order: 5, diff --git a/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx index e5fe09e99..fbcaa0e95 100644 --- a/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/ChallengePayingScreen.stories.tsx @@ -24,7 +24,7 @@ import { ChallengePayingScreen as TestedComponent } from './ChallengePayingScree export default { - title: 'Pages/recovery/__ChallengePayingScreen', + title: 'Pages/recovery/__ChallengePaying', component: TestedComponent, args: { order: 10, diff --git a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx index fc339e48e..3d5fcce55 100644 --- a/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/EditPoliciesScreen.stories.tsx @@ -26,7 +26,7 @@ import { EditPoliciesScreen as TestedComponent } from './EditPoliciesScreen'; export default { - title: 'Pages/backup/ReviewPoliciesScreen/EditPoliciesScreen', + title: 'Pages/backup/ReviewPolicies/EditPolicies', args: { order: 6, }, diff --git a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx index e952ab28d..3ddf8011e 100644 --- a/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/PoliciesPayingScreen.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -26,10 +25,10 @@ import { PoliciesPayingScreen as TestedComponent } from './PoliciesPayingScreen' export default { - title: 'Pages/backup/PoliciesPayingScreen', + title: 'Pages/backup/__PoliciesPaying', component: TestedComponent, args: { - order: 8, + order: 9, }, argTypes: { onUpdate: { action: 'onUpdate' }, diff --git a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx index 0d2ebb778..e92a231a8 100644 --- a/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/RecoveryFinishedScreen.stories.tsx @@ -26,7 +26,7 @@ import { RecoveryFinishedScreen as TestedComponent } from './RecoveryFinishedScr export default { - title: 'Pages/recovery/FinishedScreen', + title: 'Pages/recovery/Finished', args: { order: 7, }, diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx index 9f7e26c16..e348101ee 100644 --- a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -26,7 +25,7 @@ import { ReviewPoliciesScreen as TestedComponent } from './ReviewPoliciesScreen' export default { - title: 'Pages/backup/ReviewPoliciesScreen', + title: 'Pages/backup/ReviewPolicies', args: { order: 6, }, diff --git a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx index 49dd8fca8..db061d936 100644 --- a/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/SecretEditorScreen.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -26,7 +25,7 @@ import { SecretEditorScreen as TestedComponent } from './SecretEditorScreen'; export default { - title: 'Pages/backup/SecretEditorScreen', + title: 'Pages/backup/SecretInput', component: TestedComponent, args: { order: 7, diff --git a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx index 6919eebad..8d02ebfbe 100644 --- a/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/SecretSelectionScreen.stories.tsx @@ -25,7 +25,7 @@ import { SecretSelectionScreen as TestedComponent } from './SecretSelectionScree export default { - title: 'Pages/recovery/SecretSelectionScreen', + title: 'Pages/recovery/SecretSelection', component: TestedComponent, args: { order: 4, diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx index 7e3880f9c..82f06c34f 100644 --- a/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/SolveScreen.stories.tsx @@ -25,7 +25,7 @@ import { SolveScreen as TestedComponent } from './SolveScreen'; export default { - title: 'Pages/recovery/SolveScreen', + title: 'Pages/recovery/SolveChallenge/Solve', component: TestedComponent, args: { order: 6, diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx index 35db5ead0..ec6c7735b 100644 --- a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx +++ b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx @@ -1,17 +1,14 @@ import { Fragment, h, VNode } from "preact"; -import { useState } from "preact/hooks"; import { AnastasisClientFrame } from "."; import { ChallengeFeedback, - ChallengeFeedbackStatus, - ChallengeInfo, + ChallengeFeedbackStatus } from "../../../../anastasis-core/lib"; -import { AsyncButton } from "../../components/AsyncButton"; -import { TextInput } from "../../components/fields/TextInput"; import { Notifications } from "../../components/Notifications"; import { useAnastasisContext } from "../../context/anastasis"; +import { authMethods, AuthMethodSolveProps, KnownAuthMethods } from "./authMethod"; -function SolveOverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }): VNode { +export function SolveOverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }): VNode { const { feedback } = props; if (!feedback) { return
; @@ -80,7 +77,6 @@ function SolveOverviewFeedbackDisplay(props: { feedback?: ChallengeFeedback }): export function SolveScreen(): VNode { const reducer = useAnastasisContext(); - const [answer, setAnswer] = useState(""); if (!reducer) { return ( @@ -120,162 +116,30 @@ export function SolveScreen(): VNode { ); } - - const chArr = reducer.currentReducerState.recovery_information.challenges; - const challengeFeedback = - reducer.currentReducerState.challenge_feedback ?? {}; - const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; - const challenges: { - [uuid: string]: ChallengeInfo; - } = {}; - for (const ch of chArr) { - challenges[ch.uuid] = ch; - } - const selectedChallenge = challenges[selectedUuid]; - const dialogMap: Record h.JSX.Element> = { - question: SolveQuestionEntry, - sms: SolveSmsEntry, - email: SolveEmailEntry, - post: SolvePostEntry, - }; - const SolveDialog = - selectedChallenge === undefined - ? SolveUndefinedEntry - : dialogMap[selectedChallenge.type] ?? SolveUnsupportedEntry; - - async function onNext(): Promise { - return reducer?.transition("solve_challenge", { answer }); - } - function onCancel(): void { - reducer?.back(); + function SolveNotImplemented(): VNode { + return ( + +

+ The challenge selected is not supported for this UI. Please update this + version or try using another policy. +

+ {reducer && +
+ +
+ } +
+ ); } - const feedback = challengeFeedback[selectedUuid] - const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded - || feedback?.state === ChallengeFeedbackStatus.Redirect - || feedback?.state === ChallengeFeedbackStatus.Unsupported - || feedback?.state === ChallengeFeedbackStatus.TruthUnknown - - return ( - - - - -
- - {!shouldHideConfirm && - Confirm - } -
-
- ); -} - -export interface SolveEntryProps { - id: string; - challenge: ChallengeInfo; - feedback?: ChallengeFeedback; - answer: string; - setAnswer: (s: string) => void; -} - -function SolveSmsEntry({ - challenge, - answer, - setAnswer, -}: SolveEntryProps): VNode { - return ( - - -

- An sms has been sent to "{challenge.instructions}". Type the code - below -

- -
- ); -} -function SolveQuestionEntry({ - challenge, - answer, - setAnswer, -}: SolveEntryProps): VNode { - return ( - -

Type the answer to the following question:

-
{challenge.instructions}
- -
- ); -} -function SolvePostEntry({ - challenge, - answer, - setAnswer, -}: SolveEntryProps): VNode { - return ( - -

- instruction for post type challenge "{challenge.instructions}" -

- -
- ); -} + const chArr = reducer.currentReducerState.recovery_information.challenges; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const selectedChallenge = chArr.find(ch => ch.uuid === selectedUuid) -function SolveEmailEntry({ - challenge, - answer, - setAnswer, -}: SolveEntryProps): VNode { - return ( - -

- An email has been sent to "{challenge.instructions}". Type the - code below -

- -
- ); -} + const SolveDialog = !selectedChallenge || !authMethods[selectedChallenge.type as KnownAuthMethods] ? + SolveNotImplemented : + authMethods[selectedChallenge.type as KnownAuthMethods].solve ?? SolveNotImplemented -function SolveUnsupportedEntry(props: SolveEntryProps): VNode { - return ( - -

- The challenge selected is not supported for this UI. Please update this - version or try using another policy. -

-

- Challenge type: {props.challenge.type} -

-
- ); -} -function SolveUndefinedEntry(props: SolveEntryProps): VNode { - return ( - -

- There is no challenge information for id "{props.id}". Try - resetting the recovery session. -

-
- ); + return } diff --git a/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx index 657a2dd74..41082c128 100644 --- a/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx @@ -24,7 +24,7 @@ import { StartScreen as TestedComponent } from './StartScreen'; export default { - title: 'Pages/StartScreen', + title: 'Pages/Start', component: TestedComponent, args: { order: 1, diff --git a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx index 7568ccd69..38b71bc36 100644 --- a/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/TruthsPayingScreen.stories.tsx @@ -25,7 +25,7 @@ import { TruthsPayingScreen as TestedComponent } from './TruthsPayingScreen'; export default { - title: 'Pages/backup/__TruthsPayingScreen', + title: 'Pages/backup/__TruthsPaying', component: TestedComponent, args: { order: 10, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx index e178a4955..da87b7a8b 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -25,7 +24,7 @@ import { authMethods as TestedComponent, KnownAuthMethods } from './index'; export default { - title: 'Pages/backup/authMethods/email', + title: 'Pages/backup/AuthorizationMethod/AuthMethods/email', component: TestedComponent, args: { order: 5, @@ -38,11 +37,11 @@ export default { const type: KnownAuthMethods = 'email' -export const Empty = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [] }); -export const WithOneExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, @@ -51,7 +50,7 @@ export const WithOneExample = createExample(TestedComponent[type].screen, reduce }] }); -export const WithMoreExamples = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx index 1a6be1b61..27a0685b2 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSetup.tsx @@ -1,14 +1,12 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util"; -import { Fragment, h, VNode } from "preact"; +import { h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; -import { AnastasisClientFrame } from "../index"; -import { TextInput } from "../../../components/fields/TextInput"; import { EmailInput } from "../../../components/fields/EmailInput"; +import { AnastasisClientFrame } from "../index"; +import { AuthMethodSetupProps } from "./index"; const EMAIL_PATTERN = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx new file mode 100644 index 000000000..525cd2b07 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx @@ -0,0 +1,80 @@ +/* + 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core'; +import { createExample, reducerStatesExample } from '../../../utils'; +import { authMethods as TestedComponent, KnownAuthMethods } from './index'; + + +export default { + title: 'Pages/recovery/SolveChallenge/AuthMethods/email', + component: TestedComponent, + args: { + order: 5, + }, + argTypes: { + onUpdate: { action: 'onUpdate' }, + onBack: { action: 'onBack' }, + }, +}; + +const type: KnownAuthMethods = 'email' + +export const WithoutFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', +} as ReducerState, { + id: 'uuid-1', +}); + +export const PaymentFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', + challenge_feedback: { + 'uuid-1': { + state: ChallengeFeedbackStatus.Payment, + taler_pay_uri: "taler://pay/...", + provider: "https://localhost:8080/", + payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG" + } + } +} as ReducerState, { + id: 'uuid-1', +}); + diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx new file mode 100644 index 000000000..bd4f43740 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx @@ -0,0 +1,106 @@ +import { ChallengeFeedbackStatus, ChallengeInfo } from "anastasis-core"; +import { h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/AsyncButton"; +import { TextInput } from "../../../components/fields/TextInput"; +import { useAnastasisContext } from "../../../context/anastasis"; +import { AnastasisClientFrame } from "../index"; +import { SolveOverviewFeedbackDisplay } from "../SolveScreen"; +import { AuthMethodSolveProps } from "./index"; + +export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode { + const [answer, setAnswer] = useState(""); + + const reducer = useAnastasisContext(); + if (!reducer) { + return ( + +
no reducer in context
+
+ ); + } + if ( + !reducer.currentReducerState || + reducer.currentReducerState.recovery_state === undefined + ) { + return ( + +
invalid state
+
+ ); + } + + if (!reducer.currentReducerState.recovery_information) { + return ( + +
no recovery information found
+
+ ); + } + if (!reducer.currentReducerState.selected_challenge_uuid) { + return ( + +
invalid state
+
+ +
+
+ ); + } + + const chArr = reducer.currentReducerState.recovery_information.challenges; + const challengeFeedback = + reducer.currentReducerState.challenge_feedback ?? {}; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const challenges: { + [uuid: string]: ChallengeInfo; + } = {}; + for (const ch of chArr) { + challenges[ch.uuid] = ch; + } + const selectedChallenge = challenges[selectedUuid]; + const feedback = challengeFeedback[selectedUuid] + + + async function onNext(): Promise { + return reducer?.transition("solve_challenge", { answer }); + } + function onCancel(): void { + reducer?.back(); + } + + + const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded + || feedback?.state === ChallengeFeedbackStatus.Redirect + || feedback?.state === ChallengeFeedbackStatus.Unsupported + || feedback?.state === ChallengeFeedbackStatus.TruthUnknown + + return ( + + +

+ An email has been sent to "{selectedChallenge.instructions}". Type the + code below +

+ + +
+ + {!shouldHideConfirm && + Confirm + } +
+
+ ); +} diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx index 71f618646..be0a04847 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.stories.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ /* This file is part of GNU Taler (C) 2021 Taler Systems S.A. @@ -25,7 +24,7 @@ import { authMethods as TestedComponent, KnownAuthMethods } from './index'; export default { - title: 'Pages/backup/authMethods/IBAN', + title: 'Pages/backup/AuthorizationMethod/AuthMethods/IBAN', component: TestedComponent, args: { order: 5, @@ -38,11 +37,11 @@ export default { const type: KnownAuthMethods = 'iban' -export const Empty = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [] }); -export const WithOneExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, @@ -50,7 +49,7 @@ export const WithOneExample = createExample(TestedComponent[type].screen, reduce remove: () => null }] }); -export const WithMoreExamples = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx index c9edbfa07..87969ab27 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSetup.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { canonicalJson, encodeCrock, @@ -6,8 +5,8 @@ import { } from "@gnu-taler/taler-util"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; +import { AuthMethodSetupProps } from "."; import { TextInput } from "../../../components/fields/TextInput"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; import { AnastasisClientFrame } from "../index"; export function AuthMethodIbanSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode { diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx new file mode 100644 index 000000000..df73a9214 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx @@ -0,0 +1,56 @@ +/* + 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core'; +import { createExample, reducerStatesExample } from '../../../utils'; +import { authMethods as TestedComponent, KnownAuthMethods } from './index'; + + +export default { + title: 'Pages/recovery/SolveChallenge/AuthMethods/Iban', + component: TestedComponent, + args: { + order: 5, + }, + argTypes: { + onUpdate: { action: 'onUpdate' }, + onBack: { action: 'onBack' }, + }, +}; + +const type: KnownAuthMethods = 'iban' + +export const WithoutFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', +} as ReducerState, { + id: 'uuid-1', +}); + diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx new file mode 100644 index 000000000..1e4353da6 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx @@ -0,0 +1,105 @@ +import { ChallengeFeedbackStatus, ChallengeInfo } from "anastasis-core"; +import { h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/AsyncButton"; +import { TextInput } from "../../../components/fields/TextInput"; +import { useAnastasisContext } from "../../../context/anastasis"; +import { AnastasisClientFrame } from "../index"; +import { SolveOverviewFeedbackDisplay } from "../SolveScreen"; +import { AuthMethodSolveProps } from "./index"; + +export function AuthMethodIbanSolve({ id }: AuthMethodSolveProps): VNode { + const [answer, setAnswer] = useState(""); + + const reducer = useAnastasisContext(); + if (!reducer) { + return ( + +
no reducer in context
+
+ ); + } + if ( + !reducer.currentReducerState || + reducer.currentReducerState.recovery_state === undefined + ) { + return ( + +
invalid state
+
+ ); + } + + if (!reducer.currentReducerState.recovery_information) { + return ( + +
no recovery information found
+
+ ); + } + if (!reducer.currentReducerState.selected_challenge_uuid) { + return ( + +
invalid state
+
+ +
+
+ ); + } + + const chArr = reducer.currentReducerState.recovery_information.challenges; + const challengeFeedback = + reducer.currentReducerState.challenge_feedback ?? {}; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const challenges: { + [uuid: string]: ChallengeInfo; + } = {}; + for (const ch of chArr) { + challenges[ch.uuid] = ch; + } + const selectedChallenge = challenges[selectedUuid]; + const feedback = challengeFeedback[selectedUuid] + + + async function onNext(): Promise { + return reducer?.transition("solve_challenge", { answer }); + } + function onCancel(): void { + reducer?.back(); + } + + + const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded + || feedback?.state === ChallengeFeedbackStatus.Redirect + || feedback?.state === ChallengeFeedbackStatus.Unsupported + || feedback?.state === ChallengeFeedbackStatus.TruthUnknown + + return ( + + +

+ Send a wire transfer to the address +

+ + +
+ + {!shouldHideConfirm && + Confirm + } +
+
+ ); +} diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx index 0f1c17495..adc83d6fe 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx @@ -25,7 +25,7 @@ import { authMethods as TestedComponent, KnownAuthMethods } from './index'; export default { - title: 'Pages/backup/authMethods/Post', + title: 'Pages/backup/AuthorizationMethod/AuthMethods/Post', component: TestedComponent, args: { order: 5, @@ -38,11 +38,11 @@ export default { const type: KnownAuthMethods = 'post' -export const Empty = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [] }); -export const WithOneExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, @@ -51,7 +51,7 @@ export const WithOneExample = createExample(TestedComponent[type].screen, reduce }] }); -export const WithMoreExamples = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx index bfeaaa832..692421d74 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.tsx @@ -1,13 +1,12 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { canonicalJson, encodeCrock, stringToBytes } from "@gnu-taler/taler-util"; -import { Fragment, h, VNode } from "preact"; +import { h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; -import { TextInput } from "../../../components/fields/TextInput"; import { AnastasisClientFrame } from ".."; +import { TextInput } from "../../../components/fields/TextInput"; +import { AuthMethodSetupProps } from "./index"; export function AuthMethodPostSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode { const [fullName, setFullName] = useState(""); diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx new file mode 100644 index 000000000..99451090b --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx @@ -0,0 +1,56 @@ +/* + 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core'; +import { createExample, reducerStatesExample } from '../../../utils'; +import { authMethods as TestedComponent, KnownAuthMethods } from './index'; + + +export default { + title: 'Pages/recovery/SolveChallenge/AuthMethods/post', + component: TestedComponent, + args: { + order: 5, + }, + argTypes: { + onUpdate: { action: 'onUpdate' }, + onBack: { action: 'onBack' }, + }, +}; + +const type: KnownAuthMethods = 'post' + +export const WithoutFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', +} as ReducerState, { + id: 'uuid-1', +}); + diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx new file mode 100644 index 000000000..7e3c45abe --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx @@ -0,0 +1,105 @@ +import { ChallengeFeedbackStatus, ChallengeInfo } from "anastasis-core"; +import { h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/AsyncButton"; +import { TextInput } from "../../../components/fields/TextInput"; +import { useAnastasisContext } from "../../../context/anastasis"; +import { AnastasisClientFrame } from "../index"; +import { SolveOverviewFeedbackDisplay } from "../SolveScreen"; +import { AuthMethodSolveProps } from "./index"; + +export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode { + const [answer, setAnswer] = useState(""); + + const reducer = useAnastasisContext(); + if (!reducer) { + return ( + +
no reducer in context
+
+ ); + } + if ( + !reducer.currentReducerState || + reducer.currentReducerState.recovery_state === undefined + ) { + return ( + +
invalid state
+
+ ); + } + + if (!reducer.currentReducerState.recovery_information) { + return ( + +
no recovery information found
+
+ ); + } + if (!reducer.currentReducerState.selected_challenge_uuid) { + return ( + +
invalid state
+
+ +
+
+ ); + } + + const chArr = reducer.currentReducerState.recovery_information.challenges; + const challengeFeedback = + reducer.currentReducerState.challenge_feedback ?? {}; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const challenges: { + [uuid: string]: ChallengeInfo; + } = {}; + for (const ch of chArr) { + challenges[ch.uuid] = ch; + } + const selectedChallenge = challenges[selectedUuid]; + const feedback = challengeFeedback[selectedUuid] + + + async function onNext(): Promise { + return reducer?.transition("solve_challenge", { answer }); + } + function onCancel(): void { + reducer?.back(); + } + + + const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded + || feedback?.state === ChallengeFeedbackStatus.Redirect + || feedback?.state === ChallengeFeedbackStatus.Unsupported + || feedback?.state === ChallengeFeedbackStatus.TruthUnknown + + return ( + + +

+ Wait for the answer +

+ + +
+ + {!shouldHideConfirm && + Confirm + } +
+
+ ); +} diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx index 3ba4a84ca..0c3ee2b77 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.stories.tsx @@ -25,7 +25,7 @@ import { authMethods as TestedComponent, KnownAuthMethods } from './index'; export default { - title: 'Pages/backup/authMethods/Question', + title: 'Pages/backup/AuthorizationMethod/AuthMethods/Question', component: TestedComponent, args: { order: 5, @@ -38,11 +38,11 @@ export default { const type: KnownAuthMethods = 'question' -export const Empty = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [] }); -export const WithOneExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, @@ -51,7 +51,7 @@ export const WithOneExample = createExample(TestedComponent[type].screen, reduce }] }); -export const WithMoreExamples = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx index 04fa00d59..780bfcb82 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSetup.tsx @@ -1,11 +1,10 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; +import { AuthMethodSetupProps } from "./index"; import { AnastasisClientFrame } from "../index"; import { TextInput } from "../../../components/fields/TextInput"; diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx new file mode 100644 index 000000000..a325b3843 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx @@ -0,0 +1,56 @@ +/* + 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core'; +import { createExample, reducerStatesExample } from '../../../utils'; +import { authMethods as TestedComponent, KnownAuthMethods } from './index'; + + +export default { + title: 'Pages/recovery/SolveChallenge/AuthMethods/question', + component: TestedComponent, + args: { + order: 5, + }, + argTypes: { + onUpdate: { action: 'onUpdate' }, + onBack: { action: 'onBack' }, + }, +}; + +const type: KnownAuthMethods = 'question' + +export const WithoutFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', +} as ReducerState, { + id: 'uuid-1', +}); + diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx new file mode 100644 index 000000000..ee1c0028f --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx @@ -0,0 +1,105 @@ +import { ChallengeFeedbackStatus, ChallengeInfo } from "anastasis-core"; +import { h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/AsyncButton"; +import { TextInput } from "../../../components/fields/TextInput"; +import { useAnastasisContext } from "../../../context/anastasis"; +import { AnastasisClientFrame } from "../index"; +import { SolveOverviewFeedbackDisplay } from "../SolveScreen"; +import { AuthMethodSolveProps } from "./index"; + +export function AuthMethodQuestionSolve({ id }: AuthMethodSolveProps): VNode { + const [answer, setAnswer] = useState(""); + + const reducer = useAnastasisContext(); + if (!reducer) { + return ( + +
no reducer in context
+
+ ); + } + if ( + !reducer.currentReducerState || + reducer.currentReducerState.recovery_state === undefined + ) { + return ( + +
invalid state
+
+ ); + } + + if (!reducer.currentReducerState.recovery_information) { + return ( + +
no recovery information found
+
+ ); + } + if (!reducer.currentReducerState.selected_challenge_uuid) { + return ( + +
invalid state
+
+ +
+
+ ); + } + + const chArr = reducer.currentReducerState.recovery_information.challenges; + const challengeFeedback = + reducer.currentReducerState.challenge_feedback ?? {}; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const challenges: { + [uuid: string]: ChallengeInfo; + } = {}; + for (const ch of chArr) { + challenges[ch.uuid] = ch; + } + const selectedChallenge = challenges[selectedUuid]; + const feedback = challengeFeedback[selectedUuid] + + + async function onNext(): Promise { + return reducer?.transition("solve_challenge", { answer }); + } + function onCancel(): void { + reducer?.back(); + } + + + const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded + || feedback?.state === ChallengeFeedbackStatus.Redirect + || feedback?.state === ChallengeFeedbackStatus.Unsupported + || feedback?.state === ChallengeFeedbackStatus.TruthUnknown + + return ( + + +

+ Answer the question please +

+ + +
+ + {!shouldHideConfirm && + Confirm + } +
+
+ ); +} diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx index ae8297ef7..da2087ce1 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx @@ -25,7 +25,7 @@ import { authMethods as TestedComponent, KnownAuthMethods } from './index'; export default { - title: 'Pages/backup/authMethods/Sms', + title: 'Pages/backup/AuthorizationMethod/AuthMethods/Sms', component: TestedComponent, args: { order: 5, @@ -38,11 +38,11 @@ export default { const type: KnownAuthMethods = 'sms' -export const Empty = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [] }); -export const WithOneExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, @@ -51,7 +51,7 @@ export const WithOneExample = createExample(TestedComponent[type].screen, reduce }] }); -export const WithMoreExamples = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx index 9e85af2b2..cd8782b0c 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.tsx @@ -1,12 +1,11 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { useLayoutEffect, useRef, useState } from "preact/hooks"; +import { AuthMethodSetupProps } from "."; import { NumberInput } from "../../../components/fields/NumberInput"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; import { AnastasisClientFrame } from "../index"; export function AuthMethodSmsSetup({ addAuthMethod, cancel, configured }: AuthMethodSetupProps): VNode { diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx new file mode 100644 index 000000000..76e769303 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx @@ -0,0 +1,56 @@ +/* + 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core'; +import { createExample, reducerStatesExample } from '../../../utils'; +import { authMethods as TestedComponent, KnownAuthMethods } from './index'; + + +export default { + title: 'Pages/recovery/SolveChallenge/AuthMethods/sms', + component: TestedComponent, + args: { + order: 5, + }, + argTypes: { + onUpdate: { action: 'onUpdate' }, + onBack: { action: 'onBack' }, + }, +}; + +const type: KnownAuthMethods = 'sms' + +export const WithoutFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', +} as ReducerState, { + id: 'uuid-1', +}); + diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx new file mode 100644 index 000000000..ce7159bd0 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx @@ -0,0 +1,106 @@ +import { ChallengeFeedbackStatus, ChallengeInfo } from "anastasis-core"; +import { h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/AsyncButton"; +import { TextInput } from "../../../components/fields/TextInput"; +import { useAnastasisContext } from "../../../context/anastasis"; +import { AnastasisClientFrame } from "../index"; +import { SolveOverviewFeedbackDisplay } from "../SolveScreen"; +import { AuthMethodSolveProps } from "./index"; + +export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode { + const [answer, setAnswer] = useState(""); + + const reducer = useAnastasisContext(); + if (!reducer) { + return ( + +
no reducer in context
+
+ ); + } + if ( + !reducer.currentReducerState || + reducer.currentReducerState.recovery_state === undefined + ) { + return ( + +
invalid state
+
+ ); + } + + if (!reducer.currentReducerState.recovery_information) { + return ( + +
no recovery information found
+
+ ); + } + if (!reducer.currentReducerState.selected_challenge_uuid) { + return ( + +
invalid state
+
+ +
+
+ ); + } + + const chArr = reducer.currentReducerState.recovery_information.challenges; + const challengeFeedback = + reducer.currentReducerState.challenge_feedback ?? {}; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const challenges: { + [uuid: string]: ChallengeInfo; + } = {}; + for (const ch of chArr) { + challenges[ch.uuid] = ch; + } + const selectedChallenge = challenges[selectedUuid]; + const feedback = challengeFeedback[selectedUuid] + + + async function onNext(): Promise { + return reducer?.transition("solve_challenge", { answer }); + } + function onCancel(): void { + reducer?.back(); + } + + + const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded + || feedback?.state === ChallengeFeedbackStatus.Redirect + || feedback?.state === ChallengeFeedbackStatus.Unsupported + || feedback?.state === ChallengeFeedbackStatus.TruthUnknown + + return ( + + +

+ An sms has been sent to "{selectedChallenge.instructions}". Type the code + below +

+ + +
+ + {!shouldHideConfirm && + Confirm + } +
+
+ ); +} diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx index 4e46b600e..c0a52924c 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx @@ -25,7 +25,7 @@ import { authMethods as TestedComponent, KnownAuthMethods } from './index'; export default { - title: 'Pages/backup/authMethods/TOTP', + title: 'Pages/backup/AuthorizationMethod/AuthMethods/TOTP', component: TestedComponent, args: { order: 5, @@ -38,10 +38,10 @@ export default { const type: KnownAuthMethods = 'totp' -export const Empty = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [] }); -export const WithOneExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, @@ -49,7 +49,7 @@ export const WithOneExample = createExample(TestedComponent[type].screen, reduce remove: () => null }] }); -export const WithMoreExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithMoreExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx index fd0bd0224..a8ac499b2 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx @@ -1,11 +1,10 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util"; import { h, VNode } from "preact"; import { useMemo, useState } from "preact/hooks"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; +import { AuthMethodSetupProps } from "./index"; import { AnastasisClientFrame } from "../index"; import { TextInput } from "../../../components/fields/TextInput"; import { QR } from "../../../components/QR"; diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx new file mode 100644 index 000000000..a301931b2 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx @@ -0,0 +1,56 @@ +/* + 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core'; +import { createExample, reducerStatesExample } from '../../../utils'; +import { authMethods as TestedComponent, KnownAuthMethods } from './index'; + + +export default { + title: 'Pages/recovery/SolveChallenge/AuthMethods/totp', + component: TestedComponent, + args: { + order: 5, + }, + argTypes: { + onUpdate: { action: 'onUpdate' }, + onBack: { action: 'onBack' }, + }, +}; + +const type: KnownAuthMethods = 'totp' + +export const WithoutFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', +} as ReducerState, { + id: 'uuid-1', +}); + diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx new file mode 100644 index 000000000..30fc44f0e --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx @@ -0,0 +1,105 @@ +import { ChallengeFeedbackStatus, ChallengeInfo } from "anastasis-core"; +import { h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/AsyncButton"; +import { TextInput } from "../../../components/fields/TextInput"; +import { useAnastasisContext } from "../../../context/anastasis"; +import { AnastasisClientFrame } from "../index"; +import { SolveOverviewFeedbackDisplay } from "../SolveScreen"; +import { AuthMethodSolveProps } from "./index"; + +export function AuthMethodTotpSolve({ id }: AuthMethodSolveProps): VNode { + const [answer, setAnswer] = useState(""); + + const reducer = useAnastasisContext(); + if (!reducer) { + return ( + +
no reducer in context
+
+ ); + } + if ( + !reducer.currentReducerState || + reducer.currentReducerState.recovery_state === undefined + ) { + return ( + +
invalid state
+
+ ); + } + + if (!reducer.currentReducerState.recovery_information) { + return ( + +
no recovery information found
+
+ ); + } + if (!reducer.currentReducerState.selected_challenge_uuid) { + return ( + +
invalid state
+
+ +
+
+ ); + } + + const chArr = reducer.currentReducerState.recovery_information.challenges; + const challengeFeedback = + reducer.currentReducerState.challenge_feedback ?? {}; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const challenges: { + [uuid: string]: ChallengeInfo; + } = {}; + for (const ch of chArr) { + challenges[ch.uuid] = ch; + } + const selectedChallenge = challenges[selectedUuid]; + const feedback = challengeFeedback[selectedUuid] + + + async function onNext(): Promise { + return reducer?.transition("solve_challenge", { answer }); + } + function onCancel(): void { + reducer?.back(); + } + + + const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded + || feedback?.state === ChallengeFeedbackStatus.Redirect + || feedback?.state === ChallengeFeedbackStatus.Unsupported + || feedback?.state === ChallengeFeedbackStatus.TruthUnknown + + return ( + + +

+ enter the totp solution +

+ + +
+ + {!shouldHideConfirm && + Confirm + } +
+
+ ); +} diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx index 3c4c7bf39..52e897c60 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx @@ -25,7 +25,7 @@ import { authMethods as TestedComponent, KnownAuthMethods } from './index'; import logoImage from '../../../assets/logo.jpeg' export default { - title: 'Pages/backup/authMethods/Video', + title: 'Pages/backup/AuthorizationMethod/AuthMethods/Video', component: TestedComponent, args: { order: 5, @@ -38,11 +38,11 @@ export default { const type: KnownAuthMethods = 'video' -export const Empty = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const Empty = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [] }); -export const WithOneExample = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithOneExample = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, @@ -51,7 +51,7 @@ export const WithOneExample = createExample(TestedComponent[type].screen, reduce }] }); -export const WithMoreExamples = createExample(TestedComponent[type].screen, reducerStatesExample.authEditing, { +export const WithMoreExamples = createExample(TestedComponent[type].setup, reducerStatesExample.authEditing, { configured: [{ challenge: 'qwe', type, diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx index 8be999b3f..22abe4a49 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ import { encodeCrock, stringToBytes @@ -6,7 +5,7 @@ import { import { h, VNode } from "preact"; import { useState } from "preact/hooks"; import { ImageInput } from "../../../components/fields/ImageInput"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; +import { AuthMethodSetupProps } from "./index"; import { AnastasisClientFrame } from "../index"; export function AuthMethodVideoSetup({cancel, addAuthMethod, configured}: AuthMethodSetupProps): VNode { diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx new file mode 100644 index 000000000..5c4976b87 --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx @@ -0,0 +1,56 @@ +/* + 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 + */ + +/** +* +* @author Sebastian Javier Marchano (sebasjm) +*/ + +import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core'; +import { createExample, reducerStatesExample } from '../../../utils'; +import { authMethods as TestedComponent, KnownAuthMethods } from './index'; + + +export default { + title: 'Pages/recovery/SolveChallenge/AuthMethods/video', + component: TestedComponent, + args: { + order: 5, + }, + argTypes: { + onUpdate: { action: 'onUpdate' }, + onBack: { action: 'onBack' }, + }, +}; + +const type: KnownAuthMethods = 'video' + +export const WithoutFeedback = createExample(TestedComponent[type].solve, { + ...reducerStatesExample.challengeSolving, + recovery_information: { + challenges: [{ + cost: 'USD:1', + instructions: 'does P equals NP?', + type: 'question', + uuid: 'uuid-1' + }], + policies: [], + }, + selected_challenge_uuid: 'uuid-1', +} as ReducerState, { + id: 'uuid-1', +}); + diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx new file mode 100644 index 000000000..79401028a --- /dev/null +++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx @@ -0,0 +1,105 @@ +import { ChallengeFeedbackStatus, ChallengeInfo } from "anastasis-core"; +import { h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { AsyncButton } from "../../../components/AsyncButton"; +import { TextInput } from "../../../components/fields/TextInput"; +import { useAnastasisContext } from "../../../context/anastasis"; +import { AnastasisClientFrame } from "../index"; +import { SolveOverviewFeedbackDisplay } from "../SolveScreen"; +import { AuthMethodSolveProps } from "./index"; + +export function AuthMethodVideoSolve({ id }: AuthMethodSolveProps): VNode { + const [answer, setAnswer] = useState(""); + + const reducer = useAnastasisContext(); + if (!reducer) { + return ( + +
no reducer in context
+
+ ); + } + if ( + !reducer.currentReducerState || + reducer.currentReducerState.recovery_state === undefined + ) { + return ( + +
invalid state
+
+ ); + } + + if (!reducer.currentReducerState.recovery_information) { + return ( + +
no recovery information found
+
+ ); + } + if (!reducer.currentReducerState.selected_challenge_uuid) { + return ( + +
invalid state
+
+ +
+
+ ); + } + + const chArr = reducer.currentReducerState.recovery_information.challenges; + const challengeFeedback = + reducer.currentReducerState.challenge_feedback ?? {}; + const selectedUuid = reducer.currentReducerState.selected_challenge_uuid; + const challenges: { + [uuid: string]: ChallengeInfo; + } = {}; + for (const ch of chArr) { + challenges[ch.uuid] = ch; + } + const selectedChallenge = challenges[selectedUuid]; + const feedback = challengeFeedback[selectedUuid] + + + async function onNext(): Promise { + return reducer?.transition("solve_challenge", { answer }); + } + function onCancel(): void { + reducer?.back(); + } + + + const shouldHideConfirm = feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded + || feedback?.state === ChallengeFeedbackStatus.Redirect + || feedback?.state === ChallengeFeedbackStatus.Unsupported + || feedback?.state === ChallengeFeedbackStatus.TruthUnknown + + return ( + + +

+ You are gonna be called to check your identity +

+ + +
+ + {!shouldHideConfirm && + Confirm + } +
+
+ ); +} diff --git a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx index 7b0cce883..07f6ec206 100644 --- a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx +++ b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx @@ -1,22 +1,44 @@ +import { AuthMethod } from "anastasis-core"; import { h, VNode } from "preact"; -import { AuthMethodSetupProps } from "../AuthenticationEditorScreen"; - -import { AuthMethodEmailSetup as EmailScreen } from "./AuthMethodEmailSetup"; -import { AuthMethodIbanSetup as IbanScreen } from "./AuthMethodIbanSetup"; -import { AuthMethodPostSetup as PostalScreen } from "./AuthMethodPostSetup"; -import { AuthMethodQuestionSetup as QuestionScreen } from "./AuthMethodQuestionSetup"; -import { AuthMethodSmsSetup as SmsScreen } from "./AuthMethodSmsSetup"; -import { AuthMethodTotpSetup as TotpScreen } from "./AuthMethodTotpSetup"; -import { AuthMethodVideoSetup as VideScreen } from "./AuthMethodVideoSetup"; import postalIcon from '../../../assets/icons/auth_method/postal.svg'; import questionIcon from '../../../assets/icons/auth_method/question.svg'; import smsIcon from '../../../assets/icons/auth_method/sms.svg'; import videoIcon from '../../../assets/icons/auth_method/video.svg'; +import { AuthMethodEmailSetup as EmailSetup } from "./AuthMethodEmailSetup"; +import { AuthMethodEmailSolve as EmailSolve } from "./AuthMethodEmailSolve"; +import { AuthMethodIbanSetup as IbanSetup } from "./AuthMethodIbanSetup"; +import { AuthMethodPostSetup as PostalSetup } from "./AuthMethodPostSetup"; +import { AuthMethodQuestionSetup as QuestionSetup } from "./AuthMethodQuestionSetup"; +import { AuthMethodSmsSetup as SmsSetup } from "./AuthMethodSmsSetup"; +import { AuthMethodTotpSetup as TotpSetup } from "./AuthMethodTotpSetup"; +import { AuthMethodVideoSetup as VideoSetup } from "./AuthMethodVideoSetup"; + +import { AuthMethodIbanSolve as IbanSolve } from "./AuthMethodIbanSolve"; +import { AuthMethodPostSolve as PostalSolve } from "./AuthMethodPostSolve"; +import { AuthMethodQuestionSolve as QuestionSolve } from "./AuthMethodQuestionSolve"; +import { AuthMethodSmsSolve as SmsSolve } from "./AuthMethodSmsSolve"; +import { AuthMethodTotpSolve as TotpSolve } from "./AuthMethodTotpSolve"; +import { AuthMethodVideoSolve as VideoSolve } from "./AuthMethodVideoSolve"; + + +export type AuthMethodWithRemove = AuthMethod & { remove: () => void } + +export interface AuthMethodSetupProps { + method: string; + addAuthMethod: (x: any) => void; + configured: AuthMethodWithRemove[]; + cancel: () => void; +} + +export interface AuthMethodSolveProps { + id: string; +} interface AuthMethodConfiguration { icon: VNode; label: string; - screen: (props: AuthMethodSetupProps) => VNode; + setup: (props: AuthMethodSetupProps) => VNode; + solve: (props: AuthMethodSolveProps) => VNode; skip?: boolean; } export type KnownAuthMethods = "sms" | "email" | "post" | "question" | "video" | "totp" | "iban"; @@ -29,41 +51,44 @@ export const authMethods: KnowMethodConfig = { question: { icon: , label: "Question", - screen: QuestionScreen + setup: QuestionSetup, + solve: QuestionSolve, }, sms: { icon: , label: "SMS", - screen: SmsScreen + setup: SmsSetup, + solve: SmsSolve, }, email: { icon: , label: "Email", - screen: EmailScreen - + setup: EmailSetup, + solve: EmailSolve, }, iban: { icon: , label: "IBAN", - screen: IbanScreen - + setup: IbanSetup, + solve: IbanSolve, }, post: { icon: , label: "Physical mail", - screen: PostalScreen - + setup: PostalSetup, + solve: PostalSolve, }, totp: { icon: , label: "TOTP", - screen: TotpScreen - + setup: TotpSetup, + solve: TotpSolve, }, video: { icon: , label: "Video", - screen: VideScreen, - skip: true, + setup: VideoSetup, + solve: VideoSolve, + skip: true, } } \ No newline at end of file diff --git a/packages/anastasis-webui/src/pages/home/index.tsx b/packages/anastasis-webui/src/pages/home/index.tsx index 07bc7c604..cd8d6c842 100644 --- a/packages/anastasis-webui/src/pages/home/index.tsx +++ b/packages/anastasis-webui/src/pages/home/index.tsx @@ -1,8 +1,6 @@ import { BackupStates, - RecoveryStates, - ReducerStateBackup, - ReducerStateRecovery + RecoveryStates } from "anastasis-core"; import { ComponentChildren, Fragment, -- cgit v1.2.3