summaryrefslogtreecommitdiff
path: root/packages/auditor-backoffice-ui/src/ApplicationReadyRoutes.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/auditor-backoffice-ui/src/ApplicationReadyRoutes.tsx')
-rw-r--r--packages/auditor-backoffice-ui/src/ApplicationReadyRoutes.tsx175
1 files changed, 175 insertions, 0 deletions
diff --git a/packages/auditor-backoffice-ui/src/ApplicationReadyRoutes.tsx b/packages/auditor-backoffice-ui/src/ApplicationReadyRoutes.tsx
new file mode 100644
index 000000000..414eee39d
--- /dev/null
+++ b/packages/auditor-backoffice-ui/src/ApplicationReadyRoutes.tsx
@@ -0,0 +1,175 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021-2024 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ 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/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { ErrorType, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { createHashHistory } from "history";
+import { Fragment, VNode, h } from "preact";
+import { Route, Router, route } from "preact-router";
+import { useState } from "preact/hooks";
+import { InstanceRoutes } from "./InstanceRoutes.js";
+import {
+ NotConnectedAppMenu,
+ NotYetReadyAppMenu,
+ NotificationCard,
+} from "./components/menu/index.js";
+import { useBackendContext } from "./context/backend.js";
+import { LoginToken } from "./declaration.js";
+import { useBackendInstancesTestForAdmin } from "./hooks/backend.js";
+import { LoginPage } from "./paths/login/index.js";
+import { Settings } from "./paths/settings/index.js";
+import { INSTANCE_ID_LOOKUP } from "./utils/constants.js";
+
+/**
+ * Check if admin against /management/instances
+ * @returns
+ */
+export function ApplicationReadyRoutes(): VNode {
+ const { i18n } = useTranslationContext();
+ const [unauthorized, setUnauthorized] = useState(false)
+ const {
+ url: backendURL,
+ updateToken,
+ alreadyTriedLogin,
+ } = useBackendContext();
+
+ function updateLoginStatus(token: LoginToken | undefined) {
+ updateToken(token)
+ setUnauthorized(false)
+ }
+
+ const result = useBackendInstancesTestForAdmin();
+
+ const clearTokenAndGoToRoot = () => {
+ route("/");
+ };
+ const [showSettings, setShowSettings] = useState(false)
+ const unauthorizedAdmin = !result.loading
+ && !result.ok
+ && result.type === ErrorType.CLIENT
+ && result.status === HttpStatusCode.Unauthorized;
+
+ if (!alreadyTriedLogin && !result.ok) {
+ return (
+ <Fragment>
+ <NotConnectedAppMenu title="Welcome!" />
+ <LoginPage onConfirm={updateToken} />
+ </Fragment>
+ );
+ }
+
+ if (showSettings) {
+ return <Fragment>
+ <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="UI Settings" onLogout={clearTokenAndGoToRoot} isPasswordOk={false} />
+ <Settings onClose={() => setShowSettings(false)} />
+ </Fragment>
+ }
+
+ if (result.loading) {
+ return <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="Loading..." isPasswordOk={false} />;
+ }
+
+ let admin = result.ok || unauthorizedAdmin;
+ let instanceNameByBackendURL: string | undefined;
+
+ if (!admin) {
+ // * the testing against admin endpoint failed and it's not
+ // an authorization problem
+ // * merchant backend will return this SPA under the main
+ // endpoint or /instance/<id> endpoint
+ // => trying to infer the instance id
+ const path = new URL(backendURL).pathname;
+ const match = INSTANCE_ID_LOOKUP.exec(path);
+ if (!match || !match[1]) {
+ // this should be rare because
+ // query to /config is ok but the URL
+ // does not match our pattern
+ return (
+ <Fragment>
+ <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="Error" onLogout={clearTokenAndGoToRoot} isPasswordOk={false} />
+ <NotificationCard
+ notification={{
+ message: i18n.str`Couldn't access the server.`,
+ description: i18n.str`Could not infer instance id from url ${backendURL}`,
+ type: "ERROR",
+ }}
+ />
+ {/* <ConnectionPage onConfirm={changeBackend} /> */}
+ </Fragment>
+ );
+ }
+
+ instanceNameByBackendURL = match[1];
+ }
+
+ if (unauthorized || unauthorizedAdmin) {
+ return <Fragment>
+ <NotYetReadyAppMenu onShowSettings={() => setShowSettings(true)} title="Login" onLogout={clearTokenAndGoToRoot} isPasswordOk={false} />
+ <NotificationCard
+ notification={{
+ message: i18n.str`Access denied`,
+ description: i18n.str`Check your token is valid`,
+ type: "ERROR",
+ }}
+ />
+ <LoginPage onConfirm={updateLoginStatus} />
+ </Fragment>
+ }
+
+ const history = createHashHistory();
+ return (
+ <Router history={history}>
+ <Route
+ default
+ component={DefaultMainRoute}
+ admin={admin}
+ onUnauthorized={() => setUnauthorized(true)}
+ onLoginPass={() => {
+ setUnauthorized(false)
+ }}
+ instanceNameByBackendURL={instanceNameByBackendURL}
+ />
+ </Router>
+ );
+}
+
+function DefaultMainRoute({
+ instance,
+ admin,
+ onUnauthorized,
+ onLoginPass,
+ instanceNameByBackendURL,
+ url, //from preact-router
+}: any): VNode {
+ const [instanceName, setInstanceName] = useState(
+ instanceNameByBackendURL || instance || "default",
+ );
+
+ return (
+ <InstanceRoutes
+ admin={admin}
+ path={url}
+ onUnauthorized={onUnauthorized}
+ onLoginPass={onLoginPass}
+ id={instanceName}
+ setInstanceName={setInstanceName}
+ />
+ );
+}