aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-31 11:56:26 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-31 11:57:09 +0200
commit87f981d91c952e7351a06b42aa88d2401addc8f2 (patch)
treebb224a73cdb8947f6d59884b754cb8ad019cc445 /src
parent04a7800bc8c27475585fbad36c74b13a8cd814c8 (diff)
improve backend / content script messaging
Diffstat (limited to 'src')
-rw-r--r--src/webex/notify.ts137
-rw-r--r--src/webex/wxApi.ts49
-rw-r--r--src/webex/wxBackend.ts6
3 files changed, 69 insertions, 123 deletions
diff --git a/src/webex/notify.ts b/src/webex/notify.ts
index 9823c5bd2..81bc6808d 100644
--- a/src/webex/notify.ts
+++ b/src/webex/notify.ts
@@ -21,7 +21,6 @@
* to interact with the GNU Taler wallet via DOM Events.
*/
-
/**
* Imports.
*/
@@ -48,55 +47,6 @@ interface Handler {
}
const handlers: Handler[] = [];
-function queryPayment(url: string): Promise<any> {
- const walletMsg = {
- detail: { url },
- type: "query-payment",
- };
- return new Promise((resolve, reject) => {
- chrome.runtime.sendMessage(walletMsg, (resp: any) => {
- resolve(resp);
- });
- });
-}
-
-function putHistory(historyEntry: any): Promise<void> {
- const walletMsg = {
- detail: {
- historyEntry,
- },
- type: "put-history-entry",
- };
- return new Promise<void>((resolve, reject) => {
- chrome.runtime.sendMessage(walletMsg, (resp: any) => {
- resolve();
- });
- });
-}
-
-function saveOffer(offer: any): Promise<number> {
- const walletMsg = {
- detail: {
- offer: {
- H_contract: offer.hash,
- contract: offer.data,
- merchant_sig: offer.sig,
- offer_time: new Date().getTime() / 1000,
- },
- type: "save-offer",
- },
- };
- return new Promise<number>((resolve, reject) => {
- chrome.runtime.sendMessage(walletMsg, (resp: any) => {
- if (resp && resp.error) {
- reject(resp);
- } else {
- resolve(resp);
- }
- });
- });
-}
-
let sheet: CSSStyleSheet|null;
@@ -153,7 +103,7 @@ function handlePaymentResponse(walletResp: any) {
* Try to notify the wallet first, before we show a potentially
* synchronous error message (such as an alert) or leave the page.
*/
- function handleFailedPayment(r: XMLHttpRequest) {
+ async function handleFailedPayment(r: XMLHttpRequest) {
let timeoutHandle: number|null = null;
function err() {
// FIXME: proper error reporting!
@@ -165,13 +115,12 @@ function handlePaymentResponse(walletResp: any) {
}
timeoutHandle = window.setTimeout(onTimeout, 200);
- talerPaymentFailed(walletResp.H_contract).then(() => {
- if (timeoutHandle !== null) {
- clearTimeout(timeoutHandle);
- timeoutHandle = null;
- }
- err();
- });
+ await wxApi.paymentFailed(walletResp.H_contract);
+ if (timeoutHandle !== null) {
+ clearTimeout(timeoutHandle);
+ timeoutHandle = null;
+ }
+ err();
}
logVerbose && console.log("handling taler-notify-payment: ", walletResp);
@@ -185,7 +134,7 @@ function handlePaymentResponse(walletResp: any) {
r.open("post", walletResp.contract.pay_url);
r.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
r.send(JSON.stringify(walletResp.payReq));
- r.onload = () => {
+ r.onload = async () => {
if (!r) {
return;
}
@@ -193,12 +142,11 @@ function handlePaymentResponse(walletResp: any) {
case 200:
const merchantResp = JSON.parse(r.responseText);
logVerbose && console.log("got success from pay_url");
- talerPaymentSucceeded({H_contract: walletResp.H_contract, merchantSig: merchantResp.sig}).then(() => {
- const nextUrl = walletResp.contract.fulfillment_url;
- logVerbose && console.log("taler-payment-succeeded done, going to", nextUrl);
- window.location.href = nextUrl;
- window.location.reload(true);
- });
+ await wxApi.paymentSucceeded(walletResp.H_contract, merchantResp.sig);
+ const nextUrl = walletResp.contract.fulfillment_url;
+ logVerbose && console.log("taler-payment-succeeded done, going to", nextUrl);
+ window.location.href = nextUrl;
+ window.location.reload(true);
break;
default:
handleFailedPayment(r);
@@ -226,6 +174,8 @@ function handlePaymentResponse(walletResp: any) {
function init() {
+ // Only place where we don't use the nicer RPC wrapper, since the wallet
+ // backend might not be ready (during install, upgrade, etc.)
chrome.runtime.sendMessage({type: "get-tab-cookie"}, (resp) => {
if (chrome.runtime.lastError) {
logVerbose && console.log("extension not yet ready");
@@ -267,17 +217,6 @@ function init() {
type HandlerFn = (detail: any, sendResponse: (msg: any) => void) => void;
-function generateNonce(): Promise<string> {
- const walletMsg = {
- type: "generate-nonce",
- };
- return new Promise<string>((resolve, reject) => {
- chrome.runtime.sendMessage(walletMsg, (resp: any) => {
- resolve(resp);
- });
- });
-}
-
function downloadContract(url: string, nonce: string): Promise<any> {
const parsed_url = new URI(url);
url = parsed_url.setQuery({nonce}).href();
@@ -361,8 +300,8 @@ async function processProposal(proposal: any) {
timestamp: (new Date()).getTime(),
type: "offer-contract",
};
- await putHistory(historyEntry);
- const offerId = await saveOffer(proposal);
+ await wxApi.putHistory(historyEntry);
+ const offerId = await wxApi.saveOffer(proposal);
const uri = new URI(chrome.extension.getURL(
"/src/webex/pages/confirm-contract.html"));
@@ -377,14 +316,14 @@ function talerPay(msg: any): Promise<any> {
return new Promise(async(resolve, reject) => {
// current URL without fragment
const url = new URI(document.location.href).fragment("").href();
- const res = await queryPayment(url);
+ const res = await wxApi.queryPayment(url);
logVerbose && console.log("taler-pay: got response", res);
if (res && res.payReq) {
resolve(res);
return;
}
if (msg.contract_url) {
- const nonce = await generateNonce();
+ const nonce = await wxApi.generateNonce();
const proposal = await downloadContract(msg.contract_url, nonce);
if (proposal.data.nonce !== nonce) {
console.error("stale contract");
@@ -403,44 +342,6 @@ function talerPay(msg: any): Promise<any> {
});
}
-function talerPaymentFailed(H_contract: string) {
- return new Promise(async(resolve, reject) => {
- const walletMsg = {
- detail: {
- contractHash: H_contract,
- },
- type: "payment-failed",
- };
- chrome.runtime.sendMessage(walletMsg, (resp) => {
- resolve();
- });
- });
-}
-
-function talerPaymentSucceeded(msg: any) {
- return new Promise((resolve, reject) => {
- if (!msg.H_contract) {
- console.error("H_contract missing in taler-payment-succeeded");
- return;
- }
- if (!msg.merchantSig) {
- console.error("merchantSig missing in taler-payment-succeeded");
- return;
- }
- logVerbose && console.log("got taler-payment-succeeded");
- const walletMsg = {
- detail: {
- contractHash: msg.H_contract,
- merchantSig: msg.merchantSig,
- },
- type: "payment-succeeded",
- };
- chrome.runtime.sendMessage(walletMsg, (resp) => {
- resolve();
- });
- });
-}
-
function registerHandlers() {
/**
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index 248cb04b5..ff601b6f7 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -196,9 +196,10 @@ export function hashContract(contract: object): Promise<string> {
}
/**
- * Save an offer in the wallet.
+ * Save an offer in the wallet. Returns the offer id that
+ * the offer is stored under.
*/
-export function saveOffer(offer: object): Promise<void> {
+export function saveOffer(offer: object): Promise<number> {
return callBackend("save-offer", { offer });
}
@@ -208,3 +209,47 @@ export function saveOffer(offer: object): Promise<void> {
export function confirmReserve(reservePub: string): Promise<void> {
return callBackend("confirm-reserve", { reservePub });
}
+
+/**
+ * Query for a payment by fulfillment URL.
+ */
+export function queryPayment(url: string): Promise<any> {
+ return callBackend("query-payment", { url });
+}
+
+/**
+ * Add a new history item.
+ */
+export function putHistory(historyEntry: any): Promise<void> {
+ return callBackend("put-history-entry", { historyEntry });
+}
+
+/**
+ * Mark a payment as succeeded.
+ */
+export function paymentSucceeded(contractTermsHash: string, merchantSig: string): Promise<void> {
+ return callBackend("payment-succeeded", { contractTermsHash, merchantSig });
+}
+
+/**
+ * Mark a payment as succeeded.
+ */
+export function paymentFailed(contractTermsHash: string): Promise<void> {
+ return callBackend("payment-failed", { contractTermsHash });
+}
+
+/**
+ * Get the payment cookie for the current tab, or undefined if no payment
+ * cookie was set.
+ */
+export function getTabCookie(contractTermsHash: string, merchantSig: string): Promise<any> {
+ return callBackend("get-tab-cookie");
+}
+
+/**
+ * Generate a contract nonce (EdDSA key pair), store it in the wallet's
+ * database and return the public key.
+ */
+export function generateNonce(): Promise<string> {
+ return callBackend("generate-nonce");
+}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 49f6e7112..816ce0251 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -285,15 +285,15 @@ function makeHandlers(db: IDBDatabase,
return Promise.resolve();
},
["payment-succeeded"]: (detail, sender) => {
- const contractHash = detail.contractHash;
+ const contractTermsHash = detail.contractTermsHash;
const merchantSig = detail.merchantSig;
- if (!contractHash) {
+ if (!contractTermsHash) {
return Promise.reject(Error("contractHash missing"));
}
if (!merchantSig) {
return Promise.reject(Error("merchantSig missing"));
}
- return wallet.paymentSucceeded(contractHash, merchantSig);
+ return wallet.paymentSucceeded(contractTermsHash, merchantSig);
},
};
}