diff options
Diffstat (limited to 'packages/challenger-ui/src/pages/StartChallenge.tsx')
-rw-r--r-- | packages/challenger-ui/src/pages/StartChallenge.tsx | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/packages/challenger-ui/src/pages/StartChallenge.tsx b/packages/challenger-ui/src/pages/StartChallenge.tsx new file mode 100644 index 000000000..6cf982a3d --- /dev/null +++ b/packages/challenger-ui/src/pages/StartChallenge.tsx @@ -0,0 +1,138 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 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/> + */ +import { + Attention, + Button, + Loading, + LocalNotificationBanner, + ShowInputErrorLabel, + useChallengerApiContext, + useLocalNotificationHandler, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; +import { useEffect, useState } from "preact/hooks"; +import { useChallengeSession } from "../hooks/challenge.js"; +import { + ChallengerApi, + HttpStatusCode, + TalerError, + assertUnreachable, +} from "@gnu-taler/taler-util"; +import { useSessionState } from "../hooks/session.js"; + +type Form = { + email: string; +}; +export const EMAIL_REGEX = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/; + +type Props = { + nonce: string; + clientId: string; + redirectURL: URL; + state: string; + onSendSuccesful: () => void; +}; + + +export function StartChallenge({ + nonce, + clientId, + redirectURL, + state, + onSendSuccesful, +}: Props): VNode { + const { i18n } = useTranslationContext(); + const { start } = useSessionState(); + + const result = useChallengeSession(nonce, { + clientId, + redirectURL: redirectURL.href, + state, + }); + + const session = + result && !(result instanceof TalerError) && result.type === "ok" + ? result.body + : undefined; + + useEffect(() => { + if (session) { + start({ + clientId, + redirectURL: redirectURL.href, + state, + }); + onSendSuccesful(); + } + }, [session]); + + if (!result) { + return <Loading />; + } + if (result instanceof TalerError) { + return <div />; + } + + if (result.type === "fail") { + switch (result.case) { + case HttpStatusCode.BadRequest: { + return ( + <Attention type="danger" title={i18n.str`Bad request`}> + <i18n.Translate> + Could not start the challenge, check configuration. + </i18n.Translate> + </Attention> + ); + } + case HttpStatusCode.NotFound: { + return ( + <Attention type="danger" title={i18n.str`Not found`}> + <i18n.Translate>Nonce not found</i18n.Translate> + </Attention> + ); + } + case HttpStatusCode.NotAcceptable: { + return ( + <Attention type="danger" title={i18n.str`Not acceptable`}> + <i18n.Translate> + Server has wrong template configuration + </i18n.Translate> + </Attention> + ); + } + case HttpStatusCode.InternalServerError: { + return ( + <Attention type="danger" title={i18n.str`Internal error`}> + <i18n.Translate>Check logs</i18n.Translate> + </Attention> + ); + } + default: + assertUnreachable(result); + } + } + + return <Loading />; +} + +export function undefinedIfEmpty<T extends object>(obj: T): T | undefined { + return Object.keys(obj).some( + (k) => (obj as Record<string, T>)[k] !== undefined, + ) + ? obj + : undefined; +} |