refactor shop api event handling
This commit is contained in:
parent
93327f5274
commit
356a2eb01a
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
130
lib/shopApi.ts
Normal file
130
lib/shopApi.ts
Normal file
@ -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);
|
||||
});
|
||||
}
|
@ -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"]);
|
||||
|
||||
|
||||
})
|
||||
|
80
pages/execute-payment.html
Normal file
80
pages/execute-payment.html
Normal file
@ -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>
|
80
pages/offer-contract-from.html
Normal file
80
pages/offer-contract-from.html
Normal file
@ -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>
|
30
pages/offer-contract-from.tsx
Normal file
30
pages/offer-contract-from.tsx
Normal file
@ -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());
|
||||
|
||||
|
||||
}
|
@ -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"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user