commit c3281ed8cbf34f4cda4d10f5144c3162632d03f5 parent 75298771d4fd07e5c57cb08480e805469ebf511a Author: Sebastian <sebasjm@taler-systems.com> Date: Fri, 10 Jul 2026 11:21:07 -0300 pretty Diffstat:
95 files changed, 528 insertions(+), 433 deletions(-)
diff --git a/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx b/packages/anastasis-webui/src/pages/home/AuthenticationEditorScreen.tsx @@ -200,8 +200,8 @@ export function AuthenticationEditorScreen(): VNode { label="Proceed anyway" onConfirm={() => reducer.transition("next", {})} > - You have selected fewer than 3 authorization methods. We - recommend that you add at least 3. + You have selected fewer than 3 authorization methods. We recommend + that you add at least 3. </ConfirmModal> ) : null} {authAvailableSet.size === 0 && ( @@ -216,8 +216,8 @@ export function AuthenticationEditorScreen(): VNode { > <p> We have found no Anastasis providers for your chosen country / - currency. You can add providers manually. To add a provider - you must know the provider URL (e.g. https://provider.com) + currency. You can add providers manually. To add a provider you + must know the provider URL (e.g. https://provider.com) </p> <p> <a>Learn more about Anastasis providers</a> @@ -241,8 +241,7 @@ export function AuthenticationEditorScreen(): VNode { </p> {authAvailableSet.size > 0 && ( <p class="block"> - We couldn't find a provider for some of the authorization - methods. + We couldn't find a provider for some of the authorization methods. </p> )} </div> diff --git a/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx b/packages/anastasis-webui/src/pages/home/ChallengeOverviewScreen.tsx @@ -141,8 +141,8 @@ export function ChallengeOverviewScreen(): VNode { </p> ) : ( <p class="block"> - We have found {policiesWithInfo.length} policies. You need to solve all - the challenges from one policy in order to recover your secret. + We have found {policiesWithInfo.length} policies. You need to solve + all the challenges from one policy in order to recover your secret. </p> )} {policiesWithInfo.map((policy, policy_index) => { diff --git a/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx b/packages/anastasis-webui/src/pages/home/ReviewPoliciesScreen.tsx @@ -61,9 +61,9 @@ export function ReviewPoliciesScreen(): VNode { > {policies.length > 0 && ( <p class="block"> - Based on the authorization methods you configured, some - policies have been configured. In order to recover your secret you - have to solve all the challenges of at least one policy. + Based on the authorization methods you configured, some policies have + been configured. In order to recover your secret you have to solve all + the challenges of at least one policy. </p> )} {policies.length < 1 && ( diff --git a/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx b/packages/anastasis-webui/src/pages/home/authMethod/AuthMethodTotpSetup.tsx @@ -65,9 +65,9 @@ export function AuthMethodTotpSetup({ return ( <AnastasisClientFrame hideNav title="Add TOTP authorization"> <p> - For Time-based One-Time Password (TOTP) authorization, you need to set - a name for the TOTP secret. Then, you must scan the generated QR code - with your TOTP App to import the TOTP secret into your TOTP App. + For Time-based One-Time Password (TOTP) authorization, you need to set a + name for the TOTP secret. Then, you must scan the generated QR code with + your TOTP App to import the TOTP secret into your TOTP App. </p> <div class="block"> <TextInput label="TOTP Name" grabFocus bind={[name, setName]} /> diff --git a/packages/challenger-webui/src/components/CheckChallengeIsUpToDate.tsx b/packages/challenger-webui/src/components/CheckChallengeIsUpToDate.tsx @@ -51,7 +51,12 @@ export function CheckChallengeIsUpToDate({ return <Loading />; } if (result instanceof TalerError) { - return <ErrorLoading title={i18n.str`Failed to load the session.`} error={result} />; + return ( + <ErrorLoading + title={i18n.str`Failed to load the session.`} + error={result} + /> + ); } if (result.type === "fail") { diff --git a/packages/challenger-webui/src/pages/AnswerChallenge.tsx b/packages/challenger-webui/src/pages/AnswerChallenge.tsx @@ -185,31 +185,28 @@ export function AnswerChallenge({ } onComplete(); }; - check.onFail = showError( - i18n.str`Failed to solve the challenge.`, - (fail) => { - switch (fail.case) { - case HttpStatusCode.BadRequest: - return i18n.str`The request was not accepted. Try reloading the app.`; - case HttpStatusCode.Forbidden: { - revalidateChallengeSession(); - return i18n.str`Invalid TAN code.`; - } - case HttpStatusCode.NotFound: - return i18n.str`Challenge not found.`; - case HttpStatusCode.NotAcceptable: - return i18n.str`Server templates are missing due to misconfiguration.`; - case HttpStatusCode.TooManyRequests: { - revalidateChallengeSession(); - return i18n.str`There have been too many attempts to send the TAN code.`; - } - case HttpStatusCode.InternalServerError: - return i18n.str`Server is unable to respond due to internal problems.`; - default: - assertUnreachable(fail); + check.onFail = showError(i18n.str`Failed to solve the challenge.`, (fail) => { + switch (fail.case) { + case HttpStatusCode.BadRequest: + return i18n.str`The request was not accepted. Try reloading the app.`; + case HttpStatusCode.Forbidden: { + revalidateChallengeSession(); + return i18n.str`Invalid TAN code.`; } - }, - ); + case HttpStatusCode.NotFound: + return i18n.str`Challenge not found.`; + case HttpStatusCode.NotAcceptable: + return i18n.str`Server templates are missing due to misconfiguration.`; + case HttpStatusCode.TooManyRequests: { + revalidateChallengeSession(); + return i18n.str`There have been too many attempts to send the TAN code.`; + } + case HttpStatusCode.InternalServerError: + return i18n.str`Server is unable to respond due to internal problems.`; + default: + assertUnreachable(fail); + } + }); const cantTryAnymore = lastStatus?.auth_attempts_left === 0; function LastContactSent(): VNode { diff --git a/packages/challenger-webui/src/pages/AskChallenge.tsx b/packages/challenger-webui/src/pages/AskChallenge.tsx @@ -34,7 +34,7 @@ import { useChallengerApiContext, useForm, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; @@ -219,8 +219,8 @@ export function AskChallenge({ ) : ( <p class="mt-2 text-lg leading-8 text-gray-600"> <i18n.Translate> - You will receive a message with a TAN code that must be - provided on the next page. + You will receive a message with a TAN code that must be provided + on the next page. </i18n.Translate> </p> )} diff --git a/packages/challenger-webui/src/pages/Setup.tsx b/packages/challenger-webui/src/pages/Setup.tsx @@ -71,7 +71,7 @@ export function Setup({ ? undefined : [createRFC8959AccessTokenEncoded(password), url], ); - + doStart.onSuccess = (ok, token, redirect_uri) => { start(); const redirect = new URL(window.location.href); @@ -84,14 +84,17 @@ export function Setup({ onCreated(); }; - doStart.onFail = showError(i18n.str`Failed to setup a new challenge.`, (fail) => { - switch (fail.case) { - case HttpStatusCode.NotFound: - return i18n.str`The server doesn't know about this client. Either the URL or the secret is wrong.`; - default: - assertUnreachable(fail.case); - } - }); + doStart.onFail = showError( + i18n.str`Failed to setup a new challenge.`, + (fail) => { + switch (fail.case) { + case HttpStatusCode.NotFound: + return i18n.str`The server doesn't know about this client. Either the URL or the secret is wrong.`; + default: + assertUnreachable(fail.case); + } + }, + ); return ( <Fragment> diff --git a/packages/libeufin-bank-webui/src/Routing.tsx b/packages/libeufin-bank-webui/src/Routing.tsx @@ -31,7 +31,7 @@ import { TalerErrorCode, TokenRequest, assertUnreachable, - createRFC8959AccessTokenEncoded + createRFC8959AccessTokenEncoded, } from "@gnu-taler/taler-util"; import { useEffect } from "preact/hooks"; import { useBankChallengeHandlerContext } from "./context/challenge.js"; diff --git a/packages/libeufin-bank-webui/src/components/Transactions/index.ts b/packages/libeufin-bank-webui/src/components/Transactions/index.ts @@ -14,7 +14,12 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { AbsoluteTime, AmountJson, TalerError, TranslatedString } from "@gnu-taler/taler-util"; +import { + AbsoluteTime, + AmountJson, + TalerError, + TranslatedString, +} from "@gnu-taler/taler-util"; import { ErrorLoading, Loading, diff --git a/packages/libeufin-bank-webui/src/context/challenge.ts b/packages/libeufin-bank-webui/src/context/challenge.ts @@ -18,7 +18,7 @@ import { Challenge, ChallengeRequestResponse, ChallengeResponse, - TranslatedString + TranslatedString, } from "@gnu-taler/taler-util"; import { SafeHandler, @@ -142,4 +142,3 @@ export const BankChallengeHandlerProvider = ({ children, }); }; - diff --git a/packages/libeufin-bank-webui/src/pages/ConversionRateClassDetails.tsx b/packages/libeufin-bank-webui/src/pages/ConversionRateClassDetails.tsx @@ -1069,8 +1069,8 @@ function DeleteConversionClass({ title={i18n.str`Can't remove the conversion rate class`} > <i18n.Translate> - There are some users associated with this class. You need to remove - them first. + There are some users associated with this class. You need to + remove them first. </i18n.Translate> </Attention> ) : ( diff --git a/packages/libeufin-bank-webui/src/pages/NewConversionRateClass.tsx b/packages/libeufin-bank-webui/src/pages/NewConversionRateClass.tsx @@ -50,26 +50,28 @@ export function NewConversionRateClass({ // notifyInfo(i18n.str`Conversion rate class created.`); onCreated(success.conversion_rate_class_id); }; - create.onFail = showError(i18n.str`Failed to create conversion class.`,(fail) => { - switch (fail.case) { - case HttpStatusCode.Unauthorized: - return i18n.str`The rights to change the account are not sufficient`; - case HttpStatusCode.Forbidden: - return i18n.str`Wrong credentials`; - case HttpStatusCode.NotFound: - return i18n.str`Account not found`; - case HttpStatusCode.NotImplemented: - return i18n.str`Not implemented`; - case TalerErrorCode.BANK_NAME_REUSE: - return i18n.str`The name of the conversion is already used.`; - default: - assertUnreachable(fail); - } - }); + create.onFail = showError( + i18n.str`Failed to create conversion class.`, + (fail) => { + switch (fail.case) { + case HttpStatusCode.Unauthorized: + return i18n.str`The rights to change the account are not sufficient`; + case HttpStatusCode.Forbidden: + return i18n.str`Wrong credentials`; + case HttpStatusCode.NotFound: + return i18n.str`Account not found`; + case HttpStatusCode.NotImplemented: + return i18n.str`Not implemented`; + case TalerErrorCode.BANK_NAME_REUSE: + return i18n.str`The name of the conversion is already used.`; + default: + assertUnreachable(fail); + } + }, + ); return ( <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-6 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg"> - <div class="px-4 sm:px-0"> <h2 class="text-base font-semibold leading-7 text-gray-900"> <i18n.Translate>New conversion rate class</i18n.Translate> diff --git a/packages/libeufin-bank-webui/src/pages/OperationState/index.ts b/packages/libeufin-bank-webui/src/pages/OperationState/index.ts @@ -20,7 +20,7 @@ import { TalerCoreBankErrorsByMethod, TalerError, TranslatedString, - TalerWithdrawUri + TalerWithdrawUri, } from "@gnu-taler/taler-util"; import { ErrorLoading, diff --git a/packages/libeufin-bank-webui/src/pages/RegistrationPage.tsx b/packages/libeufin-bank-webui/src/pages/RegistrationPage.tsx @@ -172,7 +172,7 @@ function RegistrationForm({ }, ); - const registerRandom = register.lambda (() => { + const registerRandom = register.lambda(() => { const user = getRandomUsername(); const password = "12345678"; diff --git a/packages/libeufin-bank-webui/src/pages/ShowNotifications.tsx b/packages/libeufin-bank-webui/src/pages/ShowNotifications.tsx @@ -18,5 +18,5 @@ import { Time } from "@gnu-taler/web-util/browser"; import { VNode, h } from "preact"; export function ShowNotifications(): VNode { - return <div>tbd</div> + return <div>tbd</div>; } diff --git a/packages/libeufin-bank-webui/src/pages/WalletWithdrawForm.tsx b/packages/libeufin-bank-webui/src/pages/WalletWithdrawForm.tsx @@ -115,7 +115,7 @@ function OldWithdrawalForm({ start.onSuccess = (success) => { const uri = TalerUris.parse(success.taler_withdraw_uri); if (uri.tag === "error" || uri.value.type !== TalerUriAction.Withdraw) { - return ; + return; // notifyError( // i18n.str`The server replied with an invalid taler://withdraw URI`, // i18n.str`Withdraw URI: ${success.taler_withdraw_uri}`, diff --git a/packages/libeufin-bank-webui/src/pages/WireTransfer.tsx b/packages/libeufin-bank-webui/src/pages/WireTransfer.tsx @@ -60,7 +60,10 @@ export function WireTransfer({ if (result instanceof TalerError) { return ( <Fragment> - <ErrorLoading error={result} title={i18n.str`Failed to load account details.`} /> + <ErrorLoading + error={result} + title={i18n.str`Failed to load account details.`} + /> <LoginForm currentUser={account} /> </Fragment> ); diff --git a/packages/libeufin-bank-webui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/libeufin-bank-webui/src/pages/WithdrawalConfirmationQuestion.tsx @@ -30,7 +30,7 @@ import { RenderAmount, useBankCoreApiContext, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { ComponentChildren, Fragment, VNode, h } from "preact"; import { mutate } from "swr"; @@ -71,7 +71,7 @@ function useComponentState(opid: string) { api.confirmWithdrawalById(creds, {}, opid, { challengeIds, }), - !creds ? undefined : [creds, undefined as string[] | undefined] as const, + !creds ? undefined : ([creds, undefined as string[] | undefined] as const), ); confirm.onSuccess = () => { diff --git a/packages/libeufin-bank-webui/src/pages/account/ShowAccountDetails.tsx b/packages/libeufin-bank-webui/src/pages/account/ShowAccountDetails.tsx @@ -121,7 +121,12 @@ export function ShowAccountDetails({ ) => bank.updateAccount({ username, token }, account, { challengeIds }), !sessionToken || !submitAccount ? undefined - : ([account, sessionToken, submitAccount, undefined as string[] | undefined] as const), + : ([ + account, + sessionToken, + submitAccount, + undefined as string[] | undefined, + ] as const), ); update.onSuccess = (success) => { diff --git a/packages/libeufin-bank-webui/src/pages/admin/AccountForm.tsx b/packages/libeufin-bank-webui/src/pages/admin/AccountForm.tsx @@ -63,6 +63,8 @@ export type AccountFormData = { cashout_payto_uri?: string; email?: string; phone?: string; + // the API changed, it now support having more than one channel + // in the future we want to add support for this tan_channel?: TanChannel | "remove"; }; @@ -113,8 +115,8 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ const defaultValue: AccountFormData = { debit_threshold: Amounts.stringifyValue( template?.debit_threshold ?? - config.default_debit_threshold ?? - `${config.currency}:0`, + config.default_debit_threshold ?? + `${config.currency}:0`, ), isExchange: template?.is_taler_exchange, isPublic: template?.is_public, @@ -290,10 +292,10 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ payto_uri: internalURI, is_public: newForm.isPublic, is_taler_exchange: newForm.isExchange, - tan_channel: - newForm.tan_channel === "remove" + tan_channels: + newForm.tan_channel === undefined || newForm.tan_channel === "remove" ? undefined - : newForm.tan_channel, + : [newForm.tan_channel], }; callback(result); return; @@ -311,8 +313,8 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ debit_threshold: threshold, is_public: newForm.isPublic, name: newForm.name, - tan_channel: - newForm.tan_channel === "remove" ? null : newForm.tan_channel, + tan_channels: + newForm.tan_channel === "remove" || newForm.tan_channel === undefined ? undefined : [newForm.tan_channel], }; callback(result); return; @@ -502,7 +504,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ </div> {!config.supported_tan_channels || - config.supported_tan_channels.length === 0 ? undefined : ( + config.supported_tan_channels.length === 0 ? undefined : ( <div class="sm:col-span-5"> <label class="block text-sm font-medium leading-6 text-gray-900" @@ -513,7 +515,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ <div class="mt-2 max-w-xl text-sm text-gray-500"> <div class="px-4 mt-4 grid grid-cols-1 gap-y-6"> {config.supported_tan_channels.indexOf(TanChannel.EMAIL) === - -1 ? undefined : ( + -1 ? undefined : ( <label onClick={(e) => { if (!hasEmail) return; @@ -571,7 +573,7 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ )} {config.supported_tan_channels.indexOf(TanChannel.SMS) === - -1 ? undefined : ( + -1 ? undefined : ( <label onClick={(e) => { if (!hasPhone) return; @@ -664,9 +666,9 @@ export function AccountForm<PurposeType extends keyof ChangeByPurposeType>({ !editableThreshold ? undefined : (e) => { - form.debit_threshold = e as AmountString; - updateForm(structuredClone(form)); - } + form.debit_threshold = e as AmountString; + updateForm(structuredClone(form)); + } } /> <ShowInputErrorLabel diff --git a/packages/libeufin-bank-webui/src/pages/admin/ConversionClassList.tsx b/packages/libeufin-bank-webui/src/pages/admin/ConversionClassList.tsx @@ -65,7 +65,12 @@ export function ConversionClassList({ return <Loading />; } if (result instanceof TalerError) { - return <ErrorLoading error={result} title={i18n.str`Failed to load conversion rate.`}/>; + return ( + <ErrorLoading + error={result} + title={i18n.str`Failed to load conversion rate.`} + /> + ); } if (result.type !== "ok") { diff --git a/packages/libeufin-bank-webui/src/pages/admin/DownloadStats.tsx b/packages/libeufin-bank-webui/src/pages/admin/DownloadStats.tsx @@ -29,7 +29,7 @@ import { RouteDefinition, useBankCoreApiContext, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { VNode, h } from "preact"; import { useState } from "preact/hooks"; diff --git a/packages/libeufin-bank-webui/src/pages/admin/RemoveAccount.tsx b/packages/libeufin-bank-webui/src/pages/admin/RemoveAccount.tsx @@ -137,7 +137,10 @@ export function RemoveAccount({ api.deleteAccount(auth, { challengeIds }), !!errors || !token ? undefined - : ([{ username: account, token }, undefined as string[] | undefined] as const), + : ([ + { username: account, token }, + undefined as string[] | undefined, + ] as const), ); deleteAccount.onSuccess = (success) => { diff --git a/packages/libeufin-bank-webui/src/pages/regional/ConversionConfig.tsx b/packages/libeufin-bank-webui/src/pages/regional/ConversionConfig.tsx @@ -919,8 +919,8 @@ export function ConversionForm({ <i18n.Translate>Zero</i18n.Translate> </span> <i18n.Translate> - Amount will be rounded below to the largest possible value - smaller than the input. + Amount will be rounded below to the largest possible + value smaller than the input. </i18n.Translate> </span> </span> diff --git a/packages/libeufin-bank-webui/src/pages/regional/ShowCashoutDetails.tsx b/packages/libeufin-bank-webui/src/pages/regional/ShowCashoutDetails.tsx @@ -60,7 +60,12 @@ export function ShowCashoutDetails({ id, routeClose }: Props): VNode { return <Loading />; } if (result instanceof TalerError) { - return <ErrorLoading error={result} title={i18n.str`Failed to load cashout details.`}/>; + return ( + <ErrorLoading + error={result} + title={i18n.str`Failed to load cashout details.`} + /> + ); } if (result.type === "fail") { switch (result.case) { @@ -89,7 +94,12 @@ export function ShowCashoutDetails({ id, routeClose }: Props): VNode { } if (info instanceof TalerError) { - return <ErrorLoading error={info} title={i18n.str`Failed to load conversion rate information.`} />; + return ( + <ErrorLoading + error={info} + title={i18n.str`Failed to load conversion rate information.`} + /> + ); } if (info.type === "fail") { switch (info.case) { diff --git a/packages/taler-exchange-aml-webui/src/components/MeasureList.tsx b/packages/taler-exchange-aml-webui/src/components/MeasureList.tsx @@ -44,7 +44,12 @@ export function MeasureList({ routeToNew }: { routeToNew: RouteDefinition }) { return <Loading />; } if (measures instanceof TalerError) { - return <ErrorLoading title={i18n.str`Failed to load server measures.`} error={measures} />; + return ( + <ErrorLoading + title={i18n.str`Failed to load server measures.`} + error={measures} + /> + ); } if (measures.type === "fail") { diff --git a/packages/taler-exchange-aml-webui/src/pages/AccountDetails.tsx b/packages/taler-exchange-aml-webui/src/pages/AccountDetails.tsx @@ -215,7 +215,7 @@ export function AccountDetails({ (ct, s, ac) => lib.exchange.getAmlAttributesForAccountAsPdf(s, ac), session ? ([session, account] as const) : undefined, ); - + downloadPdf.onSuccess = (result) => { setExported({ content: new Uint8Array(result).reduce( diff --git a/packages/taler-exchange-aml-webui/src/pages/Dashboard.tsx b/packages/taler-exchange-aml-webui/src/pages/Dashboard.tsx @@ -83,7 +83,12 @@ function EventMetrics(): VNode { return <Loading />; } if (resp instanceof TalerError) { - return <ErrorLoading title={i18n.str`Failed to load TOPS statistics.`} error={resp} />; + return ( + <ErrorLoading + title={i18n.str`Failed to load TOPS statistics.`} + error={resp} + /> + ); } return ( diff --git a/packages/taler-exchange-aml-webui/src/pages/ShowCollectedInfo.tsx b/packages/taler-exchange-aml-webui/src/pages/ShowCollectedInfo.tsx @@ -65,37 +65,39 @@ export function ShowCollectedInfo({ ); } if (details.type === "fail") { - return <FailLoading - operation={details} - title={i18n.str`Failed to load the account information.`} - translate={(d) => { - switch (d.case) { - case HttpStatusCode.Forbidden: - return ( - <i18n.Translate> - This session signature is invalid, contact administrator or - create a new one. - </i18n.Translate> - ); - case HttpStatusCode.NotFound: - return ( - <i18n.Translate> - The designated AML session is not known, contact administrator - or create a new one. - </i18n.Translate> - ); - case HttpStatusCode.Conflict: - return ( - <i18n.Translate> - The designated AML session is not enabled, contact administrator - or create a new one. - </i18n.Translate> - ); - default: - assertUnreachable(d.case); - } - }} - />; + return ( + <FailLoading + operation={details} + title={i18n.str`Failed to load the account information.`} + translate={(d) => { + switch (d.case) { + case HttpStatusCode.Forbidden: + return ( + <i18n.Translate> + This session signature is invalid, contact administrator or + create a new one. + </i18n.Translate> + ); + case HttpStatusCode.NotFound: + return ( + <i18n.Translate> + The designated AML session is not known, contact administrator + or create a new one. + </i18n.Translate> + ); + case HttpStatusCode.Conflict: + return ( + <i18n.Translate> + The designated AML session is not enabled, contact + administrator or create a new one. + </i18n.Translate> + ); + default: + assertUnreachable(d.case); + } + }} + /> + ); } const { details: history } = details.body; diff --git a/packages/taler-exchange-aml-webui/src/pages/decision/Rules.tsx b/packages/taler-exchange-aml-webui/src/pages/decision/Rules.tsx @@ -453,8 +453,9 @@ function UpdateRulesForm({ case "missing-bank-rules": { return ( <i18n.Translate> - The AML account is a bank account, but not all account-related - operations are limited ({BANK_RULES.join(",")}). + The AML account is a bank account, but not all + account-related operations are limited ( + {BANK_RULES.join(",")}). </i18n.Translate> ); } diff --git a/packages/taler-exchange-aml-webui/src/pages/decision/Summary.tsx b/packages/taler-exchange-aml-webui/src/pages/decision/Summary.tsx @@ -29,7 +29,7 @@ import { Button, useExchangeApiContext, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; diff --git a/packages/taler-exchange-kyc-webui/src/pages/TriggerForms.tsx b/packages/taler-exchange-kyc-webui/src/pages/TriggerForms.tsx @@ -19,7 +19,7 @@ import { preloadedForms, UIHandlerId, useFormMeta, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; diff --git a/packages/taler-harness/src/integrationtests/test-donau-keychange.ts b/packages/taler-harness/src/integrationtests/test-donau-keychange.ts @@ -53,8 +53,7 @@ export async function runDonauKeychangeTest(t: GlobalTestState) { } = await createSimpleTestkudosEnvironmentV3(t, undefined, { merchantUseDonau: true, walletConfig: { - features: { - }, + features: {}, }, }); diff --git a/packages/taler-harness/src/integrationtests/test-donau-minus-t.ts b/packages/taler-harness/src/integrationtests/test-donau-minus-t.ts @@ -51,8 +51,7 @@ export async function runDonauMinusTTest(t: GlobalTestState) { commonDb, } = await createSimpleTestkudosEnvironmentV3(t, undefined, { walletConfig: { - features: { - }, + features: {}, }, }); diff --git a/packages/taler-harness/src/integrationtests/test-donau-multi.ts b/packages/taler-harness/src/integrationtests/test-donau-multi.ts @@ -57,8 +57,7 @@ export async function runDonauMultiTest(t: GlobalTestState) { } = await createSimpleTestkudosEnvironmentV3(t, undefined, { merchantUseDonau: true, walletConfig: { - features: { - }, + features: {}, }, }); diff --git a/packages/taler-harness/src/integrationtests/test-donau.ts b/packages/taler-harness/src/integrationtests/test-donau.ts @@ -53,8 +53,7 @@ export async function runDonauTest(t: GlobalTestState) { } = await createSimpleTestkudosEnvironmentV3(t, undefined, { merchantUseDonau: true, walletConfig: { - features: { - }, + features: {}, }, }); diff --git a/packages/taler-harness/src/integrationtests/test-kyc-new-measure.ts b/packages/taler-harness/src/integrationtests/test-kyc-new-measure.ts @@ -91,7 +91,11 @@ export async function runKycNewMeasureTest(t: GlobalTestState) { config.setString("AML-PROGRAM-P2", "fallback", "FREEZE"); config.setString("KYC-CHECK-C1", "type", "FORM"); - config.setString("KYC-CHECK-C1", "form_name", "full_name_and_birthdate"); + config.setString( + "KYC-CHECK-C1", + "form_name", + "full_name_and_birthdate", + ); config.setString("KYC-CHECK-C1", "description", "my check!"); config.setString("KYC-CHECK-C1", "description_i18n", "{}"); config.setString("KYC-CHECK-C1", "outputs", "FULL_NAME DATE_OF_BIRTH"); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-tokenfamilies.ts b/packages/taler-harness/src/integrationtests/test-merchant-tokenfamilies.ts @@ -51,8 +51,7 @@ export async function runMerchantTokenfamiliesTest(t: GlobalTestState) { defaultCoinConfig.map((x) => x("TESTKUDOS")), { walletConfig: { - features: { - }, + features: {}, }, }, ); diff --git a/packages/taler-harness/src/integrationtests/test-tops-merchant-swt-kycauth.ts b/packages/taler-harness/src/integrationtests/test-tops-merchant-swt-kycauth.ts @@ -45,7 +45,7 @@ const logger = new Logger("test-tops-merchant-kycauths.ts"); * Test short wire transfers in an exchange setup that simulates * the Taler Operations CH exchange, using libeufin-nexus * as the taler wire gateway API. - * + * * This test exercises the .../kycauths endpoint of the merchant backend. */ export async function runTopsMerchantSwtKycauthTest(t: GlobalTestState) { diff --git a/packages/taler-harness/src/integrationtests/test-wallet-tokens-discount.ts b/packages/taler-harness/src/integrationtests/test-wallet-tokens-discount.ts @@ -53,8 +53,7 @@ export async function runWalletTokensDiscountTest(t: GlobalTestState) { defaultCoinConfig.map((x) => x("TESTKUDOS")), { walletConfig: { - features: { - }, + features: {}, }, }, ); diff --git a/packages/taler-merchant-webui/src/Routing.tsx b/packages/taler-merchant-webui/src/Routing.tsx @@ -29,7 +29,7 @@ import { ToastBannerBulma, urlPattern, useRenderErrorReport, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { createHashHistory } from "history"; import { Fragment, VNode, h } from "preact"; @@ -195,7 +195,10 @@ export function Routing(_p: Props): VNode { const { state, config } = useSessionContext(); const { i18n } = useTranslationContext(); - const failed = useRenderErrorReport({ version: __VERSION__, hash: __GIT_HASH__ }); + const failed = useRenderErrorReport({ + version: __VERSION__, + hash: __GIT_HASH__, + }); const [preference] = usePreference(); const now = AbsoluteTime.now(); @@ -230,7 +233,7 @@ export function Routing(_p: Props): VNode { const shouldLogin = state.status === "loggedOut" || unauthorized; if (failed) { - return <NotConnectedAppMenu title={i18n.str`Error`} /> + return <NotConnectedAppMenu title={i18n.str`Error`} />; } if (shouldLogin) { return ( @@ -960,4 +963,3 @@ function KycBanner(): VNode { /> ); } - diff --git a/packages/taler-merchant-webui/src/components/form/InputArray.tsx b/packages/taler-merchant-webui/src/components/form/InputArray.tsx @@ -65,19 +65,16 @@ export function InputArray<T>({ >([]); const { i18n } = useTranslationContext(); - type Info = Record<string, number> - const info: Info = (array).reduce( - (prev, cur) => { - const id = toStr(cur) - if (prev[id] === undefined) { - prev[id] = 0; - } - prev[id] += 1; - return prev; - }, - {} as Info, - ); - const toRender = !unique ? (array.map(a => toStr(a))) : Object.keys(info); + type Info = Record<string, number>; + const info: Info = array.reduce((prev, cur) => { + const id = toStr(cur); + if (prev[id] === undefined) { + prev[id] = 0; + } + prev[id] += 1; + return prev; + }, {} as Info); + const toRender = !unique ? array.map((a) => toStr(a)) : Object.keys(info); return ( <div class="field is-horizontal"> @@ -159,9 +156,8 @@ export function InputArray<T>({ list={suggestions} onSelect={(p): void => { const alreadyExist = - (array as Array<string>).findIndex( - (c) => c === p.id, - ) !== -1; + (array as Array<string>).findIndex((c) => c === p.id) !== + -1; if (!unique || !alreadyExist) { onChange([fromStr(p.id), ...array] as T[keyof T]); } @@ -177,7 +173,7 @@ export function InputArray<T>({ <a class="tag is-medium is-danger is-delete mb-0" onClick={() => { - onChange(array.filter((f) => toStr(f) !== (v)) as T[keyof T]); + onChange(array.filter((f) => toStr(f) !== v) as T[keyof T]); }} /> <span @@ -191,12 +187,12 @@ export function InputArray<T>({ <a class="tag is-medium mb-0" onClick={() => { - const idx = array.findIndex((f) => toStr(f) === (v)); - console.log("minus", v, array, idx) + const idx = array.findIndex((f) => toStr(f) === v); + console.log("minus", v, array, idx); if (idx === -1) return; - const narray = [...array] + const narray = [...array]; narray.splice(idx, 1); - onChange(narray as T[keyof T]) + onChange(narray as T[keyof T]); }} > <i class="icon mdi mdi-minus" /> @@ -204,7 +200,7 @@ export function InputArray<T>({ <a class="tag is-medium mb-0" onClick={() => { - const ns = [fromStr(v), ...array] as T[keyof T] + const ns = [fromStr(v), ...array] as T[keyof T]; onChange(ns); }} > diff --git a/packages/taler-merchant-webui/src/components/form/InputWithAddon.tsx b/packages/taler-merchant-webui/src/components/form/InputWithAddon.tsx @@ -99,9 +99,7 @@ export function InputWithAddon<T>({ <a class="button is-static">{addonBefore}</a> </div> )} - <p - class={`control${expand ? " is-expanded" : ""}`} - > + <p class={`control${expand ? " is-expanded" : ""}`}> <fieldset> <InternalTextInputSwitch {...(inputExtra || {})} diff --git a/packages/taler-merchant-webui/src/components/modal/index.tsx b/packages/taler-merchant-webui/src/components/modal/index.tsx @@ -572,10 +572,18 @@ export function ValidBankAccount({ </td> </tr> {instructions.subject.type === "CH_QR_BILL" ? ( - <Row name={i18n.str`Reference`} value={instructions.subject.qr_reference_number} literal /> + <Row + name={i18n.str`Reference`} + value={instructions.subject.qr_reference_number} + literal + /> ) : undefined} {instructions.subject.type === "SIMPLE" ? ( - <Row name={i18n.str`Subject`} value={instructions.subject.subject} literal /> + <Row + name={i18n.str`Subject`} + value={instructions.subject.subject} + literal + /> ) : undefined} {receiverPostalCode ? ( <Row diff --git a/packages/taler-merchant-webui/src/context/challenge.ts b/packages/taler-merchant-webui/src/context/challenge.ts @@ -60,7 +60,10 @@ export type ChallengeState = { loadingFirstChallenge: boolean; title: TranslatedString; retry: SafeHandler<[string[]], any>; - initial?: { currentChallengeIndex: number; response?: ChallengeRequestResponse }; + initial?: { + currentChallengeIndex: number; + response?: ChallengeRequestResponse; + }; }; // FIXME: practically the same as BankChallengeHandlerProvider but we cant // reuse it because it ask for username diff --git a/packages/taler-merchant-webui/src/paths/admin/create/CreatePage.tsx b/packages/taler-merchant-webui/src/paths/admin/create/CreatePage.tsx @@ -233,7 +233,7 @@ export function CreatePage({ onConfirm, onBack, forceId }: Props): VNode { case HttpStatusCode.Forbidden: return i18n.str`forbidden`; case HttpStatusCode.PayloadTooLarge: - return i18n.str`payload too large` + return i18n.str`payload too large`; default: assertUnreachable(fail); } diff --git a/packages/taler-merchant-webui/src/paths/instance/accessTokens/create-pos/CreatePage.tsx b/packages/taler-merchant-webui/src/paths/instance/accessTokens/create-pos/CreatePage.tsx @@ -106,7 +106,7 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { i18n.str`New access token`, fail.body, create.lambda((prev, [ids]) => - !prev ? undefined : [prev[0], prev[1], ids], + !prev ? undefined : [prev[0], prev[1], ids], ), ); return undefined; @@ -119,7 +119,7 @@ export function CreatePage({ onCreated, onBack }: Props): VNode { case HttpStatusCode.Forbidden: return i18n.str`forbidden`; case HttpStatusCode.PayloadTooLarge: - return i18n.str`payload too large` + return i18n.str`payload too large`; default: assertUnreachable(fail); } diff --git a/packages/taler-merchant-webui/src/paths/instance/accounts/update/UpdatePage.tsx b/packages/taler-merchant-webui/src/paths/instance/accounts/update/UpdatePage.tsx @@ -34,7 +34,7 @@ import { dummyHttpResponse } from "@gnu-taler/taler-util/http"; import { Button, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; diff --git a/packages/taler-merchant-webui/src/paths/instance/orders/create/CreatePage.tsx b/packages/taler-merchant-webui/src/paths/instance/orders/create/CreatePage.tsx @@ -35,14 +35,14 @@ import { TalerErrorCode, TalerMerchantApi, TalerProtocolDuration, - assertUnreachable + assertUnreachable, } from "@gnu-taler/taler-util"; import { Button, RenderAmountBulma, simpleSafeHandler, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { format, isFuture } from "date-fns"; import { Fragment, VNode, h } from "preact"; @@ -62,9 +62,7 @@ import { InputLocation } from "../../../../components/form/InputLocation.js"; import { InputNumber } from "../../../../components/form/InputNumber.js"; import { InputToggle } from "../../../../components/form/InputToggle.js"; import { FragmentPersonaFlag } from "../../../../components/menu/SideBar.js"; -import { - ConfirmModal -} from "../../../../components/modal/index.js"; +import { ConfirmModal } from "../../../../components/modal/index.js"; import { InventoryProductForm } from "../../../../components/product/InventoryProductForm.js"; import { NonInventoryProductFrom } from "../../../../components/product/NonInventoryProductForm.js"; import { ProductList } from "../../../../components/product/ProductList.js"; @@ -341,7 +339,7 @@ export function CreatePage({ ...orderCommons, }; - const orderInfo: TalerMerchantApi.Order | undefined = orderV0 ?? orderV1 + const orderInfo: TalerMerchantApi.Order | undefined = orderV0 ?? orderV1; const request: undefined | TalerMerchantApi.PostOrderRequest = !orderInfo || !value.payments diff --git a/packages/taler-merchant-webui/src/paths/instance/orders/list/Table.tsx b/packages/taler-merchant-webui/src/paths/instance/orders/list/Table.tsx @@ -464,7 +464,7 @@ export function RefundModal({ onCancel={onCancel} confirm={{ handler: refund, - label: i18n.str`Confirm` + label: i18n.str`Confirm`, }} > {refunds.length > 0 && ( diff --git a/packages/taler-merchant-webui/src/paths/instance/otp_devices/create/index.tsx b/packages/taler-merchant-webui/src/paths/instance/otp_devices/create/index.tsx @@ -20,9 +20,7 @@ */ import { TalerMerchantApi } from "@gnu-taler/taler-util"; -import { - useTranslationContext, -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { useSessionContext } from "../../../../context/session.js"; diff --git a/packages/taler-merchant-webui/src/paths/instance/otp_devices/list/index.tsx b/packages/taler-merchant-webui/src/paths/instance/otp_devices/list/index.tsx @@ -25,9 +25,7 @@ import { TalerMerchantApi, assertUnreachable, } from "@gnu-taler/taler-util"; -import { - useTranslationContext, -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; import { Loading } from "../../../../components/exception/loading.js"; diff --git a/packages/taler-merchant-webui/src/paths/instance/otp_devices/update/index.tsx b/packages/taler-merchant-webui/src/paths/instance/otp_devices/update/index.tsx @@ -25,9 +25,7 @@ import { TalerMerchantApi, assertUnreachable, } from "@gnu-taler/taler-util"; -import { - useTranslationContext, -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; diff --git a/packages/taler-merchant-webui/src/paths/instance/password/index.tsx b/packages/taler-merchant-webui/src/paths/instance/password/index.tsx @@ -47,7 +47,7 @@ export interface Props { onCancel: () => void; } -const emptyList: string[] = [] +const emptyList: string[] = []; export default function PasswordPage({ onCancel, onChange }: Props): VNode { const { actionHandler, showError } = useNotificationContext(); const { state: session, lib } = useSessionContext(); diff --git a/packages/taler-merchant-webui/src/paths/instance/pots/create/CreatePage.tsx b/packages/taler-merchant-webui/src/paths/instance/pots/create/CreatePage.tsx @@ -27,7 +27,7 @@ import { import { Button, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; diff --git a/packages/taler-merchant-webui/src/paths/instance/templates/use/index.tsx b/packages/taler-merchant-webui/src/paths/instance/templates/use/index.tsx @@ -25,9 +25,7 @@ import { TalerMerchantApi, assertUnreachable, } from "@gnu-taler/taler-util"; -import { - useTranslationContext, -} from "@gnu-taler/web-util/browser"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js"; import { Loading } from "../../../../components/exception/loading.js"; diff --git a/packages/taler-merchant-webui/src/paths/instance/transfers/list/DetailsPage.tsx b/packages/taler-merchant-webui/src/paths/instance/transfers/list/DetailsPage.tsx @@ -225,7 +225,6 @@ function DetailsPageInternal({ </div> <div class="buttons is-right mt-5"> - <Button class="button is-success" submit onClick={confirm}> <i18n.Translate>I have received the wire transfer</i18n.Translate> </Button> diff --git a/packages/taler-merchant-webui/src/paths/instance/webhooks/list/Table.tsx b/packages/taler-merchant-webui/src/paths/instance/webhooks/list/Table.tsx @@ -30,7 +30,7 @@ import { PaginationControl, SafeHandler, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { StateUpdater, useState } from "preact/hooks"; diff --git a/packages/taler-merchant-webui/src/paths/login/index.tsx b/packages/taler-merchant-webui/src/paths/login/index.tsx @@ -33,7 +33,7 @@ import { Button, undefinedIfEmpty, useNotificationContext, - useTranslationContext + useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, h, VNode } from "preact"; import { useMemo, useState } from "preact/hooks"; diff --git a/packages/taler-merchant-webui/src/paths/resetAccount/index.tsx b/packages/taler-merchant-webui/src/paths/resetAccount/index.tsx @@ -53,7 +53,7 @@ interface Props { focus?: boolean; } -const emptyList: string[] = [] +const emptyList: string[] = []; export function ResetAccount({ onCancel, @@ -98,7 +98,7 @@ export function ResetAccount({ const pwd = useMemo(() => asPassword(value.password!), [value.password]); /** * Login after reset cant be implemented. - * + * * See https://bugs.gnunet.org/view.php?id=10401#c27223 */ const reset = actionHandler( @@ -110,7 +110,7 @@ export function ResetAccount({ { challengeIds }, ); // if (forgot.type !== "ok") { - return forgot; + return forgot; // } // const resp = await api.createAccessToken( // usr, @@ -120,9 +120,7 @@ export function ResetAccount({ // ); // return resp; }, - hasErrors - ? undefined - : ([instanceId, pwd, emptyList] as const), + hasErrors ? undefined : ([instanceId, pwd, emptyList] as const), ); reset.onSuccess = (suc) => { // logIn(instanceId, suc.access_token); diff --git a/packages/taler-merchant-webui/src/scss/main.scss b/packages/taler-merchant-webui/src/scss/main.scss @@ -233,7 +233,7 @@ div.buttons.is-right { div.menu.is-menu-main a { display: flex; } -button.button.is-success[data-failed="true"]{ +button.button.is-success[data-failed="true"] { background-color: #f14668; border-color: #f14668; -} -\ No newline at end of file +} diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts @@ -390,7 +390,7 @@ export class TalerCoreBankHttpClient { codecForChallengeResponse(), ); case HttpStatusCode.NoContent: - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -444,7 +444,7 @@ export class TalerCoreBankHttpClient { await this.cacheEvictor.notifySuccess( TalerCoreBankCacheEviction.UPDATE_ACCOUNT, ); - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.NotFound: @@ -508,7 +508,7 @@ export class TalerCoreBankHttpClient { codecForChallengeResponse(), ); case HttpStatusCode.NoContent: - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Unauthorized: @@ -835,7 +835,7 @@ export class TalerCoreBankHttpClient { await this.cacheEvictor.notifySuccess( TalerCoreBankCacheEviction.CONFIRM_WITHDRAWAL, ); - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); //FIXME: missing in docs case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); @@ -883,7 +883,7 @@ export class TalerCoreBankHttpClient { await this.cacheEvictor.notifySuccess( TalerCoreBankCacheEviction.ABORT_WITHDRAWAL, ); - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); //FIXME: missing in docs case HttpStatusCode.BadRequest: return opKnownHttpFailure(resp.status, resp); @@ -1156,7 +1156,7 @@ export class TalerCoreBankHttpClient { await this.cacheEvictor.notifySuccess( TalerCoreBankCacheEviction.UPDATE_CONVERSION_RATE_CLASS, ); - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Forbidden: @@ -1197,7 +1197,7 @@ export class TalerCoreBankHttpClient { await this.cacheEvictor.notifySuccess( TalerCoreBankCacheEviction.DELETE_CONVERSION_RATE_CLASS, ); - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Forbidden: @@ -1344,7 +1344,7 @@ export class TalerCoreBankHttpClient { }); switch (resp.status) { case HttpStatusCode.NoContent: - return opEmptySuccess(resp, ); + return opEmptySuccess(resp); case HttpStatusCode.Unauthorized: return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Conflict: { diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts @@ -966,7 +966,8 @@ export class TalerMerchantInstanceHttpClient { if (token) { headers.Authorization = makeBearerTokenAuthHeader(token); } - const cancellationToken = params.cancellationToken ?? this.cancellationToken; + const cancellationToken = + params.cancellationToken ?? this.cancellationToken; const resp = await this.httpLib.fetch(url.href, { method: "GET", headers, @@ -1857,7 +1858,8 @@ export class TalerMerchantInstanceHttpClient { if (token) { headers.Authorization = makeBearerTokenAuthHeader(token); } - const cancellationToken = params.cancellationToken ?? this.cancellationToken; + const cancellationToken = + params.cancellationToken ?? this.cancellationToken; const resp = await this.httpLib.fetch(url.href, { method: "GET", headers, diff --git a/packages/taler-util/src/operation.ts b/packages/taler-util/src/operation.ts @@ -79,7 +79,7 @@ export interface OperationFail<T> { detail?: TalerErrorDetail; - extra?: {}, + extra?: {}; } /** @@ -219,7 +219,7 @@ export async function opKnownHttpFailure<T extends HttpStatusCode>( extra: { requestUrl: resp.requestUrl, requestMethod: resp.requestMethod, - } + }, }; } diff --git a/packages/taler-util/src/result.ts b/packages/taler-util/src/result.ts @@ -45,7 +45,9 @@ export const Result = { }, unpack<T, Err>(r: Result<T, Err>): T { if (r.tag !== "ok") { - throw Error(`expected success, code: ${r.error} - ` + JSON.stringify(r.detail)); + throw Error( + `expected success, code: ${r.error} - ` + JSON.stringify(r.detail), + ); } return r.value; }, diff --git a/packages/taler-util/src/taleruris.test.ts b/packages/taler-util/src/taleruris.test.ts @@ -280,12 +280,11 @@ test("taler-new peer to peer push URI", (t) => { test("taler-new peer to peer push URI, merge_priv is mandatory", (t) => { const url1 = "taler://pay-push/exch.example.com/"; // const r1 = parsePayPushUri(url1); - assert.throws(() => { - Result.unpack(TalerUris.parse(url1)) - }); - return; - } -); + assert.throws(() => { + Result.unpack(TalerUris.parse(url1)); + }); + return; +}); test("taler-new peer to peer push URI (path)", (t) => { const url1 = "taler://pay-push/exch.example.com:123/bla/foo"; @@ -347,12 +346,11 @@ test("taler-new peer to peer pull URI", (t) => { test("taler-new peer to peer pull URI, contract_priv is mandatory", (t) => { const url1 = "taler://pay-pull/exch.example.com/"; // const r1 = parsePayPushUri(url1); - assert.throws(() => { - Result.unpack(TalerUris.parse(url1)) - }); - return; - } -); + assert.throws(() => { + Result.unpack(TalerUris.parse(url1)); + }); + return; +}); test("taler-new peer to peer pull URI (path)", (t) => { const url1 = "taler://pay-pull/exch.example.com:123/bla/foo"; @@ -555,10 +553,7 @@ test("taler-new withdraw exchange URI (parse)", (t) => { { const url1 = "taler://withdraw-exchange/exchange.demo.taler.net/someroot/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A2"; - failOrThrow( - TalerUris.parse(url1), - TalerUriParseError.INVALID_TARGET_PATH, - ); + failOrThrow(TalerUris.parse(url1), TalerUriParseError.INVALID_TARGET_PATH); // if (r1.type !== TalerUriAction.WithdrawExchange) { // assert.fail(); @@ -568,10 +563,7 @@ test("taler-new withdraw exchange URI (parse)", (t) => { { const url1 = "taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0"; - failOrThrow( - TalerUris.parse(url1), - TalerUriParseError.INVALID_TARGET_PATH, - ); + failOrThrow(TalerUris.parse(url1), TalerUriParseError.INVALID_TARGET_PATH); } // Now test well-formed URIs diff --git a/packages/taler-util/src/types-taler-common.ts b/packages/taler-util/src/types-taler-common.ts @@ -522,7 +522,7 @@ declare const opaque_OfficerSigningKey: unique symbol; export interface OfficerSession { id: OfficerId; /** - * Double __ to prevent accidentally + * Double __ to prevent accidentally * printing when serializing into JSON */ __signingKey: EddsaPrivP; @@ -531,7 +531,7 @@ export interface OfficerSession { export interface ReserveAccount { id: EddsaPublicKeyString; /** - * Double __ to prevent accidentally + * Double __ to prevent accidentally * printing when serializing into JSON */ __signingKey: EddsaPrivP; diff --git a/packages/taler-util/src/types-taler-corebank.ts b/packages/taler-util/src/types-taler-corebank.ts @@ -304,10 +304,11 @@ export interface RegisterAccountRequest { // @since **v9** conversion_rate_class_id?: Integer; - // If present, enables 2FA and set the TAN channel used for challenges + // If present, enables 2FA and set the TAN channels used for challenges // Only admin can set this property, other user can reconfig their account // after creation. - tan_channel?: TanChannel; + // @since **v10** + tan_channels?: TanChannel[]; // @deprecated in **v9**, use conversion_rate_class_id instead // min_cashout?: Amount; @@ -356,11 +357,11 @@ export interface AccountReconfiguration { // @since **v9** conversion_rate_class_id?: Integer | null; - // If present, enables 2FA and set the TAN channel used for challenges - tan_channel?: TanChannel | null; + // If present and not empty, enables 2FA and set the TAN channels used for challenges + // Sending null or an empty array will disable 2FA + // @since **v10** + tan_channels?: TanChannel[] | null; - // @deprecated in **v9**, user conversion rate classes instead - // min_cashout?: Amount; } export interface AccountPasswordChange { diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts @@ -415,8 +415,7 @@ async function createLocalWallet( checkEnvFlag("TALER_WALLET_STATS"), skipDefaults: walletCliArgs.wallet.skipDefaults, }, - features: { - }, + features: {}, }, } satisfies InitRequest, ); diff --git a/packages/taler-wallet-core/src/crypto/cryptoTypes.ts b/packages/taler-wallet-core/src/crypto/cryptoTypes.ts @@ -390,11 +390,11 @@ export interface SignReservePurseCreateResponse { export interface SignPreparedTransferRegisterRequest { credit_account: string; - credit_amount: AmountString, - type: 'reserve' | 'kyc', - recurrent: boolean, - alg: 'EdDSA' - account_pub: string + credit_amount: AmountString; + type: "reserve" | "kyc"; + recurrent: boolean; + alg: "EdDSA"; + account_pub: string; authorization_priv: string; } diff --git a/packages/taler-wallet-core/src/recoup.ts b/packages/taler-wallet-core/src/recoup.ts @@ -439,19 +439,27 @@ export class RecoupTransactionContext implements TransactionContext { } userAbortTransaction(): Promise<void> { - throw new Error("Method not implemented RecoupTransactionContext.userAbortTransaction"); + throw new Error( + "Method not implemented RecoupTransactionContext.userAbortTransaction", + ); } userSuspendTransaction(): Promise<void> { - throw new Error("Method not implemented RecoupTransactionContext.userSuspendTransaction"); + throw new Error( + "Method not implemented RecoupTransactionContext.userSuspendTransaction", + ); } userResumeTransaction(): Promise<void> { - throw new Error("Method not implemented RecoupTransactionContext.userResumeTransaction"); + throw new Error( + "Method not implemented RecoupTransactionContext.userResumeTransaction", + ); } userFailTransaction(): Promise<void> { - throw new Error("Method not implemented RecoupTransactionContext.userFailTransaction"); + throw new Error( + "Method not implemented RecoupTransactionContext.userFailTransaction", + ); } async userDeleteTransaction(): Promise<void> { diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts @@ -1327,7 +1327,7 @@ async function handleConfirmPay( forcedCoinSel: undefined, sessionIdOverride: req.sessionId, useDonau: req.useDonau, - noWait: req.noWait ?? wex.ws.devExperimentState.flagConfirmPayNoWait + noWait: req.noWait ?? wex.ws.devExperimentState.flagConfirmPayNoWait, }); } diff --git a/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx b/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx @@ -57,9 +57,12 @@ export function PaymentButtons({ </i18n.Translate> </Button> </section> - {!state.sharePay ? undefined : - <PayWithMobile merchantBaseUrl={state.sharePay.merchantBaseUrl} orderId={state.sharePay.orderId} /> - } + {!state.sharePay ? undefined : ( + <PayWithMobile + merchantBaseUrl={state.sharePay.merchantBaseUrl} + orderId={state.sharePay.orderId} + /> + )} </Fragment> ); } @@ -90,15 +93,17 @@ export function PaymentButtons({ case InsufficientBalanceHint.MerchantAcceptInsufficient: { BalanceMessage = i18n.str`Balance is not enough because the merchant will only accept ${Amounts.stringifyValue( balanceDetails.balanceReceiverAcceptable, - )} ${amount.currency - }. To know more you can check which exchanges the merchant accepts.`; + )} ${ + amount.currency + }. To know more you can check which exchanges the merchant accepts.`; break; } case InsufficientBalanceHint.MerchantDepositInsufficient: { BalanceMessage = i18n.str`Balance is not enough because the merchant will only accept ${Amounts.stringifyValue( balanceDetails.balanceReceiverDepositable, - )} ${amount.currency - }. To know more you can check which wire methods the merchant accepts.`; + )} ${ + amount.currency + }. To know more you can check which wire methods the merchant accepts.`; break; } case InsufficientBalanceHint.AgeRestricted: { @@ -110,8 +115,9 @@ export function PaymentButtons({ case InsufficientBalanceHint.WalletBalanceMaterialInsufficient: { BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue( balanceDetails.balanceMaterial, - )} ${amount.currency - } to spend right now. There are some coins that need to be refreshed.`; + )} ${ + amount.currency + } to spend right now. There are some coins that need to be refreshed.`; break; } case InsufficientBalanceHint.WalletBalanceAvailableInsufficient: { @@ -130,8 +136,9 @@ export function PaymentButtons({ Amounts.sub(amount, balanceDetails.maxEffectiveSpendAmount) .amount, ), - )} ${amount.currency - } more balance in your wallet or ask your merchant to cover more of the fees.`; + )} ${ + amount.currency + } more balance in your wallet or ask your merchant to cover more of the fees.`; break; } case undefined: { @@ -158,9 +165,12 @@ export function PaymentButtons({ <i18n.Translate>Get digital cash</i18n.Translate> </Button> </section> - {!state.sharePay ? undefined : - <PayWithMobile merchantBaseUrl={state.sharePay.merchantBaseUrl} orderId={state.sharePay.orderId} /> - } + {!state.sharePay ? undefined : ( + <PayWithMobile + merchantBaseUrl={state.sharePay.merchantBaseUrl} + orderId={state.sharePay.orderId} + /> + )} </Fragment> ); } @@ -170,19 +180,26 @@ export function PaymentButtons({ } } -function PayWithMobile({ merchantBaseUrl, orderId }: { +function PayWithMobile({ + merchantBaseUrl, + orderId, +}: { merchantBaseUrl: string; orderId: string; }): VNode { const { i18n } = useTranslationContext(); const api = useBackendContext(); - const [showQR, setShowQR] = useState<string | undefined>(undefined); - const privateUri = showQR ? Result.orUndefined(TalerUris.parse(showQR)) : undefined + const privateUri = showQR + ? Result.orUndefined(TalerUris.parse(showQR)) + : undefined; async function sharePrivatePaymentURI() { if (!showQR) { - const result = await api.wallet.call(WalletApiOperation.SharePayment, { merchantBaseUrl, orderId }); + const result = await api.wallet.call(WalletApiOperation.SharePayment, { + merchantBaseUrl, + orderId, + }); setShowQR(result.privatePayUri); } else { setShowQR(undefined); diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts @@ -14,11 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - AbsoluteTime, - Amounts, - NotificationType -} from "@gnu-taler/taler-util"; +import { AbsoluteTime, Amounts, NotificationType } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useEffect } from "preact/hooks"; diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/stories.tsx b/packages/taler-wallet-webextension/src/cta/InvoicePay/stories.tsx @@ -45,8 +45,8 @@ export const Ready = tests.createExample(ReadyView, { expiration: AbsoluteTime.fromMilliseconds( new Date().getTime() + 1000 * 60 * 60, ), - cancel: async () => { }, - goToWalletManualWithdraw: async () => { }, + cancel: async () => {}, + goToWalletManualWithdraw: async () => {}, choices: undefined, error: undefined, merchant: undefined, diff --git a/packages/taler-wallet-webextension/src/cta/Payment/index.ts b/packages/taler-wallet-webextension/src/cta/Payment/index.ts @@ -27,7 +27,10 @@ import { Loading } from "../../components/Loading.js"; import { ErrorAlert } from "../../context/alert.js"; import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; -import { useComponentStateFromUri, useComponentStateFromTxId } from "./state.js"; +import { + useComponentStateFromUri, + useComponentStateFromTxId, +} from "./state.js"; import { BaseView, PaymentStates } from "./views.js"; export interface PropsByTxId { @@ -63,10 +66,12 @@ export namespace State { expiration: AbsoluteTime; merchant: MerchantInfo | undefined; transactionId: TransactionIdStr; - sharePay: { - merchantBaseUrl: string; - orderId: string; - } | undefined, + sharePay: + | { + merchantBaseUrl: string; + orderId: string; + } + | undefined; error: undefined; goToWalletManualWithdraw: (amount?: string) => Promise<void>; cancel: () => Promise<void>; @@ -77,12 +82,12 @@ export namespace State { balanceDetails: PaymentInsufficientBalanceDetails | undefined; effective: undefined; choices: - | undefined - | { - list: MerchantContractChoice[]; - index: number; - select: (d: number) => void; - }; + | undefined + | { + list: MerchantContractChoice[]; + index: number; + select: (d: number) => void; + }; } export interface Ready extends BaseInfo { @@ -90,12 +95,12 @@ export namespace State { payHandler: ButtonHandler; effective: AmountJson; choices: - | undefined - | { - list: MerchantContractChoice[]; - index: number; - select: (d: number) => void; - }; + | undefined + | { + list: MerchantContractChoice[]; + index: number; + select: (d: number) => void; + }; } export interface Confirmed extends BaseInfo { diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts @@ -24,7 +24,7 @@ import { Result, TransactionMajorState, TransactionType, - TranslatedString + TranslatedString, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -67,9 +67,15 @@ export function useComponentStateFromUri({ ), }; } - const { txId: transactionId } = prepareHook.response + const { txId: transactionId } = prepareHook.response; - return () => useComponentStateFromTxId({ cancel, transactionId, goToWalletManualWithdraw, onSuccess }) + return () => + useComponentStateFromTxId({ + cancel, + transactionId, + goToWalletManualWithdraw, + onSuccess, + }); } export function useComponentStateFromTxId({ @@ -83,21 +89,20 @@ export function useComponentStateFromTxId({ const api = useBackendContext(); const { i18n } = useTranslationContext(); const hook = useAsyncAsHook(async () => { - const transaction = await api.wallet.call( - WalletApiOperation.GetTransactionById, { transactionId, includeContractTerms: true } + WalletApiOperation.GetTransactionById, + { transactionId, includeContractTerms: true }, ); - const choices = Result.orUndefined(await api.wallet.callForResult( - WalletApiOperation.GetChoicesForPayment, { transactionId } - )); - - + const choices = Result.orUndefined( + await api.wallet.callForResult(WalletApiOperation.GetChoicesForPayment, { + transactionId, + }), + ); return { transaction, choices }; }, []); - useEffect( () => api.listener.onUpdateNotification( @@ -109,13 +114,16 @@ export function useComponentStateFromTxId({ useEffect(() => { if (!hook || hook.hasError) return; - const tx = hook.response.transaction - if (tx.type !== TransactionType.Payment - || tx.txState.major !== TransactionMajorState.Done - || tx.contractTerms === undefined) return; - const terms = tx.contractTerms + const tx = hook.response.transaction; + if ( + tx.type !== TransactionType.Payment || + tx.txState.major !== TransactionMajorState.Done || + tx.contractTerms === undefined + ) + return; + const terms = tx.contractTerms; if (!terms.fulfillment_url) return; - const url = terms.fulfillment_url + const url = terms.fulfillment_url; setTimeout(() => { document.location.href = url; }, 2000); @@ -132,8 +140,11 @@ export function useComponentStateFromTxId({ ), }; } - const payStatus = hook.response.transaction.type === TransactionType.Payment ? hook.response.transaction : undefined; - const contractTerms = payStatus?.contractTerms + const payStatus = + hook.response.transaction.type === TransactionType.Payment + ? hook.response.transaction + : undefined; + const contractTerms = payStatus?.contractTerms; const { choices } = hook.response; if (!contractTerms) return { status: "loading", error: undefined }; if (!choices) return { status: "loading", error: undefined }; @@ -165,7 +176,6 @@ export function useComponentStateFromTxId({ contractTerms.pay_deadline, ); - const baseResult = { transactionId: payStatus.transactionId, receiver: contractTerms.merchant, @@ -183,7 +193,7 @@ export function useComponentStateFromTxId({ }; if (payStatus.txState.major !== TransactionMajorState.Dialog) { - const paid = payStatus.txState.major === TransactionMajorState.Done + const paid = payStatus.txState.major === TransactionMajorState.Done; return { status: "confirmed", amount: Amounts.parseOrThrow(payStatus.amountRaw), @@ -194,16 +204,11 @@ export function useComponentStateFromTxId({ }; } - const selectedChoiceData = choices.choices[selectedChoice]; const amount = Amounts.parseOrThrow(selectedChoiceData.amountRaw); - const choicesSelector = { - list: - contractTerms.version === 1 - ? contractTerms.choices - : [], + list: contractTerms.version === 1 ? contractTerms.choices : [], index: selectedChoice, select: onSelectChoice, }; @@ -235,5 +240,4 @@ export function useComponentStateFromTxId({ assertUnreachable(selectedChoiceData); } } - } diff --git a/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx b/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx @@ -299,7 +299,6 @@ export const PaymentPossible = tests.createExample(BaseView, { // }, }); - export const PaymentPossibleWithFee = tests.createExample(BaseView, { status: "ready", error: undefined, @@ -308,7 +307,6 @@ export const PaymentPossibleWithFee = tests.createExample(BaseView, { onClick: nullFunction, }, expiration: AbsoluteTime.never(), - }); export const TicketWithAProductList = tests.createExample(BaseView, { @@ -319,8 +317,6 @@ export const TicketWithAProductList = tests.createExample(BaseView, { onClick: nullFunction, }, expiration: AbsoluteTime.never(), - - }); export const TicketWithShipping = tests.createExample(BaseView, { diff --git a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts @@ -14,7 +14,14 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { Amounts, PreparePayResult, PreparePayV2Result, TemplateType, Transaction, TransactionIdStr } from "@gnu-taler/taler-util"; +import { + Amounts, + PreparePayResult, + PreparePayV2Result, + TemplateType, + Transaction, + TransactionIdStr, +} from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useState } from "preact/hooks"; @@ -56,7 +63,11 @@ export function useComponentState({ ); } const balance = await api.wallet.call(WalletApiOperation.GetBalances, {}); - return { transaction: paymentTransaction?.transactionId, balance, templateP }; + return { + transaction: paymentTransaction?.transactionId, + balance, + templateP, + }; }, []); if (!hook) { diff --git a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx @@ -41,7 +41,9 @@ export function WaitingView(state: State.Waiting): VNode { <Fragment> <section> <p> - <i18n.Translate>Waiting information of the merchant and the purchase.</i18n.Translate> + <i18n.Translate> + Waiting information of the merchant and the purchase. + </i18n.Translate> </p> </section> </Fragment> diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx @@ -31,9 +31,7 @@ export function AmountOrCurrencyErrorView( const { i18n } = useTranslationContext(); return ( - <ErrorMessage - title={i18n.str`Please specify a currency or an amount.`} - /> + <ErrorMessage title={i18n.str`Please specify a currency or an amount.`} /> ); } @@ -154,7 +152,10 @@ export function ReadyView(state: State.Ready): VNode { </p> <Grid container spacing={2} columns={1}> <Grid item xs={1}> - <AmountField label={i18n.str`Gross amount`} handler={state.amount} /> + <AmountField + label={i18n.str`Gross amount`} + handler={state.amount} + /> </Grid> <Grid item xs={1}> <AmountField diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx @@ -179,9 +179,9 @@ export function ComparingView({ </h2> <p> <i18n.Translate> - Fees in this section may vary by denomination - value and are valid for a limited period of time. The exchange will charge - the indicated amount every time a coin is used in such operation. + Fees in this section may vary by denomination value and are valid + for a limited period of time. The exchange will charge the indicated + amount every time a coin is used in such operation. </i18n.Translate> </p> <p> @@ -303,9 +303,9 @@ export function ComparingView({ </h2> <p> <i18n.Translate> - Fees in this section may vary by transfer type - and are valid for a limited period of time. The exchange will charge the - indicated amount every time a transfer is made. + Fees in this section may vary by transfer type and are valid for a + limited period of time. The exchange will charge the indicated + amount every time a transfer is made. </i18n.Translate> </p> {missingWireTYpe.map((type) => { @@ -384,9 +384,9 @@ export function ComparingView({ </h2> <p> <i18n.Translate> - Fees in this section may vary by transfer type - and are valid for a limited period of time. The exchange will charge the - indicated amount every time a transfer is made. + Fees in this section may vary by transfer type and are valid for a + limited period of time. The exchange will charge the indicated + amount every time a transfer is made. </i18n.Translate> </p> <table class={styles.feeDescriptionTable}> @@ -522,9 +522,9 @@ export function ReadyView({ </h2> <p> <i18n.Translate> - Fees in this section may vary by denomination - value and are valid for a limited period of time. The exchange will charge - the indicated amount every time a coin is used in such operation. + Fees in this section may vary by denomination value and are valid + for a limited period of time. The exchange will charge the indicated + amount every time a coin is used in such operation. </i18n.Translate> </p> <p> @@ -634,9 +634,9 @@ export function ReadyView({ </h2> <p> <i18n.Translate> - Fees in this section may vary by transfer type - and are valid for a limited period of time. The exchange will charge the - indicated amount every time a transfer is made. + Fees in this section may vary by transfer type and are valid for a + limited period of time. The exchange will charge the indicated + amount every time a transfer is made. </i18n.Translate> </p> {Object.entries(selected.transferFees).map(([type, fees], idx) => { @@ -672,9 +672,9 @@ export function ReadyView({ </h2> <p> <i18n.Translate> - Fees in this section may vary by transfer type - and are valid for a limited period of time. The exchange will charge the - indicated amount every time a transfer is made. + Fees in this section may vary by transfer type and are valid for a + limited period of time. The exchange will charge the indicated + amount every time a transfer is made. </i18n.Translate> </p> <table class={styles.feeDescriptionTable}> diff --git a/packages/taler-wallet-webextension/src/wallet/Mailbox.tsx b/packages/taler-wallet-webextension/src/wallet/Mailbox.tsx @@ -197,10 +197,7 @@ interface MessageProps { function MailboxMessageLayout(props: MessageProps): VNode { const { i18n } = useTranslationContext(); - const uri = Result.orElse( - TalerUris.parse(props.message.talerUri), - undefined, - ); + const uri = Result.orElse(TalerUris.parse(props.message.talerUri), undefined); function toDateString(t: TalerProtocolTimestamp): string { if (t.t_s === "never") { return t.t_s; diff --git a/packages/taler-wallet-webextension/src/wallet/QrReader.tsx b/packages/taler-wallet-webextension/src/wallet/QrReader.tsx @@ -416,7 +416,9 @@ export function QrReaderPage({ onDetected }: Props): VNode { e.stop(); }); } catch (error) { - setError(i18n.str`Unexpected error occurred reading the camera: ${error}`); + setError( + i18n.str`Unexpected error occurred reading the camera: ${error}`, + ); } } diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -43,7 +43,7 @@ import { TransactionType, TransactionWithdrawal, TranslatedString, - WithdrawalType + WithdrawalType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { QR_Taler, useTranslationContext } from "@gnu-taler/web-util/browser"; @@ -51,7 +51,10 @@ import { isPast } from "date-fns"; import { ComponentChildren, Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; import { Amount } from "../components/Amount.js"; -import { BankDetailsForKycAuth, BankDetailsForWithdrawal } from "../components/BankDetailsByPaytoType.js"; +import { + BankDetailsForKycAuth, + BankDetailsForWithdrawal, +} from "../components/BankDetailsByPaytoType.js"; import { AlertView, ErrorAlertView } from "../components/CurrentAlerts.js"; import { Loading } from "../components/Loading.js"; import { Kind, Part } from "../components/Part.js"; @@ -235,7 +238,9 @@ function TransactionTemplate({ switch (transaction.txState.minor) { case TransactionMinorState.KycAuthRequired: { if (!transaction.kycAuthTransferInfo) { - throw Error("transaction in KycAuthRequired state, the field kycAuthTransferInfo is expected to be present") + throw Error( + "transaction in KycAuthRequired state, the field kycAuthTransferInfo is expected to be present", + ); } pendingOrKycInfo = ( <AlertView @@ -245,7 +250,10 @@ function TransactionTemplate({ description: ( <div> <p> - <i18n.Translate>To continue you need to validate the ownership of the account.</i18n.Translate> + <i18n.Translate> + To continue you need to validate the ownership of the + account. + </i18n.Translate> </p> </div> ), @@ -309,8 +317,8 @@ function TransactionTemplate({ <Fragment> <section style={{ padding: 8, textAlign: "center" }}> {transaction?.error && - // FIXME: wallet core should stop sending this error on KYC - transaction.error.code !== + // FIXME: wallet core should stop sending this error on KYC + transaction.error.code !== TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED ? ( <ErrorAlertView error={alertFromError( @@ -507,9 +515,9 @@ export function TransactionView({ </Header> {transaction.txState.major !== TransactionMajorState.Pending || - blockedByKycOrAml ? undefined : transaction.withdrawalDetails.type === + blockedByKycOrAml ? undefined : transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer && - transaction.withdrawalDetails.exchangeCreditAccountDetails ? ( + transaction.withdrawalDetails.exchangeCreditAccountDetails ? ( <Fragment> <InfoBox> {transaction.withdrawalDetails.exchangeCreditAccountDetails @@ -554,7 +562,7 @@ export function TransactionView({ } /> {transaction.txState.major === TransactionMajorState.Aborted && - transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer ? ( + transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer ? ( <AlertView alert={{ type: "info", @@ -746,7 +754,7 @@ export function TransactionView({ // const blockedByKycOrAml = // transaction.txState.minor === TransactionMinorState.KycAuthRequired; - const info = transaction.kycAuthTransferInfo + const info = transaction.kycAuthTransferInfo; const wireTime = AbsoluteTime.fromProtocolTimestamp( transaction.wireTransferDeadline, ); @@ -770,9 +778,7 @@ export function TransactionView({ > {!payto ? transaction.targetPaytoUri : <NicePayto payto={payto} />} </Header> - {!info ? undefined : - <BankDetailsForKycAuth info={info}/> - } + {!info ? undefined : <BankDetailsForKycAuth info={info} />} <Part title={i18n.str`Details`} text={ @@ -969,9 +975,7 @@ export function TransactionView({ title={i18n.str`URI`} text={ <ShowQrWithCopy - uri={Result.unpack( - TalerUris.parse(transaction.talerUri), - )} + uri={Result.unpack(TalerUris.parse(transaction.talerUri))} startOpen onForwardToContact={() => { onForwardToContact && @@ -1556,7 +1560,7 @@ export function WithdrawDetails({ </td> </tr> {conversion.fraction === amount.value.fraction && - conversion.value === amount.value.value ? undefined : ( + conversion.value === amount.value.value ? undefined : ( <tr> <td> <i18n.Translate>Converted</i18n.Translate> diff --git a/packages/web-util/src/components/Attention.tsx b/packages/web-util/src/components/Attention.tsx @@ -52,7 +52,7 @@ export function Attention({ stroke="none" viewBox="0 0 24 24" fill="currentColor" - style={{width:24, height: 24}} + style={{ width: 24, height: 24 }} // class="w-8 h-8 group-[.attention-info]:text-blue-400 group-[.attention-warning]:text-yellow-400 group-[.attention-danger]:text-red-400 group-[.attention-success]:text-green-400" > {(() => { diff --git a/packages/web-util/src/components/ErrorLoadingMerchant.tsx b/packages/web-util/src/components/ErrorLoadingMerchant.tsx @@ -14,10 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - TalerError, - TranslatedString -} from "@gnu-taler/taler-util"; +import { TalerError, TranslatedString } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; import { translateTalerError, @@ -46,10 +43,7 @@ export function ErrorLoading({ const { i18n } = useTranslationContext(); const description = translateTalerError(error, i18n); return ( - <Attention - type="danger" - title={title} - > + <Attention type="danger" title={title}> {(description ?? []).map((d) => ( <p>{d}</p> ))} diff --git a/packages/web-util/src/context/bank-api.ts b/packages/web-util/src/context/bank-api.ts @@ -129,12 +129,19 @@ export const BankApiProvider = ({ if (checked === undefined) { return h(frameOnError, { - children: h("div", {}, i18n.str`Checking compatibility of this webapp with backend service...`), + children: h( + "div", + {}, + i18n.str`Checking compatibility of this webapp with backend service...`, + ), }); } if (checked.type === "error") { return h(frameOnError, { - children: h(ErrorLoading, { title: i18n.str`There was an error trying to contact the backend service.`, error: checked.error }), + children: h(ErrorLoading, { + title: i18n.str`There was an error trying to contact the backend service.`, + error: checked.error, + }), }); } if (checked.type === "incompatible") { diff --git a/packages/web-util/src/context/challenger-api.ts b/packages/web-util/src/context/challenger-api.ts @@ -131,12 +131,19 @@ export const ChallengerApiProvider = ({ if (checked === undefined) { return h(frameOnError, { - children: h("div", {}, i18n.str`Checking compatibility of this webapp with backend service...`), + children: h( + "div", + {}, + i18n.str`Checking compatibility of this webapp with backend service...`, + ), }); } if (checked.type === "error") { return h(frameOnError, { - children: h(ErrorLoading, { title: i18n.str`There was an error trying to contact the backend service.`, error: checked.error }), + children: h(ErrorLoading, { + title: i18n.str`There was an error trying to contact the backend service.`, + error: checked.error, + }), }); } if (checked.type === "incompatible") { diff --git a/packages/web-util/src/hooks/errors.ts b/packages/web-util/src/hooks/errors.ts @@ -38,4 +38,3 @@ function convert(error: any) { } return error; } - diff --git a/packages/web-util/src/hooks/useAsync.ts b/packages/web-util/src/hooks/useAsync.ts @@ -171,12 +171,14 @@ export function useLongPolling<Res>( * @param ms * @returns */ -export async function delayMs(ms: number, ct?:CancellationToken): Promise<void> { - +export async function delayMs( + ms: number, + ct?: CancellationToken, +): Promise<void> { return new Promise((resolve, reject) => { setTimeout(() => resolve(), ms); if (ct) { - ct.onCancelled(reject) + ct.onCancelled(reject); } }); } diff --git a/packages/web-util/src/hooks/useNotifications.ts b/packages/web-util/src/hooks/useNotifications.ts @@ -69,18 +69,21 @@ function hash(msg: NotificationMessage): string { export function useNotificationHandler() { const [notification, setNotification] = useState<Notification[]>([]); - function pushNotification(n:Notification) { - setNotification((ns)=>[n,...ns]) + function pushNotification(n: Notification) { + setNotification((ns) => [n, ...ns]); } function ackNotification(when: AbsoluteTime) { - return ():void => setNotification((ns) => ns.filter(n => n.message.when.t_ms !== when.t_ms)) + return (): void => + setNotification((ns) => + ns.filter((n) => n.message.when.t_ms !== when.t_ms), + ); } function displayError( title: TranslatedString, debug: Error | TalerError | unknown | undefined, ...description: TranslatedString[] ) { - const when = AbsoluteTime.now() + const when = AbsoluteTime.now(); pushNotification({ message: { title, @@ -93,7 +96,7 @@ export function useNotificationHandler() { }); } function displayInfo(title: TranslatedString) { - const when = AbsoluteTime.now() + const when = AbsoluteTime.now(); pushNotification({ message: { title, @@ -316,7 +319,7 @@ export interface SafeHandler<Args extends any[], OpType> { /** * Be careful of not settings the args with always-changing values * like `[]` or `{}` (which returns new instance every time) - * + * * The list of arguments is subject to be used as an useEffect dependency array * for re-render purpose */ @@ -370,9 +373,9 @@ export function simpleSafeHandler(fn: () => void) { type: "ok", body: undefined, case: "ok", - response: {} as any - } - },[]) + response: {} as any, + }; + }, []); } export function newSafeHandlerBuilder< diff --git a/packages/web-util/src/live-reload.ts b/packages/web-util/src/live-reload.ts @@ -71,15 +71,15 @@ export async function poll() { } } -function tryJson(d:string) { +function tryJson(d: string) { try { - const j = JSON.parse(d) - return JSON.stringify(j, undefined, 2) - } catch(e) { - return d + const j = JSON.parse(d); + return JSON.stringify(j, undefined, 2); + } catch (e) { + return d; } } -type ErrorMsg = {path:string, error:unknown} +type ErrorMsg = { path: string; error: unknown }; function showErrorOnOverlay(data: ErrorMsg): void { const h1 = document.getElementById("overlay-text"); if (h1) { @@ -89,15 +89,18 @@ function showErrorOnOverlay(data: ErrorMsg): void { } const div = document.getElementById("overlay"); if (div) { - const content = typeof data.error === "string" ? tryJson(data.error) : JSON.stringify(data.error, undefined, 2); + const content = + typeof data.error === "string" + ? tryJson(data.error) + : JSON.stringify(data.error, undefined, 2); const h1 = document.createElement("h1"); h1.textContent = data.path; h1.style.marginBottom = "20px"; - h1.style.maxWidth = "90%" + h1.style.maxWidth = "90%"; const pre = document.createElement("pre"); pre.id = "error-text"; pre.style.margin = ""; - pre.style.maxWidth = "90%" + pre.style.maxWidth = "90%"; pre.textContent = content; div.style.backgroundColor = "rgba(0,0,0,0.8)"; div.style.flexDirection = "column"; diff --git a/packages/web-util/src/serve.ts b/packages/web-util/src/serve.ts @@ -230,4 +230,3 @@ export async function serve(opts: { logger.info(`Serving ${opts.folder} on ${socketFile} via plain HTTP`); httpServer.listen(socketFile); } -