diff options
Diffstat (limited to 'packages/bank-ui/src/context/config.ts')
-rw-r--r-- | packages/bank-ui/src/context/config.ts | 318 |
1 files changed, 0 insertions, 318 deletions
diff --git a/packages/bank-ui/src/context/config.ts b/packages/bank-ui/src/context/config.ts deleted file mode 100644 index 86b6df5f3..000000000 --- a/packages/bank-ui/src/context/config.ts +++ /dev/null @@ -1,318 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -import { - LibtoolVersion, - ObservableHttpClientLibrary, - TalerAuthenticationHttpClient, - TalerBankConversionCacheEviction, - TalerBankConversionHttpClient, - TalerCoreBankCacheEviction, - TalerCoreBankHttpClient, - TalerCorebankApi, - TalerError, - assertUnreachable, - CacheEvictor, - ObservabilityEvent, -} from "@gnu-taler/taler-util"; -import { - BrowserFetchHttpLib, - ErrorLoading, - useTranslationContext, -} from "@gnu-taler/web-util/browser"; -import { - ComponentChildren, - FunctionComponent, - VNode, - createContext, - h, -} from "preact"; -import { useContext, useEffect, useState } from "preact/hooks"; -import { - revalidateAccountDetails, - revalidatePublicAccounts, - revalidateTransactions, -} from "../hooks/account.js"; -import { - revalidateBusinessAccounts, - revalidateCashouts, - revalidateConversionInfo, -} from "../hooks/regional.js"; - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ - -export type Type = { - url: URL; - config: TalerCorebankApi.Config; - bank: TalerCoreBankHttpClient; - conversion: TalerBankConversionHttpClient; - authenticator: (user: string) => TalerAuthenticationHttpClient; - hints: VersionHint[]; - onBackendActivity: (fn: Listener) => Unsuscriber; - cancelRequest: (eventId: string) => void; -}; - -// FIXME: below -// @ts-expect-error default value to undefined, should it be another thing? -const Context = createContext<Type>(undefined); - -export const useBankCoreApiContext = (): Type => useContext(Context); - -export enum VersionHint { - /** - * when this flag is on, server is running an old version with cashout before implementing 2fa API - */ - CASHOUT_BEFORE_2FA, -} - -const observers = new Array<(e: ObservabilityEvent) => void>(); -type Listener = (e: ObservabilityEvent) => void; -type Unsuscriber = () => void; - -const activity = Object.freeze({ - notify: (data: ObservabilityEvent) => - observers.forEach((observer) => observer(data)), - subscribe: (func: Listener): Unsuscriber => { - observers.push(func); - return () => { - observers.forEach((observer, index) => { - if (observer === func) { - observers.splice(index, 1); - } - }); - }; - }, -}); - -export type ConfigResult = - | undefined - | { type: "ok"; config: TalerCorebankApi.Config; hints: VersionHint[] } - | { type: "incompatible"; result: TalerCorebankApi.Config; supported: string } - | { type: "error"; error: TalerError }; - -export const BankCoreApiProvider = ({ - baseUrl, - children, - frameOnError, -}: { - baseUrl: string; - children: ComponentChildren; - frameOnError: FunctionComponent<{ children: ComponentChildren }>; -}): VNode => { - const [checked, setChecked] = useState<ConfigResult>(); - const { i18n } = useTranslationContext(); - - const { bankClient, conversionClient, authClient, cancelRequest } = - buildApiClient(new URL(baseUrl)); - - useEffect(() => { - bankClient - .getConfig() - .then((resp) => { - if (bankClient.isCompatible(resp.body.version)) { - setChecked({ type: "ok", config: resp.body, hints: [] }); - } else { - // this API supports version 3.0.3 - const compare = LibtoolVersion.compare("3:0:3", resp.body.version); - if (compare?.compatible ?? false) { - setChecked({ - type: "ok", - config: resp.body, - hints: [VersionHint.CASHOUT_BEFORE_2FA], - }); - } else { - setChecked({ - type: "incompatible", - result: resp.body, - supported: bankClient.PROTOCOL_VERSION, - }); - } - } - }) - .catch((error: unknown) => { - if (error instanceof TalerError) { - setChecked({ type: "error", error }); - } - }); - }, []); - - if (checked === undefined) { - return h(frameOnError, { children: h("div", {}, "loading...") }); - } - if (checked.type === "error") { - return h(frameOnError, { - children: h(ErrorLoading, { error: checked.error, showDetail: true }), - }); - } - if (checked.type === "incompatible") { - return h(frameOnError, { - children: h( - "div", - {}, - i18n.str`The bank backend is not supported. Supported version "${checked.supported}", server version "${checked.result.version}"`, - ), - }); - } - const value: Type = { - url: new URL(bankClient.baseUrl), - config: checked.config, - bank: bankClient, - onBackendActivity: activity.subscribe, - conversion: conversionClient, - authenticator: authClient, - cancelRequest, - hints: checked.hints, - }; - return h(Context.Provider, { - value, - children, - }); -}; - -/** - * build http client with cache breaker due to SWR - * @param url - * @returns - */ -function buildApiClient(url: URL) { - const httpFetch = new BrowserFetchHttpLib({ - enableThrottling: true, - requireTls: false, - }); - const httpLib = new ObservableHttpClientLibrary(httpFetch, { - observe(ev) { - activity.notify(ev); - }, - }); - - function cancelRequest(id: string) { - httpLib.cancelRequest(id); - } - - const bankClient = new TalerCoreBankHttpClient( - url.href, - httpLib, - evictBankSwrCache, - ); - const conversionClient = new TalerBankConversionHttpClient( - bankClient.getConversionInfoAPI().href, - httpLib, - evictConversionSwrCache, - ); - const authClient = (user: string) => - new TalerAuthenticationHttpClient( - bankClient.getAuthenticationAPI(user).href, - httpLib, - ); - - return { bankClient, conversionClient, authClient, cancelRequest }; -} - -export const BankCoreApiProviderTesting = ({ - children, - state, - url, -}: { - children: ComponentChildren; - state: TalerCorebankApi.Config; - url: string; -}): VNode => { - const value: Type = { - url: new URL(url), - config: state, - // @ts-expect-error this API is not being used, not really needed - bank: undefined, - hints: [], - }; - - return h(Context.Provider, { - value, - children, - }); -}; - -const evictBankSwrCache: CacheEvictor<TalerCoreBankCacheEviction> = { - async notifySuccess(op) { - switch (op) { - case TalerCoreBankCacheEviction.DELETE_ACCOUNT: { - await Promise.all([ - revalidatePublicAccounts(), - revalidateBusinessAccounts(), - ]); - return; - } - case TalerCoreBankCacheEviction.CREATE_ACCOUNT: { - // admin balance change on new account - await Promise.all([ - revalidateAccountDetails(), - revalidateTransactions(), - revalidatePublicAccounts(), - revalidateBusinessAccounts(), - ]); - return; - } - case TalerCoreBankCacheEviction.UPDATE_ACCOUNT: { - await Promise.all([revalidateAccountDetails()]); - return; - } - case TalerCoreBankCacheEviction.CREATE_TRANSACTION: { - await Promise.all([ - revalidateAccountDetails(), - revalidateTransactions(), - ]); - return; - } - case TalerCoreBankCacheEviction.CONFIRM_WITHDRAWAL: { - await Promise.all([ - revalidateAccountDetails(), - revalidateTransactions(), - ]); - return; - } - case TalerCoreBankCacheEviction.CREATE_CASHOUT: { - await Promise.all([ - revalidateAccountDetails(), - revalidateCashouts(), - revalidateTransactions(), - ]); - return; - } - case TalerCoreBankCacheEviction.UPDATE_PASSWORD: - case TalerCoreBankCacheEviction.ABORT_WITHDRAWAL: - case TalerCoreBankCacheEviction.CREATE_WITHDRAWAL: - return; - default: - assertUnreachable(op); - } - }, -}; - -const evictConversionSwrCache: CacheEvictor<TalerBankConversionCacheEviction> = -{ - async notifySuccess(op) { - switch (op) { - case TalerBankConversionCacheEviction.UPDATE_RATE: { - await revalidateConversionInfo(); - return; - } - default: - assertUnreachable(op); - } - }, -}; |