/*
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 {
AbsoluteTime,
HttpStatusCode,
TalerCorebankApi,
TalerError,
TalerErrorCode,
TranslatedString,
assertUnreachable,
} from "@gnu-taler/taler-util";
import {
Loading,
LocalNotificationBanner,
notifyInfo,
useLocalNotification,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
import { ErrorLoadingWithDebug } from "../../components/ErrorLoadingWithDebug.js";
import { useBankCoreApiContext } from "../../context/config.js";
import { useAccountDetails } from "../../hooks/account.js";
import { useSessionState } from "../../hooks/session.js";
import { useBankState } from "../../hooks/bank-state.js";
import { RouteDefinition } from "../../route.js";
import { LoginForm } from "../LoginForm.js";
import { ProfileNavigation } from "../ProfileNavigation.js";
import { AccountForm } from "../admin/AccountForm.js";
export function ShowAccountDetails({
account,
routeClose,
onUpdateSuccess,
onAuthorizationRequired,
routeMyAccountCashout,
routeMyAccountDelete,
routeMyAccountDetails,
routeHere,
routeMyAccountPassword,
routeConversionConfig,
}: {
routeClose: RouteDefinition;
routeHere: RouteDefinition<{ account: string }>;
routeMyAccountDetails: RouteDefinition;
routeMyAccountDelete: RouteDefinition;
routeMyAccountPassword: RouteDefinition;
routeMyAccountCashout: RouteDefinition;
routeConversionConfig: RouteDefinition;
onUpdateSuccess: () => void;
onAuthorizationRequired: () => void;
account: string;
}): VNode {
const { i18n } = useTranslationContext();
const { state: credentials } = useSessionState();
const creds = credentials.status !== "loggedIn" ? undefined : credentials;
const { bank: api } = useBankCoreApiContext();
const accountIsTheCurrentUser =
credentials.status === "loggedIn"
? credentials.username === account
: false;
const [submitAccount, setSubmitAccount] = useState<
TalerCorebankApi.AccountReconfiguration | undefined
>();
const [notification, notify, handleError] = useLocalNotification();
const [, updateBankState] = useBankState();
const result = useAccountDetails(account);
if (!result) {
return ;
}
if (result instanceof TalerError) {
return ;
}
if (result.type === "fail") {
switch (result.case) {
case HttpStatusCode.Unauthorized:
case HttpStatusCode.NotFound:
return ;
default:
assertUnreachable(result);
}
}
async function doUpdate() {
if (!submitAccount || !creds) return;
await handleError(async () => {
const resp = await api.updateAccount(
{
token: creds.token,
username: account,
},
submitAccount,
);
if (resp.type === "ok") {
notifyInfo(i18n.str`Account updated`);
onUpdateSuccess();
} else {
switch (resp.case) {
case HttpStatusCode.Unauthorized:
return notify({
type: "error",
title: i18n.str`The rights to change the account are not sufficient`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
case HttpStatusCode.NotFound:
return notify({
type: "error",
title: i18n.str`The username was not found`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
case TalerErrorCode.BANK_NON_ADMIN_PATCH_LEGAL_NAME:
return notify({
type: "error",
title: i18n.str`You can't change the legal name, please contact the your account administrator.`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
case TalerErrorCode.BANK_NON_ADMIN_PATCH_DEBT_LIMIT:
return notify({
type: "error",
title: i18n.str`You can't change the debt limit, please contact the your account administrator.`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
case TalerErrorCode.BANK_NON_ADMIN_PATCH_CASHOUT:
return notify({
type: "error",
title: i18n.str`You can't change the cashout address, please contact the your account administrator.`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
case TalerErrorCode.BANK_MISSING_TAN_INFO:
return notify({
type: "error",
title: i18n.str`No information for the selected authentication channel.`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
case HttpStatusCode.Accepted: {
updateBankState("currentChallenge", {
operation: "update-account",
id: String(resp.body.challenge_id),
location: routeHere.url({ account }),
sent: AbsoluteTime.never(),
request: submitAccount,
});
return onAuthorizationRequired();
}
case TalerErrorCode.BANK_TAN_CHANNEL_NOT_SUPPORTED: {
return notify({
type: "error",
title: i18n.str`Authentication channel is not supported.`,
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
});
}
default:
assertUnreachable(resp);
}
}
});
}
return (
{accountIsTheCurrentUser ? (
) : (
Account "{account}"
)}
);
}