commit 16765d1477999b3d513e265c1e465a825d1face2
parent 29118e7c544af1a90465050e1f25da2a1451edd1
Author: Florian Dold <dold@taler.net>
Date: Tue, 21 Jul 2026 01:57:11 +0200
util: normalize x-taler-bank paytos like the C exchange
Diffstat:
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
@@ -225,8 +225,10 @@ export namespace Paytos {
// An unsupported target type keeps the raw value in `target`, since it is
// by definition not a member of PaytoType.
const target = p.targetType ?? (p as PaytoUnsupported).target;
- const url = new URL(`${PAYTO_PREFIX}${target}/${p.normalizedPath}`);
- return url.href as NormalizedPaytoString;
+ // Concatenate directly rather than via a URL parser: normalizedPath is
+ // already canonical, and passing it through `new URL` would resolve dot
+ // segments, diverging from the C normalizer and thus from H_PAYTO.
+ return `${PAYTO_PREFIX}${target}/${p.normalizedPath}` as NormalizedPaytoString;
}
/**
* A **full** payto-URI is not expected to have a canonical form for
@@ -487,17 +489,28 @@ export namespace Paytos {
url: HostPortPath,
account: string,
params: Record<string, string> = {},
+ rawSegments?: string[],
): PaytoTalerBank {
const path = withoutScheme(url);
const host = path.endsWith("/") ? path.substring(0, path.length - 1) : path;
+ // Match normalize_payto_x_taler_bank in the C exchange: lowercase only the
+ // host, preserve the case of the account path, and do not resolve dot
+ // segments. Both forms are built from the raw segments so that going
+ // through a URL parser (which would lowercase or resolve) cannot change
+ // H_PAYTO.
+ const segments = rawSegments ?? [host, account];
+ const normalizedPath = `${segments[0].toLowerCase()}/${segments
+ .slice(1)
+ .join("/")}`;
+ const fullPath = segments.join("/");
return {
targetType: PaytoType.TalerBank,
host,
url,
account,
params,
- normalizedPath: `${path.toLowerCase()}${account}`,
- fullPath: `${path}${account}`,
+ normalizedPath,
+ fullPath,
displayName: `${account}@${url}`,
};
}
@@ -729,8 +742,9 @@ export namespace Paytos {
return Result.of(
createTalerBank(
host ?? (cs[0] as HostPortPath),
- account ?? cs[1],
+ account ?? cs[cs.length - 1],
params,
+ cs,
),
);
}