taler-typescript-core

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

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:
Mpackages/taler-util/src/bank-api-client.ts | 8++++----
Mpackages/taler-util/src/http-client/bank-core.ts | 12++++++------
Mpackages/taler-util/src/http-client/exchange-client.ts | 2+-
Mpackages/taler-util/src/http-client/merchant.ts | 4++--
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, );