commit 36c201fbc464667ec1b5b6f1a291cdbf69222f3b
parent 465c167cfbc09b79073c15d5a7c72e23d034565a
Author: Florian Dold <dold@taler.net>
Date: Tue, 21 Jul 2026 11:01:38 +0200
util: escape path parameters in multi-line URL builders
The earlier escaping pass only covered call sites where the URL template
fits on one line, leaving eleven path parameters unescaped, among them the
user-chosen corebank username.
Diffstat:
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/packages/taler-util/src/bank-api-client.ts b/packages/taler-util/src/bank-api-client.ts
@@ -139,7 +139,7 @@ export class TalerCorebankApiClient {
target: PaytoString,
): Promise<void> {
const reqUrl = new URL(
- `accounts/${this.args.auth!.username}/transactions`,
+ `accounts/${pathSegment(this.args.auth!.username)}/transactions`,
this.baseUrl,
);
const resp = await this.httpLib.fetch(reqUrl.href, {
@@ -278,7 +278,7 @@ export class TalerCorebankApiClient {
wopi: ConfirmWithdrawalArgs,
) {
const url = new URL(
- `accounts/${username}/withdrawals/${wopi.withdrawalOperationId}/confirm`,
+ `accounts/${pathSegment(username)}/withdrawals/${pathSegment(wopi.withdrawalOperationId)}/confirm`,
this.baseUrl,
);
logger.info(`confirming withdrawal operation via ${url.href}`);
@@ -302,7 +302,7 @@ export class TalerCorebankApiClient {
async abortWithdrawalOperation(wopi: WithdrawalOperationInfo): Promise<void> {
const url = new URL(
- `withdrawals/${wopi.withdrawal_id}/abort`,
+ `withdrawals/${pathSegment(wopi.withdrawal_id)}/abort`,
this.baseUrl,
);
const resp = await this.httpLib.fetch(url.href, {
@@ -318,7 +318,7 @@ export class TalerCorebankApiClient {
wopi: WithdrawalOperationInfo,
): Promise<void> {
const url = new URL(
- `accounts/${username}/withdrawals/${wopi.withdrawal_id}/abort`,
+ `accounts/${pathSegment(username)}/withdrawals/${pathSegment(wopi.withdrawal_id)}/abort`,
this.baseUrl,
);
const resp = await this.httpLib.fetch(url.href, {
diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts
@@ -693,7 +693,7 @@ export class TalerCoreBankHttpClient {
*/
async getTransactionById(auth: UserAndToken, txid: number) {
const url = new URL(
- `accounts/${auth.username}/transactions/${String(txid)}`,
+ `accounts/${pathSegment(auth.username)}/transactions/${pathSegment(txid)}`,
this.baseUrl,
);
const resp = await this.httpLib.fetch(url.href, {
@@ -842,7 +842,7 @@ export class TalerCoreBankHttpClient {
| OperationFail<TalerErrorCode.BANK_AMOUNT_REQUIRED>
> {
const url = new URL(
- `accounts/${auth.username}/withdrawals/${wid}/confirm`,
+ `accounts/${pathSegment(auth.username)}/withdrawals/${pathSegment(wid)}/confirm`,
this.baseUrl,
);
const headers: Record<string, string> = {};
@@ -900,7 +900,7 @@ export class TalerCoreBankHttpClient {
*/
async abortWithdrawalById(auth: UserAndToken, wid: string) {
const url = new URL(
- `accounts/${auth.username}/withdrawals/${wid}/abort`,
+ `accounts/${pathSegment(auth.username)}/withdrawals/${pathSegment(wid)}/abort`,
this.baseUrl,
);
const resp = await this.httpLib.fetch(url.href, {
@@ -1044,7 +1044,7 @@ export class TalerCoreBankHttpClient {
*/
async getCashoutById(auth: UserAndToken, cid: number) {
const url = new URL(
- `accounts/${auth.username}/cashouts/${cid}`,
+ `accounts/${pathSegment(auth.username)}/cashouts/${pathSegment(cid)}`,
this.baseUrl,
);
const resp = await this.httpLib.fetch(url.href, {
@@ -1381,7 +1381,7 @@ export class TalerCoreBankHttpClient {
body: ChallengeSolveRequest,
) {
const url = new URL(
- `accounts/${username}/challenge/${cid}/confirm`,
+ `accounts/${pathSegment(username)}/challenge/${pathSegment(cid)}/confirm`,
this.baseUrl,
);
const resp = await this.httpLib.fetch(url.href, {
@@ -1520,7 +1520,7 @@ export class TalerCoreBankHttpClient {
*/
getConversionInfoAPIForClass(classId: number): URL {
return new URL(
- `conversion-rate-classes/${String(classId)}/conversion-info/`,
+ `conversion-rate-classes/${pathSegment(classId)}/conversion-info/`,
this.baseUrl,
);
}
diff --git a/packages/taler-util/src/http-client/exchange-client.ts b/packages/taler-util/src/http-client/exchange-client.ts
@@ -991,7 +991,7 @@ export class TalerExchangeHttpClient {
} = {},
) {
const url = new URL(
- `aml/${auth.id}/kyc-statistics/${names.join(" ")}`,
+ `aml/${pathSegment(auth.id)}/kyc-statistics/${names.join(" ")}`,
this.baseUrl,
);
diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts
@@ -895,7 +895,7 @@ export class TalerMerchantInstanceHttpClient {
},
) {
const url = new URL(
- `private/accounts/${params.wireAccountHash}/kycauth`,
+ `private/accounts/${pathSegment(params.wireAccountHash)}/kycauth`,
this.baseUrl,
);
@@ -3742,7 +3742,7 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
} = {},
) {
const url = new URL(
- `management/instances/${instanceId}/auth`,
+ `management/instances/${pathSegment(instanceId)}/auth`,
this.baseUrl,
);