summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-08-04 13:32:08 -0300
committerSebastian <sebasjm@gmail.com>2023-08-07 08:14:43 -0300
commit37d0f9438e6e6507c46d56324e38a5f0c391ab45 (patch)
tree7cf2dfa017e5130ebc07e4692a897cb74a840df8
parent44aeaba7b4d21e518928ca545b114e2a8e8c2a24 (diff)
downloadwallet-core-37d0f9438e6e6507c46d56324e38a5f0c391ab45.tar.gz
wallet-core-37d0f9438e6e6507c46d56324e38a5f0c391ab45.tar.bz2
wallet-core-37d0f9438e6e6507c46d56324e38a5f0c391ab45.zip
accesstoken in memory and better login when switching between accounts
-rw-r--r--packages/merchant-backoffice-ui/src/components/exception/login.tsx97
-rw-r--r--packages/merchant-backoffice-ui/src/components/menu/index.tsx7
-rw-r--r--packages/merchant-backoffice-ui/src/hooks/index.ts25
-rw-r--r--packages/merchant-backoffice-ui/src/paths/notfound/index.tsx1
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>