gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 01/08: accesstoken in memory and better login when s


From: gnunet
Subject: [taler-wallet-core] 01/08: accesstoken in memory and better login when switching between accounts
Date: Mon, 07 Aug 2023 13:14:51 +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 37d0f9438e6e6507c46d56324e38a5f0c391ab45
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Fri Aug 4 13:32:08 2023 -0300

    accesstoken in memory and better login when switching between accounts
---
 .../src/components/exception/login.tsx             | 97 ++++++++++++++++++++--
 .../src/components/menu/index.tsx                  |  7 +-
 packages/merchant-backoffice-ui/src/hooks/index.ts | 25 +++---
 .../src/paths/notfound/index.tsx                   |  1 -
 4 files changed, 111 insertions(+), 19 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/components/exception/login.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/login.tsx
index 42c5e89d0..984b6fe06 100644
--- a/packages/merchant-backoffice-ui/src/components/exception/login.tsx
+++ b/packages/merchant-backoffice-ui/src/components/exception/login.tsx
@@ -20,7 +20,7 @@
  */
 
 import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { h, VNode } from "preact";
+import { ComponentChildren, h, VNode } from "preact";
 import { useState } from "preact/hooks";
 import { useBackendContext } from "../../context/backend.js";
 import { useInstanceContext } from "../../context/instance.js";
@@ -40,7 +40,7 @@ function getTokenValuePart(t: string): string {
 }
 
 function normalizeToken(r: string): string {
-  return `secret-token:${encodeURIComponent(r)}`;
+  return `secret-token:${r}`;
 }
 
 function cleanUp(s: string): string {
@@ -53,7 +53,7 @@ function cleanUp(s: string): string {
 
 export function LoginModal({ onConfirm, withMessage }: Props): VNode {
   const { url: backendUrl, token: baseToken } = useBackendContext();
-  const { admin, token: instanceToken } = useInstanceContext();
+  const { admin, token: instanceToken, id } = useInstanceContext();
   const testLogin = useCredentialsChecker();
   const currentToken = getTokenValuePart(
     (!admin ? baseToken : instanceToken) ?? "",
@@ -63,6 +63,78 @@ export function LoginModal({ onConfirm, withMessage }: 
Props): VNode {
   const [url, setURL] = useState(cleanUp(backendUrl));
   const { i18n } = useTranslationContext();
 
+  if (admin && id !== "default") {
+    //admin trying to access another instance
+    return (<div class="columns is-centered" style={{ margin: "auto" }}>
+      <div class="column is-two-thirds ">
+        <div class="modal-card" style={{ width: "100%", margin: 0 }}>
+          <header
+            class="modal-card-head"
+            style={{ border: "1px solid", borderBottom: 0 }}
+          >
+            <p class="modal-card-title">{i18n.str`Login required`}</p>
+          </header>
+          <section
+            class="modal-card-body"
+            style={{ border: "1px solid", borderTop: 0, borderBottom: 0 }}
+          >
+            <p>
+              <i18n.Translate>Need the access token for the 
instance.</i18n.Translate>
+            </p>
+            <div class="field is-horizontal">
+              <div class="field-label is-normal">
+                <label class="label">
+                  <i18n.Translate>Access Token</i18n.Translate>
+                </label>
+              </div>
+              <div class="field-body">
+                <div class="field">
+                  <p class="control is-expanded">
+                    <input
+                      class="input"
+                      type="password"
+                      placeholder={"set new access token"}
+                      name="token"
+                      onKeyPress={(e) =>
+                        e.keyCode === 13
+                          ? onConfirm(url, normalizeToken(token))
+                          : null
+                      }
+                      value={token}
+                      onInput={(e): void => setToken(e?.currentTarget.value)}
+                    />
+                  </p>
+                </div>
+              </div>
+            </div>
+          </section>
+          <footer
+            class="modal-card-foot "
+            style={{
+              justifyContent: "flex-end",
+              border: "1px solid",
+              borderTop: 0,
+            }}
+          >
+            <AsyncButton
+              onClick={async () => {
+                const secretToken = normalizeToken(token);
+                const { valid, cause } = await 
testLogin(`${url}/instances/${id}`, secretToken);
+                if (valid) {
+                  onConfirm(url, secretToken);
+                } else {
+                  onConfirm(url);
+                }
+              }}
+            >
+              <i18n.Translate>Confirm</i18n.Translate>
+            </AsyncButton>
+          </footer>
+        </div>
+      </div>
+    </div>)
+  }
+
   return (
     <div class="columns is-centered" style={{ margin: "auto" }}>
       <div class="column is-two-thirds ">
@@ -137,8 +209,7 @@ export function LoginModal({ onConfirm, withMessage }: 
Props): VNode {
               borderTop: 0,
             }}
           >
-            <button
-              class="button is-info"
+            <AsyncButton
               onClick={async () => {
                 const secretToken = normalizeToken(token);
                 const { valid, cause } = await testLogin(url, secretToken);
@@ -150,10 +221,24 @@ export function LoginModal({ onConfirm, withMessage }: 
Props): VNode {
               }}
             >
               <i18n.Translate>Confirm</i18n.Translate>
-            </button>
+            </AsyncButton>
           </footer>
         </div>
       </div>
     </div>
   );
 }
+
+function AsyncButton({onClick, children}:{onClick: () => Promise<void>, 
children: ComponentChildren}):VNode {
+  const [running, setRunning] = useState(false)
+  return <button class="button is-info" disabled={running} onClick={() => {
+    setRunning(true)
+    onClick().then(() => {
+      setRunning(false)
+    }).catch(() => {
+      setRunning(false)
+    })
+  }}>
+    {children}
+  </button>
+}
diff --git a/packages/merchant-backoffice-ui/src/components/menu/index.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
index 56573b8ca..2beaf6956 100644
--- a/packages/merchant-backoffice-ui/src/components/menu/index.tsx
+++ b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
@@ -130,7 +130,12 @@ export function Menu({
         )}
 
         {mimic && (
-          <nav class="level">
+          <nav class="level" style={{
+            zIndex: 100,
+            position:"fixed",
+            width:"50%",
+            marginLeft: "20%"
+          }}>
             <div class="level-item has-text-centered has-background-warning">
               <p class="is-size-5">
                 You are viewing the instance <b>&quot;{instance}&quot;</b>.{" 
"}
diff --git a/packages/merchant-backoffice-ui/src/hooks/index.ts 
b/packages/merchant-backoffice-ui/src/hooks/index.ts
index 316620cf7..10e77716e 100644
--- a/packages/merchant-backoffice-ui/src/hooks/index.ts
+++ b/packages/merchant-backoffice-ui/src/hooks/index.ts
@@ -21,6 +21,7 @@
 
 import { StateUpdater, useCallback, useState } from "preact/hooks";
 import { ValueOrFunction } from "../utils/types.js";
+import { useMemoryStorage } from "@gnu-taler/web-util/browser";
 
 const calculateRootPath = () => {
   const rootPath =
@@ -52,14 +53,15 @@ export function useBackendURL(
 
 export function useBackendDefaultToken(
   initialValue?: string,
-): [string | undefined, StateUpdater<string | undefined>] {
-  return useLocalStorage("backend-token", initialValue);
+): [string | undefined, ((d:string | undefined) => void)] {
+  const {update, value} = useMemoryStorage(`backend-token`, initialValue)
+  return [value, update];
 }
 
 export function useBackendInstanceToken(
   id: string,
-): [string | undefined, StateUpdater<string | undefined>] {
-  const [token, setToken] = useLocalStorage(`backend-token-${id}`);
+): [string | undefined, ((d:string | undefined) => void)] {
+  const {update:setToken, value:token, reset} = 
useMemoryStorage(`backend-token-${id}`)
   const [defaultToken, defaultSetToken] = useBackendDefaultToken();
 
   // instance named 'default' use the default token
@@ -67,15 +69,16 @@ export function useBackendInstanceToken(
     return [defaultToken, defaultSetToken];
   }
   function updateToken(
-    value:
-      | (string | undefined)
-      | ((s: string | undefined) => string | undefined),
+    value: (string | undefined)
   ): void {
-    setToken((p) => {
-      const toStore = value instanceof Function ? value(p) : value;
-      return toStore;
-    });
+    console.log("seeting token", value)
+    if (value === undefined) {
+      reset()
+    } else {
+      setToken(value)
+    }
   }
+  console.log("token", token)
 
   return [token, updateToken];
 }
diff --git a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
index b58948dbd..061a67025 100644
--- a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
@@ -25,7 +25,6 @@ import { Link } from "preact-router";
 export default function NotFoundPage(): VNode {
   return (
     <div>
-      <h1>Error 404</h1>
       <p>That page doesn&apos;t exist.</p>
       <Link href="/">
         <h4>Back to Home</h4>

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