aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-06-13 15:22:43 -0300
committerSebastian <sebasjm@gmail.com>2024-06-13 15:23:40 -0300
commit70926f609c766d47235a1fc47f189482bc9052bd (patch)
tree57b6b6881acf5120f5b4392d5a3a747da11ba559 /packages
parent331ff2a22ddbe7512e3a54235a986e7275b88920 (diff)
downloadwallet-core-70926f609c766d47235a1fc47f189482bc9052bd.tar.xz
fix encoding payto parms
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-util/src/payto.test.ts9
-rw-r--r--packages/taler-util/src/payto.ts64
2 files changed, 51 insertions, 22 deletions
diff --git a/packages/taler-util/src/payto.test.ts b/packages/taler-util/src/payto.test.ts
index 66a05b3a2..0802e1cd4 100644
--- a/packages/taler-util/src/payto.test.ts
+++ b/packages/taler-util/src/payto.test.ts
@@ -16,7 +16,7 @@
import test from "ava";
-import { parsePaytoUri } from "./payto.js";
+import { PaytoString, parsePaytoUri, stringifyPaytoUri } from "./payto.js";
test("basic payto parsing", (t) => {
const r1 = parsePaytoUri("https://example.com/");
@@ -29,3 +29,10 @@ test("basic payto parsing", (t) => {
t.is(r3?.targetType, "x-taler-bank");
t.is(r3?.targetPath, "123");
});
+
+test("parsing payto and stringify again", (t) => {
+ const payto1 =
+ "payto://iban/DE1231231231?reciever-name=John%20Doe" as PaytoString;
+
+ t.is(stringifyPaytoUri(parsePaytoUri(payto1)!), payto1);
+});
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
index ac21fc398..ff33519c5 100644
--- a/packages/taler-util/src/payto.ts
+++ b/packages/taler-util/src/payto.ts
@@ -15,7 +15,14 @@
*/
import { generateFakeSegwitAddress } from "./bitcoin.js";
-import { Codec, Context, DecodingError, buildCodecForObject, codecForStringURL, renderContext } from "./codec.js";
+import {
+ Codec,
+ Context,
+ DecodingError,
+ buildCodecForObject,
+ codecForStringURL,
+ renderContext,
+} from "./codec.js";
import { AccessToken, codecForAccessToken, codecOptional } from "./index.js";
import { URLSearchParams } from "./url.js";
@@ -152,15 +159,33 @@ export function addPaytoQueryParams(
params: { [name: string]: string },
): string {
const [acct, search] = s.slice(paytoPfx.length).split("?");
- const searchParams = new URLSearchParams(search || "");
- const keys = Object.keys(params);
- if (keys.length === 0) {
+ const paramList = !params ? [] : Object.entries(params);
+ if (paramList.length === 0) {
return paytoPfx + acct;
}
- for (const k of keys) {
- searchParams.set(k, params[k]);
- }
- return paytoPfx + acct + "?" + searchParams.toString();
+ return paytoPfx + acct + "?" + createSearchParams(paramList);
+
+}
+
+/**
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#encoding_for_rfc3986
+ */
+function encodeRFC3986URIComponent(str: string): string {
+ return encodeURIComponent(str).replace(
+ /[!'()*]/g,
+ (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
+ );
+}
+const rfc3986 = encodeRFC3986URIComponent;
+
+/**
+ *
+ * https://www.rfc-editor.org/rfc/rfc3986
+ */
+function createSearchParams(paramList: [string, string][]): string {
+ return paramList
+ .map(([key, value]) => `${rfc3986(key)}=${rfc3986(value)}`)
+ .join("&");
}
/**
@@ -172,9 +197,7 @@ export function addPaytoQueryParams(
export function stringifyPaytoUri(p: PaytoUri): PaytoString {
const url = new URL(`${paytoPfx}${p.targetType}/${p.targetPath}`);
const paramList = !p.params ? [] : Object.entries(p.params);
- paramList.forEach(([key, value]) => {
- url.searchParams.set(key, value);
- });
+ url.search = createSearchParams(paramList)
return url.href as PaytoString;
}
@@ -206,7 +229,7 @@ export function parsePaytoUri(s: string): PaytoUri | undefined {
const searchParams = new URLSearchParams(search || "");
searchParams.forEach((v, k) => {
- params[k] = v;
+ params[k] = decodeURIComponent(v);
});
if (targetType === "x-taler-bank") {
@@ -295,9 +318,9 @@ export function talerPaytoFromExchangeReserve(
/**
* The account letter is all the information
- * the merchant backend requires from the
+ * the merchant backend requires from the
* bank account to check transfer.
- *
+ *
*/
export type AccountLetter = {
accountURI: PaytoString;
@@ -305,10 +328,9 @@ export type AccountLetter = {
accountToken?: AccessToken;
};
-export const codecForAccountLetter =
- (): Codec<AccountLetter> =>
- buildCodecForObject<AccountLetter>()
- .property("infoURL", codecForStringURL(true))
- .property("accountURI", codecForPaytoString())
- .property("accountToken", codecOptional(codecForAccessToken()))
- .build("AccountLetter");
+export const codecForAccountLetter = (): Codec<AccountLetter> =>
+ buildCodecForObject<AccountLetter>()
+ .property("infoURL", codecForStringURL(true))
+ .property("accountURI", codecForPaytoString())
+ .property("accountToken", codecOptional(codecForAccessToken()))
+ .build("AccountLetter");