diff options
Diffstat (limited to 'packages/taler-util/src/taleruri.ts')
-rw-r--r-- | packages/taler-util/src/taleruri.ts | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts index 4e47acbce..2aa9cb030 100644 --- a/packages/taler-util/src/taleruri.ts +++ b/packages/taler-util/src/taleruri.ts @@ -16,7 +16,6 @@ import { BackupRecovery } from "./backup-types.js"; import { canonicalizeBaseUrl } from "./helpers.js"; -import { initNodePrng } from "./prng-node.js"; import { URLSearchParams, URL } from "./url.js"; export interface PayUriResult { @@ -27,6 +26,12 @@ export interface PayUriResult { noncePriv: string | undefined; } +export interface PayTemplateUriResult { + merchantBaseUrl: string; + templateId: string; + templateParams: Record<string, string>; +} + export interface WithdrawUriResult { bankIntegrationApiBaseUrl: string; withdrawalOperationId: string; @@ -91,6 +96,7 @@ export function parseWithdrawUri(s: string): WithdrawUriResult | undefined { export enum TalerUriType { TalerPay = "taler-pay", + TalerTemplate = "taler-template", TalerWithdraw = "taler-withdraw", TalerTip = "taler-tip", TalerRefund = "taler-refund", @@ -103,6 +109,7 @@ export enum TalerUriType { const talerActionPayPull = "pay-pull"; const talerActionPayPush = "pay-push"; +const talerActionPayTemplate = "pay-template"; /** * Classify a taler:// URI. @@ -121,6 +128,12 @@ export function classifyTalerUri(s: string): TalerUriType { if (sl.startsWith("taler+http://pay/")) { return TalerUriType.TalerPay; } + if (sl.startsWith("taler://pay-template/")) { + return TalerUriType.TalerPay; + } + if (sl.startsWith("taler+http://pay-template/")) { + return TalerUriType.TalerPay; + } if (sl.startsWith("taler://tip/")) { return TalerUriType.TalerTip; } @@ -216,6 +229,38 @@ export function parsePayUri(s: string): PayUriResult | undefined { }; } +export function parsePayTemplateUri( + s: string, +): PayTemplateUriResult | undefined { + const pi = parseProtoInfo(s, talerActionPayTemplate); + if (!pi) { + return undefined; + } + const c = pi?.rest.split("?"); + const q = new URLSearchParams(c[1] ?? ""); + const parts = c[0].split("/"); + if (parts.length < 2) { + return undefined; + } + const host = parts[0].toLowerCase(); + const templateId = parts[parts.length - 1]; + const pathSegments = parts.slice(1, parts.length - 1); + const p = [host, ...pathSegments].join("/"); + const merchantBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`); + + const params: Record<string, string> = {}; + + q.forEach((v, k) => { + params[k] = v; + }); + + return { + merchantBaseUrl, + templateId, + templateParams: params, + }; +} + export function constructPayUri( merchantBaseUrl: string, orderId: string, @@ -227,9 +272,21 @@ export function constructPayUri( const url = new URL(base); const isHttp = base.startsWith("http://"); let result = isHttp ? `taler+http://pay/` : `taler://pay/`; - result += `${url.hostname}${url.pathname}${orderId}/${sessionId}?`; - if (claimToken) result += `c=${claimToken}`; - if (noncePriv) result += `n=${noncePriv}`; + result += url.hostname; + if (url.port != "") { + result += `:${url.port}`; + } + result += `${url.pathname}${orderId}/${sessionId}`; + let queryPart = ""; + if (claimToken) { + queryPart += `c=${claimToken}`; + } + if (noncePriv) { + queryPart += `n=${noncePriv}`; + } + if (queryPart) { + result += "?" + queryPart; + } return result; } |