gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 01/03: refactor to keep the challenge status up to d


From: gnunet
Subject: [taler-wallet-core] 01/03: refactor to keep the challenge status up to date
Date: Mon, 22 Apr 2024 17:18:47 +0200

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

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

commit 82ec30e81e4352146de6e3de668465100ef4274d
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Apr 22 11:38:28 2024 -0300

    refactor to keep the challenge status up to date
---
 packages/challenger-ui/src/Routing.tsx             |  90 +++++++++++---
 .../CheckChallengeIsUpToDate.tsx}                  | 109 +++++++---------
 packages/challenger-ui/src/hooks/session.ts        |  30 ++++-
 .../challenger-ui/src/pages/AnswerChallenge.tsx    |  87 +++----------
 packages/challenger-ui/src/pages/AskChallenge.tsx  | 138 +++++++--------------
 packages/web-util/src/utils/http-impl.sw.ts        |   2 +
 6 files changed, 209 insertions(+), 247 deletions(-)

diff --git a/packages/challenger-ui/src/Routing.tsx 
b/packages/challenger-ui/src/Routing.tsx
index e1e9434e5..eae182be5 100644
--- a/packages/challenger-ui/src/Routing.tsx
+++ b/packages/challenger-ui/src/Routing.tsx
@@ -15,6 +15,7 @@
  */
 
 import {
+  Loading,
   urlPattern,
   useCurrentLocation,
   useNavigationContext,
@@ -22,14 +23,15 @@ import {
 import { Fragment, VNode, h } from "preact";
 
 import { assertUnreachable } from "@gnu-taler/taler-util";
+import { CheckChallengeIsUpToDate } from 
"./components/CheckChallengeIsUpToDate.js";
+import { SessionId, useSessionState } from "./hooks/session.js";
 import { AnswerChallenge } from "./pages/AnswerChallenge.js";
 import { AskChallenge } from "./pages/AskChallenge.js";
+import { CallengeCompleted } from "./pages/CallengeCompleted.js";
 import { Frame } from "./pages/Frame.js";
 import { MissingParams } from "./pages/MissingParams.js";
 import { NonceNotFound } from "./pages/NonceNotFound.js";
-import { StartChallenge } from "./pages/StartChallenge.js";
 import { Setup } from "./pages/Setup.js";
-import { CallengeCompleted } from "./pages/CallengeCompleted.js";
 
 export function Routing(): VNode {
   // check session and defined if this is
@@ -84,6 +86,7 @@ function safeToURL(s: string | undefined): URL | undefined {
 function PublicRounting(): VNode {
   const location = useCurrentLocation(publicPages);
   const { navigateTo } = useNavigationContext();
+  const { start } = useSessionState();
 
   if (location === undefined) {
     return <NonceNotFound />;
@@ -95,7 +98,7 @@ function PublicRounting(): VNode {
         <Setup
           clientId={location.values.client}
           onCreated={(nonce) => {
-            navigateTo(publicPages.ask.url({ nonce }))
+            navigateTo(publicPages.ask.url({ nonce }));
             //response_type=code
             //client_id=1
             
//redirect_uri=http://exchange.taler.test:1180/kyc-proof/kyc-provider-wallet
@@ -107,7 +110,7 @@ function PublicRounting(): VNode {
     case "authorize": {
       const responseType = safeGetParam(location.params, "response_type");
       const clientId = safeGetParam(location.params, "client_id");
-      const redirectURI = safeToURL(
+      const redirectURL = safeToURL(
         safeGetParam(location.params, "redirect_uri"),
       );
       const state = safeGetParam(location.params, "state");
@@ -119,58 +122,107 @@ function PublicRounting(): VNode {
       if (
         !responseType ||
         !clientId ||
-        !redirectURI ||
+        !redirectURL ||
         !state ||
         responseType !== "code"
       ) {
         return <MissingParams />;
       }
+      const sessionId: SessionId = {
+        clientId,
+        redirectURL: redirectURL.href,
+        state,
+      };
       return (
-        <StartChallenge
+        <CheckChallengeIsUpToDate
+          sessionId={sessionId}
           nonce={location.values.nonce}
-          clientId={clientId}
-          redirectURL={redirectURI}
-          state={state}
-          onSendSuccesful={() => {
+          onCompleted={() => {
+            start(sessionId);
+            navigateTo(
+              publicPages.completed.url({
+                nonce: location.values.nonce,
+              }),
+            );
+          }}
+          onChangeLeft={() => {
+            start(sessionId);
             navigateTo(
               publicPages.ask.url({
                 nonce: location.values.nonce,
               }),
             );
           }}
-        />
+          onNoMoreChanges={() => {
+            start(sessionId);
+            navigateTo(
+              publicPages.ask.url({
+                nonce: location.values.nonce,
+              }),
+            );
+          }}
+        >
+          <Loading />
+        </CheckChallengeIsUpToDate>
       );
     }
     case "ask": {
       return (
-        <AskChallenge
+        <CheckChallengeIsUpToDate
           nonce={location.values.nonce}
-          onSendSuccesful={() => {
+          onCompleted={() => {
             navigateTo(
-              publicPages.answer.url({
+              publicPages.completed.url({
                 nonce: location.values.nonce,
               }),
             );
           }}
-        />
+        >
+          <AskChallenge
+            nonce={location.values.nonce}
+            routeSolveChallenge={publicPages.answer}
+            onSendSuccesful={() => {
+              navigateTo(
+                publicPages.answer.url({
+                  nonce: location.values.nonce,
+                }),
+              );
+            }}
+          />
+        </CheckChallengeIsUpToDate>
       );
     }
     case "answer": {
       return (
-        <AnswerChallenge
+        <CheckChallengeIsUpToDate
           nonce={location.values.nonce}
-          onComplete={() => {
+          onCompleted={() => {
             navigateTo(
               publicPages.completed.url({
                 nonce: location.values.nonce,
               }),
             );
           }}
-        />
+        >
+          <AnswerChallenge
+            nonce={location.values.nonce}
+            onComplete={() => {
+              navigateTo(
+                publicPages.completed.url({
+                  nonce: location.values.nonce,
+                }),
+              );
+            }}
+          />
+        </CheckChallengeIsUpToDate>
       );
     }
     case "completed": {
-      return <CallengeCompleted nonce={location.values.nonce} />;
+      return (
+        <CheckChallengeIsUpToDate nonce={location.values.nonce}>
+          <CallengeCompleted nonce={location.values.nonce} />
+        </CheckChallengeIsUpToDate>
+      );
     }
     default:
       assertUnreachable(location);
diff --git a/packages/challenger-ui/src/pages/StartChallenge.tsx 
b/packages/challenger-ui/src/components/CheckChallengeIsUpToDate.tsx
similarity index 64%
rename from packages/challenger-ui/src/pages/StartChallenge.tsx
rename to packages/challenger-ui/src/components/CheckChallengeIsUpToDate.tsx
index 6cf982a3d..04556696b 100644
--- a/packages/challenger-ui/src/pages/StartChallenge.tsx
+++ b/packages/challenger-ui/src/components/CheckChallengeIsUpToDate.tsx
@@ -13,72 +13,50 @@
  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 {
+  HttpStatusCode,
+  TalerError,
+  assertUnreachable
+} from "@gnu-taler/taler-util";
 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 { ComponentChildren, Fragment, VNode, h } from "preact";
 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}$/;
+import { SessionId, useSessionState } from "../hooks/session.js";
 
-type Props = {
+interface Props {
   nonce: string;
-  clientId: string;
-  redirectURL: URL;
-  state: string;
-  onSendSuccesful: () => void;
-};
-
-
-export function StartChallenge({
+  children: ComponentChildren;
+  sessionId?: SessionId;
+  onCompleted?: () => void;
+  onChangeLeft?: () => void;
+  onNoMoreChanges?: () => void;
+}
+export function CheckChallengeIsUpToDate({
+  sessionId: sessionFromParam,
   nonce,
-  clientId,
-  redirectURL,
-  state,
-  onSendSuccesful,
+  children,
+  onCompleted,
+  onChangeLeft,
+  onNoMoreChanges,
 }: Props): VNode {
+  const { state, updateStatus } = useSessionState();
   const { i18n } = useTranslationContext();
-  const { start } = useSessionState();
 
-  const result = useChallengeSession(nonce, {
-    clientId,
-    redirectURL: redirectURL.href,
-    state,
-  });
+  const sessionId = sessionFromParam
+    ? sessionFromParam
+    : !state
+      ? undefined
+      : {
+          clientId: state.clientId,
+          redirectURL: state.redirectURL,
+          state: state.state,
+        };
 
-  const session =
-    result && !(result instanceof TalerError) && result.type === "ok"
-      ? result.body
-      : undefined;
-
-  useEffect(() => {
-    if (session) {
-      start({
-        clientId,
-        redirectURL: redirectURL.href,
-        state,
-      });
-      onSendSuccesful();
-    }
-  }, [session]);
+  const result = useChallengeSession(nonce, sessionId);
 
   if (!result) {
     return <Loading />;
@@ -126,13 +104,22 @@ export function StartChallenge({
     }
   }
 
-  return <Loading />;
-}
+  updateStatus(result.body);
+
+  if (onCompleted && "redirectURL" in result.body) {
+    onCompleted();
+    return <Loading />;
+  }
+
+  if (onNoMoreChanges && !result.body.changes_left) {
+    onNoMoreChanges();
+    return <Loading />;
+  }
+
+  if (onChangeLeft && !result.body.changes_left) {
+    onChangeLeft();
+    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;
+  return <Fragment>{children}</Fragment>;
 }
diff --git a/packages/challenger-ui/src/hooks/session.ts 
b/packages/challenger-ui/src/hooks/session.ts
index 4bb1bfbc8..4d0ffeccf 100644
--- a/packages/challenger-ui/src/hooks/session.ts
+++ b/packages/challenger-ui/src/hooks/session.ts
@@ -15,13 +15,14 @@
  */
 
 import {
+  ChallengerApi,
   Codec,
   buildCodecForObject,
   codecForBoolean,
+  codecForChallengeStatus,
   codecForNumber,
   codecForString,
   codecForStringURL,
-  codecForURL,
   codecOptional,
 } from "@gnu-taler/taler-util";
 import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
@@ -46,6 +47,7 @@ export type LastChallengeResponse = {
 export type SessionState = SessionId & {
   email: string | undefined;
   lastTry: LastChallengeResponse | undefined;
+  challengeStatus: ChallengerApi.ChallengeStatus | undefined;
   completedURL: string | undefined;
 };
 export const codecForLastChallengeResponse = (): Codec<LastChallengeResponse> 
=>
@@ -61,6 +63,7 @@ export const codecForSessionState = (): Codec<SessionState> =>
     .property("redirectURL", codecForStringURL())
     .property("completedURL", codecOptional(codecForStringURL()))
     .property("state", codecForString())
+    .property("challengeStatus", codecOptional(codecForChallengeStatus()))
     .property("lastTry", codecOptional(codecForLastChallengeResponse()))
     .property("email", codecOptional(codecForString()))
     .build("SessionState");
@@ -70,6 +73,7 @@ export interface SessionStateHandler {
   start(s: SessionId): void;
   accepted(e: string, l: LastChallengeResponse): void;
   completed(e: URL): void;
+  updateStatus(s: ChallengerApi.ChallengeStatus): void;
 }
 
 const SESSION_STATE_KEY = buildStorageKey(
@@ -92,6 +96,7 @@ export function useSessionState(): SessionStateHandler {
         ...info,
         lastTry: undefined,
         completedURL: undefined,
+        challengeStatus: undefined,
         email: undefined,
       });
       cleanAllCache();
@@ -111,6 +116,29 @@ export function useSessionState(): SessionStateHandler {
         completedURL: url.href,
       });
     },
+    updateStatus(st: ChallengerApi.ChallengeStatus) {
+      if (!state) return;
+      if (!state.challengeStatus) {
+        update({
+          ...state,
+          challengeStatus: st,
+        });
+        return;
+      }
+      // current status
+      const cu = state.challengeStatus;
+      if (
+        cu.changes_left !== st.changes_left ||
+        cu.fix_address !== st.fix_address ||
+        cu.last_address !== st.last_address
+      ) {
+        update({
+          ...state,
+          challengeStatus: st,
+        });
+        return;
+      }
+    },
   };
 }
 
diff --git a/packages/challenger-ui/src/pages/AnswerChallenge.tsx 
b/packages/challenger-ui/src/pages/AnswerChallenge.tsx
index 69600e2ba..bad6d70de 100644
--- a/packages/challenger-ui/src/pages/AnswerChallenge.tsx
+++ b/packages/challenger-ui/src/pages/AnswerChallenge.tsx
@@ -16,15 +16,16 @@
 import {
   ChallengerApi,
   HttpStatusCode,
-  assertUnreachable,
+  assertUnreachable
 } from "@gnu-taler/taler-util";
 import {
+  Attention,
   Button,
   LocalNotificationBanner,
   ShowInputErrorLabel,
   useChallengerApiContext,
   useLocalNotificationHandler,
-  useTranslationContext,
+  useTranslationContext
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useState } from "preact/hooks";
@@ -37,13 +38,7 @@ type Props = {
   onComplete: () => void;
 };
 
-function SolveChallengeForm({
-  nonce,
-  onComplete,
-}: {
-  nonce: string;
-  onComplete: () => void;
-}): VNode {
+export function AnswerChallenge({ nonce, onComplete }: Props): VNode {
   const { lib } = useChallengerApiContext();
   const { i18n } = useTranslationContext();
   const { state, accepted, completed } = useSessionState();
@@ -64,8 +59,8 @@ function SolveChallengeForm({
             return await lib.bank.challenge(nonce, { email: state.email });
           },
           (ok) => {
-            if ('redirectURL' in ok.body) {
-              completed(ok.body.redirectURL)
+            if ("redirectURL" in ok.body) {
+              completed(ok.body.redirectURL);
             } else {
               accepted(state.email!, {
                 attemptsLeft: ok.body.attempts_left,
@@ -99,7 +94,7 @@ function SolveChallengeForm({
             return lib.bank.solve(nonce, { pin: pin! });
           },
           (ok) => {
-            completed(ok.body.redirectURL as URL)
+            completed(ok.body.redirectURL as URL);
             onComplete();
           },
           (fail) => {
@@ -149,11 +144,13 @@ function SolveChallengeForm({
                 A TAN was sent to your address &quot;{state.email}&quot;.
               </i18n.Translate>
             ) : (
-              <i18n.Translate>
-                We recently already sent a TAN to your address &quot;
-                {state.email}&quot;. A new TAN will not be transmitted again
-                before {state.lastTry.nextSend}.
-              </i18n.Translate>
+              <Attention title={i18n.str`Resend failed`} type="warning">
+                <i18n.Translate>
+                  We recently already sent a TAN to your address &quot;
+                  {state.email}&quot;. A new TAN will not be transmitted again
+                  before &quot;{state.lastTry.nextSend}&quot;.
+                </i18n.Translate>
+              </Attention>
             )}
           </p>
           {!lastTryError ? undefined : (
@@ -230,61 +227,7 @@ function SolveChallengeForm({
         </form>
       </div>
     </Fragment>
-  );
-}
-
-export function AnswerChallenge({ nonce, onComplete }: Props): VNode {
-  const { i18n } = useTranslationContext();
-
-  // const result = useChallengeSession(nonce, clientId, redirectURI, state);
-
-  // 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 <SolveChallengeForm nonce={nonce} onComplete={onComplete} />;
+  )
 }
 
 export function undefinedIfEmpty<T extends object>(obj: T): T | undefined {
diff --git a/packages/challenger-ui/src/pages/AskChallenge.tsx 
b/packages/challenger-ui/src/pages/AskChallenge.tsx
index 71f45dde3..675e2b869 100644
--- a/packages/challenger-ui/src/pages/AskChallenge.tsx
+++ b/packages/challenger-ui/src/pages/AskChallenge.tsx
@@ -13,25 +13,21 @@
  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 {
+  HttpStatusCode
+} from "@gnu-taler/taler-util";
 import {
   Attention,
   Button,
-  Loading,
   LocalNotificationBanner,
+  RouteDefinition,
   ShowInputErrorLabel,
   useChallengerApiContext,
   useLocalNotificationHandler,
-  useTranslationContext,
+  useTranslationContext
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { 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 = {
@@ -42,33 +38,29 @@ export const EMAIL_REGEX = 
/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/;
 type Props = {
   nonce: string;
   onSendSuccesful: () => void;
+  routeSolveChallenge: RouteDefinition<{nonce:string}>,
 };
 
-function ChallengeForm({
-  nonce,
-  status,
-  onSendSuccesful,
-}: {
-  nonce: string;
-  status: ChallengerApi.ChallengeStatus;
-  onSendSuccesful: () => void;
-}): VNode {
-  const prevEmail = !status.last_address
-    ? undefined
-    : ((status.last_address as any)["email"] as string);
-  const regexEmail = !status.restrictions
-    ? undefined
-    : ((status.restrictions as any)["email"] as {
-        regex?: string;
-        hint?: string;
-        hint_i18n?: string;
-      });
+export function AskChallenge({ nonce, onSendSuccesful,routeSolveChallenge }: 
Props): VNode {
+  const { state, accepted, completed } = useSessionState();
+  const status = state?.challengeStatus;
+  const prevEmail =
+    !status || !status.last_address
+      ? undefined
+      : ((status.last_address as any)["email"] as string);
+  const regexEmail =
+    !status || !status.restrictions
+      ? undefined
+      : ((status.restrictions as any)["email"] as {
+          regex?: string;
+          hint?: string;
+          hint_i18n?: string;
+        });
 
   const { lib } = useChallengerApiContext();
   const { i18n } = useTranslationContext();
   const [notification, withErrorHandler] = useLocalNotificationHandler();
   const [email, setEmail] = useState<string | undefined>(prevEmail);
-  const { accepted, completed } = useSessionState();
   const [repeat, setRepeat] = useState<string | undefined>();
 
   const errors = undefinedIfEmpty({
@@ -82,10 +74,12 @@ function ChallengeForm({
           : undefined
         : !EMAIL_REGEX.test(email)
           ? i18n.str`invalid email`
-          : email !== repeat
-            ? i18n.str`emails don't match`
-            : undefined,
-    repeat: !repeat ? i18n.str`required` : undefined,
+          : undefined,
+    repeat: !repeat
+      ? i18n.str`required`
+      : email !== repeat
+        ? i18n.str`emails doesn't match`
+        : undefined,
   });
 
   const onSend = withErrorHandler(
@@ -120,6 +114,10 @@ function ChallengeForm({
     },
   );
 
+  if (!status) {
+    return <div>no status loaded</div>;
+  }
+
   return (
     <Fragment>
       <LocalNotificationBanner notification={notification} />
@@ -136,6 +134,15 @@ function ChallengeForm({
             </i18n.Translate>
           </p>
         </div>
+        {state.lastTry && (
+          <Fragment>
+            <Attention title={i18n.str`A code has been sent to 
${state.email}`}>
+              <i18n.Translate>
+                You can change the destination or <a 
href={routeSolveChallenge.url({nonce })}><i18n.Translate>complete the challenge 
here</i18n.Translate></a>.
+              </i18n.Translate>
+            </Attention>
+          </Fragment>
+        )}
         <form
           method="POST"
           class="mx-auto mt-16 max-w-xl sm:mt-20"
@@ -191,6 +198,10 @@ function ChallengeForm({
                   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"
                 />
+                <ShowInputErrorLabel
+                  message={errors?.repeat}
+                  isDirty={repeat !== undefined}
+                />
               </div>
             </div>
 
@@ -217,67 +228,6 @@ function ChallengeForm({
   );
 }
 
-export function AskChallenge({ nonce, onSendSuccesful }: Props): VNode {
-  const { i18n } = useTranslationContext();
-  const { state } = useSessionState();
-
-  const result = useChallengeSession(nonce, state);
-
-  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 (
-    <ChallengeForm
-      nonce={nonce}
-      status={result.body}
-      onSendSuccesful={onSendSuccesful}
-    />
-  );
-}
-
 export function undefinedIfEmpty<T extends object>(obj: T): T | undefined {
   return Object.keys(obj).some(
     (k) => (obj as Record<string, T>)[k] !== undefined,
diff --git a/packages/web-util/src/utils/http-impl.sw.ts 
b/packages/web-util/src/utils/http-impl.sw.ts
index 3c4b8b587..9c820bb4b 100644
--- a/packages/web-util/src/utils/http-impl.sw.ts
+++ b/packages/web-util/src/utils/http-impl.sw.ts
@@ -59,6 +59,7 @@ export class BrowserFetchHttpLib implements 
HttpRequestLibrary {
     const requestTimeout =
       options?.timeout ?? 
Duration.fromMilliseconds(DEFAULT_REQUEST_TIMEOUT_MS);
     const requestCancel = options?.cancellationToken;
+    const requestRedirect = options?.redirect;
 
     const parsedUrl = new URL(requestUrl);
     if (this.throttlingEnabled && this.throttle.applyThrottle(requestUrl)) {
@@ -115,6 +116,7 @@ export class BrowserFetchHttpLib implements 
HttpRequestLibrary {
         body: myBody,
         method: requestMethod,
         signal: controller.signal,
+        redirect: requestRedirect
       });
 
       if (timeoutId) {

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