gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: lang selector and fix logout


From: gnunet
Subject: [taler-wallet-core] branch master updated: lang selector and fix logout
Date: Tue, 26 Sep 2023 20:18:54 +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 1e4f21cc7 lang selector and fix logout
1e4f21cc7 is described below

commit 1e4f21cc76345f3881ea8e5ea0e94d27d26da609
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue Sep 26 15:18:43 2023 -0300

    lang selector and fix logout
---
 packages/demobank-ui/package.json                  |   2 +-
 .../demobank-ui/src/components/LangSelector.tsx    |  78 ++++++------
 packages/demobank-ui/src/components/app.tsx        |   6 +-
 packages/demobank-ui/src/context/backend.ts        |   4 +
 packages/demobank-ui/src/declaration.d.ts          |   4 +-
 packages/demobank-ui/src/hooks/backend.ts          |  44 +++++--
 packages/demobank-ui/src/hooks/circuit.ts          |   4 +-
 packages/demobank-ui/src/hooks/config.ts           |  20 +--
 .../demobank-ui/src/hooks/useCredentialsChecker.ts |   2 +-
 packages/demobank-ui/src/pages/BankFrame.tsx       | 128 ++++++-------------
 packages/demobank-ui/src/pages/LoginForm.tsx       |  27 ++--
 .../demobank-ui/src/pages/OperationState/views.tsx |  17 +--
 .../demobank-ui/src/pages/RegistrationPage.tsx     | 138 +++++++++++++++------
 packages/demobank-ui/src/pages/admin/Account.tsx   |   2 +-
 packages/demobank-ui/src/pages/business/Home.tsx   |   2 -
 packages/demobank-ui/src/settings.ts               |  14 +--
 16 files changed, 272 insertions(+), 220 deletions(-)

diff --git a/packages/demobank-ui/package.json 
b/packages/demobank-ui/package.json
index 744cb4180..b430ebc24 100644
--- a/packages/demobank-ui/package.json
+++ b/packages/demobank-ui/package.json
@@ -1,7 +1,7 @@
 {
   "private": true,
   "name": "@gnu-taler/demobank-ui",
-  "version": "0.1.0",
+  "version": "0.9.3-dev.17",
   "license": "AGPL-3.0-OR-LATER",
   "type": "module",
   "scripts": {
diff --git a/packages/demobank-ui/src/components/LangSelector.tsx 
b/packages/demobank-ui/src/components/LangSelector.tsx
index ca4411682..c1d0f64ef 100644
--- a/packages/demobank-ui/src/components/LangSelector.tsx
+++ b/packages/demobank-ui/src/components/LangSelector.tsx
@@ -42,11 +42,11 @@ function getLangName(s: keyof LangsNames | string): string {
   return String(s);
 }
 
-// FIXME: explain "like py".
-export function LangSelectorLikePy(): VNode {
+export function LangSelector(): VNode {
   const [updatingLang, setUpdatingLang] = useState(false);
   const { lang, changeLanguage } = useTranslationContext();
   const [hidden, setHidden] = useState(true);
+
   useEffect(() => {
     function bodyKeyPress(event: KeyboardEvent) {
       if (event.code === "Escape") setHidden(true);
@@ -62,51 +62,49 @@ export function LangSelectorLikePy(): VNode {
     };
   }, []);
   return (
-    <Fragment>
-      <a
-        href="#"
-        class="pure-button"
-        name="language"
-        onClick={(ev) => {
-          ev.preventDefault();
-          setHidden((h) => !h);
-          ev.stopPropagation();
-        }}
-      >
-        {getLangName(lang)}
-      </a>
-      <div
-        id="lang"
-        class={hidden ? "hide" : ""}
-        style={{
-          display: "inline-block",
-        }}
-      >
-        <div style="position: relative; overflow: visible;">
-          <div
-            class="nav"
-            style="position: absolute; max-height: 60vh; overflow-y: auto; 
margin-left: -120px; margin-top: 20px"
-          >
+    <div>
+      <div class="relative mt-2">
+        <button type="button" class="relative w-full cursor-default rounded-md 
bg-white py-1.5 pl-3 pr-10 text-left text-gray-900 shadow-sm ring-1 ring-inset 
ring-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-600 sm:text-sm 
sm:leading-6" aria-haspopup="listbox" aria-expanded="true" 
aria-labelledby="listbox-label"
+          onClick={() => {
+            setHidden((h) => !h);
+          }}>
+          <span class="flex items-center">
+            <img src="https://taler.net/images/languageicon.svg"; alt="" 
class="h-5 w-5 flex-shrink-0 rounded-full" />
+            <span class="ml-3 block truncate">{getLangName(lang)}</span>
+          </span>
+          <span class="pointer-events-none absolute inset-y-0 right-0 flex 
items-center pr-2">
+            <svg class="h-5 w-5 text-gray-400" viewBox="0 0 20 20" 
fill="currentColor" aria-hidden="true">
+              <path fill-rule="evenodd" d="M10 3a.75.75 0 01.55.24l3.25 
3.5a.75.75 0 11-1.1 1.02L10 4.852 7.3 7.76a.75.75 0 01-1.1-1.02l3.25-3.5A.75.75 
0 0110 3zm-3.76 9.2a.75.75 0 011.06.04l2.7 2.908 2.7-2.908a.75.75 0 111.1 
1.02l-3.25 3.5a.75.75 0 01-1.1 0l-3.25-3.5a.75.75 0 01.04-1.06z" 
clip-rule="evenodd" />
+            </svg>
+          </span>
+        </button>
+
+        {!hidden &&
+          <ul class="absolute z-10 mt-1 max-h-60 w-full overflow-auto 
rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 
focus:outline-none sm:text-sm" tabIndex={-1} role="listbox" 
aria-labelledby="listbox-label" aria-activedescendant="listbox-option-3">
             {Object.keys(messages)
               .filter((l) => l !== lang)
-              .map((l) => (
-                <a
-                  key={l}
-                  href="#"
-                  class="navbtn langbtn"
-                  value={l}
+              .map((lang) => (
+                <li class="text-gray-900 hover:bg-indigo-600 hover:text-white 
cursor-pointer relative select-none py-2 pl-3 pr-9" role="option"
                   onClick={() => {
-                    changeLanguage(l);
+                    changeLanguage(lang);
                     setUpdatingLang(false);
+                    setHidden(true)
                   }}
                 >
-                  {getLangName(l)}
-                </a>
+                  <span class="font-normal block 
truncate">{getLangName(lang)}</span>
+
+                  <span class="text-indigo-600 absolute inset-y-0 right-0 flex 
items-center pr-4">
+                    {/* <svg class="h-5 w-5" viewBox="0 0 20 20" 
fill="currentColor" aria-hidden="true">
+                        <path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 
01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 
3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" />
+                      </svg> */}
+                  </span>
+                </li>
               ))}
-            <br />
-          </div>
-        </div>
+
+          </ul>
+        }
+
       </div>
-    </Fragment>
+    </div>
   );
 }
diff --git a/packages/demobank-ui/src/components/app.tsx 
b/packages/demobank-ui/src/components/app.tsx
index a587c6f1e..f15a9ee6a 100644
--- a/packages/demobank-ui/src/components/app.tsx
+++ b/packages/demobank-ui/src/components/app.tsx
@@ -78,17 +78,17 @@ function VersionCheck({ children }: { children: 
ComponentChildren }): VNode {
   if (checked === undefined) {
     return <Loading />
   }
-  if (typeof checked ===  "string") {
+  if (checked.type === "wrong") {
     return <BankFrame>
       the bank backend is not supported. supported version 
"{BANK_INTEGRATION_PROTOCOL_VERSION}", server version "{checked}"
     </BankFrame>
   }
-  if (checked === true) {
+  if (checked.type === "ok") {
     return <Fragment>{children}</Fragment>
   }
   
   return <BankFrame>
-    <ErrorLoading error={checked}/>
+    <ErrorLoading error={checked.result}/>
   </BankFrame>
 }
 
diff --git a/packages/demobank-ui/src/context/backend.ts 
b/packages/demobank-ui/src/context/backend.ts
index b311ddbb0..eae187c6d 100644
--- a/packages/demobank-ui/src/context/backend.ts
+++ b/packages/demobank-ui/src/context/backend.ts
@@ -34,6 +34,9 @@ const initial: Type = {
   logOut() {
     null;
   },
+  expired() {
+    null;
+  },
   logIn(info) {
     null;
   },
@@ -65,6 +68,7 @@ export const BackendStateProviderTesting = ({
   const value: BackendStateHandler = {
     state,
     logIn: () => {},
+    expired: () => {},
     logOut: () => {},
   };
 
diff --git a/packages/demobank-ui/src/declaration.d.ts 
b/packages/demobank-ui/src/declaration.d.ts
index d3d9e02ef..bd7edf033 100644
--- a/packages/demobank-ui/src/declaration.d.ts
+++ b/packages/demobank-ui/src/declaration.d.ts
@@ -74,7 +74,9 @@ type HashCode = string;
 type EddsaPublicKey = string;
 type EddsaSignature = string;
 type WireTransferIdentifierRawP = string;
-type RelativeTime = Duration;
+type RelativeTime = {
+  d_us: number | "forever"
+};
 type ImageDataUrl = string;
 
 interface WithId {
diff --git a/packages/demobank-ui/src/hooks/backend.ts 
b/packages/demobank-ui/src/hooks/backend.ts
index 3d5bfa360..889618646 100644
--- a/packages/demobank-ui/src/hooks/backend.ts
+++ b/packages/demobank-ui/src/hooks/backend.ts
@@ -46,16 +46,18 @@ import { AccessToken } from "./useCredentialsChecker.js";
  * Has the information to reach and
  * authenticate at the bank's backend.
  */
-export type BackendState = LoggedIn | LoggedOut;
+export type BackendState = LoggedIn | LoggedOut | Expired;
 
-export interface BackendCredentials {
+interface LoggedIn {
+  status: "loggedIn";
+  isUserAdministrator: boolean;
   username: string;
   token: AccessToken;
 }
-
-interface LoggedIn extends BackendCredentials {
-  status: "loggedIn";
+interface Expired {
+  status: "expired";
   isUserAdministrator: boolean;
+  username: string;
 }
 interface LoggedOut {
   status: "loggedOut";
@@ -69,6 +71,13 @@ export const codecForBackendStateLoggedIn = (): 
Codec<LoggedIn> =>
     .property("isUserAdministrator", codecForBoolean())
     .build("BackendState.LoggedIn");
 
+export const codecForBackendStateExpired = (): Codec<Expired> =>
+  buildCodecForObject<Expired>()
+    .property("status", codecForConstString("expired"))
+    .property("username", codecForString())
+    .property("isUserAdministrator", codecForBoolean())
+    .build("BackendState.Expired");
+
 export const codecForBackendStateLoggedOut = (): Codec<LoggedOut> =>
   buildCodecForObject<LoggedOut>()
     .property("status", codecForConstString("loggedOut"))
@@ -79,6 +88,7 @@ export const codecForBackendState = (): Codec<BackendState> =>
     .discriminateOn("status")
     .alternative("loggedIn", codecForBackendStateLoggedIn())
     .alternative("loggedOut", codecForBackendStateLoggedOut())
+    .alternative("expired", codecForBackendStateExpired())
     .build("BackendState");
 
 export function getInitialBackendBaseURL(): string {
@@ -94,8 +104,9 @@ export function getInitialBackendBaseURL(): string {
         "ERROR: backendBaseURL was overridden by a setting file and missing. 
Setting value to 'window.origin'",
       );
       result = window.origin
+    } else {
+      result = bankUiSettings.backendBaseURL;
     }
-    result = bankUiSettings.backendBaseURL;
   } else {
     // testing/development path
     result = overrideUrl
@@ -115,7 +126,8 @@ export const defaultState: BackendState = {
 export interface BackendStateHandler {
   state: BackendState;
   logOut(): void;
-  logIn(info: BackendCredentials): void;
+  expired(): void;
+  logIn(info: {username: string, token: AccessToken}): void;
 }
 
 const BACKEND_STATE_KEY = buildStorageKey(
@@ -133,12 +145,22 @@ export function useBackendState(): BackendStateHandler {
     BACKEND_STATE_KEY,
     defaultState,
   );
+  const mutateAll = useMatchMutate();
 
   return {
     state,
     logOut() {
       update(defaultState);
     },
+    expired() {
+      if (state.status === "loggedOut") return;
+      const nextState: BackendState = {
+        status: "expired",
+        username: state.username,
+        isUserAdministrator: state.username === "admin",
+      };
+      update(nextState);
+    },
     logIn(info) {
       //admin is defined by the username
       const nextState: BackendState = {
@@ -147,6 +169,7 @@ export function useBackendState(): BackendStateHandler {
         isUserAdministrator: info.username === "admin",
       };
       update(nextState);
+      mutateAll(/.*/)
     },
   };
 }
@@ -194,7 +217,7 @@ export function usePublicBackend(): useBackendType {
       number,
     ]): Promise<HttpResponseOk<T>> {
       const delta = -1 * size //descending order
-      const params = start ? { delta, start } : {delta}
+      const params = start ? { delta, start } : { delta }
       return requestHandler<T>(baseUrl, endpoint, {
         params,
       });
@@ -262,7 +285,8 @@ export function useAuthenticatedBackend(): useBackendType {
   const { state } = useBackendContext();
   const { request: requestHandler } = useApiContext();
 
-  const creds = state.status === "loggedIn" ? state.token : undefined;
+  // FIXME: libeufin returns 400 insteand of 401 if there is no auth token
+  const creds = state.status === "loggedIn" ? state.token : "secret-token:a"; 
   const baseUrl = getInitialBackendBaseURL();
 
   const request = useCallback(
@@ -288,7 +312,7 @@ export function useAuthenticatedBackend(): useBackendType {
       number,
     ]): Promise<HttpResponseOk<T>> {
       const delta = -1 * size //descending order
-      const params = start ? { delta, start } : {delta}
+      const params = start ? { delta, start } : { delta }
       return requestHandler<T>(baseUrl, endpoint, {
         token: creds,
         params,
diff --git a/packages/demobank-ui/src/hooks/circuit.ts 
b/packages/demobank-ui/src/hooks/circuit.ts
index 4ef80b055..82caafdf2 100644
--- a/packages/demobank-ui/src/hooks/circuit.ts
+++ b/packages/demobank-ui/src/hooks/circuit.ts
@@ -268,7 +268,7 @@ export function useEstimator(): CashoutEstimators {
   const { state } = useBackendContext();
   const { request } = useApiContext();
   const creds =
-    state.status === "loggedOut"
+    state.status !== "loggedIn"
       ? undefined
       : state.token;
   return {
@@ -340,7 +340,7 @@ export function useBusinessAccountFlag(): boolean | 
undefined {
   const { state } = useBackendContext();
   const { request } = useApiContext();
   const creds =
-    state.status === "loggedOut"
+    state.status !== "loggedIn"
       ? undefined
       : {user: state.username, token: state.token};
 
diff --git a/packages/demobank-ui/src/hooks/config.ts 
b/packages/demobank-ui/src/hooks/config.ts
index 4cf677d35..bb5134510 100644
--- a/packages/demobank-ui/src/hooks/config.ts
+++ b/packages/demobank-ui/src/hooks/config.ts
@@ -18,23 +18,29 @@ async function getConfigState(
   return result.data;
 }
 
-export function useConfigState(): undefined | true | string | 
HttpError<SandboxBackend.SandboxError> {
-  const [checked, setChecked] = useState<true | string | 
HttpError<SandboxBackend.SandboxError>>()
+type Result = undefined
+  | { type: "ok", result: SandboxBackend.Config }
+  | { type: "wrong", result: SandboxBackend.Config }
+  | { type: "error", result: HttpError<SandboxBackend.SandboxError> }
+
+export function useConfigState(): Result {
+  const [checked, setChecked] = useState<Result>()
   const { request } = useApiContext();
 
   useEffect(() => {
     getConfigState(request)
-      .then((s) => {
-        const r = LibtoolVersion.compare(BANK_INTEGRATION_PROTOCOL_VERSION, 
s.version)
+      .then((result) => {
+        const r = LibtoolVersion.compare(BANK_INTEGRATION_PROTOCOL_VERSION, 
result.version)
         if (r?.compatible) {
-          setChecked(true);
+          setChecked({ type: "ok",result });
         } else {
-          setChecked(s.version)
+          setChecked({ type: "wrong",result })
         }
       })
       .catch((error: unknown) => {
         if (error instanceof RequestError) {
-          setChecked(error.cause);
+          const result = error.cause
+          setChecked({ type:"error", result });
         }
       });
   }, []);
diff --git a/packages/demobank-ui/src/hooks/useCredentialsChecker.ts 
b/packages/demobank-ui/src/hooks/useCredentialsChecker.ts
index f66a4a7c6..02f4544db 100644
--- a/packages/demobank-ui/src/hooks/useCredentialsChecker.ts
+++ b/packages/demobank-ui/src/hooks/useCredentialsChecker.ts
@@ -15,7 +15,7 @@ export function useCredentialsChecker() {
       scope: "readwrite" as "write", //FIX: different than merchant
       duration: {
         // d_us: "forever" //FIX: should return shortest
-        d_us: 1000 * 60 * 60 * 23
+        d_us: 1000 * 1000 * 5 //60 * 60 * 24 * 7
       },
       refreshable: true,
     }
diff --git a/packages/demobank-ui/src/pages/BankFrame.tsx 
b/packages/demobank-ui/src/pages/BankFrame.tsx
index 5c43d2c3e..3d09fcec7 100644
--- a/packages/demobank-ui/src/pages/BankFrame.tsx
+++ b/packages/demobank-ui/src/pages/BankFrame.tsx
@@ -18,7 +18,7 @@ import { Amounts, Logger, PaytoUriIBAN, TranslatedString, 
parsePaytoUri, stringi
 import { notifyError, notifyException, useNotifications, useTranslationContext 
} from "@gnu-taler/web-util/browser";
 import { ComponentChildren, Fragment, h, VNode } from "preact";
 import { StateUpdater, useEffect, useErrorBoundary, useState } from 
"preact/hooks";
-import { LangSelectorLikePy as LangSelector } from 
"../components/LangSelector.js";
+import { LangSelector } from "../components/LangSelector.js";
 import { useBackendContext } from "../context/backend.js";
 import { useBusinessAccountDetails } from "../hooks/circuit.js";
 import { bankUiSettings } from "../settings.js";
@@ -65,12 +65,14 @@ export function BankFrame({
   }, [error])
 
   const demo_sites = [];
-  for (const i in bankUiSettings.demoSites)
-    demo_sites.push(
-      <a href={bankUiSettings.demoSites[i][1]}>
-        {bankUiSettings.demoSites[i][0]}
-      </a>,
-    );
+  if (bankUiSettings.demoSites) {
+    for (const i in bankUiSettings.demoSites)
+      demo_sites.push(
+        <a href={bankUiSettings.demoSites[i][1]}>
+          {bankUiSettings.demoSites[i][0]}
+        </a>,
+      );
+  }
 
   return (<div class="min-h-full flex flex-col m-0" style="min-height: 100vh;">
     <div class="bg-indigo-600 pb-32">
@@ -88,14 +90,16 @@ export function BankFrame({
                   />
                 </a>
               </div>
-              <div class="hidden sm:block lg:ml-10 ">
-                <div class="flex space-x-4">
-                  {/* <!-- Current: "bg-indigo-700 text-white", Default: 
"text-white hover:bg-indigo-500 hover:bg-opacity-75" --> */}
-                  {bankUiSettings.demoSites.map(([name, url]) => {
-                    return <a href={url} class="text-white hover:bg-indigo-500 
hover:bg-opacity-75 rounded-md py-2 px-3 text-sm font-medium">{name}</a>
-                  })}
+              {bankUiSettings.demoSites &&
+                <div class="hidden sm:block lg:ml-10 ">
+                  <div class="flex space-x-4">
+                    {/* <!-- Current: "bg-indigo-700 text-white", Default: 
"text-white hover:bg-indigo-500 hover:bg-opacity-75" --> */}
+                    {bankUiSettings.demoSites.map(([name, url]) => {
+                      return <a href={url} class="text-white 
hover:bg-indigo-500 hover:bg-opacity-75 rounded-md py-2 px-3 text-sm 
font-medium">{name}</a>
+                    })}
+                  </div>
                 </div>
-              </div>
+              }
             </div>
 
             <div class="flex">
@@ -166,26 +170,29 @@ export function BankFrame({
                                 <svg class="h-6 w-6 shrink-0 text-indigo-600" 
fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" 
aria-hidden="true">
                                   <path stroke-linecap="round" 
stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 
0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 
1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 
1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
                                 </svg>
-                                Log out
-                                {/* <span class="ml-auto w-9 min-w-max 
whitespace-nowrap rounded-full bg-gray-50 px-2.5 py-0.5 text-center text-xs 
font-medium leading-5 text-gray-600 ring-1 ring-inset ring-gray-200" 
aria-hidden="true">5</span> */}
+                                <i18n.Translate>Log out</i18n.Translate>
                               </a>
                             </li>
-                            <li class="sm:hidden">
-                              <div class="text-xs font-semibold leading-6 
text-gray-400">
-                                <i18n.Translate>Sites</i18n.Translate>
-                              </div>
-                              <ul role="list" class="-mx-2 mt-2 space-y-1">
-                                {bankUiSettings.demoSites.map(([name, url]) => 
{
-                                  return <li>
-                                    <a href={url} target="_blank" 
rel="noopener noreferrer" class="text-gray-700 hover:text-indigo-600 
hover:bg-gray-100 group flex gap-x-3 rounded-md p-2 text-sm leading-6 
font-semibold">
-                                      <span class="flex h-6 w-6 shrink-0 
items-center justify-center rounded-lg border text-[0.625rem] font-medium 
bg-white text-gray-400 border-gray-200 group-hover:border-indigo-600 
group-hover:text-indigo-600">&gt;</span>
-                                      <span class="truncate">{name}</span>
-                                    </a>
-                                  </li>
-                                })}
-                              </ul>
+                            <li>
+                              <LangSelector />
                             </li>
-
+                            {bankUiSettings.demoSites &&
+                              <li class="sm:hidden">
+                                <div class="text-xs font-semibold leading-6 
text-gray-400">
+                                  <i18n.Translate>Sites</i18n.Translate>
+                                </div>
+                                <ul role="list" class="-mx-2 mt-2 space-y-1">
+                                  {bankUiSettings.demoSites.map(([name, url]) 
=> {
+                                    return <li>
+                                      <a href={url} target="_blank" 
rel="noopener noreferrer" class="text-gray-700 hover:text-indigo-600 
hover:bg-gray-100 group flex gap-x-3 rounded-md p-2 text-sm leading-6 
font-semibold">
+                                        <span class="flex h-6 w-6 shrink-0 
items-center justify-center rounded-lg border text-[0.625rem] font-medium 
bg-white text-gray-400 border-gray-200 group-hover:border-indigo-600 
group-hover:text-indigo-600">&gt;</span>
+                                        <span class="truncate">{name}</span>
+                                      </a>
+                                    </li>
+                                  })}
+                                </ul>
+                              </li>
+                            }
                             <li>
                               <ul role="list" class="space-y-1">
                                 <li class="mt-2">
@@ -291,63 +298,6 @@ export function BankFrame({
     <Footer />
   </div >
 
-    // <Fragment>
-    //   <header
-    //     class="demobar"
-    //     style="display: flex; flex-direction: row; justify-content: 
space-between;"
-    //   >
-    //     <a href="#main" class="skip">{i18n.str`Skip to main content`}</a>
-    //     <div style="max-width: 50em; margin-left: 2em; margin-right: 2em;">
-    //       {maybeDemoContent(
-    //         <p>
-    //           {IS_PUBLIC_ACCOUNT_ENABLED ? (
-    //             <i18n.Translate>
-    //               This part of the demo shows how a bank that supports Taler
-    //               directly would work. In addition to using your own bank
-    //               account, you can also see the transaction history of 
some{" "}
-    //               <a href="/public-accounts">Public Accounts</a>.
-    //             </i18n.Translate>
-    //           ) : (
-    //             <i18n.Translate>
-    //               This part of the demo shows how a bank that supports Taler
-    //               directly would work.
-    //             </i18n.Translate>
-    //           )}
-    //         </p>,
-    //       )}
-    //     </div>
-    //   </header>
-    //   <div style="display:flex; flex-direction: column;" 
class="navcontainer">
-    //     <nav class="demolist">
-    //       {maybeDemoContent(<Fragment>{demo_sites}</Fragment>)}
-    //       {backend.state.status === "loggedIn" ? (
-    //         <Fragment>
-    //           {goToBusinessAccount && !backend.state.isUserAdministrator ? (
-    //             <MaybeBusinessButton
-    //               account={backend.state.username}
-    //               onClick={goToBusinessAccount}
-    //             />
-    //           ) : undefined}
-
-    // <LangSelector />
-
-    //           <a
-    //             href="#"
-    //             class="pure-button logout-button"
-    // onClick={() => {
-    //   backend.logOut();
-    //   updateSettings("currentWithdrawalOperationId", undefined);
-    // }}
-    //           >{i18n.str`Logout`}</a>
-    //         </Fragment>
-    //       ) : undefined}
-    //     </nav>
-    //   </div>
-    //   <section id="main" class="content">
-    //     <StatusBanner />
-    //     {children}
-    //   </section>
-    // </Fragment>
   );
 }
 
@@ -393,7 +343,7 @@ function StatusBanner(): VNode {
               }
               {n.message.debug &&
                 <div class="mt-2 text-sm text-red-700 font-mono break-all">
-                    {n.message.debug}
+                  {n.message.debug}
                 </div>
               }
             </div>
diff --git a/packages/demobank-ui/src/pages/LoginForm.tsx 
b/packages/demobank-ui/src/pages/LoginForm.tsx
index 786399d55..14d261622 100644
--- a/packages/demobank-ui/src/pages/LoginForm.tsx
+++ b/packages/demobank-ui/src/pages/LoginForm.tsx
@@ -30,14 +30,32 @@ import { undefinedIfEmpty } from "../utils.js";
  */
 export function LoginForm({ onRegister }: { onRegister?: () => void }): VNode {
   const backend = useBackendContext();
-  const currentUser = backend.state.status === "loggedIn" ? 
backend.state.username : undefined
+  const currentUser = backend.state.status !== "loggedOut" ? 
backend.state.username : undefined
   const [username, setUsername] = useState<string | undefined>(currentUser);
   const [password, setPassword] = useState<string | undefined>();
   const { i18n } = useTranslationContext();
   const { requestNewLoginToken, refreshLoginToken } = useCredentialsChecker();
 
+
+  /**
+   * Register form may be shown in the initialization step.
+   * If this is an error when usgin the app the registration
+   * callback is not set
+   */
+  const isSessionExpired = !onRegister
+
+  // useEffect(() => {
+  //   if (backend.state.status === "loggedIn") {
+  //     backend.expired()
+  //   }
+  // },[])
   const ref = useRef<HTMLInputElement>(null);
   useEffect(function focusInput() {
+    //FIXME: show invalidate session and allow relogin
+    if (isSessionExpired) {
+      localStorage.removeItem("backend-state");
+      window.location.reload()
+    }
     ref.current?.focus();
   }, []);
   const [busy, setBusy] = useState<Record<string, undefined>>()
@@ -124,13 +142,6 @@ export function LoginForm({ onRegister }: { onRegister?: 
() => void }): VNode {
     setBusy(undefined)
   }
 
-  /**
-   * Register form may be shown in the initialization step.
-   * If this is an error when usgin the app the registration
-   * callback is not set
-   */
-  const isSessionExpired = !onRegister
-
   return (
     <div class="flex min-h-full flex-col justify-center">
 
diff --git a/packages/demobank-ui/src/pages/OperationState/views.tsx 
b/packages/demobank-ui/src/pages/OperationState/views.tsx
index 681a3b94d..93b3694d7 100644
--- a/packages/demobank-ui/src/pages/OperationState/views.tsx
+++ b/packages/demobank-ui/src/pages/OperationState/views.tsx
@@ -14,20 +14,15 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { Amounts, stringifyPaytoUri, stringifyWithdrawUri } from 
"@gnu-taler/taler-util";
+import { stringifyWithdrawUri } from "@gnu-taler/taler-util";
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
-import { Transactions } from "../../components/Transactions/index.js";
-import { PaymentOptions } from "../PaymentOptions.js";
-import { State } from "./index.js";
-import { CopyButton } from "../../components/CopyButton.js";
-import { bankUiSettings } from "../../settings.js";
-import { useBusinessAccountDetails } from "../../hooks/circuit.js";
-import { useSettings } from "../../hooks/settings.js";
+import { Fragment, VNode, h } from "preact";
 import { useEffect, useMemo, useState } from "preact/hooks";
-import { undefinedIfEmpty } from "../../utils.js";
-import { ShowInputErrorLabel } from "../../components/ShowInputErrorLabel.js";
 import { QR } from "../../components/QR.js";
+import { ShowInputErrorLabel } from "../../components/ShowInputErrorLabel.js";
+import { useSettings } from "../../hooks/settings.js";
+import { undefinedIfEmpty } from "../../utils.js";
+import { State } from "./index.js";
 
 export function InvalidPaytoView({ payto, onClose }: State.InvalidPayto) {
   return (
diff --git a/packages/demobank-ui/src/pages/RegistrationPage.tsx 
b/packages/demobank-ui/src/pages/RegistrationPage.tsx
index a2543f977..2e931a144 100644
--- a/packages/demobank-ui/src/pages/RegistrationPage.tsx
+++ b/packages/demobank-ui/src/pages/RegistrationPage.tsx
@@ -49,6 +49,8 @@ export function RegistrationPage({
 }
 
 export const USERNAME_REGEX = /^[a-z][a-zA-Z0-9-]*$/;
+export const PHONE_REGEX = /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$/;
+export const EMAIL_REGEX = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/;
 
 /**
  * Collect and submit registration data.
@@ -58,21 +60,33 @@ function RegistrationForm({ onComplete, onCancel }: { 
onComplete: () => void, on
   const [username, setUsername] = useState<string | undefined>();
   const [name, setName] = useState<string | undefined>();
   const [password, setPassword] = useState<string | undefined>();
+  const [phone, setPhone] = useState<string | undefined>();
+  const [email, setEmail] = useState<string | undefined>();
   const [repeatPassword, setRepeatPassword] = useState<string | undefined>();
-  const {requestNewLoginToken} = useCredentialsChecker()
+  const { requestNewLoginToken } = useCredentialsChecker()
 
   const { register } = useTestingAPI();
   const { i18n } = useTranslationContext();
 
   const errors = undefinedIfEmpty({
-    name: !name
-      ? i18n.str`Missing name`
-      : undefined,
+    // name: !name
+    //   ? i18n.str`Missing name`
+    //   : undefined,
     username: !username
       ? i18n.str`Missing username`
       : !USERNAME_REGEX.test(username)
         ? i18n.str`Use letters and numbers only, and start with a lowercase 
letter`
         : undefined,
+    phone: !phone
+      ? undefined
+      : !PHONE_REGEX.test(phone)
+        ? i18n.str`Use letters and numbers only, and start with a lowercase 
letter`
+        : undefined,
+    email: !email
+      ? undefined
+      : !EMAIL_REGEX.test(email)
+        ? i18n.str`Use letters and numbers only, and start with a lowercase 
letter`
+        : undefined,
     password: !password ? i18n.str`Missing password` : undefined,
     repeatPassword: !repeatPassword
       ? i18n.str`Missing password`
@@ -82,9 +96,9 @@ function RegistrationForm({ onComplete, onCancel }: { 
onComplete: () => void, on
   });
 
   async function doRegistrationStep() {
-    if (!username || !password || !name) return;
+    if (!username || !password) return;
     try {
-      await register({ name, username, password });
+      await register({ name: name ?? "", username, password });
       const resp = await requestNewLoginToken(username, password)
       setUsername(undefined);
       if (resp.valid) {
@@ -167,7 +181,7 @@ function RegistrationForm({ onComplete, onCancel }: { 
onComplete: () => void, on
 
       <div class="flex min-h-full flex-col justify-center">
         <div class="sm:mx-auto sm:w-full sm:max-w-sm">
-          <h2 class="text-center text-2xl font-bold leading-9 tracking-tight 
text-gray-900">{i18n.str`Sign up!`}</h2>
+          <h2 class="text-center text-2xl font-bold leading-9 tracking-tight 
text-gray-900">{i18n.str`Registration form`}</h2>
         </div>
 
         <div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
@@ -178,34 +192,6 @@ function RegistrationForm({ onComplete, onCancel }: { 
onComplete: () => void, on
             autoCapitalize="none"
             autoCorrect="off"
           >
-            <div>
-              <label for="name" class="block text-sm font-medium leading-6 
text-gray-900">
-                <i18n.Translate>Name</i18n.Translate>
-                <b style={{ color: "red" }}> *</b>
-              </label>
-              <div class="mt-2">
-                <input
-                  autoFocus
-                  type="text"
-                  name="name"
-                  id="name"
-                  class="block w-full rounded-md border-0 py-1.5 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"
-                  value={name ?? ""}
-                  enterkeyhint="next"
-                  placeholder="your name"
-                  autocomplete="name"
-                  required
-                  onInput={(e): void => {
-                    setName(e.currentTarget.value);
-                  }}
-                />
-                <ShowInputErrorLabel
-                  message={errors?.name}
-                  isDirty={name !== undefined}
-                />
-              </div>
-            </div>
-
             <div>
               <label for="username" class="block text-sm font-medium leading-6 
text-gray-900">
                 <i18n.Translate>Username</i18n.Translate>
@@ -237,7 +223,7 @@ function RegistrationForm({ onComplete, onCancel }: { 
onComplete: () => void, on
             <div>
               <div class="flex items-center justify-between">
                 <label for="password" class="block text-sm font-medium 
leading-6 text-gray-900">
-                  Password
+                  <i18n.Translate>Password</i18n.Translate>
                   <b style={{ color: "red" }}> *</b>
                 </label>
               </div>
@@ -266,7 +252,7 @@ function RegistrationForm({ onComplete, onCancel }: { 
onComplete: () => void, on
             <div>
               <div class="flex items-center justify-between">
                 <label for="register-repeat" class="block text-sm font-medium 
leading-6 text-gray-900">
-                  Repeat assword
+                  <i18n.Translate>Repeat password</i18n.Translate>
                   <b style={{ color: "red" }}> *</b>
                 </label>
               </div>
@@ -292,6 +278,84 @@ function RegistrationForm({ onComplete, onCancel }: { 
onComplete: () => void, on
               </div>
             </div>
 
+            <div>
+              <label for="name" class="block text-sm font-medium leading-6 
text-gray-900">
+                <i18n.Translate>Name</i18n.Translate>
+              </label>
+              <div class="mt-2">
+                <input
+                  autoFocus
+                  type="text"
+                  name="name"
+                  id="name"
+                  class="block w-full rounded-md border-0 py-1.5 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"
+                  value={name ?? ""}
+                  enterkeyhint="next"
+                  placeholder="your name"
+                  autocomplete="name"
+                  required
+                  onInput={(e): void => {
+                    setName(e.currentTarget.value);
+                  }}
+                />
+                {/* <ShowInputErrorLabel
+                  message={errors?.name}
+                  isDirty={name !== undefined}
+                /> */}
+              </div>
+            </div>
+
+            {/* <div>
+              <label for="phone" class="block text-sm font-medium leading-6 
text-gray-900">
+                <i18n.Translate>Phone</i18n.Translate>
+              </label>
+              <div class="mt-2">
+                <input
+                  autoFocus
+                  type="text"
+                  name="phone"
+                  id="phone"
+                  class="block w-full rounded-md border-0 py-1.5 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"
+                  value={phone ?? ""}
+                  enterkeyhint="next"
+                  placeholder="your phone"
+                  autocomplete="none"
+                  onInput={(e): void => {
+                    setPhone(e.currentTarget.value);
+                  }}
+                />
+                <ShowInputErrorLabel
+                  message={errors?.phone}
+                  isDirty={phone !== undefined}
+                />
+              </div>
+            </div>
+            <div>
+              <label for="email" class="block text-sm font-medium leading-6 
text-gray-900">
+                <i18n.Translate>Email</i18n.Translate>
+              </label>
+              <div class="mt-2">
+                <input
+                  autoFocus
+                  type="text"
+                  name="email"
+                  id="email"
+                  class="block w-full rounded-md border-0 py-1.5 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"
+                  value={email ?? ""}
+                  enterkeyhint="next"
+                  placeholder="your email"
+                  autocomplete="email"
+                  onInput={(e): void => {
+                    setEmail(e.currentTarget.value);
+                  }}
+                />
+                <ShowInputErrorLabel
+                  message={errors?.email}
+                  isDirty={email !== undefined}
+                />
+              </div>
+            </div> */}
+
             <div class="flex w-full justify-between">
               <button type="submit"
                 class="ring-1 ring-gray-600 rounded-md bg-white 
disabled:bg-gray-300 px-3 py-1.5 text-sm font-semibold leading-6 text-black 
shadow-sm hover:bg-white-500 focus-visible:outline focus-visible:outline-2 
focus-visible:outline-offset-2"
diff --git a/packages/demobank-ui/src/pages/admin/Account.tsx 
b/packages/demobank-ui/src/pages/admin/Account.tsx
index 521bc8eb3..676fc43d0 100644
--- a/packages/demobank-ui/src/pages/admin/Account.tsx
+++ b/packages/demobank-ui/src/pages/admin/Account.tsx
@@ -9,7 +9,7 @@ import { Fragment, h, VNode } from "preact";
 export function AdminAccount({ onRegister }: { onRegister: () => void }): 
VNode {
   const { i18n } = useTranslationContext();
   const r = useBackendContext();
-  const account = r.state.status === "loggedIn" ? r.state.username : "admin";
+  const account = r.state.status !== "loggedOut" ? r.state.username : "admin";
   const result = useAccountDetails(account);
 
   if (!result.ok) {
diff --git a/packages/demobank-ui/src/pages/business/Home.tsx 
b/packages/demobank-ui/src/pages/business/Home.tsx
index c9d798082..2945cb65a 100644
--- a/packages/demobank-ui/src/pages/business/Home.tsx
+++ b/packages/demobank-ui/src/pages/business/Home.tsx
@@ -32,7 +32,6 @@ import { Fragment, VNode, h } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import { Cashouts } from "../../components/Cashouts/index.js";
 import { ShowInputErrorLabel } from "../../components/ShowInputErrorLabel.js";
-import { useBackendContext } from "../../context/backend.js";
 import { useAccountDetails } from "../../hooks/access.js";
 import {
   useCashoutDetails,
@@ -46,7 +45,6 @@ import {
   undefinedIfEmpty,
 } from "../../utils.js";
 import { handleNotOkResult } from "../HomePage.js";
-import { LoginForm } from "../LoginForm.js";
 import { Amount } from "../PaytoWireTransferForm.js";
 import { ShowAccountDetails } from "../ShowAccountDetails.js";
 import { UpdateAccountPassword } from "../UpdateAccountPassword.js";
diff --git a/packages/demobank-ui/src/settings.ts 
b/packages/demobank-ui/src/settings.ts
index f33bf07e2..c4b510b30 100644
--- a/packages/demobank-ui/src/settings.ts
+++ b/packages/demobank-ui/src/settings.ts
@@ -15,13 +15,13 @@
  */
 
 export interface BankUiSettings {
-  backendBaseURL: string;
-  allowRegistrations: boolean;
-  showDemoNav: boolean;
-  simplePasswordForRandomAccounts: boolean;
-  allowRandomAccountCreation: boolean;
-  bankName: string;
-  demoSites: [string, string][];
+  backendBaseURL?: string;
+  allowRegistrations?: boolean;
+  showDemoNav?: boolean;
+  simplePasswordForRandomAccounts?: boolean;
+  allowRandomAccountCreation?: boolean;
+  bankName?: string;
+  demoSites?: [string, string][];
 }
 
 /**

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