commit 6274c66b7e79ee96f4d49c45ff5017d5141969b2
parent ff35b68f10d8982e40eabf828310bbf5af29df95
Author: Sebastian <sebasjm@gmail.com>
Date: Mon, 3 Nov 2025 13:06:06 -0300
fix payto normalizing
Diffstat:
5 files changed, 60 insertions(+), 37 deletions(-)
diff --git a/packages/aml-backoffice-ui/src/pages/decision/Summary.tsx b/packages/aml-backoffice-ui/src/pages/decision/Summary.tsx
@@ -17,16 +17,16 @@ import {
AbsoluteTime,
AmlDecisionRequest,
assertUnreachable,
+ encodeCrock,
HttpStatusCode,
opEmptySuccess,
- parsePaytoUri,
- stringifyPaytoUri,
+ Paytos,
+ succeedOrThrow,
TalerError,
TOPS_AmlEventsName,
} from "@gnu-taler/taler-util";
import {
Attention,
- Button,
ButtonBetter,
LocalNotificationBanner,
useExchangeApiContext,
@@ -129,46 +129,54 @@ export function Summary({
onMove(undefined);
}
- const fullPayto = !newPayto ? undefined : parsePaytoUri(newPayto);
- if (fullPayto && decision.accountName) {
- fullPayto.params["receiver-name"] = decision.accountName;
+ const fullPayto = !newPayto ? undefined : Paytos.fromString(newPayto);
+ if (fullPayto && fullPayto.type === "ok" && decision.accountName) {
+ fullPayto.body.params["receiver-name"] = decision.accountName;
}
- const request: Omit<AmlDecisionRequest, "officer_sig"> = {
- h_payto: account!,
- decision_time: AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now()),
- justification: decision.justification!,
- payto_uri: !fullPayto ? undefined : stringifyPaytoUri(fullPayto),
- keep_investigating: decision.keep_investigating ?? false,
- new_rules: {
- expiration_time: AbsoluteTime.toProtocolTimestamp(decision.deadline!),
- rules: decision.rules!,
- successor_measure: decision.onExpire_measure,
- custom_measures: decision.custom_measures ?? {},
- },
- attributes_expiration: decision.attributes?.expiration
- ? AbsoluteTime.toProtocolTimestamp(decision.attributes.expiration)
- : undefined,
- events: decision.triggering_events,
- attributes: decision.attributes?.data,
- properties: decision.properties!,
- new_measures:
- !decision.new_measures || !decision.new_measures.length
- ? undefined
- : decision.new_measures.join(" "),
- };
+ const request: undefined | Omit<AmlDecisionRequest, "officer_sig"> =
+ CANT_SUBMIT
+ ? undefined
+ : {
+ h_payto: account!,
+ decision_time: AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now()),
+ justification: decision.justification!,
+ payto_uri:
+ !fullPayto || fullPayto.type === "fail"
+ ? undefined
+ : Paytos.toFullString(fullPayto.body),
+ keep_investigating: decision.keep_investigating ?? false,
+ new_rules: {
+ expiration_time: AbsoluteTime.toProtocolTimestamp(
+ decision.deadline!,
+ ),
+ rules: decision.rules!,
+ successor_measure: decision.onExpire_measure,
+ custom_measures: decision.custom_measures ?? {},
+ },
+ attributes_expiration: decision.attributes?.expiration
+ ? AbsoluteTime.toProtocolTimestamp(decision.attributes.expiration)
+ : undefined,
+ events: decision.triggering_events,
+ attributes: decision.attributes?.data,
+ properties: decision.properties!,
+ new_measures:
+ !decision.new_measures || !decision.new_measures.length
+ ? undefined
+ : decision.new_measures.join(" "),
+ };
const [submitConfirmation, setSubmitConfirmation] = useState<boolean>(false);
const requiresConfirmation = MROS_REPORT_COMPLETED;
const submit = safeFunctionHandler(
- async () => {
+ async (req) => {
if (requiresConfirmation && !submitConfirmation) {
setSubmitConfirmation(true);
return opEmptySuccess();
}
- return lib.exchange.makeAmlDesicion(session, request);
+ return lib.exchange.makeAmlDesicion(session, req);
},
- CANT_SUBMIT ? undefined : [],
+ !request ? undefined : [request],
);
submit.onSuccess = clearUp;
diff --git a/packages/taler-util/src/iban.test.ts b/packages/taler-util/src/iban.test.ts
@@ -25,6 +25,5 @@ test("iban validation", (t) => {
test("iban generation", (t) => {
let iban1 = generateIban("DE", 10);
- console.log("generated IBAN", iban1);
t.assert(validateIban(iban1).type === "valid");
});
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
@@ -339,12 +339,13 @@ export namespace Paytos {
bic: string | undefined,
params: Record<string, string> = {},
): PaytoIBAN {
+ iban = iban.toUpperCase() as IbanString
return {
targetType: PaytoType.IBAN,
iban,
bic,
params,
- normalizedPath: iban.toLocaleLowerCase(),
+ normalizedPath: iban,
fullPath: !bic ? iban : `${bic}/${iban}`,
displayName: iban,
};
diff --git a/packages/taler-util/src/paytos.test.ts b/packages/taler-util/src/paytos.test.ts
@@ -57,19 +57,35 @@ test("basic x-taler-bank payto string", (t) => {
t.is(result.account, "accountName");
});
-test("parsing payto and stringify again", (t) => {
+test("parsing payto and stringify again on normalized strings are unchanged", (t) => {
const payto1 = "payto://iban/DE1231231231?reciever-name=John%20Doe";
t.is(
Paytos.toFullString(succeedOrThrow(Paytos.fromString(payto1))),
payto1 as Paytos.FullPaytoString,
);
- const normalized = "payto://iban/de1231231231";
+ const normalized = "payto://iban/DE1231231231";
t.is(
Paytos.toNormalizedString(succeedOrThrow(Paytos.fromString(payto1))),
normalized as Paytos.NormalizedPaytoString,
);
});
+test("parsing payto and stringify again converts to the normal form", (t) => {
+ const fullPayto_not_normalized = "payto://iban/de1231231231?reciever-name=John%20Doe";
+ // after normalization the country code is uppercased
+ const fullPayto_normalized = "payto://iban/DE1231231231?reciever-name=John%20Doe" as Paytos.FullPaytoString;
+ t.is(
+ Paytos.toFullString(succeedOrThrow(Paytos.fromString(fullPayto_not_normalized))),
+ fullPayto_normalized,
+ );
+
+ const normalized_lowercase = "payto://iban/DE1231231231";
+ const normalized_uppercase = "payto://iban/DE1231231231" as Paytos.NormalizedPaytoString;
+ t.is(
+ Paytos.toNormalizedString(succeedOrThrow(Paytos.fromString(normalized_lowercase))),
+ normalized_uppercase,
+ );
+});
test("parsing payto with % carh", (t) => {
const payto1 =
"payto://iban/DE7763544441436?receiver-name=Test%20123%2B-%24%25%5E%3Cem%3Ehi%3C%2Fem%3E" as Paytos.FullPaytoString;
diff --git a/packages/taler-util/src/talerconfig.test.ts b/packages/taler-util/src/talerconfig.test.ts
@@ -113,7 +113,6 @@ test("path expansion", (t) => {
});
test("recursive path resolution", (t) => {
- console.log("recursive test");
const config = new Configuration();
config.setString("paths", "a", "x${b}");
config.setString("paths", "b", "y${a}");