/* 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 */ import { HttpStatusCode } from "@gnu-taler/taler-util"; import { Attention, Button, LocalNotificationBanner, RouteDefinition, ShowInputErrorLabel, useChallengerApiContext, useLocalNotificationHandler, useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { useSessionState } from "../hooks/session.js"; import { doAutoFocus } from "./AnswerChallenge.js"; type Form = { email: string; }; export const EMAIL_REGEX = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/; type Props = { nonce: string; onSendSuccesful: () => void; routeSolveChallenge: RouteDefinition<{ nonce: string }>; focus?: boolean; }; export function AskChallenge({ nonce, onSendSuccesful, routeSolveChallenge, focus, }: Props): VNode { const { state, accepted, completed } = useSessionState(); const status = state?.lastStatus; const prevEmail = !status || !status.last_address ? undefined : status.last_address["email"]; const regexEmail = !status || !status.restrictions ? undefined : status.restrictions["email"]; const { lib } = useChallengerApiContext(); const { i18n } = useTranslationContext(); const [notification, withErrorHandler] = useLocalNotificationHandler(); const [email, setEmail] = useState(); const [repeat, setRepeat] = useState(); const regexTest = regexEmail && regexEmail.regex ? new RegExp(regexEmail.regex) : EMAIL_REGEX; const regexHint = regexEmail && regexEmail.hint ? regexEmail.hint : i18n.str`invalid email`; const errors = undefinedIfEmpty({ email: !email ? i18n.str`required` : !regexTest.test(email) ? regexHint : prevEmail !== undefined && email === prevEmail ? i18n.str`email should be different` : undefined, repeat: !repeat ? i18n.str`required` : email !== repeat ? i18n.str`emails doesn't match` : undefined, }); const onSend = errors ? undefined : withErrorHandler( async () => { return lib.challenger.challenge(nonce, { email: email! }); }, (ok) => { if ("redirectURL" in ok.body) { completed(ok.body.redirectURL); } else { accepted({ attemptsLeft: ok.body.attempts_left, nextSend: ok.body.next_tx_time, transmitted: ok.body.transmitted, }); } onSendSuccesful(); }, (fail) => { switch (fail.case) { case HttpStatusCode.BadRequest: return i18n.str``; case HttpStatusCode.NotFound: return i18n.str``; case HttpStatusCode.NotAcceptable: return i18n.str``; case HttpStatusCode.TooManyRequests: return i18n.str``; case HttpStatusCode.InternalServerError: return i18n.str``; } }, ); if (!status) { return
no status loaded
; } return (

Enter contact details

You will receive an email with a TAN code that must be provided on the next page.

{state.lastTry && ( Complete the challenge here. )}
{ e.preventDefault(); }} >
{ setEmail(e.currentTarget.value); }} placeholder={prevEmail} readOnly={status.fix_address} class="block w-full read-only:bg-slate-200 rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" />
{status.fix_address ? undefined : (
{ setRepeat(e.currentTarget.value); }} autocomplete="email" class="block w-full rounded-md border-0 px-3.5 py-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" />
)} {!status.changes_left ? (

No more changes left

) : (

You can change your email address another{" "} {status.changes_left} times.

)}
{!prevEmail ? (
) : (
)}
); } export function undefinedIfEmpty(obj: T): T | undefined { return Object.keys(obj).some( (k) => (obj as Record)[k] !== undefined, ) ? obj : undefined; }