aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2016-09-06 14:39:45 +0200
committerFlorian Dold <florian.dold@gmail.com>2016-09-06 14:39:45 +0200
commit356a2eb01a792e4e5ef1887ef02ad2d7c1613ca3 (patch)
tree0b9a1b77a7bfcfd8a185e405556e1803826322bf
parent93327f5274d3a081d56a41df0809f4c4e7535c99 (diff)
refactor shop api event handling
-rw-r--r--content_scripts/notify.ts110
-rw-r--r--lib/shopApi.ts130
-rw-r--r--lib/wallet/wxMessaging.ts35
-rw-r--r--pages/execute-payment.html80
-rw-r--r--pages/offer-contract-from.html80
-rw-r--r--pages/offer-contract-from.tsx30
-rw-r--r--tsconfig.json2
7 files changed, 345 insertions, 122 deletions
diff --git a/content_scripts/notify.ts b/content_scripts/notify.ts
index 54d7b6acb..f5c3fb575 100644
--- a/content_scripts/notify.ts
+++ b/content_scripts/notify.ts
@@ -27,18 +27,14 @@
"use strict";
+import {createReserve, confirmContract, executeContract} from "../lib/shopApi";
+
// Make sure we don't pollute the namespace too much.
namespace TalerNotify {
const PROTOCOL_VERSION = 1;
console.log("Taler injected", chrome.runtime.id);
- function subst(url: string, H_contract) {
- url = url.replace("${H_contract}", H_contract);
- url = url.replace("${$}", "$");
- return url;
- }
-
const handlers = [];
function init() {
@@ -65,8 +61,6 @@ namespace TalerNotify {
init();
function registerHandlers() {
- const $ = (x) => document.getElementById(x);
-
function addHandler(type, listener) {
document.addEventListener(type, listener);
handlers.push({type, listener});
@@ -91,16 +85,7 @@ namespace TalerNotify {
});
addHandler("taler-create-reserve", function(e: CustomEvent) {
- console.log("taler-create-reserve with " + JSON.stringify(e.detail));
- let params = {
- amount: JSON.stringify(e.detail.amount),
- callback_url: URI(e.detail.callback_url)
- .absoluteTo(document.location.href),
- bank_url: document.location.href,
- wt_types: JSON.stringify(e.detail.wt_types),
- };
- let uri = URI(chrome.extension.getURL("pages/confirm-create-reserve.html"));
- document.location.href = uri.query(params).href();
+ createReserve(e.detail.amount, e.detail.callback_url, e.detail.wt_types);
});
addHandler("taler-confirm-reserve", function(e: CustomEvent) {
@@ -116,53 +101,8 @@ namespace TalerNotify {
});
});
-
addHandler("taler-confirm-contract", function(e: CustomEvent) {
- if (!e.detail.contract_wrapper) {
- console.error("contract wrapper missing");
- return;
- }
-
- const offer = e.detail.contract_wrapper;
-
- if (!offer.contract) {
- console.error("contract field missing");
- return;
- }
-
- const msg = {
- type: "check-repurchase",
- detail: {
- contract: offer.contract
- },
- };
-
- chrome.runtime.sendMessage(msg, (resp) => {
- if (resp.error) {
- console.error("wallet backend error", resp);
- return;
- }
- if (resp.isRepurchase) {
- console.log("doing repurchase");
- console.assert(resp.existingFulfillmentUrl);
- console.assert(resp.existingContractHash);
- window.location.href = subst(resp.existingFulfillmentUrl,
- resp.existingContractHash);
-
- } else {
- const uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
- const params = {
- offer: JSON.stringify(offer),
- merchantPageUrl: document.location.href,
- };
- const target = uri.query(params).href();
- if (e.detail.replace_navigation === true) {
- document.location.replace(target);
- } else {
- document.location.href = target;
- }
- }
- });
+ confirmContract(e.detail.contract_wrapper, e.detail.replace_navigation);
});
addHandler("taler-payment-failed", (e: CustomEvent) => {
@@ -178,48 +118,8 @@ namespace TalerNotify {
});
});
- // Should be: taler-request-payment, taler-result-payment
-
addHandler("taler-execute-contract", (e: CustomEvent) => {
- console.log("got taler-execute-contract in content page");
- const msg = {
- type: "execute-payment",
- detail: {
- H_contract: e.detail.H_contract,
- },
- };
-
- chrome.runtime.sendMessage(msg, (resp) => {
- console.log("got resp");
- console.dir(resp);
- if (!resp.success) {
- console.log("got event detial:");
- console.dir(e.detail);
- if (e.detail.offering_url) {
- console.log("offering url", e.detail.offering_url);
- window.location.href = e.detail.offering_url;
- } else {
- console.error("execute-payment failed");
- }
- return;
- }
- let contract = resp.contract;
- if (!contract) {
- throw Error("contract missing");
- }
-
- // We have the details for then payment, the merchant page
- // is responsible to give it to the merchant.
-
- let evt = new CustomEvent("taler-notify-payment", {
- detail: {
- H_contract: e.detail.H_contract,
- contract: resp.contract,
- payment: resp.payReq,
- }
- });
- document.dispatchEvent(evt);
- });
+ executeContract(e.detail.H_contract, e.detail.offering_url);
});
}
} \ No newline at end of file
diff --git a/lib/shopApi.ts b/lib/shopApi.ts
new file mode 100644
index 000000000..b110e2e75
--- /dev/null
+++ b/lib/shopApi.ts
@@ -0,0 +1,130 @@
+/*
+ This file is part of TALER
+ (C) 2015 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+
+/**
+ * Implementation of the shop API, either invoked via HTTP or
+ * via a JS DOM Events.
+ *
+ * @author Florian Dold
+ */
+
+
+
+function subst(url: string, H_contract) {
+ url = url.replace("${H_contract}", H_contract);
+ url = url.replace("${$}", "$");
+ return url;
+}
+
+export function createReserve(amount: any, callback_url: any, wt_types: any) {
+ let params = {
+ amount: JSON.stringify(amount),
+ callback_url: URI(callback_url)
+ .absoluteTo(document.location.href),
+ bank_url: document.location.href,
+ wt_types: JSON.stringify(wt_types),
+ };
+ let uri = URI(chrome.extension.getURL("pages/confirm-create-reserve.html"));
+ document.location.href = uri.query(params).href();
+}
+
+export function confirmContract(contract_wrapper: any, replace_navigation: any) {
+ if (contract_wrapper) {
+ console.error("contract wrapper missing");
+ return;
+ }
+
+ const offer = contract_wrapper;
+
+ if (!offer.contract) {
+ console.error("contract field missing");
+ return;
+ }
+
+ const msg = {
+ type: "check-repurchase",
+ detail: {
+ contract: offer.contract
+ },
+ };
+
+ chrome.runtime.sendMessage(msg, (resp) => {
+ if (resp.error) {
+ console.error("wallet backend error", resp);
+ return;
+ }
+ if (resp.isRepurchase) {
+ console.log("doing repurchase");
+ console.assert(resp.existingFulfillmentUrl);
+ console.assert(resp.existingContractHash);
+ window.location.href = subst(resp.existingFulfillmentUrl,
+ resp.existingContractHash);
+
+ } else {
+ const uri = URI(chrome.extension.getURL("pages/confirm-contract.html"));
+ const params = {
+ offer: JSON.stringify(offer),
+ merchantPageUrl: document.location.href,
+ };
+ const target = uri.query(params).href();
+ if (replace_navigation === true) {
+ document.location.replace(target);
+ } else {
+ document.location.href = target;
+ }
+ }
+ });
+}
+
+
+export function executeContract(H_contract: any, offering_url: any) {
+ console.log("got taler-execute-contract in content page");
+ const msg = {
+ type: "execute-payment",
+ detail: {H_contract},
+ };
+
+ chrome.runtime.sendMessage(msg, (resp) => {
+ console.log("got resp");
+ console.dir(resp);
+ if (!resp.success) {
+ if (offering_url) {
+ console.log("offering url", offering_url);
+ window.location.href = offering_url;
+ } else {
+ console.error("execute-payment failed");
+ }
+ return;
+ }
+ let contract = resp.contract;
+ if (!contract) {
+ throw Error("contract missing");
+ }
+
+ // We have the details for then payment, the merchant page
+ // is responsible to give it to the merchant.
+
+ let evt = new CustomEvent("taler-notify-payment", {
+ detail: {
+ H_contract: H_contract,
+ contract: resp.contract,
+ payment: resp.payReq,
+ }
+ });
+ document.dispatchEvent(evt);
+ });
+} \ No newline at end of file
diff --git a/lib/wallet/wxMessaging.ts b/lib/wallet/wxMessaging.ts
index 68c744901..faff0d220 100644
--- a/lib/wallet/wxMessaging.ts
+++ b/lib/wallet/wxMessaging.ts
@@ -15,7 +15,13 @@
*/
-import {Wallet, Offer, Badge, ConfirmReserveRequest, CreateReserveRequest} from "./wallet";
+import {
+ Wallet,
+ Offer,
+ Badge,
+ ConfirmReserveRequest,
+ CreateReserveRequest
+} from "./wallet";
import {deleteDb, exportDb, openTalerDb} from "./db";
import {BrowserHttpLib} from "./http";
import {Checkable} from "./checkable";
@@ -230,16 +236,9 @@ class ChromeNotifier implements Notifier {
}
}
-function executePayment(contractHash: string, payUrl: string, offerUrl: string) {
-}
-
-function offerContractFromUrl(contractUrl: string) {
-
-}
-
-
-function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[], url) {
+function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[],
+ url): any {
const headers = {};
for (let kv of headerList) {
headers[kv.name.toLowerCase()] = kv.value;
@@ -249,8 +248,10 @@ function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[], url) {
if (contractUrl !== undefined) {
// The web shop is proposing a contract, we need to fetch it
// and show it to the user
- offerContractFromUrl(contractUrl);
- return;
+ const walletUrl = URI(chrome.extension.getURL(
+ "pages/offer-contract-from.html"));
+ walletUrl.query({contractUrl});
+ return {redirectUrl: walletUrl.href()};
}
const contractHash = headers["x-taler-contract-hash"];
@@ -264,14 +265,15 @@ function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[], url) {
// Offer URL is optional
const offerUrl = headers["x-taler-offer-url"];
- executePayment(contractHash, payUrl, offerUrl);
- return;
+ const walletUrl = URI(chrome.extension.getURL(
+ "pages/execute-payment.html"));
+ walletUrl.query({contractHash, offerUrl, payUrl});
+ return {redirectUrl: walletUrl.href()};
}
// looks like it's not a taler request, it might be
// for a different payment system (or the shop is buggy)
console.log("ignoring non-taler 402 response");
-
}
@@ -330,8 +332,7 @@ export function wxMain() {
return;
}
return handleHttpPayment(details.responseHeaders, details.url);
- details.responseHeaders
- }, {urls: ["<all_urls>"]}, ["responseHeaders"]);
+ }, {urls: ["<all_urls>"]}, ["responseHeaders", "blocking"]);
})
diff --git a/pages/execute-payment.html b/pages/execute-payment.html
new file mode 100644
index 000000000..b2ed86562
--- /dev/null
+++ b/pages/execute-payment.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Taler Wallet: Confirm Reserve Creation</title>
+
+ <link rel="stylesheet" type="text/css" href="../style/lang.css">
+
+ <script src="../lib/vendor/URI.js"></script>
+ <script src="../lib/vendor/mithril.js"></script>
+ <script src="../lib/vendor/lodash.core.min.js"></script>
+ <script src="../lib/vendor/system-csp-production.src.js"></script>
+ <script src="../lib/vendor/jed.js"></script>
+ <script src="../i18n/strings.js"></script>
+ <script src="../lib/i18n.js"></script>
+ <script src="../lib/module-trampoline.js"></script>
+
+ <style>
+ #main {
+ border: solid 1px black;
+ border-radius: 10px;
+ margin: auto;
+ max-width: 50%;
+ padding: 2em;
+ }
+
+ button.accept {
+ background-color: #5757D2;
+ border: 1px solid black;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: white;
+ }
+ button.linky {
+ background:none!important;
+ border:none;
+ padding:0!important;
+
+ font-family:arial,sans-serif;
+ color:#069;
+ text-decoration:underline;
+ cursor:pointer;
+ }
+
+ input.url {
+ width: 25em;
+ }
+
+
+ button.accept:disabled {
+ background-color: #dedbe8;
+ border: 1px solid white;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: #2C2C2C;
+ }
+
+ .errorbox {
+ border: 1px solid;
+ display: inline-block;
+ margin: 1em;
+ padding: 1em;
+ font-weight: bold;
+ background: #FF8A8A;
+ }
+ </style>
+</head>
+
+<body>
+ <section id="main">
+ <h1>GNU Taler Wallet</h1>
+ Executing payment ...
+ </section>
+</body>
+
+</html>
diff --git a/pages/offer-contract-from.html b/pages/offer-contract-from.html
new file mode 100644
index 000000000..7bf017c4e
--- /dev/null
+++ b/pages/offer-contract-from.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Taler Wallet: Confirm Reserve Creation</title>
+
+ <link rel="stylesheet" type="text/css" href="../style/lang.css">
+
+ <script src="../lib/vendor/URI.js"></script>
+ <script src="../lib/vendor/mithril.js"></script>
+ <script src="../lib/vendor/lodash.core.min.js"></script>
+ <script src="../lib/vendor/system-csp-production.src.js"></script>
+ <script src="../lib/vendor/jed.js"></script>
+ <script src="../i18n/strings.js"></script>
+ <script src="../lib/i18n.js"></script>
+ <script src="../lib/module-trampoline.js"></script>
+
+ <style>
+ #main {
+ border: solid 1px black;
+ border-radius: 10px;
+ margin: auto;
+ max-width: 50%;
+ padding: 2em;
+ }
+
+ button.accept {
+ background-color: #5757D2;
+ border: 1px solid black;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: white;
+ }
+ button.linky {
+ background:none!important;
+ border:none;
+ padding:0!important;
+
+ font-family:arial,sans-serif;
+ color:#069;
+ text-decoration:underline;
+ cursor:pointer;
+ }
+
+ input.url {
+ width: 25em;
+ }
+
+
+ button.accept:disabled {
+ background-color: #dedbe8;
+ border: 1px solid white;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: #2C2C2C;
+ }
+
+ .errorbox {
+ border: 1px solid;
+ display: inline-block;
+ margin: 1em;
+ padding: 1em;
+ font-weight: bold;
+ background: #FF8A8A;
+ }
+ </style>
+</head>
+
+<body>
+ <section id="main">
+ <h1>GNU Taler Wallet</h1>
+ Fetching contract ...
+ </section>
+</body>
+
+</html>
diff --git a/pages/offer-contract-from.tsx b/pages/offer-contract-from.tsx
new file mode 100644
index 000000000..389e96876
--- /dev/null
+++ b/pages/offer-contract-from.tsx
@@ -0,0 +1,30 @@
+/*
+ This file is part of TALER
+ (C) 2015 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Download a contract from a Url (given as query parameter 'contractUrl' to
+ * this page) and offer the contract to the user.
+ *
+ * @author Florian Dold
+ */
+
+
+export function main() {
+ const url = URI(document.location.href);
+ const query: any = URI.parseQuery(url.query());
+
+
+} \ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 0e6337d86..5fa388aa9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,6 +12,7 @@
"files": [
"lib/i18n.ts",
"lib/refs.ts",
+ "lib/shopApi.ts",
"lib/wallet/checkable.ts",
"lib/wallet/cryptoApi.ts",
"lib/wallet/cryptoLib.ts",
@@ -31,6 +32,7 @@
"pages/show-db.ts",
"pages/confirm-contract.tsx",
"pages/confirm-create-reserve.tsx",
+ "pages/offer-contract-from.tsx",
"test/tests/taler.ts"
]
} \ No newline at end of file