/*
This file is part of GNU Taler
(C) 2022-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
*/
import {
LocalNotificationBanner,
useLocalNotification,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import {
AccessToken,
HttpStatusCode,
TranslatedString,
assertUnreachable,
} from "@gnu-taler/taler-util";
import { useBankCoreApiContext } from "./context/config.js";
import { useSettingsContext } from "./context/settings.js";
import { useBackendState } from "./hooks/backend.js";
import { AccountPage } from "./pages/AccountPage/index.js";
import { BankFrame } from "./pages/BankFrame.js";
import { DownloadStats } from "./pages/DownloadStats.js";
import { LoginForm } from "./pages/LoginForm.js";
import { PublicHistoriesPage } from "./pages/PublicHistoriesPage.js";
import { RegistrationPage } from "./pages/RegistrationPage.js";
import { SolveChallengePage } from "./pages/SolveChallengePage.js";
import { WireTransfer } from "./pages/WireTransfer.js";
import { WithdrawalOperationPage } from "./pages/WithdrawalOperationPage.js";
import { CashoutListForAccount } from "./pages/account/CashoutListForAccount.js";
import { ShowAccountDetails } from "./pages/account/ShowAccountDetails.js";
import { UpdateAccountPassword } from "./pages/account/UpdateAccountPassword.js";
import { AdminHome } from "./pages/admin/AdminHome.js";
import { CreateNewAccount } from "./pages/admin/CreateNewAccount.js";
import { RemoveAccount } from "./pages/admin/RemoveAccount.js";
import { CreateCashout } from "./pages/business/CreateCashout.js";
import { ShowCashoutDetails } from "./pages/business/ShowCashoutDetails.js";
import { RouteParamsType, urlPattern, useCurrentLocation } from "./route.js";
import { useNavigationContext } from "./context/navigation.js";
import { useEffect } from "preact/hooks";
export function Routing(): VNode {
const backend = useBackendState();
if (backend.state.status === "loggedIn") {
const { isUserAdministrator, username } = backend.state;
return (
);
}
return (
{
backend.logIn({ username, token: token });
}}
/>
);
}
const publicPages = {
login: urlPattern(/\/login/, () => "#/login"),
register: urlPattern(/\/register/, () => "#/register"),
publicAccounts: urlPattern(/\/public-accounts/, () => "#/public-accounts"),
operationDetails: urlPattern<{ wopid: string }>(
/\/operation\/(?[a-zA-Z0-9]+)/,
({ wopid }) => `#/operation/${wopid}`,
),
solveSecondFactor: urlPattern(/\/2fa/, () => "#/2fa"),
};
function PublicRounting({
onLoggedUser,
}: {
onLoggedUser: (username: string, token: AccessToken) => void;
}): VNode {
const settings = useSettingsContext();
const { i18n } = useTranslationContext();
const location = useCurrentLocation(publicPages);
const { navigateTo } = useNavigationContext();
const { api } = useBankCoreApiContext();
const [notification, notify, handleError] = useLocalNotification();
useEffect(() => {
if (location === undefined) {
navigateTo(publicPages.login.url({}));
}
}, [location]);
if (location === undefined) {
return ;
}
async function doAutomaticLogin(username: string, password: string) {
await handleError(async () => {
const resp = await api
.getAuthenticationAPI(username)
.createAccessToken(password, {
scope: "readwrite",
duration: { d_us: "forever" },
refreshable: true,
});
if (resp.type === "ok") {
onLoggedUser(username, resp.body.access_token);
} else {
switch (resp.case) {
case HttpStatusCode.Unauthorized:
return notify({
type: "error",
title: i18n.str`Wrong credentials for "${username}"`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
case HttpStatusCode.NotFound:
return notify({
type: "error",
title: i18n.str`Account not found`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
default:
assertUnreachable(resp);
}
}
});
}
switch (location.name) {
case "login": {
return (