diff options
Diffstat (limited to 'packages')
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>"{instance}"</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't exist.</p>        <Link href="/">          <h4>Back to Home</h4>  | 
