aboutsummaryrefslogtreecommitdiff
path: root/lib/wallet/wxMessaging.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/wallet/wxMessaging.ts')
-rw-r--r--lib/wallet/wxMessaging.ts92
1 files changed, 83 insertions, 9 deletions
diff --git a/lib/wallet/wxMessaging.ts b/lib/wallet/wxMessaging.ts
index a8dc27524..9c08b20ca 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";
@@ -48,11 +54,17 @@ function makeHandlers(db: IDBDatabase,
return exportDb(db);
},
["ping"]: function(detail, sender) {
- return Promise.resolve({});
+ if (!sender || !sender.tab || !sender.tab.id) {
+ return Promise.resolve();
+ }
+ let id: number = sender.tab.id;
+ let info: any = <any>paymentRequestCookies[id];
+ delete paymentRequestCookies[id];
+ return Promise.resolve(info);
},
["reset"]: function(detail, sender) {
if (db) {
- let tx = db.transaction(db.objectStoreNames, 'readwrite');
+ let tx = db.transaction(Array.from(db.objectStoreNames), 'readwrite');
for (let i = 0; i < db.objectStoreNames.length; i++) {
tx.objectStore(db.objectStoreNames[i]).clear();
}
@@ -81,7 +93,7 @@ function makeHandlers(db: IDBDatabase,
return wallet.confirmReserve(req);
},
["confirm-pay"]: function(detail, sender) {
- let offer;
+ let offer: Offer;
try {
offer = Offer.checked(detail.offer);
} catch (e) {
@@ -100,7 +112,7 @@ function makeHandlers(db: IDBDatabase,
return wallet.confirmPay(offer);
},
["check-pay"]: function(detail, sender) {
- let offer;
+ let offer: Offer;
try {
offer = Offer.checked(detail.offer);
} catch (e) {
@@ -173,14 +185,14 @@ class ChromeBadge implements Badge {
}
-function dispatch(handlers, req, sender, sendResponse) {
+function dispatch(handlers: any, req: any, sender: any, sendResponse: any) {
if (req.type in handlers) {
Promise
.resolve()
.then(() => {
const p = handlers[req.type](req.detail, sender);
- return p.then((r) => {
+ return p.then((r: any) => {
sendResponse(r);
})
})
@@ -231,12 +243,58 @@ class ChromeNotifier implements Notifier {
}
+/**
+ * Mapping from tab ID to payment information (if any).
+ */
+let paymentRequestCookies: {[n: number]: any} = {};
+
+function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[],
+ url: string, tabId: number): any {
+ const headers: {[s: string]: string} = {};
+ for (let kv of headerList) {
+ if (kv.value) {
+ headers[kv.name.toLowerCase()] = kv.value;
+ }
+ }
+
+ const contractUrl = headers["x-taler-contract-url"];
+ if (contractUrl !== undefined) {
+ paymentRequestCookies[tabId] = {type: "fetch", contractUrl};
+ return;
+ }
+
+ const contractHash = headers["x-taler-contract-hash"];
+
+ if (contractHash !== undefined) {
+ const payUrl = headers["x-taler-pay-url"];
+ if (payUrl === undefined) {
+ console.log("malformed 402, X-Taler-Pay-Url missing");
+ return;
+ }
+
+ // Offer URL is optional
+ const offerUrl = headers["x-taler-offer-url"];
+ paymentRequestCookies[tabId] = {
+ type: "execute",
+ offerUrl,
+ payUrl,
+ contractHash
+ };
+ return;
+ }
+
+ // 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");
+}
+
+
export function wxMain() {
chrome.browserAction.setBadgeText({text: ""});
chrome.tabs.query({}, function(tabs) {
for (let tab of tabs) {
- if (!tab.url) {
+ if (!tab.url || !tab.id) {
return;
}
let uri = URI(tab.url);
@@ -255,11 +313,14 @@ export function wxMain() {
console.error("could not open database");
console.error(e);
})
- .then((db) => {
+ .then((db: IDBDatabase) => {
let http = new BrowserHttpLib();
let badge = new ChromeBadge();
let notifier = new ChromeNotifier();
let wallet = new Wallet(db, http, badge, notifier);
+
+ // Handlers for messages coming directly from the content
+ // script on the page
let handlers = makeHandlers(db, wallet);
chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
try {
@@ -276,6 +337,19 @@ export function wxMain() {
return false;
}
});
+
+ // Handlers for catching HTTP requests
+ chrome.webRequest.onHeadersReceived.addListener((details) => {
+ if (details.statusCode != 402) {
+ return;
+ }
+ console.log(`got 402 from ${details.url}`);
+ return handleHttpPayment(details.responseHeaders || [],
+ details.url,
+ details.tabId);
+ }, {urls: ["<all_urls>"]}, ["responseHeaders", "blocking"]);
+
+
})
.catch((e) => {
console.error("could not initialize wallet messaging");