gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated (bd76b5d7 -> aad836ee)


From: gnunet
Subject: [taler-wallet-core] branch master updated (bd76b5d7 -> aad836ee)
Date: Wed, 13 Apr 2022 23:46:37 +0200

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

dold pushed a change to branch master
in repository wallet-core.

    from bd76b5d7 fix: #7072
     new 4e1fe5eb anastasis-webui: updated challenge feedback
     new aad836ee lockfile

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../anastasis-core/src/challenge-feedback-types.ts | 109 ++++++++--------
 packages/anastasis-core/src/index.ts               | 139 ++++++++++++++++-----
 packages/anastasis-core/src/provider-types.ts      |  90 +++++++++++++
 packages/anastasis-core/src/reducer-types.ts       |   2 -
 packages/anastasis-webui/package.json              |   3 +-
 .../src/hooks/use-anastasis-reducer.ts             |  20 ++-
 .../pages/home/AddingProviderScreen.stories.tsx    |   8 --
 .../pages/home/ChallengeOverviewScreen.stories.tsx |  15 +--
 .../src/pages/home/ChallengeOverviewScreen.tsx     |  20 +--
 .../anastasis-webui/src/pages/home/SolveScreen.tsx |  35 +-----
 .../authMethod/AuthMethodEmailSolve.stories.tsx    |   2 +-
 .../pages/home/authMethod/AuthMethodEmailSolve.tsx |   9 +-
 .../pages/home/authMethod/AuthMethodIbanSolve.tsx  |  10 +-
 .../pages/home/authMethod/AuthMethodPostSolve.tsx  |   9 +-
 .../authMethod/AuthMethodQuestionSolve.stories.tsx |  77 ++----------
 .../home/authMethod/AuthMethodQuestionSolve.tsx    |   9 +-
 .../pages/home/authMethod/AuthMethodSmsSolve.tsx   |   9 +-
 .../pages/home/authMethod/AuthMethodTotpSolve.tsx  |   9 +-
 .../authMethod/AuthMethodVideoSetup.stories.tsx    |  83 ------------
 .../pages/home/authMethod/AuthMethodVideoSetup.tsx |  92 --------------
 .../authMethod/AuthMethodVideoSolve.stories.tsx    |  63 ----------
 .../pages/home/authMethod/AuthMethodVideoSolve.tsx | 114 -----------------
 .../src/pages/home/authMethod/helpers.ts           |  12 ++
 .../src/pages/home/authMethod/index.tsx            |  21 +---
 packages/taler-util/src/payto.ts                   |  86 +++++++------
 pnpm-lock.yaml                                     |   3 +
 26 files changed, 364 insertions(+), 685 deletions(-)
 delete mode 100644 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
 delete mode 100644 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx
 delete mode 100644 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
 delete mode 100644 
packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx
 create mode 100644 
packages/anastasis-webui/src/pages/home/authMethod/helpers.ts

diff --git a/packages/anastasis-core/src/challenge-feedback-types.ts 
b/packages/anastasis-core/src/challenge-feedback-types.ts
index 0770d929..30f42288 100644
--- a/packages/anastasis-core/src/challenge-feedback-types.ts
+++ b/packages/anastasis-core/src/challenge-feedback-types.ts
@@ -1,29 +1,48 @@
+/*
+ This file is part of GNU Anastasis
+ (C) 2021-2022 Anastasis SARL
+
+ GNU Anastasis is free software; you can redistribute it and/or modify it 
under the
+ terms of the GNU Affero General Public License as published by the Free 
Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Anastasis 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 Affero General Public License for more 
details.
+
+ You should have received a copy of the GNU Affero General Public License 
along with
+ GNU Anastasis; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Imports.
+ */
 import { AmountString, HttpStatusCode } from "@gnu-taler/taler-util";
 
 export enum ChallengeFeedbackStatus {
   Solved = "solved",
+  CodeInFile = "code-in-file",
+  CodeSent = "code-sent",
   ServerFailure = "server-failure",
   TruthUnknown = "truth-unknown",
-  Redirect = "redirect",
-  Payment = "payment",
-  Pending = "pending",
-  Message = "message",
+  TalerPayment = "taler-payment",
   Unsupported = "unsupported",
   RateLimitExceeded = "rate-limit-exceeded",
   AuthIban = "auth-iban",
+  IncorrectAnswer = "incorrect-answer",
 }
 
 export type ChallengeFeedback =
   | ChallengeFeedbackSolved
-  | ChallengeFeedbackPending
-  | ChallengeFeedbackPayment
+  | ChallengeFeedbackCodeInFile
+  | ChallengeFeedbackCodeSent
+  | ChallengeFeedbackIncorrectAnswer
+  | ChallengeFeedbackTalerPaymentRequired
   | ChallengeFeedbackServerFailure
   | ChallengeFeedbackRateLimitExceeded
   | ChallengeFeedbackTruthUnknown
-  | ChallengeFeedbackRedirect
-  | ChallengeFeedbackMessage
   | ChallengeFeedbackUnsupported
-  | ChallengeFeedbackAuthIban;
+  | ChallengeFeedbackBankTransferRequired;
 
 /**
  * Challenge has been solved and the key share has
@@ -33,13 +52,29 @@ export interface ChallengeFeedbackSolved {
   state: ChallengeFeedbackStatus.Solved;
 }
 
+export interface ChallengeFeedbackIncorrectAnswer {
+  state: ChallengeFeedbackStatus.IncorrectAnswer;
+}
+
+export interface ChallengeFeedbackCodeInFile {
+  state: ChallengeFeedbackStatus.CodeInFile;
+  filename: string;
+  display_hint: string;
+}
+
+export interface ChallengeFeedbackCodeSent {
+  state: ChallengeFeedbackStatus.CodeSent;
+  display_hint: string;
+  address_hint: string;
+}
+
 /**
  * The challenge given by the server is unsupported
  * by the current anastasis client.
  */
 export interface ChallengeFeedbackUnsupported {
   state: ChallengeFeedbackStatus.Unsupported;
-  http_status: HttpStatusCode;
+
   /**
    * Human-readable identifier of the unsupported method.
    */
@@ -57,7 +92,7 @@ export interface ChallengeFeedbackRateLimitExceeded {
  * Instructions for performing authentication via an
  * IBAN bank transfer.
  */
-export interface ChallengeFeedbackAuthIban {
+export interface ChallengeFeedbackBankTransferRequired {
   state: ChallengeFeedbackStatus.AuthIban;
 
   /**
@@ -68,12 +103,12 @@ export interface ChallengeFeedbackAuthIban {
   /**
    * Account that should be credited.
    */
-  credit_iban: string;
+  target_iban: string;
 
   /**
    * Creditor name.
    */
-  business_name: string;
+  target_business_name: string;
 
   /**
    * Unstructured remittance information that should
@@ -81,41 +116,7 @@ export interface ChallengeFeedbackAuthIban {
    */
   wire_transfer_subject: string;
 
-  /**
-   * FIXME: This field is only present for compatibility with
-   * the C reducer test suite.
-   */
-  method: "iban";
-
   answer_code: number;
-
-  /**
-   * FIXME: This field is only present for compatibility with
-   * the C reducer test suite.
-   */
-  details: {
-    challenge_amount: AmountString;
-    credit_iban: string;
-    business_name: string;
-    wire_transfer_subject: string;
-  };
-}
-
-/**
- * Challenge still needs to be solved.
- */
-export interface ChallengeFeedbackPending {
-  state: ChallengeFeedbackStatus.Pending;
-}
-
-/**
- * Human-readable response from the provider
- * after the user failed to solve the challenge
- * correctly.
- */
-export interface ChallengeFeedbackMessage {
-  state: ChallengeFeedbackStatus.Message;
-  message: string;
 }
 
 /**
@@ -140,22 +141,12 @@ export interface ChallengeFeedbackTruthUnknown {
   state: ChallengeFeedbackStatus.TruthUnknown;
 }
 
-/**
- * The user should be asked to go to a URL
- * to complete the authentication there.
- */
-export interface ChallengeFeedbackRedirect {
-  state: ChallengeFeedbackStatus.Redirect;
-  http_status: number;
-  redirect_url: string;
-}
-
 /**
  * A payment is required before the user can
  * even attempt to solve the challenge.
  */
-export interface ChallengeFeedbackPayment {
-  state: ChallengeFeedbackStatus.Payment;
+export interface ChallengeFeedbackTalerPaymentRequired {
+  state: ChallengeFeedbackStatus.TalerPayment;
 
   taler_pay_uri: string;
 
diff --git a/packages/anastasis-core/src/index.ts 
b/packages/anastasis-core/src/index.ts
index 98aba2ce..055f3fb6 100644
--- a/packages/anastasis-core/src/index.ts
+++ b/packages/anastasis-core/src/index.ts
@@ -25,6 +25,7 @@ import {
 } from "@gnu-taler/taler-util";
 import { anastasisData } from "./anastasis-data.js";
 import {
+  codecForChallengeInstructionMessage,
   EscrowConfigurationResponse,
   RecoveryMetaResponse,
   TruthUploadRequest,
@@ -363,9 +364,10 @@ async function getTruthValue(
     case "email":
     case "totp":
     case "iban":
+    case "post":
       return authMethod.challenge;
     default:
-      throw Error("unknown auth type");
+      throw Error(`unknown auth type '${authMethod.type}'`);
   }
 }
 
@@ -947,17 +949,27 @@ async function requestTruth(
 
   const hresp = await getResponseHash(truth, solveRequest);
 
-  const resp = await fetch(url.href, {
-    method: "POST",
-    headers: {
-      Accept: "application/json",
-      "Content-Type": "application/json",
-    },
-    body: JSON.stringify({
-      truth_decryption_key: truth.truth_key,
-      h_response: hresp,
-    }),
-  });
+  let resp: Response;
+
+  try {
+    resp = await fetch(url.href, {
+      method: "POST",
+      headers: {
+        Accept: "application/json",
+        "Content-Type": "application/json",
+      },
+      body: JSON.stringify({
+        truth_decryption_key: truth.truth_key,
+        h_response: hresp,
+      }),
+    });
+  } catch (e) {
+    return {
+      reducer_type: "error",
+      code: TalerErrorCode.ANASTASIS_TRUTH_CHALLENGE_FAILED,
+      hint: "network error",
+    } as ReducerStateError;
+  }
 
   logger.info(
     `got POST /truth/.../solve response from ${truth.url}, http status 
${resp.status}`,
@@ -1007,6 +1019,19 @@ async function requestTruth(
     return tryRecoverSecret(newState);
   }
 
+  if (resp.status === HttpStatusCode.Forbidden) {
+    const challengeFeedback: { [x: string]: ChallengeFeedback } = {
+      ...state.challenge_feedback,
+      [truth.uuid]: {
+        state: ChallengeFeedbackStatus.IncorrectAnswer,
+      },
+    };
+    return {
+      ...state,
+      challenge_feedback: challengeFeedback,
+    };
+  }
+
   return {
     reducer_type: "error",
     code: TalerErrorCode.ANASTASIS_TRUTH_CHALLENGE_FAILED,
@@ -1072,6 +1097,9 @@ async function selectChallenge(
 
   const url = new URL(`/truth/${truth.uuid}/challenge`, truth.url);
 
+  const newFeedback = { ...state.challenge_feedback };
+  delete newFeedback[truth.uuid];
+
   switch (truth.escrow_type) {
     case ChallengeType.Question:
     case ChallengeType.Totp: {
@@ -1079,51 +1107,93 @@ async function selectChallenge(
         ...state,
         recovery_state: RecoveryStates.ChallengeSolving,
         selected_challenge_uuid: truth.uuid,
-        challenge_feedback: {
-          ...state.challenge_feedback,
-          [truth.uuid]: {
-            state: ChallengeFeedbackStatus.Pending,
-          },
-        },
+        challenge_feedback: newFeedback,
       };
     }
   }
 
-  const resp = await fetch(url.href, {
-    method: "POST",
-    headers: {
-      Accept: "application/json",
-      "Content-Type": "application/json",
-    },
-    body: JSON.stringify({
-      truth_decryption_key: truth.truth_key,
-    }),
-  });
+  let resp: Response;
+
+  try {
+    resp = await fetch(url.href, {
+      method: "POST",
+      headers: {
+        Accept: "application/json",
+        "Content-Type": "application/json",
+      },
+      body: JSON.stringify({
+        truth_decryption_key: truth.truth_key,
+      }),
+    });
+  } catch (e) {
+    const feedback: ChallengeFeedback = {
+      state: ChallengeFeedbackStatus.ServerFailure,
+      http_status: 0,
+    };
+    return {
+      ...state,
+      recovery_state: RecoveryStates.ChallengeSelecting,
+      selected_challenge_uuid: truth.uuid,
+      challenge_feedback: {
+        ...state.challenge_feedback,
+        [truth.uuid]: feedback,
+      },
+    };
+  }
 
   logger.info(
     `got GET /truth/.../challenge response from ${truth.url}, http status 
${resp.status}`,
   );
 
   if (resp.status === HttpStatusCode.Ok) {
+    const respBodyJson = await resp.json();
+    const instr = codecForChallengeInstructionMessage().decode(respBodyJson);
+    let feedback: ChallengeFeedback;
+    switch (instr.method) {
+      case "FILE_WRITTEN": {
+        feedback = {
+          state: ChallengeFeedbackStatus.CodeInFile,
+          display_hint: "TAN code is in file (for debugging)",
+          filename: instr.filename,
+        };
+        break;
+      }
+      case "IBAN_WIRE": {
+        feedback = {
+          state: ChallengeFeedbackStatus.AuthIban,
+          answer_code: instr.answer_code,
+          target_business_name: instr.business_name,
+          challenge_amount: instr.amount,
+          target_iban: instr.credit_iban,
+          wire_transfer_subject: instr.wire_transfer_subject,
+        };
+        break;
+      }
+      case "TAN_SENT": {
+        feedback = {
+          state: ChallengeFeedbackStatus.CodeSent,
+          address_hint: instr.tan_address_hint,
+          display_hint: "Code sent to address",
+        };
+      }
+    }
     return {
       ...state,
       recovery_state: RecoveryStates.ChallengeSolving,
       selected_challenge_uuid: truth.uuid,
       challenge_feedback: {
         ...state.challenge_feedback,
-        [truth.uuid]: {
-          state: ChallengeFeedbackStatus.Pending,
-        },
+        [truth.uuid]: feedback,
       },
     };
   }
 
-  // FIXME: look at response, include in challenge_feedback!
+  // FIXME: look at more error codes in response
 
   return {
     reducer_type: "error",
     code: TalerErrorCode.ANASTASIS_TRUTH_CHALLENGE_FAILED,
-    hint: "got unexpected /truth/.../challenge response status",
+    hint: `got unexpected /truth/.../challenge response status 
(${resp.status})`,
     http_status: resp.status,
   } as ReducerStateError;
 }
@@ -1727,8 +1797,9 @@ export async function reduceAction(
   }
   try {
     return await h.handler(state, parsedArgs);
-  } catch (e) {
+  } catch (e: any) {
     logger.error("action handler failed");
+    logger.error(`${e?.stack ?? e}`);
     if (e instanceof ReducerError) {
       return {
         reducer_type: "error",
diff --git a/packages/anastasis-core/src/provider-types.ts 
b/packages/anastasis-core/src/provider-types.ts
index 72f2dc6e..4da62fc0 100644
--- a/packages/anastasis-core/src/provider-types.ts
+++ b/packages/anastasis-core/src/provider-types.ts
@@ -16,6 +16,13 @@
 
 import {
   AmountString,
+  buildCodecForObject,
+  buildCodecForUnion,
+  Codec,
+  codecForAmountString,
+  codecForConstString,
+  codecForNumber,
+  codecForString,
   TalerProtocolTimestamp,
 } from "@gnu-taler/taler-util";
 
@@ -122,3 +129,86 @@ export interface RecoveryMetaDataItem {
   // document was uploaded.
   upload_time: TalerProtocolTimestamp;
 }
+
+export type ChallengeInstructionMessage =
+  | FileChallengeInstructionMessage
+  | IbanChallengeInstructionMessage
+  | PinChallengeInstructionMessage;
+
+export interface IbanChallengeInstructionMessage {
+  // What kind of challenge is this?
+  method: "IBAN_WIRE";
+
+  // How much should be wired?
+  amount: AmountString;
+
+  // What is the target IBAN?
+  credit_iban: string;
+
+  // What is the receiver name?
+  business_name: string;
+
+  // What is the expected wire transfer subject?
+  wire_transfer_subject: string;
+
+  // What is the numeric code (also part of the
+  // wire transfer subject) to be hashed when
+  // solving the challenge?
+  answer_code: number;
+
+  // Hint about the origin account that must be used.
+  debit_account_hint: string;
+}
+
+export interface PinChallengeInstructionMessage {
+  // What kind of challenge is this?
+  method: "TAN_SENT";
+
+  // Where was the PIN code sent? Note that this
+  // address will most likely have been obscured
+  // to improve privacy.
+  tan_address_hint: string;
+}
+
+export interface FileChallengeInstructionMessage {
+  // What kind of challenge is this?
+  method: "FILE_WRITTEN";
+
+  // Name of the file where the PIN code was written.
+  filename: string;
+}
+
+export const codecForFileChallengeInstructionMessage =
+  (): Codec<FileChallengeInstructionMessage> =>
+    buildCodecForObject<FileChallengeInstructionMessage>()
+      .property("method", codecForConstString("FILE_WRITTEN"))
+      .property("filename", codecForString())
+      .build("FileChallengeInstructionMessage");
+
+export const codecForPinChallengeInstructionMessage =
+  (): Codec<PinChallengeInstructionMessage> =>
+    buildCodecForObject<PinChallengeInstructionMessage>()
+      .property("method", codecForConstString("TAN_SENT"))
+      .property("tan_address_hint", codecForString())
+      .build("PinChallengeInstructionMessage");
+
+export const codecForIbanChallengeInstructionMessage =
+  (): Codec<IbanChallengeInstructionMessage> =>
+    buildCodecForObject<IbanChallengeInstructionMessage>()
+      .property("method", codecForConstString("IBAN_WIRE"))
+      .property("amount", codecForAmountString())
+      .property("business_name", codecForString())
+      .property("credit_iban", codecForString())
+      .property("wire_transfer_subject", codecForString())
+      .property("answer_code", codecForNumber())
+      .property("debit_account_hint", codecForString())
+      .build("IbanChallengeInstructionMessage");
+
+export const codecForChallengeInstructionMessage =
+  (): Codec<ChallengeInstructionMessage> =>
+    buildCodecForUnion<ChallengeInstructionMessage>()
+      .discriminateOn("method")
+      .alternative("FILE_WRITTEN", codecForFileChallengeInstructionMessage())
+      .alternative("IBAN_WIRE", codecForIbanChallengeInstructionMessage())
+      .alternative("TAN_SENT", codecForPinChallengeInstructionMessage())
+      .build("ChallengeInstructionMessage");
diff --git a/packages/anastasis-core/src/reducer-types.ts 
b/packages/anastasis-core/src/reducer-types.ts
index 5b5f4029..b7e3148c 100644
--- a/packages/anastasis-core/src/reducer-types.ts
+++ b/packages/anastasis-core/src/reducer-types.ts
@@ -220,8 +220,6 @@ export interface ReducerStateRecovery {
 
   /**
    * Explicitly selected version by the user.
-   * FIXME: In the C reducer this is called "version".
-   * FIXME: rename to selected_secret / selected_policy?
    */
   selected_version?: AggregatedPolicyMetaInfo;
 
diff --git a/packages/anastasis-webui/package.json 
b/packages/anastasis-webui/package.json
index 2327b5e1..a855ffa9 100644
--- a/packages/anastasis-webui/package.json
+++ b/packages/anastasis-webui/package.json
@@ -15,7 +15,6 @@
     "pretty": "prettier --write src",
     "storybook": "start-storybook -p 6006"
   },
-  "type": "module",
   "eslintConfig": {
     "parser": "@typescript-eslint/parser",
     "extends": [
@@ -62,4 +61,4 @@
     "sirv-cli": "^1.0.14",
     "typescript": "^4.5.4"
   }
-}
\ No newline at end of file
+}
diff --git a/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts 
b/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts
index 7274c3d0..434e5fb0 100644
--- a/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts
+++ b/packages/anastasis-webui/src/hooks/use-anastasis-reducer.ts
@@ -1,3 +1,22 @@
+/*
+ This file is part of GNU Anastasis
+ (C) 2021-2022 Anastasis SARL
+
+ GNU Anastasis is free software; you can redistribute it and/or modify it 
under the
+ terms of the GNU Affero General Public License as published by the Free 
Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Anastasis 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 Affero General Public License for more 
details.
+
+ You should have received a copy of the GNU Affero General Public License 
along with
+ GNU Anastasis; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Imports.
+ */
 import { TalerErrorCode } from "@gnu-taler/taler-util";
 import {
   AggregatedPolicyMetaInfo,
@@ -7,7 +26,6 @@ import {
   getBackupStartState,
   getRecoveryStartState,
   mergeDiscoveryAggregate,
-  PolicyMetaInfo,
   RecoveryStates,
   reduceAction,
   ReducerState,
diff --git 
a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
index e26ba706..49cddc8b 100644
--- a/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
+++ b/packages/anastasis-webui/src/pages/home/AddingProviderScreen.stories.tsx
@@ -44,14 +44,6 @@ export const NewProviderWithoutProviderList = 
createExample(TestedComponent, {
   authentication_providers: {},
 } as ReducerState);
 
-export const NewVideoProvider = createExample(
-  TestedComponent,
-  {
-    ...reducerStatesExample.authEditing,
-  } as ReducerState,
-  { providerType: "video" },
-);
-
 export const NewSmsProvider = createExample(
   TestedComponent,
   {
diff --git 
a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx 
b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
index 3bd6a0c1..3d765aa8 100644
--- 
a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.stories.tsx
@@ -249,19 +249,15 @@ export const 
OnePolicyWithAllTheChallengesInDifferentState = createExample(
     },
     challenge_feedback: {
       "uuid-1": { state: ChallengeFeedbackStatus.Solved.toString() },
-      "uuid-2": {
-        state: ChallengeFeedbackStatus.Message.toString(),
-        message: "Challenge should be solved",
-      },
       "uuid-3": {
         state: ChallengeFeedbackStatus.AuthIban.toString(),
         challenge_amount: "EUR:1",
-        credit_iban: "DE12345789000",
-        business_name: "Data Loss Incorporated",
+        target_iban: "DE12345789000",
+        target_business_name: "Data Loss Incorporated",
         wire_transfer_subject: "Anastasis 987654321",
       },
       "uuid-4": {
-        state: ChallengeFeedbackStatus.Payment.toString(),
+        state: ChallengeFeedbackStatus.TalerPayment.toString(),
         taler_pay_uri: "taler://pay/...",
         provider: "https://localhost:8080/";,
         payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
@@ -270,11 +266,6 @@ export const OnePolicyWithAllTheChallengesInDifferentState 
= createExample(
         state: ChallengeFeedbackStatus.RateLimitExceeded.toString(),
         // "error_code": 8121
       },
-      "uuid-6": {
-        state: ChallengeFeedbackStatus.Redirect.toString(),
-        redirect_url: "https://videoconf.example.com/";,
-        http_status: 303,
-      },
       "uuid-7": {
         state: ChallengeFeedbackStatus.ServerFailure.toString(),
         http_status: 500,
diff --git 
a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx 
b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
index c4047f0b..6660e63d 100644
--- a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx
@@ -14,11 +14,8 @@ function OverviewFeedbackDisplay(props: { feedback?: 
ChallengeFeedback }) {
     return null;
   }
   switch (feedback.state) {
-    case ChallengeFeedbackStatus.Message:
-      return <div class="block has-text-danger">{feedback.message}</div>;
     case ChallengeFeedbackStatus.Solved:
       return <div />;
-    case ChallengeFeedbackStatus.Pending:
     case ChallengeFeedbackStatus.AuthIban:
       return null;
     case ChallengeFeedbackStatus.ServerFailure:
@@ -43,7 +40,6 @@ function OverviewFeedbackDisplay(props: { feedback?: 
ChallengeFeedback }) {
           provider for further information.
         </div>
       );
-    case ChallengeFeedbackStatus.Redirect:
     default:
       return <div />;
   }
@@ -178,7 +174,7 @@ export function ChallengeOverviewScreen(): VNode {
               case ChallengeFeedbackStatus.RateLimitExceeded:
                 return <div />;
               case ChallengeFeedbackStatus.AuthIban:
-              case ChallengeFeedbackStatus.Payment:
+              case ChallengeFeedbackStatus.TalerPayment:
                 return (
                   <div>
                     <AsyncButton
@@ -192,20 +188,6 @@ export function ChallengeOverviewScreen(): VNode {
                     </AsyncButton>
                   </div>
                 );
-              case ChallengeFeedbackStatus.Redirect:
-                return (
-                  <div>
-                    <AsyncButton
-                      class="button"
-                      disabled={
-                        atLeastThereIsOnePolicySolved && !policy.isPolicySolved
-                      }
-                      onClick={selectChallenge}
-                    >
-                      Go to {feedback.redirect_url}
-                    </AsyncButton>
-                  </div>
-                );
               case ChallengeFeedbackStatus.Solved:
                 return (
                   <div>
diff --git a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx 
b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
index 1070cf8a..3691d141 100644
--- a/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
+++ b/packages/anastasis-webui/src/pages/home/SolveScreen.tsx
@@ -16,19 +16,7 @@ export function SolveOverviewFeedbackDisplay(props: {
     return <div />;
   }
   switch (feedback.state) {
-    case ChallengeFeedbackStatus.Message:
-      return (
-        <Notifications
-          notifications={[
-            {
-              type: "INFO",
-              message: `Message from provider`,
-              description: feedback.message,
-            },
-          ]}
-        />
-      );
-    case ChallengeFeedbackStatus.Payment:
+    case ChallengeFeedbackStatus.TalerPayment:
       return (
         <Notifications
           notifications={[
@@ -51,7 +39,7 @@ export function SolveOverviewFeedbackDisplay(props: {
             {
               type: "INFO",
               message: `Message from provider`,
-              description: `Need to send a wire transfer to 
"${feedback.business_name}"`,
+              description: `Need to send a wire transfer to 
"${feedback.target_business_name}"`,
             },
           ]}
         />
@@ -80,22 +68,6 @@ export function SolveOverviewFeedbackDisplay(props: {
           ]}
         />
       );
-    case ChallengeFeedbackStatus.Redirect:
-      return (
-        <Notifications
-          notifications={[
-            {
-              type: "INFO",
-              message: `Message from provider`,
-              description: (
-                <span>
-                  Please visit this link: <a>{feedback.redirect_url}</a>
-                </span>
-              ),
-            },
-          ]}
-        />
-      );
     case ChallengeFeedbackStatus.Unsupported:
       return (
         <Notifications
@@ -121,6 +93,9 @@ export function SolveOverviewFeedbackDisplay(props: {
         />
       );
     default:
+      console.warn(
+        `unknown challenge feedback status ${JSON.stringify(feedback)}`,
+      );
       return <div />;
   }
 }
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx
index 1e7053df..d8211197 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.stories.tsx
@@ -80,7 +80,7 @@ export const PaymentFeedback = createExample(
     selected_challenge_uuid: "uuid-1",
     challenge_feedback: {
       "uuid-1": {
-        state: ChallengeFeedbackStatus.Payment,
+        state: ChallengeFeedbackStatus.TalerPayment,
         taler_pay_uri: "taler://pay/...",
         provider: "https://localhost:8080/";,
         payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx
index 4f7f2132..935b45a7 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodEmailSolve.tsx
@@ -9,6 +9,7 @@ import { TextInput } from 
"../../../components/fields/TextInput";
 import { useAnastasisContext } from "../../../context/anastasis";
 import { AnastasisClientFrame } from "../index";
 import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
+import { shouldHideConfirm } from "./helpers";
 import { AuthMethodSolveProps } from "./index";
 
 export function AuthMethodEmailSolve({ id }: AuthMethodSolveProps): VNode {
@@ -103,12 +104,6 @@ export function AuthMethodEmailSolve({ id }: 
AuthMethodSolveProps): VNode {
     reducer?.back();
   }
 
-  const shouldHideConfirm =
-    feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
-    feedback?.state === ChallengeFeedbackStatus.Redirect ||
-    feedback?.state === ChallengeFeedbackStatus.Unsupported ||
-    feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
-
   return (
     <AnastasisClientFrame hideNav title="Email challenge">
       <SolveOverviewFeedbackDisplay feedback={feedback} />
@@ -160,7 +155,7 @@ export function AuthMethodEmailSolve({ id }: 
AuthMethodSolveProps): VNode {
         <button class="button" onClick={onCancel}>
           Cancel
         </button>
-        {!shouldHideConfirm && (
+        {!shouldHideConfirm(feedback) && (
           <AsyncButton class="button is-info" onClick={onNext}>
             Confirm
           </AsyncButton>
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx
index b58952fe..39788b53 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodIbanSolve.tsx
@@ -5,10 +5,10 @@ import {
 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 { shouldHideConfirm } from "./helpers";
 import { AuthMethodSolveProps } from "./index";
 
 export function AuthMethodIbanSolve({ id }: AuthMethodSolveProps): VNode {
@@ -79,12 +79,6 @@ export function AuthMethodIbanSolve({ id }: 
AuthMethodSolveProps): VNode {
     reducer?.back();
   }
 
-  const shouldHideConfirm =
-    feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
-    feedback?.state === ChallengeFeedbackStatus.Redirect ||
-    feedback?.state === ChallengeFeedbackStatus.Unsupported ||
-    feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
-
   return (
     <AnastasisClientFrame hideNav title="IBAN Challenge">
       <SolveOverviewFeedbackDisplay feedback={feedback} />
@@ -101,7 +95,7 @@ export function AuthMethodIbanSolve({ id }: 
AuthMethodSolveProps): VNode {
         <button class="button" onClick={onCancel}>
           Cancel
         </button>
-        {!shouldHideConfirm && (
+        {!shouldHideConfirm(feedback) && (
           <AsyncButton class="button is-info" onClick={onNext}>
             Confirm
           </AsyncButton>
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx
index fcff0b49..382ffa00 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodPostSolve.tsx
@@ -9,6 +9,7 @@ import { TextInput } from 
"../../../components/fields/TextInput";
 import { useAnastasisContext } from "../../../context/anastasis";
 import { AnastasisClientFrame } from "../index";
 import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
+import { shouldHideConfirm } from "./helpers";
 import { AuthMethodSolveProps } from "./index";
 
 export function AuthMethodPostSolve({ id }: AuthMethodSolveProps): VNode {
@@ -102,12 +103,6 @@ export function AuthMethodPostSolve({ id }: 
AuthMethodSolveProps): VNode {
     reducer?.back();
   }
 
-  const shouldHideConfirm =
-    feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
-    feedback?.state === ChallengeFeedbackStatus.Redirect ||
-    feedback?.state === ChallengeFeedbackStatus.Unsupported ||
-    feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
-
   return (
     <AnastasisClientFrame hideNav title="Postal Challenge">
       <SolveOverviewFeedbackDisplay feedback={feedback} />
@@ -130,7 +125,7 @@ export function AuthMethodPostSolve({ id }: 
AuthMethodSolveProps): VNode {
         <button class="button" onClick={onCancel}>
           Cancel
         </button>
-        {!shouldHideConfirm && (
+        {!shouldHideConfirm(feedback) && (
           <AsyncButton class="button is-info" onClick={onNext}>
             Confirm
           </AsyncButton>
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
index c24ab050..51d0a999 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.stories.tsx
@@ -20,6 +20,7 @@
  */
 
 import {
+  ChallengeFeedbackBankTransferRequired,
   ChallengeFeedbackStatus,
   ReducerState,
 } from "@gnu-taler/anastasis-core";
@@ -62,28 +63,6 @@ export const WithoutFeedback = createExample(
   },
 );
 
-export const MessageFeedback = createExample(TestedComponent[type].solve, {
-  ...reducerStatesExample.challengeSolving,
-  recovery_information: {
-    challenges: [
-      {
-        cost: "USD:1",
-        instructions: "does P equals NP?",
-        type: "question",
-        uuid: "ASDASDSAD!1",
-      },
-    ],
-    policies: [],
-  },
-  selected_challenge_uuid: "ASDASDSAD!1",
-  challenge_feedback: {
-    "ASDASDSAD!1": {
-      state: ChallengeFeedbackStatus.Message,
-      message: "Challenge should be solved",
-    },
-  },
-} as ReducerState);
-
 export const ServerFailureFeedback = createExample(
   TestedComponent[type].solve,
   {
@@ -92,7 +71,7 @@ export const ServerFailureFeedback = createExample(
       challenges: [
         {
           cost: "USD:1",
-          instructions: "does P equals NP?",
+          instructions: "does P equal NP?",
           type: "question",
           uuid: "ASDASDSAD!1",
         },
@@ -110,29 +89,6 @@ export const ServerFailureFeedback = createExample(
   } as ReducerState,
 );
 
-export const RedirectFeedback = createExample(TestedComponent[type].solve, {
-  ...reducerStatesExample.challengeSolving,
-  recovery_information: {
-    challenges: [
-      {
-        cost: "USD:1",
-        instructions: "does P equals NP?",
-        type: "question",
-        uuid: "ASDASDSAD!1",
-      },
-    ],
-    policies: [],
-  },
-  selected_challenge_uuid: "ASDASDSAD!1",
-  challenge_feedback: {
-    "ASDASDSAD!1": {
-      state: ChallengeFeedbackStatus.Redirect,
-      http_status: 302,
-      redirect_url: "http://video.taler.net";,
-    },
-  },
-} as ReducerState);
-
 export const MessageRateLimitExceededFeedback = createExample(
   TestedComponent[type].solve,
   {
@@ -201,6 +157,15 @@ export const TruthUnknownFeedback = 
createExample(TestedComponent[type].solve, {
   },
 } as ReducerState);
 
+const ibanFeedback: ChallengeFeedbackBankTransferRequired = {
+  state: ChallengeFeedbackStatus.AuthIban,
+  challenge_amount: "EUR:1",
+  target_iban: "DE12345789000",
+  target_business_name: "Data Loss Incorporated",
+  wire_transfer_subject: "Anastasis 987654321",
+  answer_code: 987654321,
+};
+
 export const AuthIbanFeedback = createExample(TestedComponent[type].solve, {
   ...reducerStatesExample.challengeSolving,
   recovery_information: {
@@ -216,23 +181,7 @@ export const AuthIbanFeedback = 
createExample(TestedComponent[type].solve, {
   },
   selected_challenge_uuid: "ASDASDSAD!1",
   challenge_feedback: {
-    "ASDASDSAD!1": {
-      state: ChallengeFeedbackStatus.AuthIban,
-      challenge_amount: "EUR:1",
-      credit_iban: "DE12345789000",
-      business_name: "Data Loss Incorporated",
-      wire_transfer_subject: "Anastasis 987654321",
-      answer_code: 987654321,
-      // Fields that follow are only for compatibility with C reducer,
-      // will be removed eventually,
-      details: {
-        business_name: "foo",
-        challenge_amount: "foo",
-        credit_iban: "foo",
-        wire_transfer_subject: "foo",
-      },
-      method: "iban",
-    },
+    "ASDASDSAD!1": ibanFeedback,
   },
 } as ReducerState);
 
@@ -252,7 +201,7 @@ export const PaymentFeedback = 
createExample(TestedComponent[type].solve, {
   selected_challenge_uuid: "ASDASDSAD!1",
   challenge_feedback: {
     "ASDASDSAD!1": {
-      state: ChallengeFeedbackStatus.Payment,
+      state: ChallengeFeedbackStatus.TalerPayment,
       taler_pay_uri: "taler://pay/...",
       provider: "https://localhost:8080/";,
       payment_secret: "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG",
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx
index 058efe00..bc0b67dc 100644
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx
+++ 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodQuestionSolve.tsx
@@ -9,6 +9,7 @@ import { TextInput } from 
"../../../components/fields/TextInput";
 import { useAnastasisContext } from "../../../context/anastasis";
 import { AnastasisClientFrame } from "../index";
 import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
+import { shouldHideConfirm } from "./helpers";
 import { AuthMethodSolveProps } from "./index";
 
 export function AuthMethodQuestionSolve({ id }: AuthMethodSolveProps): VNode {
@@ -79,12 +80,6 @@ export function AuthMethodQuestionSolve({ id }: 
AuthMethodSolveProps): VNode {
     reducer?.back();
   }
 
-  const shouldHideConfirm =
-    feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
-    feedback?.state === ChallengeFeedbackStatus.Redirect ||
-    feedback?.state === ChallengeFeedbackStatus.Unsupported ||
-    feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
-
   return (
     <AnastasisClientFrame hideNav title="Question challenge">
       <SolveOverviewFeedbackDisplay feedback={feedback} />
@@ -110,7 +105,7 @@ export function AuthMethodQuestionSolve({ id }: 
AuthMethodSolveProps): VNode {
         <button class="button" onClick={onCancel}>
           Cancel
         </button>
-        {!shouldHideConfirm && (
+        {!shouldHideConfirm(feedback) && (
           <AsyncButton class="button is-info" onClick={onNext}>
             Confirm
           </AsyncButton>
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx
index 3b00f6f2..f3d304c7 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodSmsSolve.tsx
@@ -9,6 +9,7 @@ import { TextInput } from 
"../../../components/fields/TextInput";
 import { useAnastasisContext } from "../../../context/anastasis";
 import { AnastasisClientFrame } from "../index";
 import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
+import { shouldHideConfirm } from "./helpers";
 import { AuthMethodSolveProps } from "./index";
 
 export function AuthMethodSmsSolve({ id }: AuthMethodSolveProps): VNode {
@@ -103,12 +104,6 @@ export function AuthMethodSmsSolve({ id }: 
AuthMethodSolveProps): VNode {
     reducer?.back();
   }
 
-  const shouldHideConfirm =
-    feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
-    feedback?.state === ChallengeFeedbackStatus.Redirect ||
-    feedback?.state === ChallengeFeedbackStatus.Unsupported ||
-    feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
-
   return (
     <AnastasisClientFrame hideNav title="SMS Challenge">
       <SolveOverviewFeedbackDisplay feedback={feedback} />
@@ -160,7 +155,7 @@ export function AuthMethodSmsSolve({ id }: 
AuthMethodSolveProps): VNode {
         <button class="button" onClick={onCancel}>
           Cancel
         </button>
-        {!shouldHideConfirm && (
+        {!shouldHideConfirm(feedback) && (
           <AsyncButton class="button is-info" onClick={onNext}>
             Confirm
           </AsyncButton>
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx
index ee493744..6b98f8ec 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSolve.tsx
@@ -9,6 +9,7 @@ import { TextInput } from 
"../../../components/fields/TextInput";
 import { useAnastasisContext } from "../../../context/anastasis";
 import { AnastasisClientFrame } from "../index";
 import { SolveOverviewFeedbackDisplay } from "../SolveScreen";
+import { shouldHideConfirm } from "./helpers";
 import { AuthMethodSolveProps } from "./index";
 
 export function AuthMethodTotpSolve(props: AuthMethodSolveProps): VNode {
@@ -81,12 +82,6 @@ export function AuthMethodTotpSolve(props: 
AuthMethodSolveProps): VNode {
     reducer?.back();
   }
 
-  const shouldHideConfirm =
-    feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
-    feedback?.state === ChallengeFeedbackStatus.Redirect ||
-    feedback?.state === ChallengeFeedbackStatus.Unsupported ||
-    feedback?.state === ChallengeFeedbackStatus.TruthUnknown;
-
   return (
     <AnastasisClientFrame hideNav title="TOTP Challenge">
       <SolveOverviewFeedbackDisplay feedback={feedback} />
@@ -108,7 +103,7 @@ export function AuthMethodTotpSolve(props: 
AuthMethodSolveProps): VNode {
         <button class="button" onClick={onCancel}>
           Cancel
         </button>
-        {!shouldHideConfirm && (
+        {!shouldHideConfirm(feedback) && (
           <AsyncButton class="button is-info" onClick={onNext}>
             Confirm
           </AsyncButton>
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
deleted file mode 100644
index 4aad0a09..00000000
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.stories.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-/* eslint-disable @typescript-eslint/camelcase */
-/*
- This file is part of GNU Taler
- (C) 2021 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { createExample, reducerStatesExample } from "../../../utils";
-import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
-import logoImage from "../../../assets/logo.jpeg";
-
-export default {
-  title: "Pages/backup/AuthorizationMethod/AuthMethods/Video",
-  component: TestedComponent,
-  args: {
-    order: 5,
-  },
-  argTypes: {
-    onUpdate: { action: "onUpdate" },
-    onBack: { action: "onBack" },
-  },
-};
-
-const type: KnownAuthMethods = "video";
-
-export const Empty = createExample(
-  TestedComponent[type].setup,
-  reducerStatesExample.authEditing,
-  {
-    configured: [],
-  },
-);
-
-export const WithOneExample = createExample(
-  TestedComponent[type].setup,
-  reducerStatesExample.authEditing,
-  {
-    configured: [
-      {
-        challenge: "qwe",
-        type,
-        instructions: logoImage,
-        remove: () => null,
-      },
-    ],
-  },
-);
-
-export const WithMoreExamples = createExample(
-  TestedComponent[type].setup,
-  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/AuthMethodVideoSetup.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx
deleted file mode 100644
index 04a129c4..00000000
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSetup.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import { encodeCrock, stringToBytes } from "@gnu-taler/taler-util";
-import { h, VNode } from "preact";
-import { useState } from "preact/hooks";
-import { ImageInput } from "../../../components/fields/ImageInput";
-import { AuthMethodSetupProps } from "./index";
-import { AnastasisClientFrame } from "../index";
-
-export function AuthMethodVideoSetup({
-  cancel,
-  addAuthMethod,
-  configured,
-}: AuthMethodSetupProps): VNode {
-  const [image, setImage] = useState("");
-  const addVideoAuth = (): void => {
-    addAuthMethod({
-      authentication_method: {
-        type: "video",
-        instructions: "Join a video call",
-        challenge: encodeCrock(stringToBytes(image)),
-      },
-    });
-  };
-  function goNextIfNoErrors(): void {
-    addVideoAuth();
-  }
-  return (
-    <AnastasisClientFrame hideNav title="Add video authentication">
-      <p>
-        For video identification, you need to provide a passport-style
-        photograph. When recovering your secret, you will be asked to join a
-        video call. During that call, a human will use the photograph to verify
-        your identity.
-      </p>
-      <div style={{ textAlign: "center" }}>
-        <ImageInput
-          label="Choose photograph"
-          grabFocus
-          onConfirm={goNextIfNoErrors}
-          bind={[image, setImage]}
-        />
-      </div>
-      {configured.length > 0 && (
-        <section class="section">
-          <div class="block">Your photographs:</div>
-          <div class="block">
-            {configured.map((c, i) => {
-              return (
-                <div
-                  key={i}
-                  class="box"
-                  style={{ display: "flex", justifyContent: "space-between" }}
-                >
-                  <img
-                    style={{
-                      marginTop: "auto",
-                      marginBottom: "auto",
-                      width: 100,
-                      height: 100,
-                      border: "solid 1px black",
-                    }}
-                    src={c.instructions}
-                  />
-                  <div style={{ marginTop: "auto", marginBottom: "auto" }}>
-                    <button class="button is-danger" onClick={c.remove}>
-                      Delete
-                    </button>
-                  </div>
-                </div>
-              );
-            })}
-          </div>
-        </section>
-      )}
-      <div>
-        <div
-          style={{
-            marginTop: "2em",
-            display: "flex",
-            justifyContent: "space-between",
-          }}
-        >
-          <button class="button" onClick={cancel}>
-            Cancel
-          </button>
-          <button class="button is-info" onClick={addVideoAuth}>
-            Add
-          </button>
-        </div>
-      </div>
-    </AnastasisClientFrame>
-  );
-}
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
deleted file mode 100644
index 0e454dd7..00000000
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.stories.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- 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 "@gnu-taler/anastasis-core";
-import { createExample, reducerStatesExample } from "../../../utils";
-import { authMethods as TestedComponent, KnownAuthMethods } from "./index";
-
-export default {
-  title: "Pages/recovery/SolveChallenge/AuthMethods/video",
-  component: TestedComponent,
-  args: {
-    order: 5,
-  },
-  argTypes: {
-    onUpdate: { action: "onUpdate" },
-    onBack: { action: "onBack" },
-  },
-};
-
-const type: KnownAuthMethods = "video";
-
-export const WithoutFeedback = createExample(
-  TestedComponent[type].solve,
-  {
-    ...reducerStatesExample.challengeSolving,
-    recovery_information: {
-      challenges: [
-        {
-          cost: "USD:1",
-          instructions: "does P equals NP?",
-          type: "question",
-          uuid: "uuid-1",
-        },
-      ],
-      policies: [],
-    },
-    selected_challenge_uuid: "uuid-1",
-  } as ReducerState,
-  {
-    id: "uuid-1",
-  },
-);
diff --git 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx
deleted file mode 100644
index e0ebdce7..00000000
--- 
a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodVideoSolve.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import {
-  ChallengeFeedbackStatus,
-  ChallengeInfo,
-} from "@gnu-taler/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_type !== "recovery"
-  ) {
-    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/helpers.ts 
b/packages/anastasis-webui/src/pages/home/authMethod/helpers.ts
new file mode 100644
index 00000000..2f5e3773
--- /dev/null
+++ b/packages/anastasis-webui/src/pages/home/authMethod/helpers.ts
@@ -0,0 +1,12 @@
+import {
+  ChallengeFeedback,
+  ChallengeFeedbackStatus,
+} from "@gnu-taler/anastasis-core";
+
+export function shouldHideConfirm(feedback: ChallengeFeedback): boolean {
+  return (
+    feedback?.state === ChallengeFeedbackStatus.RateLimitExceeded ||
+    feedback?.state === ChallengeFeedbackStatus.Unsupported ||
+    feedback?.state === ChallengeFeedbackStatus.TruthUnknown
+  );
+}
diff --git a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx 
b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
index 64cf07cd..a1ab9cd2 100644
--- a/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
+++ b/packages/anastasis-webui/src/pages/home/authMethod/index.tsx
@@ -3,22 +3,18 @@ import { h, VNode } from "preact";
 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 { AuthMethodPostSetup as PostalSetup } from "./AuthMethodPostSetup";
 import { AuthMethodPostSolve as PostalSolve } from "./AuthMethodPostSolve";
+import { AuthMethodQuestionSetup as QuestionSetup } from 
"./AuthMethodQuestionSetup";
 import { AuthMethodQuestionSolve as QuestionSolve } from 
"./AuthMethodQuestionSolve";
+import { AuthMethodSmsSetup as SmsSetup } from "./AuthMethodSmsSetup";
 import { AuthMethodSmsSolve as SmsSolve } from "./AuthMethodSmsSolve";
+import { AuthMethodTotpSetup as TotpSetup } from "./AuthMethodTotpSetup";
 import { AuthMethodTotpSolve as TotpSolve } from "./AuthMethodTotpSolve";
-import { AuthMethodVideoSolve as VideoSolve } from "./AuthMethodVideoSolve";
 
 export type AuthMethodWithRemove = AuthMethod & { remove: () => void };
 
@@ -40,14 +36,12 @@ interface AuthMethodConfiguration {
   solve: (props: AuthMethodSolveProps) => VNode;
   skip?: boolean;
 }
-// export type KnownAuthMethods = "sms" | "email" | "post" | "question" | 
"video" | "totp" | "iban";
 
 const ALL_METHODS = [
   "sms",
   "email",
   "post",
   "question",
-  "video",
   "totp",
   "iban",
 ] as const;
@@ -97,11 +91,4 @@ export const authMethods: KnowMethodConfig = {
     setup: TotpSetup,
     solve: TotpSolve,
   },
-  video: {
-    icon: <img src={videoIcon} />,
-    label: "Video",
-    setup: VideoSetup,
-    solve: VideoSolve,
-    skip: true,
-  },
 };
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
index c9889160..09d6856c 100644
--- a/packages/taler-util/src/payto.ts
+++ b/packages/taler-util/src/payto.ts
@@ -14,10 +14,14 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { generateFakeSegwitAddress } from "./index.js";
+import { generateFakeSegwitAddress } from "./bitcoin.js";
 import { URLSearchParams } from "./url.js";
 
-export type PaytoUri = PaytoUriUnknown | PaytoUriIBAN | PaytoUriTalerBank | 
PaytoUriBitcoin;
+export type PaytoUri =
+  | PaytoUriUnknown
+  | PaytoUriIBAN
+  | PaytoUriTalerBank
+  | PaytoUriBitcoin;
 
 interface PaytoUriGeneric {
   targetType: string;
@@ -31,38 +35,41 @@ interface PaytoUriUnknown extends PaytoUriGeneric {
 
 interface PaytoUriIBAN extends PaytoUriGeneric {
   isKnown: true;
-  targetType: 'iban',
+  targetType: "iban";
   iban: string;
 }
 
 interface PaytoUriTalerBank extends PaytoUriGeneric {
   isKnown: true;
-  targetType: 'x-taler-bank',
+  targetType: "x-taler-bank";
   host: string;
   account: string;
 }
 
 interface PaytoUriBitcoin extends PaytoUriGeneric {
   isKnown: true;
-  targetType: 'bitcoin',
-  generateSegwitAddress: (r: string) => { addr1: string, addr2: string };
-  addr1?: string, addr2?: string,
+  targetType: "bitcoin";
+  generateSegwitAddress: (r: string) => { addr1: string; addr2: string };
+  addr1?: string;
+  addr2?: string;
 }
 
 const paytoPfx = "payto://";
 
-
-
 function buildSegwitGenerator(result: PaytoUriBitcoin, targetPath: string) {
   //generate segwit address just once, save addr in payto object
   //and use it as cache
-  return function generateSegwitAddress(reserve: string): { addr1: string, 
addr2: string } {
-    if (result.addr1 && result.addr2) return { addr1: result.addr1, addr2: 
result.addr2 };
-    const { addr1, addr2 } = generateFakeSegwitAddress(reserve, targetPath)
-    result.addr1 = addr1
-    result.addr2 = addr2
-    return { addr1, addr2 }
-  }
+  return function generateSegwitAddress(reserve: string): {
+    addr1: string;
+    addr2: string;
+  } {
+    if (result.addr1 && result.addr2)
+      return { addr1: result.addr1, addr2: result.addr2 };
+    const { addr1, addr2 } = generateFakeSegwitAddress(reserve, targetPath);
+    result.addr1 = addr1;
+    result.addr2 = addr2;
+    return { addr1, addr2 };
+  };
 }
 /**
  * Add query parameters to a payto URI
@@ -81,27 +88,27 @@ export function addPaytoQueryParams(
 
 /**
  * Serialize a PaytoURI into a valid payto:// string
- * 
- * @param p 
- * @returns 
+ *
+ * @param p
+ * @returns
  */
 export function stringifyPaytoUri(p: PaytoUri): string {
-  const url = `${paytoPfx}${p.targetType}//${p.targetPath}`
+  const url = `${paytoPfx}${p.targetType}//${p.targetPath}`;
   if (p.params) {
     const search = Object.entries(p.params)
       .map(([key, value]) => `${key}=${value}`)
       .join("&");
-    return `${url}?${search}`
+    return `${url}?${search}`;
   }
-  return url
+  return url;
 }
 
 /**
  * Parse a valid payto:// uri into a PaytoUri object
  * RFC 8905
- * 
- * @param s 
- * @returns 
+ *
+ * @param s
+ * @returns
  */
 export function parsePaytoUri(s: string): PaytoUri | undefined {
   if (!s.startsWith(paytoPfx)) {
@@ -127,47 +134,44 @@ export function parsePaytoUri(s: string): PaytoUri | 
undefined {
     params[v] = k;
   });
 
-  if (targetType === 'x-taler-bank') {
-    const parts = targetPath.split('/')
-    const host = parts[0]
-    const account = parts[1]
+  if (targetType === "x-taler-bank") {
+    const parts = targetPath.split("/");
+    const host = parts[0];
+    const account = parts[1];
     return {
       targetPath,
       targetType,
       params,
       isKnown: true,
-      host, account,
+      host,
+      account,
     };
-
   }
-  if (targetType === 'iban') {
+  if (targetType === "iban") {
     return {
       isKnown: true,
       targetPath,
       targetType,
       params,
-      iban: targetPath
+      iban: targetPath,
     };
-
   }
-  if (targetType === 'bitcoin') {
-
+  if (targetType === "bitcoin") {
     const result: PaytoUriBitcoin = {
       isKnown: true,
       targetPath,
       targetType,
       params,
-      generateSegwitAddress: (): any => null
-    }
+      generateSegwitAddress: (): any => null,
+    };
 
-    result.generateSegwitAddress = buildSegwitGenerator(result, targetPath)
+    result.generateSegwitAddress = buildSegwitGenerator(result, targetPath);
     return result;
-
   }
   return {
     targetPath,
     targetType,
     params,
-    isKnown: false
+    isKnown: false,
   };
 }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 89a87ff0..1066300e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7401,6 +7401,7 @@ packages:
 
   /bindings/1.5.0:
     resolution: {integrity: 
sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
+    requiresBuild: true
     dependencies:
       file-uri-to-path: 1.0.0
     dev: true
@@ -10555,6 +10556,7 @@ packages:
 
   /file-uri-to-path/1.0.0:
     resolution: {integrity: 
sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
+    requiresBuild: true
     dev: true
     optional: true
 
@@ -13462,6 +13464,7 @@ packages:
 
   /nan/2.15.0:
     resolution: {integrity: 
sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==}
+    requiresBuild: true
     dev: true
     optional: true
 

-- 
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]