taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 8bde9bb1a8a4687b9c888db2a91524d168953d31
parent 47a2966562d691cbeffeccf0f915dfcd89a5f8fa
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Fri,  9 Jan 2026 12:15:56 -0300

fix #10859

Diffstat:
Mpackages/merchant-backoffice-ui/src/components/SolveMFA.tsx | 6+++---
Mpackages/merchant-backoffice-ui/src/paths/resetAccount/index.tsx | 27++++++++++++---------------
Mpackages/taler-util/src/http-client/merchant.ts | 11+++++++++--
3 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/components/SolveMFA.tsx b/packages/merchant-backoffice-ui/src/components/SolveMFA.tsx @@ -99,11 +99,11 @@ function SolveChallenge({ case HttpStatusCode.Unauthorized: return i18n.str`Unauthorized`; case TalerErrorCode.MERCHANT_TAN_CHALLENGE_FAILED: - return i18n.str`Sending the code failed`; + return i18n.str`The code is not correct.`; case TalerErrorCode.MERCHANT_TAN_CHALLENGE_UNKNOWN: - return i18n.str`Challenge expired`; + return i18n.str`The challenge is not known anymore.`; case TalerErrorCode.MERCHANT_TAN_TOO_MANY_ATTEMPTS: - return i18n.str`Too many attempts`; + return i18n.str`Too many attempts trying to solve the challenge.`; default: assertUnreachable(fail); } diff --git a/packages/merchant-backoffice-ui/src/paths/resetAccount/index.tsx b/packages/merchant-backoffice-ui/src/paths/resetAccount/index.tsx @@ -19,6 +19,7 @@ import { HttpStatusCode, MerchantAuthMethod, opFixedSuccess, + TalerErrorCode, } from "@gnu-taler/taler-util"; import { ButtonBetterBulma, @@ -37,6 +38,7 @@ import { Input } from "../../components/form/Input.js"; import { SolveMFAChallenges } from "../../components/SolveMFA.js"; import { useSessionContext } from "../../context/session.js"; import { FOREVER_REFRESHABLE_TOKEN } from "../login/index.js"; +import { undefinedIfEmpty } from "../../utils/table.js"; const TALER_SCREEN_ID = 82; @@ -63,14 +65,15 @@ export function ResetAccount({ // repeat: "asd", }); - const errors: FormErrors<Form> = { + const errors = undefinedIfEmpty<FormErrors<Form>>({ password: !value.password ? i18n.str`Required` : undefined, repeat: !value.repeat ? i18n.str`Required` : value.password !== value.repeat ? i18n.str`Doesn't match` : undefined, - }; + }); + const hasErrors = errors !== undefined; function valueHandler(s: (d: Partial<Form>) => Partial<Form>): void { const next = s(value); @@ -92,33 +95,27 @@ export function ResetAccount({ { challengeIds }, ); - if (forgot.type === "fail") { return forgot; - } - const login = await lib.instance.createAccessToken( - instanceId, - value.password!, - FOREVER_REFRESHABLE_TOKEN(i18n.str`Password reset`), - ); - if (login.type === "fail") return login; - return opFixedSuccess(login.body); }, + hasErrors ? undefined : [value.password!, []], ); reset.onSuccess = (suc) => { - logIn(instanceId, suc.access_token); + // logIn(instanceId, suc.access_token); onReseted(); }; reset.onFail = (fail) => { switch (fail.case) { + case TalerErrorCode.MERCHANT_GENERIC_MFA_MISSING: + return i18n.str`The instance is not properly configured to allow MFA.`; case HttpStatusCode.Accepted: mfa.onChallengeRequired(fail.body); return undefined; - case HttpStatusCode.Unauthorized: - return i18n.str`Unauthorized.`; + // case HttpStatusCode.Unauthorized: + // return i18n.str`Unauthorized.`; case HttpStatusCode.Forbidden: return i18n.str`Forbidden.`; case HttpStatusCode.NotFound: - return i18n.str`Not found.`; + return i18n.str`The instance "${instanceId}" was not found.`; default: assertUnreachable(fail); } diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts @@ -2726,8 +2726,15 @@ export class TalerMerchantInstanceHttpClient { return opKnownHttpFailure(resp.status, resp); case HttpStatusCode.Forbidden: return opKnownHttpFailure(resp.status, resp); - case HttpStatusCode.Unauthorized: - return opKnownHttpFailure(resp.status, resp); + case HttpStatusCode.Unauthorized: { + const details = await readTalerErrorResponse(resp); + switch (details.code) { + case TalerErrorCode.MERCHANT_GENERIC_MFA_MISSING: + return opKnownTalerFailure(details.code, details); + default: + return opUnknownHttpFailure(resp, details); + } + } default: return opUnknownHttpFailure(resp); }