aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2019-12-06 12:47:28 +0100
committerFlorian Dold <florian.dold@gmail.com>2019-12-06 12:47:28 +0100
commitee1fc03ae82f2f4662041af3d4243113e92ffeaf (patch)
treeb01ab0adf1b2d551db3a4f4ee89b41379d945a54 /src/util
parentb4d36fca180602d6d90440f9ba257b92fc626e6c (diff)
downloadwallet-core-ee1fc03ae82f2f4662041af3d4243113e92ffeaf.tar.xz
case-insensitive URIs
Diffstat (limited to 'src/util')
-rw-r--r--src/util/taleruri-test.ts55
-rw-r--r--src/util/taleruri.ts81
2 files changed, 82 insertions, 54 deletions
diff --git a/src/util/taleruri-test.ts b/src/util/taleruri-test.ts
index c687a6717..de4a90697 100644
--- a/src/util/taleruri-test.ts
+++ b/src/util/taleruri-test.ts
@@ -22,23 +22,6 @@ import {
parseTipUri,
} from "./taleruri";
-test("taler pay url parsing: http(s)", t => {
- const url1 = "https://example.com/bar?spam=eggs";
- const r1 = parsePayUri(url1);
- if (!r1) {
- t.fail();
- return;
- }
- t.is(r1.downloadUrl, url1);
- t.is(r1.sessionId, undefined);
- const url2 = "http://example.com/bar?spam=eggs";
- const r2 = parsePayUri(url2);
- if (!r2) {
- t.fail();
- return;
- }
-});
-
test("taler pay url parsing: wrong scheme", t => {
const url1 = "talerfoo://";
const r1 = parsePayUri(url1);
@@ -56,7 +39,7 @@ test("taler pay url parsing: defaults", t => {
t.fail();
return;
}
- t.is(r1.downloadUrl, "https://example.com/public/proposal?order_id=myorder");
+ t.is(r1.merchantBaseUrl, "https://example.com/public/");
t.is(r1.sessionId, undefined);
const url2 = "taler://pay/example.com/-/-/myorder/mysession";
@@ -65,7 +48,7 @@ test("taler pay url parsing: defaults", t => {
t.fail();
return;
}
- t.is(r2.downloadUrl, "https://example.com/public/proposal?order_id=myorder");
+ t.is(r2.merchantBaseUrl, "https://example.com/public/");
t.is(r2.sessionId, "mysession");
});
@@ -76,7 +59,7 @@ test("taler pay url parsing: trailing parts", t => {
t.fail();
return;
}
- t.is(r1.downloadUrl, "https://example.com/public/proposal?order_id=myorder");
+ t.is(r1.merchantBaseUrl, "https://example.com/public/");
t.is(r1.sessionId, "mysession");
});
@@ -87,10 +70,8 @@ test("taler pay url parsing: instance", t => {
t.fail();
return;
}
- t.is(
- r1.downloadUrl,
- "https://example.com/public/instances/myinst/proposal?order_id=myorder",
- );
+ t.is(r1.merchantBaseUrl, "https://example.com/public/instances/myinst/");
+ t.is(r1.orderId, "myorder");
});
test("taler pay url parsing: path prefix and instance", t => {
@@ -100,10 +81,7 @@ test("taler pay url parsing: path prefix and instance", t => {
t.fail();
return;
}
- t.is(
- r1.downloadUrl,
- "https://example.com/mypfx/instances/myinst/proposal?order_id=myorder",
- );
+ t.is(r1.merchantBaseUrl, "https://example.com/mypfx/instances/myinst/");
});
test("taler pay url parsing: complex path prefix", t => {
@@ -113,10 +91,9 @@ test("taler pay url parsing: complex path prefix", t => {
t.fail();
return;
}
- t.is(
- r1.downloadUrl,
- "https://example.com/mypfx/public/proposal?order_id=myorder",
- );
+ t.is(r1.merchantBaseUrl, "https://example.com/mypfx/public/");
+ t.is(r1.orderId, "myorder");
+ t.is(r1.sessionId, undefined);
});
test("taler pay url parsing: complex path prefix and instance", t => {
@@ -126,10 +103,8 @@ test("taler pay url parsing: complex path prefix and instance", t => {
t.fail();
return;
}
- t.is(
- r1.downloadUrl,
- "https://example.com/mypfx/public/instances/foo/proposal?order_id=myorder",
- );
+ t.is(r1.merchantBaseUrl, "https://example.com/mypfx/public/instances/foo/");
+ t.is(r1.orderId, "myorder");
});
test("taler pay url parsing: non-https #1", t => {
@@ -138,8 +113,9 @@ test("taler pay url parsing: non-https #1", t => {
if (!r1) {
t.fail();
return;
- }
- t.is(r1.downloadUrl, "http://example.com/public/proposal?order_id=myorder");
+ }
+ t.is(r1.merchantBaseUrl, "http://example.com/public/");
+ t.is(r1.orderId, "myorder")
});
test("taler pay url parsing: non-https #2", t => {
@@ -149,7 +125,8 @@ test("taler pay url parsing: non-https #2", t => {
t.fail();
return;
}
- t.is(r1.downloadUrl, "https://example.com/public/proposal?order_id=myorder");
+ t.is(r1.merchantBaseUrl, "https://example.com/public/");
+ t.is(r1.orderId, "myorder");
});
test("taler withdraw uri parsing", t => {
diff --git a/src/util/taleruri.ts b/src/util/taleruri.ts
index 50886a916..f34b82a59 100644
--- a/src/util/taleruri.ts
+++ b/src/util/taleruri.ts
@@ -15,7 +15,8 @@
*/
export interface PayUriResult {
- downloadUrl: string;
+ merchantBaseUrl: string;
+ orderId: string;
sessionId?: string;
}
@@ -36,7 +37,7 @@ export interface TipUriResult {
export function parseWithdrawUri(s: string): WithdrawUriResult | undefined {
const pfx = "taler://withdraw/";
- if (!s.startsWith(pfx)) {
+ if (!s.toLowerCase().startsWith(pfx)) {
return undefined;
}
@@ -44,6 +45,20 @@ export function parseWithdrawUri(s: string): WithdrawUriResult | undefined {
let [host, path, withdrawId] = rest.split("/");
+ if (!host) {
+ return undefined;
+ }
+
+ host = host.toLowerCase();
+
+ if (!path) {
+ return undefined;
+ }
+
+ if (!withdrawId) {
+ return undefined;
+ }
+
if (path === "-") {
path = "api/withdraw-operation";
}
@@ -53,15 +68,45 @@ export function parseWithdrawUri(s: string): WithdrawUriResult | undefined {
};
}
-export function parsePayUri(s: string): PayUriResult | undefined {
- if (s.startsWith("https://") || s.startsWith("http://")) {
- return {
- downloadUrl: s,
- sessionId: undefined,
- };
+export const enum TalerUriType {
+ TalerPay = "taler-pay",
+ TalerWithdraw = "taler-withdraw",
+ TalerTip = "taler-tip",
+ TalerRefund = "taler-refund",
+ TalerNotifyReserve = "taler-notify-reserve",
+ Unknown = "unknown",
+}
+
+export function classifyTalerUri(s: string): TalerUriType {
+ const sl = s.toLowerCase();
+ if (sl.startsWith("taler://pay/")) {
+ return TalerUriType.TalerPay;
}
+ if (sl.startsWith("taler://tip/")) {
+ return TalerUriType.TalerTip;
+ }
+ if (sl.startsWith("taler://refund/")) {
+ return TalerUriType.TalerRefund;
+ }
+ if (sl.startsWith("taler://withdraw/")) {
+ return TalerUriType.TalerWithdraw;
+ }
+ if (sl.startsWith("taler://notify-reserve/")) {
+ return TalerUriType.TalerWithdraw;
+ }
+ return TalerUriType.Unknown;
+
+}
+
+export function getOrderDownloadUrl(merchantBaseUrl: string, orderId: string) {
+ const u = new URL("proposal", merchantBaseUrl);
+ u.searchParams.set("order_id", orderId);
+ return u.href
+}
+
+export function parsePayUri(s: string): PayUriResult | undefined {
const pfx = "taler://pay/";
- if (!s.startsWith(pfx)) {
+ if (!s.toLowerCase().startsWith(pfx)) {
return undefined;
}
@@ -75,6 +120,8 @@ export function parsePayUri(s: string): PayUriResult | undefined {
return undefined;
}
+ host = host.toLowerCase();
+
if (!maybePath) {
return undefined;
}
@@ -99,21 +146,21 @@ export function parsePayUri(s: string): PayUriResult | undefined {
protocol = "http";
}
- const downloadUrl =
+ const merchantBaseUrl =
`${protocol}://${host}/` +
decodeURIComponent(maybePath) +
- maybeInstancePath +
- `proposal?order_id=${orderId}`;
+ maybeInstancePath;
return {
- downloadUrl,
+ merchantBaseUrl,
+ orderId,
sessionId: maybeSessionid,
};
}
export function parseTipUri(s: string): TipUriResult | undefined {
const pfx = "taler://tip/";
- if (!s.startsWith(pfx)) {
+ if (!s.toLowerCase().startsWith(pfx)) {
return undefined;
}
@@ -125,6 +172,8 @@ export function parseTipUri(s: string): TipUriResult | undefined {
return undefined;
}
+ host = host.toLowerCase();
+
if (!maybePath) {
return undefined;
}
@@ -155,7 +204,7 @@ export function parseTipUri(s: string): TipUriResult | undefined {
export function parseRefundUri(s: string): RefundUriResult | undefined {
const pfx = "taler://refund/";
- if (!s.startsWith(pfx)) {
+ if (!s.toLowerCase().startsWith(pfx)) {
return undefined;
}
@@ -167,6 +216,8 @@ export function parseRefundUri(s: string): RefundUriResult | undefined {
return undefined;
}
+ host = host.toLowerCase();
+
if (!maybePath) {
return undefined;
}