diff options
Diffstat (limited to 'packages/anastasis-webui')
20 files changed, 71 insertions, 549 deletions
diff --git a/packages/anastasis-webui/package.json b/packages/anastasis-webui/package.json index 2327b5e12..a855ffa94 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 7274c3d03..434e5fb09 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 e26ba706f..49cddc8b7 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 3bd6a0c17..3d765aa86 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 c4047f0b3..6660e63de 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 1070cf8a9..3691d1416 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 1e7053df5..d82111979 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 4f7f21324..935b45a77 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 b58952feb..39788b538 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 fcff0b498..382ffa00a 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 c24ab0503..51d0a9993 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 058efe009..bc0b67dcb 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 3b00f6f2a..f3d304c74 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 ee4937441..6b98f8ece 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 4aad0a097..000000000 --- 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 04a129c4a..000000000 --- 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 0e454dd73..000000000 --- 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 e0ebdce76..000000000 --- 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 000000000..2f5e3773e --- /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 64cf07cd6..a1ab9cd28 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, - }, }; |