gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: some solve challenge examples


From: gnunet
Subject: [taler-wallet-core] branch master updated: some solve challenge examples, WIP
Date: Mon, 08 Nov 2021 13:56:15 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 6ef5fd21 some solve challenge examples, WIP
6ef5fd21 is described below

commit 6ef5fd21fc365d780da42170ce85042f874ed1dc
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Nov 8 09:56:06 2021 -0300

    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 +-
 ...stories.tsx => AuthMethodIbanSolve.stories.tsx} |  46 ++----
 .../pages/home/authMethod/AuthMethodIbanSolve.tsx  | 105 ++++++++++++
 .../authMethod/AuthMethodPostSetup.stories.tsx     |   8 +-
 .../pages/home/authMethod/AuthMethodPostSetup.tsx  |   7 +-
 ...stories.tsx => AuthMethodPostSolve.stories.tsx} |  42 ++---
 .../pages/home/authMethod/AuthMethodPostSolve.tsx  | 105 ++++++++++++
 .../authMethod/AuthMethodQuestionSetup.stories.tsx |   8 +-
 .../home/authMethod/AuthMethodQuestionSetup.tsx    |   3 +-
 ...ies.tsx => AuthMethodQuestionSolve.stories.tsx} |  46 ++----
 .../home/authMethod/AuthMethodQuestionSolve.tsx    | 105 ++++++++++++
 .../home/authMethod/AuthMethodSmsSetup.stories.tsx |   8 +-
 .../pages/home/authMethod/AuthMethodSmsSetup.tsx   |   3 +-
 ....stories.tsx => AuthMethodSmsSolve.stories.tsx} |  42 ++---
 .../pages/home/authMethod/AuthMethodSmsSolve.tsx   | 106 ++++++++++++
 .../authMethod/AuthMethodTotpSetup.stories.tsx     |   8 +-
 .../pages/home/authMethod/AuthMethodTotpSetup.tsx  |   3 +-
 ...stories.tsx => AuthMethodTotpSolve.stories.tsx} |  42 ++---
 .../pages/home/authMethod/AuthMethodTotpSolve.tsx  | 105 ++++++++++++
 .../authMethod/AuthMethodVideoSetup.stories.tsx    |   8 +-
 .../pages/home/authMethod/AuthMethodVideoSetup.tsx |   3 +-
 ...tories.tsx => AuthMethodVideoSolve.stories.tsx} |  44 ++---
 .../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, 1053 insertions(+), 443 deletions(-)

diff --git 
a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
index 43807fef..d290a660 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 54968661..9cdd132e 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 5077c3eb..2712522c 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 93ca8119..a71220c5 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 <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 [addingProvider, setAddingProvider] = useState<string | 
undefined>(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 (<Fragment>
       <AuthSetup
         cancel={cancel}
@@ -88,10 +86,6 @@ export function AuthenticationEditorScreen(): VNode {
     );
   }
 
-  if (addingProvider !== undefined) {
-    return <div />
-  }
-
   function MethodButton(props: { method: KnownAuthMethods }): VNode {
     if (authMethods[props.method].skip) return <div />
     
@@ -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 (
     <AnastasisClientFrame hideNav title={`Add ${props.method} authentication`}>
diff --git 
a/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/BackupFinishedScreen.stories.tsx
index b71a7972..306adacb 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 e001ed15..46c574cf 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 e5fe09e9..fbcaa0e9 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 fc339e48..3d5fcce5 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 e952ab28..3ddf8011 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 0d2ebb77..e92a231a 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 9f7e26c1..e348101e 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 49dd8fca..db061d93 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 6919eeba..8d02ebfb 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 7e3880f9..82f06c34 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 35db5ead..ec6c7735 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 <div />;
@@ -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 {
       </AnastasisClientFrame>
     );
   }
-
-  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<string, (p: SolveEntryProps) => h.JSX.Element> = {
-    question: SolveQuestionEntry,
-    sms: SolveSmsEntry,
-    email: SolveEmailEntry,
-    post: SolvePostEntry,
-  };
-  const SolveDialog =
-    selectedChallenge === undefined
-      ? SolveUndefinedEntry
-      : dialogMap[selectedChallenge.type] ?? SolveUnsupportedEntry;
-
-  async function onNext(): Promise<void> {
-    return reducer?.transition("solve_challenge", { answer });
-  }
-  function onCancel(): void {
-    reducer?.back();
+  function SolveNotImplemented(): VNode {
+    return (
+      <AnastasisClientFrame hideNav title="Not implemented">
+        <p>
+          The challenge selected is not supported for this UI. Please update 
this
+          version or try using another policy.
+        </p>
+        {reducer &&
+          <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+            <button class="button" onClick={() => reducer.back()}>Back</button>
+          </div>
+        }
+      </AnastasisClientFrame>
+    );
   }
 
-  const feedback = challengeFeedback[selectedUuid]
-  const shouldHideConfirm = feedback?.state === 
ChallengeFeedbackStatus.RateLimitExceeded
-    || feedback?.state === ChallengeFeedbackStatus.Redirect
-    || feedback?.state === ChallengeFeedbackStatus.Unsupported
-    || feedback?.state === ChallengeFeedbackStatus.TruthUnknown
-
-  return (
-    <AnastasisClientFrame hideNav title="Recovery: Solve challenge">
-      <SolveOverviewFeedbackDisplay
-        feedback={feedback}
-      />
-      <SolveDialog
-        id={selectedUuid}
-        answer={answer}
-        setAnswer={setAnswer}
-        challenge={selectedChallenge}
-        feedback={feedback}
-      />
-
-      <div
-        style={{
-          marginTop: "2em",
-          display: "flex",
-          justifyContent: "space-between",
-        }}
-      >
-        <button class="button" onClick={onCancel}>
-          Cancel
-        </button>
-        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
-          Confirm
-        </AsyncButton>}
-      </div>
-    </AnastasisClientFrame>
-  );
-}
-
-export interface SolveEntryProps {
-  id: string;
-  challenge: ChallengeInfo;
-  feedback?: ChallengeFeedback;
-  answer: string;
-  setAnswer: (s: string) => void;
-}
-
-function SolveSmsEntry({
-  challenge,
-  answer,
-  setAnswer,
-}: SolveEntryProps): VNode {
-  return (
-    <Fragment>
-
-      <p>
-        An sms has been sent to "<b>{challenge.instructions}</b>". Type the 
code
-        below
-      </p>
-      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
-    </Fragment>
-  );
-}
-function SolveQuestionEntry({
-  challenge,
-  answer,
-  setAnswer,
-}: SolveEntryProps): VNode {
-  return (
-    <Fragment>
-      <p>Type the answer to the following question:</p>
-      <pre>{challenge.instructions}</pre>
-      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
-    </Fragment>
-  );
-}
 
-function SolvePostEntry({
-  challenge,
-  answer,
-  setAnswer,
-}: SolveEntryProps): VNode {
-  return (
-    <Fragment>
-      <p>
-        instruction for post type challenge "<b>{challenge.instructions}</b>"
-      </p>
-      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
-    </Fragment>
-  );
-}
+  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 (
-    <Fragment>
-      <p>
-        An email has been sent to "<b>{challenge.instructions}</b>". Type the
-        code below
-      </p>
-      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
-    </Fragment>
-  );
-}
+  const SolveDialog = !selectedChallenge || 
!authMethods[selectedChallenge.type as KnownAuthMethods] ?
+    SolveNotImplemented :
+    authMethods[selectedChallenge.type as KnownAuthMethods].solve ?? 
SolveNotImplemented
 
-function SolveUnsupportedEntry(props: SolveEntryProps): VNode {
-  return (
-    <Fragment>
-      <p>
-        The challenge selected is not supported for this UI. Please update this
-        version or try using another policy.
-      </p>
-      <p>
-        <b>Challenge type:</b> {props.challenge.type}
-      </p>
-    </Fragment>
-  );
-}
-function SolveUndefinedEntry(props: SolveEntryProps): VNode {
-  return (
-    <Fragment>
-      <p>
-        There is no challenge information for id <b>"{props.id}"</b>. Try
-        resetting the recovery session.
-      </p>
-    </Fragment>
-  );
+  return <SolveDialog id={selectedUuid} />
 }
diff --git a/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/StartScreen.stories.tsx
index 657a2dd7..41082c12 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 7568ccd6..38b71bc3 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 e178a495..da87b7a8 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 1a6be1b6..27a0685b 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 00000000..525cd2b0
--- /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 <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @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 00000000..bd4f4374
--- /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 (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>no reducer in context</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (
+    !reducer.currentReducerState ||
+    reducer.currentReducerState.recovery_state === undefined
+  ) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  if (!reducer.currentReducerState.recovery_information) {
+    return (
+      <AnastasisClientFrame
+        hideNext="Recovery document not found"
+        title="Recovery problem"
+      >
+        <div>no recovery information found</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (!reducer.currentReducerState.selected_challenge_uuid) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={() => reducer.back()}>Back</button>
+        </div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  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<void> {
+    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 (
+    <AnastasisClientFrame hideNav title="Add email authentication">
+      <SolveOverviewFeedbackDisplay feedback={feedback} />
+      <p>
+        An email has been sent to "<b>{selectedChallenge.instructions}</b>". 
Type the
+        code below
+      </p>
+      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+
+      <div
+        style={{
+          marginTop: "2em",
+          display: "flex",
+          justifyContent: "space-between",
+        }}
+      >
+        <button class="button" onClick={onCancel}>
+          Cancel
+        </button>
+        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
+          Confirm
+        </AsyncButton>}
+      </div>
+    </AnastasisClientFrame>
+  );
+}
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 71f61864..be0a0484 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 c9edbfa0..87969ab2 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/AuthMethodSmsSetup.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx
similarity index 56%
copy from 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
copy to 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx
index ae8297ef..df73a921 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.stories.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 /*
  This file is part of GNU Taler
  (C) 2021 Taler Systems S.A.
@@ -20,12 +19,13 @@
 * @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/backup/authMethods/Sms',
+  title: 'Pages/recovery/SolveChallenge/AuthMethods/Iban',
   component: TestedComponent,
   args: {
     order: 5,
@@ -36,31 +36,21 @@ export default {
   },
 };
 
-const type: KnownAuthMethods = 'sms'
-
-export const Empty = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: []
-});
-
-export const WithOneExample = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-1234-2345',
-    remove: () => null
-  }]
+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',
 });
 
-export const WithMoreExamples = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-1234-2345',
-    remove: () => null
-  },{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-5555-2345',
-    remove: () => null
-  }]
-});
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 00000000..1e4353da
--- /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 (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>no reducer in context</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (
+    !reducer.currentReducerState ||
+    reducer.currentReducerState.recovery_state === undefined
+  ) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  if (!reducer.currentReducerState.recovery_information) {
+    return (
+      <AnastasisClientFrame
+        hideNext="Recovery document not found"
+        title="Recovery problem"
+      >
+        <div>no recovery information found</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (!reducer.currentReducerState.selected_challenge_uuid) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={() => reducer.back()}>Back</button>
+        </div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  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<void> {
+    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 (
+    <AnastasisClientFrame hideNav title="Add email authentication">
+      <SolveOverviewFeedbackDisplay feedback={feedback} />
+      <p>
+        Send a wire transfer to the address
+      </p>
+      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+
+      <div
+        style={{
+          marginTop: "2em",
+          display: "flex",
+          justifyContent: "space-between",
+        }}
+      >
+        <button class="button" onClick={onCancel}>
+          Cancel
+        </button>
+        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
+          Confirm
+        </AsyncButton>}
+      </div>
+    </AnastasisClientFrame>
+  );
+}
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 0f1c1749..adc83d6f 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 bfeaaa83..692421d7 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/AuthMethodPostSetup.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx
similarity index 56%
copy from 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx
copy to 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx
index 0f1c1749..99451090 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSetup.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.stories.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 /*
  This file is part of GNU Taler
  (C) 2021 Taler Systems S.A.
@@ -20,12 +19,13 @@
 * @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/backup/authMethods/Post',
+  title: 'Pages/recovery/SolveChallenge/AuthMethods/post',
   component: TestedComponent,
   args: {
     order: 5,
@@ -38,29 +38,19 @@ export default {
 
 const type: KnownAuthMethods = 'post'
 
-export const Empty = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: []
-});
-
-export const WithOneExample = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'Letter to address in postal code QWE456',
-    remove: () => null
-  }]
+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 WithMoreExamples = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'Letter to address in postal code QWE456',
-    remove: () => null
-  },{
-    challenge: 'qwe',
-    type,
-    instructions: 'Letter to address in postal code ABC123',
-    remove: () => null
-  }]
-});
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 00000000..7e3c45ab
--- /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 (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>no reducer in context</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (
+    !reducer.currentReducerState ||
+    reducer.currentReducerState.recovery_state === undefined
+  ) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  if (!reducer.currentReducerState.recovery_information) {
+    return (
+      <AnastasisClientFrame
+        hideNext="Recovery document not found"
+        title="Recovery problem"
+      >
+        <div>no recovery information found</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (!reducer.currentReducerState.selected_challenge_uuid) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={() => reducer.back()}>Back</button>
+        </div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  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<void> {
+    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 (
+    <AnastasisClientFrame hideNav title="Add email authentication">
+      <SolveOverviewFeedbackDisplay feedback={feedback} />
+      <p>
+        Wait for the answer
+      </p>
+      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+
+      <div
+        style={{
+          marginTop: "2em",
+          display: "flex",
+          justifyContent: "space-between",
+        }}
+      >
+        <button class="button" onClick={onCancel}>
+          Cancel
+        </button>
+        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
+          Confirm
+        </AsyncButton>}
+      </div>
+    </AnastasisClientFrame>
+  );
+}
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 3ba4a84c..0c3ee2b7 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 04fa00d5..780bfcb8 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/AuthMethodSmsSetup.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
similarity index 56%
copy from 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
copy to 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
index ae8297ef..a325b384 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 /*
  This file is part of GNU Taler
  (C) 2021 Taler Systems S.A.
@@ -20,12 +19,13 @@
 * @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/backup/authMethods/Sms',
+  title: 'Pages/recovery/SolveChallenge/AuthMethods/question',
   component: TestedComponent,
   args: {
     order: 5,
@@ -36,31 +36,21 @@ export default {
   },
 };
 
-const type: KnownAuthMethods = 'sms'
-
-export const Empty = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: []
-});
-
-export const WithOneExample = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-1234-2345',
-    remove: () => null
-  }]
+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',
 });
 
-export const WithMoreExamples = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-1234-2345',
-    remove: () => null
-  },{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-5555-2345',
-    remove: () => null
-  }]
-});
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 00000000..ee1c0028
--- /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 (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>no reducer in context</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (
+    !reducer.currentReducerState ||
+    reducer.currentReducerState.recovery_state === undefined
+  ) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  if (!reducer.currentReducerState.recovery_information) {
+    return (
+      <AnastasisClientFrame
+        hideNext="Recovery document not found"
+        title="Recovery problem"
+      >
+        <div>no recovery information found</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (!reducer.currentReducerState.selected_challenge_uuid) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={() => reducer.back()}>Back</button>
+        </div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  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<void> {
+    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 (
+    <AnastasisClientFrame hideNav title="Add email authentication">
+      <SolveOverviewFeedbackDisplay feedback={feedback} />
+      <p>
+        Answer the question please
+      </p>
+      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+
+      <div
+        style={{
+          marginTop: "2em",
+          display: "flex",
+          justifyContent: "space-between",
+        }}
+      >
+        <button class="button" onClick={onCancel}>
+          Cancel
+        </button>
+        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
+          Confirm
+        </AsyncButton>}
+      </div>
+    </AnastasisClientFrame>
+  );
+}
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 ae8297ef..da2087ce 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 9e85af2b..cd8782b0 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/AuthMethodSmsSetup.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx
similarity index 58%
copy from 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
copy to 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx
index ae8297ef..76e76930 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSetup.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.stories.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 /*
  This file is part of GNU Taler
  (C) 2021 Taler Systems S.A.
@@ -20,12 +19,13 @@
 * @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/backup/authMethods/Sms',
+  title: 'Pages/recovery/SolveChallenge/AuthMethods/sms',
   component: TestedComponent,
   args: {
     order: 5,
@@ -38,29 +38,19 @@ export default {
 
 const type: KnownAuthMethods = 'sms'
 
-export const Empty = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: []
-});
-
-export const WithOneExample = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-1234-2345',
-    remove: () => null
-  }]
+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 WithMoreExamples = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-1234-2345',
-    remove: () => null
-  },{
-    challenge: 'qwe',
-    type,
-    instructions: 'SMS to +11-5555-2345',
-    remove: () => null
-  }]
-});
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 00000000..ce7159bd
--- /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 (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>no reducer in context</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (
+    !reducer.currentReducerState ||
+    reducer.currentReducerState.recovery_state === undefined
+  ) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  if (!reducer.currentReducerState.recovery_information) {
+    return (
+      <AnastasisClientFrame
+        hideNext="Recovery document not found"
+        title="Recovery problem"
+      >
+        <div>no recovery information found</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (!reducer.currentReducerState.selected_challenge_uuid) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={() => reducer.back()}>Back</button>
+        </div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  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<void> {
+    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 (
+    <AnastasisClientFrame hideNav title="Add email authentication">
+      <SolveOverviewFeedbackDisplay feedback={feedback} />
+      <p>
+        An sms has been sent to "<b>{selectedChallenge.instructions}</b>". 
Type the code
+        below
+      </p>
+      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+
+      <div
+        style={{
+          marginTop: "2em",
+          display: "flex",
+          justifyContent: "space-between",
+        }}
+      >
+        <button class="button" onClick={onCancel}>
+          Cancel
+        </button>
+        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
+          Confirm
+        </AsyncButton>}
+      </div>
+    </AnastasisClientFrame>
+  );
+}
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 4e46b600..c0a52924 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 fd0bd022..a8ac499b 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/AuthMethodTotpSetup.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx
similarity index 57%
copy from 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx
copy to 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx
index 4e46b600..a301931b 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.stories.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 /*
  This file is part of GNU Taler
  (C) 2021 Taler Systems S.A.
@@ -20,12 +19,13 @@
 * @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/backup/authMethods/TOTP',
+  title: 'Pages/recovery/SolveChallenge/AuthMethods/totp',
   component: TestedComponent,
   args: {
     order: 5,
@@ -38,27 +38,19 @@ export default {
 
 const type: KnownAuthMethods = 'totp'
 
-export const Empty = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: []
-});
-export const WithOneExample = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'Enter 8 digits code for "Anastasis"',
-    remove: () => null
-  }]
-});
-export const WithMoreExample = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: 'Enter 8 digits code for "Anastasis1"',
-    remove: () => null
-  },{
-    challenge: 'qwe',
-    type,
-    instructions: 'Enter 8 digits code for "Anastasis2"',
-    remove: () => null
-  }]
+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 00000000..30fc44f0
--- /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 (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>no reducer in context</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (
+    !reducer.currentReducerState ||
+    reducer.currentReducerState.recovery_state === undefined
+  ) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  if (!reducer.currentReducerState.recovery_information) {
+    return (
+      <AnastasisClientFrame
+        hideNext="Recovery document not found"
+        title="Recovery problem"
+      >
+        <div>no recovery information found</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (!reducer.currentReducerState.selected_challenge_uuid) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={() => reducer.back()}>Back</button>
+        </div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  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<void> {
+    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 (
+    <AnastasisClientFrame hideNav title="Add email authentication">
+      <SolveOverviewFeedbackDisplay feedback={feedback} />
+      <p>
+        enter the totp solution
+      </p>
+      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+
+      <div
+        style={{
+          marginTop: "2em",
+          display: "flex",
+          justifyContent: "space-between",
+        }}
+      >
+        <button class="button" onClick={onCancel}>
+          Cancel
+        </button>
+        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
+          Confirm
+        </AsyncButton>}
+      </div>
+    </AnastasisClientFrame>
+  );
+}
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 3c4c7bf3..52e897c6 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 8be999b3..22abe4a4 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/AuthMethodVideoSetup.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
similarity index 58%
copy from 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
copy to 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
index 3c4c7bf3..5c4976b8 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 /*
  This file is part of GNU Taler
  (C) 2021 Taler Systems S.A.
@@ -20,12 +19,13 @@
 * @author Sebastian Javier Marchano (sebasjm)
 */
 
+import { ChallengeFeedbackStatus, ReducerState } from 'anastasis-core';
 import { createExample, reducerStatesExample } from '../../../utils';
 import { authMethods as TestedComponent, KnownAuthMethods } from './index';
-import logoImage from '../../../assets/logo.jpeg'
+
 
 export default {
-  title: 'Pages/backup/authMethods/Video',
+  title: 'Pages/recovery/SolveChallenge/AuthMethods/video',
   component: TestedComponent,
   args: {
     order: 5,
@@ -38,29 +38,19 @@ export default {
 
 const type: KnownAuthMethods = 'video'
 
-export const Empty = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: []
-});
-
-export const WithOneExample = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: logoImage,
-    remove: () => null
-  }]
+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 WithMoreExamples = createExample(TestedComponent[type].screen, 
reducerStatesExample.authEditing, {
-  configured: [{
-    challenge: 'qwe',
-    type,
-    instructions: logoImage,
-    remove: () => null
-  },{
-    challenge: 'qwe',
-    type,
-    instructions: logoImage,
-    remove: () => null
-  }]
-});
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 00000000..79401028
--- /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 (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>no reducer in context</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (
+    !reducer.currentReducerState ||
+    reducer.currentReducerState.recovery_state === undefined
+  ) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  if (!reducer.currentReducerState.recovery_information) {
+    return (
+      <AnastasisClientFrame
+        hideNext="Recovery document not found"
+        title="Recovery problem"
+      >
+        <div>no recovery information found</div>
+      </AnastasisClientFrame>
+    );
+  }
+  if (!reducer.currentReducerState.selected_challenge_uuid) {
+    return (
+      <AnastasisClientFrame hideNav title="Recovery problem">
+        <div>invalid state</div>
+        <div style={{ marginTop: '2em', display: 'flex', justifyContent: 
'space-between' }}>
+          <button class="button" onClick={() => reducer.back()}>Back</button>
+        </div>
+      </AnastasisClientFrame>
+    );
+  }
+
+  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<void> {
+    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 (
+    <AnastasisClientFrame hideNav title="Add email authentication">
+      <SolveOverviewFeedbackDisplay feedback={feedback} />
+      <p>
+        You are gonna be called to check your identity
+      </p>
+      <TextInput label="Answer" grabFocus bind={[answer, setAnswer]} />
+
+      <div
+        style={{
+          marginTop: "2em",
+          display: "flex",
+          justifyContent: "space-between",
+        }}
+      >
+        <button class="button" onClick={onCancel}>
+          Cancel
+        </button>
+        {!shouldHideConfirm && <AsyncButton class="button is-info" 
onClick={onNext}>
+          Confirm
+        </AsyncButton>}
+      </div>
+    </AnastasisClientFrame>
+  );
+}
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
index 7b0cce88..07f6ec20 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: <img src={questionIcon} />,
     label: "Question",
-    screen: QuestionScreen
+    setup: QuestionSetup,
+    solve: QuestionSolve,
   },
   sms: {
     icon: <img src={smsIcon} />,
     label: "SMS",
-    screen: SmsScreen
+    setup: SmsSetup,
+    solve: SmsSolve,
   },
   email: {
     icon: <i class="mdi mdi-email" />,
     label: "Email",
-    screen: EmailScreen
-    
+    setup: EmailSetup,
+    solve: EmailSolve,
   },
   iban: {
     icon: <i class="mdi mdi-bank" />,
     label: "IBAN",
-    screen: IbanScreen
-    
+    setup: IbanSetup,
+    solve: IbanSolve,
   },
   post: {
     icon: <img src={postalIcon} />,
     label: "Physical mail",
-    screen: PostalScreen
-    
+    setup: PostalSetup,
+    solve: PostalSolve,
   },
   totp: {
     icon: <i class="mdi mdi-devices" />,
     label: "TOTP",
-    screen: TotpScreen
-    
+    setup: TotpSetup,
+    solve: TotpSolve,
   },
   video: {
     icon: <img src={videoIcon} />,
     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 07bc7c60..cd8d6c84 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,

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]