gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: update cache when sending cod


From: gnunet
Subject: [taler-wallet-core] branch master updated: update cache when sending code and checking code
Date: Mon, 01 Jul 2024 20:30:42 +0200

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

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

The following commit(s) were added to refs/heads/master by this push:
     new da3208f85 update cache when sending code and checking code
da3208f85 is described below

commit da3208f85716af2b150a4bb717092d5fac3bec27
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Jul 1 15:04:42 2024 -0300

    update cache when sending code and checking code
---
 packages/challenger-ui/src/Routing.tsx             |   2 +-
 packages/challenger-ui/src/app.tsx                 |  17 +-
 .../src/components/CheckChallengeIsUpToDate.tsx    |  23 ++-
 .../challenger-ui/src/pages/AnswerChallenge.tsx    | 215 ++++++++++++---------
 .../challenger-ui/src/pages/CallengeCompleted.tsx  |  25 ++-
 packages/challenger-ui/src/pages/Frame.tsx         |   6 +-
 packages/taler-util/src/http-client/challenger.ts  |  12 +-
 7 files changed, 185 insertions(+), 115 deletions(-)

diff --git a/packages/challenger-ui/src/Routing.tsx 
b/packages/challenger-ui/src/Routing.tsx
index 179263286..74c1687bb 100644
--- a/packages/challenger-ui/src/Routing.tsx
+++ b/packages/challenger-ui/src/Routing.tsx
@@ -98,7 +98,7 @@ function PublicRounting(): VNode {
         <Setup
           clientId={location.values.client}
           secret={secret}
-          // "http://exchange.taler.test:1180/kyc-proof/kyc-provider-wallet";
+          // 
redirect_url=http://exchange.taler.test:1180/kyc-proof/kyc-provider-wallet&secret=chal-secret
           redirectURL={redirectURL}
           onCreated={() => {
             navigateTo(publicPages.ask.url({}));
diff --git a/packages/challenger-ui/src/app.tsx 
b/packages/challenger-ui/src/app.tsx
index 07b0fe261..655e46a5c 100644
--- a/packages/challenger-ui/src/app.tsx
+++ b/packages/challenger-ui/src/app.tsx
@@ -29,18 +29,15 @@ import {
   TalerWalletIntegrationBrowserProvider,
   TranslationProvider,
 } from "@gnu-taler/web-util/browser";
+import { VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { SWRConfig } from "swr";
 import { Routing } from "./Routing.js";
-// import { BankCoreApiProvider } from "./context/config.js";
-// import { BrowserHashNavigationProvider } from "./context/navigation.js";
 import { SettingsProvider } from "./context/settings.js";
-// import { TalerWalletIntegrationBrowserProvider } from 
"./context/wallet-integration.js";
-import { VNode, h } from "preact";
+import { revalidateChallengeSession } from "./hooks/challenge.js";
 import { strings } from "./i18n/strings.js";
-import { ChallengerUiSettings, fetchSettings } from "./settings.js";
 import { Frame } from "./pages/Frame.js";
-import { revalidateChallengeSession } from "./hooks/challenge.js";
+import { ChallengerUiSettings, fetchSettings } from "./settings.js";
 
 const WITH_LOCAL_STORAGE_CACHE = false;
 
@@ -83,11 +80,9 @@ export function App(): VNode {
         <ChallengerApiProvider
           baseUrl={new URL("/", baseUrl)}
           frameOnError={Frame}
-          evictors={
-            {
-              // challenger: evictBankSwrCache,
-            }
-          }
+          evictors={{
+            challenger: evictBankSwrCache,
+          }}
         >
           <SWRConfig
             value={{
diff --git a/packages/challenger-ui/src/components/CheckChallengeIsUpToDate.tsx 
b/packages/challenger-ui/src/components/CheckChallengeIsUpToDate.tsx
index 1ff7197bf..8ceb969b5 100644
--- a/packages/challenger-ui/src/components/CheckChallengeIsUpToDate.tsx
+++ b/packages/challenger-ui/src/components/CheckChallengeIsUpToDate.tsx
@@ -44,7 +44,9 @@ export function CheckChallengeIsUpToDate({
   const { state } = useSessionState();
   const { i18n } = useTranslationContext();
 
-  const result = useChallengeSession(session ?? state);
+  const id = session ?? state;
+
+  const result = useChallengeSession(id);
 
   if (!result) {
     return <Loading />;
@@ -87,6 +89,25 @@ export function CheckChallengeIsUpToDate({
           </Attention>
         );
       }
+      case HttpStatusCode.TooManyRequests: {
+        return (
+          <Fragment>
+            <Attention
+              type="danger"
+              title={i18n.str`Can't complete this challenge`}
+            >
+              <i18n.Translate>
+                There have been too many attempts to request challenge
+                transmissions and check the TAN code.
+              </i18n.Translate>
+            </Attention>
+
+            <div class="mt-2">
+              <a href={id?.redirectURL ?? ""}>{id?.redirectURL}</a>
+            </div>
+          </Fragment>
+        );
+      }
       default:
         assertUnreachable(result);
     }
diff --git a/packages/challenger-ui/src/pages/AnswerChallenge.tsx 
b/packages/challenger-ui/src/pages/AnswerChallenge.tsx
index 1576f2cf2..265bda038 100644
--- a/packages/challenger-ui/src/pages/AnswerChallenge.tsx
+++ b/packages/challenger-ui/src/pages/AnswerChallenge.tsx
@@ -15,11 +15,9 @@
  */
 import {
   AbsoluteTime,
-  ChallengerApi,
   EmptyObject,
   HttpStatusCode,
   TalerError,
-  TalerProtocolTimestamp,
   assertUnreachable,
 } from "@gnu-taler/taler-util";
 import {
@@ -35,8 +33,11 @@ import {
 } from "@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
+import {
+  revalidateChallengeSession,
+  useChallengeSession,
+} from "../hooks/challenge.js";
 import { useSessionState } from "../hooks/session.js";
-import { useChallengeSession } from "../hooks/challenge.js";
 
 export const EMAIL_REGEX = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/;
 
@@ -48,19 +49,20 @@ type Props = {
 
 function useReloadOnDeadline(deadline: AbsoluteTime): void {
   const [, set] = useState(false);
+  function toggle(): void {
+    set((s) => !s);
+  }
   useEffect(() => {
     if (AbsoluteTime.isExpired(deadline)) {
       return;
     }
     const diff = AbsoluteTime.difference(AbsoluteTime.now(), deadline);
     if (diff.d_ms === "forever") return;
-    const p = setTimeout(() => {
-      set(true);
-    }, diff.d_ms);
+    const timer = setTimeout(toggle, diff.d_ms);
     return () => {
-      clearTimeout(p);
+      clearTimeout(timer);
     };
-  }, []);
+  }, [deadline]);
 }
 
 export function AnswerChallenge({ focus, onComplete, routeAsk }: Props): VNode 
{
@@ -98,7 +100,7 @@ export function AnswerChallenge({ focus, onComplete, 
routeAsk }: Props): VNode {
     !state?.nonce ||
     contact === undefined ||
     lastStatus == undefined ||
-    lastStatus.auth_attempts_left === 0 ||
+    lastStatus.pin_transmissions_left === 0 ||
     !deadline ||
     !AbsoluteTime.isExpired(deadline)
       ? undefined
@@ -112,7 +114,6 @@ export function AnswerChallenge({ focus, onComplete, 
routeAsk }: Props): VNode {
             } else {
               sent(ok.body);
             }
-            return undefined;
           },
           (fail) => {
             switch (fail.case) {
@@ -153,14 +154,17 @@ export function AnswerChallenge({ focus, onComplete, 
routeAsk }: Props): VNode {
               case HttpStatusCode.BadRequest:
                 return i18n.str`The request was not accepted, try reloading 
the app.`;
               case HttpStatusCode.Forbidden: {
+                revalidateChallengeSession();
                 return i18n.str`Invalid pin.`;
               }
               case HttpStatusCode.NotFound:
                 return i18n.str`Challenge not found.`;
               case HttpStatusCode.NotAcceptable:
                 return i18n.str`Server templates are missing due to 
misconfiguration.`;
-              case HttpStatusCode.TooManyRequests:
+              case HttpStatusCode.TooManyRequests: {
+                revalidateChallengeSession();
                 return i18n.str`There have been too many attempts to request 
challenge transmissions.`;
+              }
               case HttpStatusCode.InternalServerError:
                 return i18n.str`Server is not able to respond due to internal 
problems.`;
               default:
@@ -168,6 +172,110 @@ export function AnswerChallenge({ focus, onComplete, 
routeAsk }: Props): VNode {
             }
           },
         );
+  const cantTryAnymore = lastStatus?.auth_attempts_left === 0;
+
+  function LastContactSent(): VNode {
+    return (
+      <p class="mt-2 text-lg leading-8 text-gray-600">
+        {!lastStatus || !deadline || AbsoluteTime.isExpired(deadline) ? (
+          <i18n.Translate>
+            Last TAN code was sent to your address &quot;{contact?.email}
+            &quot; is not valid anymore.
+          </i18n.Translate>
+        ) : (
+          <Attention
+            title={i18n.str`A TAN code was sent to your address 
"${contact?.email}"`}
+          >
+            <i18n.Translate>
+              You should wait until &quot;
+              <Time format="dd/MM/yyyy HH:mm:ss" timestamp={deadline} />
+              &quot; to send a new one.
+            </i18n.Translate>
+          </Attention>
+        )}
+      </p>
+    );
+  }
+
+  function TryAnotherCode(): VNode {
+    return (
+      <div class="mx-auto mt-4 max-w-xl flex justify-between">
+        <div>
+          <a
+            data-disabled={unableToChangeAddr}
+            href={unableToChangeAddr ? undefined : routeAsk.url({})}
+            class="relative data-[disabled=true]:bg-gray-300 
data-[disabled=true]:text-white data-[disabled=true]:cursor-default inline-flex 
items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 
ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0"
+          >
+            <i18n.Translate>Try with another address</i18n.Translate>
+          </a>
+          {lastStatus === undefined ? undefined : (
+            <p class="mt-2 text-sm leading-6 text-gray-400">
+              {lastStatus.changes_left < 1 ? (
+                <i18n.Translate>
+                  You can&#39;t change the email anymore.
+                </i18n.Translate>
+              ) : lastStatus.changes_left === 1 ? (
+                <i18n.Translate>
+                  You can change the email one last time.
+                </i18n.Translate>
+              ) : (
+                <i18n.Translate>
+                  You can change the email {lastStatus.changes_left} more 
times.
+                </i18n.Translate>
+              )}
+            </p>
+          )}
+        </div>
+        <div>
+          <Button
+            type="submit"
+            disabled={!onSendAgain}
+            class="block w-full disabled:bg-gray-300 rounded-md bg-indigo-600 
px-3.5 py-2.5 text-center text-sm font-semibold text-white shadow-sm 
hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
+            handler={onSendAgain}
+          >
+            <i18n.Translate>Send new code</i18n.Translate>
+          </Button>
+          {lastStatus === undefined ? undefined : (
+            <p class="mt-2 text-sm leading-6 text-gray-400">
+              {lastStatus.pin_transmissions_left < 1 ? (
+                <i18n.Translate>
+                  We can&#39;t send you the code anymore.
+                </i18n.Translate>
+              ) : lastStatus.pin_transmissions_left === 1 ? (
+                <i18n.Translate>
+                  We can send the code one last time.
+                </i18n.Translate>
+              ) : (
+                <i18n.Translate>
+                  We can send the code {lastStatus.pin_transmissions_left} more
+                  times.
+                </i18n.Translate>
+              )}
+            </p>
+          )}
+        </div>
+      </div>
+    );
+  }
+
+  if (cantTryAnymore) {
+    return (
+      <Fragment>
+        <LocalNotificationBanner notification={notification} />
+        <div class="isolate bg-white px-6 py-12">
+          <div class="mx-auto max-w-2xl text-center">
+            <h2 class="text-3xl font-bold tracking-tight text-gray-900 
sm:text-4xl">
+              <i18n.Translate>Last TAN code can not be used.</i18n.Translate>
+            </h2>
+
+            <LastContactSent />
+          </div>
+
+          <TryAnotherCode />
+        </div>
+      </Fragment>
+    );
+  }
 
   return (
     <Fragment>
@@ -180,29 +288,8 @@ export function AnswerChallenge({ focus, onComplete, 
routeAsk }: Props): VNode {
               Enter the TAN you received to authenticate.
             </i18n.Translate>
           </h2>
-          <p class="mt-2 text-lg leading-8 text-gray-600">
-            {!lastStatus || !deadline || AbsoluteTime.isExpired(deadline) ? (
-              <i18n.Translate>
-                Last TAN code was sent to your address &quot;{contact?.email}
-                &quot;.
-              </i18n.Translate>
-            ) : (
-              <Attention title={i18n.str`Unable send the code again`}>
-                <i18n.Translate>
-                  We recently already sent a TAN to your address &quot;
-                  {contact?.email}&quot;. A new TAN will not be transmitted
-                  again before &quot;
-                  <Time
-                    format="dd/MM/yyyy HH:mm:ss"
-                    timestamp={AbsoluteTime.fromProtocolTimestamp(
-                      lastStatus.retransmission_time,
-                    )}
-                  />
-                  &quot;.
-                </i18n.Translate>
-              </Attention>
-            )}
-          </p>
+          <LastContactSent />
+
           {lastStatus === undefined ? undefined : (
             <p class="mt-2 text-lg leading-8 text-gray-600">
               {lastStatus.auth_attempts_left < 1 ? (
@@ -222,6 +309,7 @@ export function AnswerChallenge({ focus, onComplete, 
routeAsk }: Props): VNode {
             </p>
           )}
         </div>
+
         <form
           method="POST"
           class="mx-auto mt-4 max-w-xl"
@@ -270,64 +358,9 @@ export function AnswerChallenge({ focus, onComplete, 
routeAsk }: Props): VNode {
               <i18n.Translate>Check</i18n.Translate>
             </Button>
           </div>
-          <div class="mt-10 flex justify-between">
-            <div>
-              <a
-                data-disabled={unableToChangeAddr}
-                href={unableToChangeAddr ? undefined : routeAsk.url({})}
-                class="relative data-[disabled=true]:bg-gray-300 
data-[disabled=true]:text-white data-[disabled=true]:cursor-default inline-flex 
items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 
ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline-offset-0"
-              >
-                <i18n.Translate>Change email</i18n.Translate>
-              </a>
-              {lastStatus === undefined ? undefined : (
-                <p class="mt-2 text-sm leading-6 text-gray-400">
-                  {lastStatus.changes_left < 1 ? (
-                    <i18n.Translate>
-                      You can&#39;t change the email anymore.
-                    </i18n.Translate>
-                  ) : lastStatus.changes_left === 1 ? (
-                    <i18n.Translate>
-                      You can change the email one last time.
-                    </i18n.Translate>
-                  ) : (
-                    <i18n.Translate>
-                      You can change the email {lastStatus.changes_left} more
-                      times.
-                    </i18n.Translate>
-                  )}
-                </p>
-              )}
-            </div>
-            <div>
-              <Button
-                type="submit"
-                disabled={!onSendAgain}
-                class="block w-full disabled:bg-gray-300 rounded-md 
bg-indigo-600 px-3.5 py-2.5 text-center text-sm font-semibold text-white 
shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
-                handler={onSendAgain}
-              >
-                <i18n.Translate>Send code again</i18n.Translate>
-              </Button>
-              {lastStatus === undefined ? undefined : (
-                <p class="mt-2 text-sm leading-6 text-gray-400">
-                  {lastStatus.pin_transmissions_left < 1 ? (
-                    <i18n.Translate>
-                      We can&#39;t send you the code anymore.
-                    </i18n.Translate>
-                  ) : lastStatus.pin_transmissions_left === 1 ? (
-                    <i18n.Translate>
-                      We can send the code one last time.
-                    </i18n.Translate>
-                  ) : (
-                    <i18n.Translate>
-                      We can send the code 
{lastStatus.pin_transmissions_left}{" "}
-                      more times.
-                    </i18n.Translate>
-                  )}
-                </p>
-              )}
-            </div>
-          </div>
         </form>
+
+        <TryAnotherCode />
       </div>
     </Fragment>
   );
diff --git a/packages/challenger-ui/src/pages/CallengeCompleted.tsx 
b/packages/challenger-ui/src/pages/CallengeCompleted.tsx
index e897bae5b..67b26b452 100644
--- a/packages/challenger-ui/src/pages/CallengeCompleted.tsx
+++ b/packages/challenger-ui/src/pages/CallengeCompleted.tsx
@@ -13,13 +13,13 @@
  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 { VNode, h } from "preact";
+import { TalerError } from "@gnu-taler/taler-util";
+import { Attention, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { Fragment, VNode, h } from "preact";
 import { useChallengeSession } from "../hooks/challenge.js";
 import { useSessionState } from "../hooks/session.js";
-import { TalerError } from "@gnu-taler/taler-util";
 
-type Props = {};
-export function CallengeCompleted({}: Props): VNode {
+export function CallengeCompleted(): VNode {
   const { state } = useSessionState();
   const result = useChallengeSession(state);
 
@@ -28,5 +28,20 @@ export function CallengeCompleted({}: Props): VNode {
       ? result.body
       : undefined;
 
-  return <div>completed {lastStatus}</div>;
+  const { i18n } = useTranslationContext();
+  
+  return (
+    <div class="m-4">
+      <Attention
+        title={i18n.str`Challenge completed`}
+        type="success"
+      >
+        <i18n.Translate>
+          You will be redirected to <a href={state?.completedURL} 
class="break-all">&quot;
+          {state?.completedURL}
+          &quot;</a>
+        </i18n.Translate>
+      </Attention>
+    </div>
+  );
 }
diff --git a/packages/challenger-ui/src/pages/Frame.tsx 
b/packages/challenger-ui/src/pages/Frame.tsx
index dd2a13d8c..7f81b9d77 100644
--- a/packages/challenger-ui/src/pages/Frame.tsx
+++ b/packages/challenger-ui/src/pages/Frame.tsx
@@ -14,6 +14,7 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+import { TranslatedString } from "@gnu-taler/taler-util";
 import {
   Footer,
   Header,
@@ -22,15 +23,14 @@ import {
   notifyException,
   useTranslationContext,
 } from "@gnu-taler/web-util/browser";
-import { ComponentChildren, Fragment, h, VNode } from "preact";
-import { useSettingsContext } from "../context/settings.js";
+import { ComponentChildren, Fragment, VNode, h } from "preact";
 import { useEffect, useErrorBoundary } from "preact/hooks";
-import { TranslatedString } from "@gnu-taler/taler-util";
 import {
   getAllBooleanPreferences,
   getLabelForPreferences,
   usePreferences,
 } from "../context/preferences.js";
+import { useSettingsContext } from "../context/settings.js";
 
 const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : 
undefined;
 const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined;
diff --git a/packages/taler-util/src/http-client/challenger.ts 
b/packages/taler-util/src/http-client/challenger.ts
index 6a920749c..951bad845 100644
--- a/packages/taler-util/src/http-client/challenger.ts
+++ b/packages/taler-util/src/http-client/challenger.ts
@@ -8,7 +8,7 @@ import {
   opKnownAlternativeFailure,
   opKnownHttpFailure,
   opSuccessFromHttp,
-  opUnknownFailure
+  opUnknownFailure,
 } from "../operation.js";
 import {
   AccessToken,
@@ -19,7 +19,7 @@ import {
   codecForChallengeStatus,
   codecForChallengerAuthResponse,
   codecForChallengerInfoResponse,
-  codecForChallengerTermsOfServiceResponse
+  codecForChallengerTermsOfServiceResponse,
 } from "./types.js";
 import {
   CacheEvictor,
@@ -131,6 +131,8 @@ export class ChallengerHttpClient {
         return opKnownHttpFailure(resp.status, resp);
       case HttpStatusCode.NotAcceptable:
         return opKnownHttpFailure(resp.status, resp);
+      case HttpStatusCode.TooManyRequests:
+        return opKnownHttpFailure(resp.status, resp);
       case HttpStatusCode.InternalServerError:
         return opKnownHttpFailure(resp.status, resp);
       default:
@@ -203,7 +205,11 @@ export class ChallengerHttpClient {
       case HttpStatusCode.BadRequest:
         return opKnownHttpFailure(resp.status, resp);
       case HttpStatusCode.Forbidden:
-        return opKnownAlternativeFailure(resp, HttpStatusCode.Forbidden, 
codecForChallengeInvalidPinResponse());
+        return opKnownAlternativeFailure(
+          resp,
+          HttpStatusCode.Forbidden,
+          codecForChallengeInvalidPinResponse(),
+        );
       case HttpStatusCode.NotFound:
         return opKnownHttpFailure(resp.status, resp);
       case HttpStatusCode.NotAcceptable:

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