commit 8194dbff4a8d6d0b4fe061ea3a9ff1033be7bb7f
parent 07c83c95c103e013db1c202fd193d4636ad2c5a4
Author: Sebastian <sebasjm@taler-systems.com>
Date: Wed, 10 Jun 2026 13:42:40 -0300
fix #11508
Diffstat:
4 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/packages/taler-merchant-webui/src/components/SolveMFA.tsx b/packages/taler-merchant-webui/src/components/SolveMFA.tsx
@@ -291,6 +291,7 @@ function SolveChallenge({
label: i18n.str`Verify`,
}
} // first try is going to be automatically
+ zIndex={50} // above any current dialog
>
<FormProvider<Form>
name="settings"
@@ -545,6 +546,7 @@ function SolveMFAChallenges({
<ConfirmModal
title={i18n.str`Multi-factor authentication required.`}
focus
+ zIndex={50} // above any current dialog
preventBackgroundClose
onCancel={onCancel}
confirm={
diff --git a/packages/taler-merchant-webui/src/components/modal/index.tsx b/packages/taler-merchant-webui/src/components/modal/index.tsx
@@ -53,6 +53,7 @@ interface ConfirmProps {
children?: ComponentChildren;
danger?: boolean;
focus?: boolean;
+ zIndex?: number;
preventBackgroundClose?: boolean;
}
interface BlockingProps {
@@ -79,11 +80,12 @@ export function ConfirmModal({
children,
danger,
focus,
+ zIndex,
preventBackgroundClose,
}: ConfirmProps): VNode {
const { i18n } = useTranslationContext();
return (
- <div class="modal is-active">
+ <div class="modal is-active" style={zIndex ? {zIndex } : undefined}>
<div
class="modal-background "
onClick={preventBackgroundClose ? undefined : onCancel}
diff --git a/packages/taler-merchant-webui/src/paths/instance/accounts/list/Table.tsx b/packages/taler-merchant-webui/src/paths/instance/accounts/list/Table.tsx
@@ -38,6 +38,7 @@ import { StateUpdater, useState } from "preact/hooks";
import { ConfirmModal } from "../../../../components/modal/index.js";
import { useSessionContext } from "../../../../context/session.js";
import { Tooltip } from "../../../../components/Tooltip.js";
+import { useMerchantChallengeHandlerContext } from "../../../../context/challenge.js";
const TALER_SCREEN_ID = 35;
@@ -57,16 +58,27 @@ export function CardTable({ accounts, onCreate, onSelect }: Props): VNode {
const { actionHandler, showError } = useNotificationContext();
const [deleting, setDeleting] =
useState<TalerMerchantApi.BankAccountEntry | null>(null);
+ const mfa = useMerchantChallengeHandlerContext();
const remove = actionHandler(
/*delete bank account*/
- (ct, t, w) => lib.instance.deleteBankAccount(t, w),
+ (ct, t, w, challengeIds: string[]) =>
+ lib.instance.deleteBankAccount(t, w, { challengeIds }),
!session.token || !deleting
? undefined
- : ([session.token, deleting.h_wire] as const),
+ : ([session.token, deleting.h_wire, []] as const),
);
remove.onFail = showError(i18n.str`Delete failed`, (fail) => {
switch (fail.case) {
+ case HttpStatusCode.Accepted:
+ mfa.onNewChallenge(
+ i18n.str`New account`,
+ fail.body,
+ remove.lambda((prev, [ids]) =>
+ !prev ? undefined : [prev[0], prev[1], ids],
+ ),
+ );
+ return undefined;
case HttpStatusCode.Unauthorized:
return i18n.str`Unauthorized`;
case HttpStatusCode.NotFound:
diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts
@@ -1119,10 +1119,19 @@ export class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-accounts-$H_WIRE
*/
- async deleteBankAccount(token: AccessToken, wireAccount: string) {
+ async deleteBankAccount(
+ token: AccessToken,
+ wireAccount: string,
+ params: {
+ challengeIds?: string[];
+ } = {},
+ ) {
const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
const headers: Record<string, string> = {};
+ if (params.challengeIds && params.challengeIds.length > 0) {
+ headers["Taler-Challenge-Ids"] = params.challengeIds.join(", ");
+ }
if (token) {
headers.Authorization = makeBearerTokenAuthHeader(token);
}
@@ -1138,6 +1147,12 @@ export class TalerMerchantInstanceHttpClient {
);
return opEmptySuccess(resp);
}
+ case HttpStatusCode.Accepted:
+ return opKnownAlternativeHttpFailure(
+ resp,
+ resp.status,
+ codecForChallengeResponse(),
+ );
case HttpStatusCode.Unauthorized: // FIXME: missing in docs
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound: