aboutsummaryrefslogtreecommitdiff
path: root/extension/pages
diff options
context:
space:
mode:
Diffstat (limited to 'extension/pages')
-rw-r--r--extension/pages/confirm-contract.js10
-rw-r--r--extension/pages/confirm-contract.tsx2
-rw-r--r--extension/pages/confirm-create-reserve.html24
-rw-r--r--extension/pages/confirm-create-reserve.js201
-rw-r--r--extension/pages/confirm-create-reserve.tsx177
5 files changed, 311 insertions, 103 deletions
diff --git a/extension/pages/confirm-contract.js b/extension/pages/confirm-contract.js
index d715985b5..5e7d82f98 100644
--- a/extension/pages/confirm-contract.js
+++ b/extension/pages/confirm-contract.js
@@ -13,11 +13,11 @@
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
*/
-System.register(["../lib/web-common"], function(exports_1, context_1) {
+System.register(["../lib/wallet/helpers"], function(exports_1, context_1) {
/// <reference path="../lib/decl/handlebars/handlebars.d.ts" />
"use strict";
var __moduleName = context_1 && context_1.id;
- var web_common_1;
+ var helpers_1;
function prettyAmount(amount) {
var v = amount.value + amount.fraction / 1e6;
return v.toFixed(2) + " " + amount.currency;
@@ -55,15 +55,15 @@ System.register(["../lib/web-common"], function(exports_1, context_1) {
}
var c = d.offer.contract;
console.log("contract", c);
- document.location.href = web_common_1.substituteFulfillmentUrl(c.fulfillment_url, offer);
+ document.location.href = helpers_1.substituteFulfillmentUrl(c.fulfillment_url, offer);
});
}
}
exports_1("main", main);
return {
setters:[
- function (web_common_1_1) {
- web_common_1 = web_common_1_1;
+ function (helpers_1_1) {
+ helpers_1 = helpers_1_1;
}],
execute: function() {
}
diff --git a/extension/pages/confirm-contract.tsx b/extension/pages/confirm-contract.tsx
index 35d050c19..055490175 100644
--- a/extension/pages/confirm-contract.tsx
+++ b/extension/pages/confirm-contract.tsx
@@ -17,7 +17,7 @@
/// <reference path="../lib/decl/handlebars/handlebars.d.ts" />
"use strict";
-import {substituteFulfillmentUrl} from "../lib/web-common";
+import {substituteFulfillmentUrl} from "../lib/wallet/helpers";
declare var m: any;
diff --git a/extension/pages/confirm-create-reserve.html b/extension/pages/confirm-create-reserve.html
index 7af54a828..522efc872 100644
--- a/extension/pages/confirm-create-reserve.html
+++ b/extension/pages/confirm-create-reserve.html
@@ -4,6 +4,8 @@
<head>
<title>Taler Wallet: Select Taler Provider</title>
<script src="../lib/vendor/URI.js"></script>
+ <script src="../lib/i18n.js"></script>
+ <script src="../lib/vendor/mithril.js"></script>
<script src="../lib/vendor/system-csp-production.src.js"></script>
<script src="../lib/module-trampoline.js"></script>
<link rel="stylesheet" type="text/css" href="../style/wallet.css">
@@ -22,27 +24,7 @@
<section id="main">
<article>
- <p>
- You asked to withdraw <span id="show-amount">(loading...)</span> from your
- bank account.
- </p>
- <p>
- Please specify the base URL of the Taler mint you want to use. The Taler
- mint will process the payments, possibly for a fee. The mint underwrites
- electronic coins and will hold matching funds in reserve in its bank
- account. Mints are expected to be regularly audited by a trusted party to
- ensure that they have sufficient reserves to cover all outstanding
- obligations.
- </p>
-
- <div class="formish">
- <div class="form-row">
- <label for="mint-url">Mint URL</label>
- <input class="url" id="mint-url" type="text"
- value="http://mint.demo.taler.net/"/>
- </div>
- <button id="confirm">Confirm Mint Selection</button>
- </div>
+ <div id="mint-selection"></div>
</article>
</section>
diff --git a/extension/pages/confirm-create-reserve.js b/extension/pages/confirm-create-reserve.js
index 3ac757249..124abdf22 100644
--- a/extension/pages/confirm-create-reserve.js
+++ b/extension/pages/confirm-create-reserve.js
@@ -13,69 +13,176 @@
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
*/
-System.register(["../lib/web-common", "../lib/wallet/wallet"], function(exports_1, context_1) {
+System.register(["../lib/wallet/helpers", "../lib/wallet/types"], function(exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
- var web_common_1, wallet_1;
+ var helpers_1, types_1;
+ var DelayTimer, Controller;
function main() {
- function updateAmount() {
- var showAmount = document.getElementById("show-amount");
- console.log("Query is " + JSON.stringify(query));
- var amount = wallet_1.AmountJson.checked(JSON.parse(query.amount));
- showAmount.textContent = web_common_1.amountToPretty(amount);
- }
var url = URI(document.location.href);
var query = URI.parseQuery(url.query());
- updateAmount();
- document.getElementById("confirm").addEventListener("click", function (e) {
- var d = {
- mint: document.getElementById('mint-url').value,
- amount: JSON.parse(query.amount)
- };
- if (!d.mint) {
- // FIXME: indicate error instead!
- throw Error("mint missing");
- }
- if (!d.amount) {
- // FIXME: indicate error instead!
- throw Error("amount missing");
- }
- var cb = function (rawResp) {
- if (!rawResp) {
- throw Error("empty response");
- }
- if (!rawResp.error) {
- var resp = wallet_1.CreateReserveResponse.checked(rawResp);
- var q = {
- mint: resp.mint,
- reserve_pub: resp.reservePub,
- amount: query.amount,
- };
- var url_1 = URI(query.callback_url).addQuery(q);
- if (!url_1.is("absolute")) {
- throw Error("callback url is not absolute");
+ var amount = types_1.AmountJson.checked(JSON.parse(query.amount));
+ var callback_url = query.callback_url;
+ var MintSelection = {
+ controller: function () { return new Controller(); },
+ view: function (ctrl) {
+ var controls = [];
+ var mx = function () {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i - 0] = arguments[_i];
}
- document.location.href = url_1.href();
+ return controls.push(m.apply(void 0, args));
+ };
+ mx("p", (_a = ["The bank wants to create a reserve over ", "."], _a.raw = ["The bank wants to create a reserve over ", "."], i18n(_a, helpers_1.amountToPretty(amount))));
+ mx("input.url", {
+ type: "text",
+ spellcheck: false,
+ oninput: m.withAttr("value", ctrl.onUrlChanged.bind(ctrl)),
+ });
+ if (ctrl.isValidMint) {
+ mx("button", {
+ onclick: function () { return ctrl.confirmReserve(ctrl.url, amount, callback_url); }
+ }, "Confirm mint selection");
}
- else {
- document.body.innerHTML =
- "Oops, something went wrong. It looks like the bank could not\n transfer funds to the mint. Please go back to your bank's website\n to check what happened.";
+ if (ctrl.errorString) {
+ mx("p", ctrl.errorString);
}
- };
- chrome.runtime.sendMessage({ type: 'create-reserve', detail: d }, cb);
- });
+ return m("div", controls);
+ var _a;
+ }
+ };
+ m.mount(document.getElementById("mint-selection"), MintSelection);
}
exports_1("main", main);
return {
setters:[
- function (web_common_1_1) {
- web_common_1 = web_common_1_1;
+ function (helpers_1_1) {
+ helpers_1 = helpers_1_1;
},
- function (wallet_1_1) {
- wallet_1 = wallet_1_1;
+ function (types_1_1) {
+ types_1 = types_1_1;
}],
execute: function() {
"use strict";
+ /**
+ * Execute something after a delay, with the possibility
+ * to reset the delay.
+ */
+ DelayTimer = (function () {
+ function DelayTimer(ms, f) {
+ this.timerId = null;
+ this.f = f;
+ this.ms = ms;
+ }
+ DelayTimer.prototype.bump = function () {
+ var _this = this;
+ if (this.timerId !== null) {
+ window.clearTimeout(this.timerId);
+ }
+ var handler = function () {
+ _this.f();
+ };
+ this.timerId = window.setTimeout(handler, this.ms);
+ };
+ return DelayTimer;
+ }());
+ Controller = (function () {
+ function Controller() {
+ var _this = this;
+ this.url = null;
+ this.errorString = null;
+ this.isValidMint = false;
+ this.update();
+ this.timer = new DelayTimer(800, function () { return _this.update(); });
+ }
+ Controller.prototype.update = function () {
+ var _this = this;
+ var doUpdate = function () {
+ if (!_this.url) {
+ _this.errorString = (_a = ["Please enter a URL"], _a.raw = ["Please enter a URL"], i18n(_a));
+ return;
+ }
+ _this.errorString = null;
+ var parsedUrl = URI(_this.url);
+ if (parsedUrl.is("relative")) {
+ _this.errorString = (_b = ["The URL you've entered is not valid (must be absolute)"], _b.raw = ["The URL you've entered is not valid (must be absolute)"], i18n(_b));
+ return;
+ }
+ var keysUrl = URI("/keys").absoluteTo(helpers_1.canonicalizeBaseUrl(_this.url));
+ console.log("requesting keys from '" + keysUrl + "'");
+ _this.request = new XMLHttpRequest();
+ _this.request.onreadystatechange = function () {
+ if (_this.request.readyState == XMLHttpRequest.DONE) {
+ switch (_this.request.status) {
+ case 200:
+ _this.isValidMint = true;
+ break;
+ case 0:
+ _this.errorString = "unknown request error";
+ break;
+ default:
+ _this.errorString = "request failed with status " + _this.request.status;
+ break;
+ }
+ m.redraw();
+ }
+ };
+ _this.request.open("get", keysUrl.href());
+ _this.request.send();
+ var _a, _b;
+ };
+ doUpdate();
+ m.redraw();
+ console.log("got update");
+ };
+ Controller.prototype.reset = function () {
+ this.isValidMint = false;
+ this.errorString = null;
+ if (this.request) {
+ this.request.abort();
+ this.request = null;
+ }
+ m.redraw();
+ };
+ Controller.prototype.confirmReserve = function (mint, amount, callback_url) {
+ var _this = this;
+ var d = { mint: mint, amount: amount };
+ var cb = function (rawResp) {
+ if (!rawResp) {
+ throw Error("empty response");
+ }
+ if (!rawResp.error) {
+ var resp = types_1.CreateReserveResponse.checked(rawResp);
+ var q = {
+ mint: resp.mint,
+ reserve_pub: resp.reservePub,
+ amount_value: amount.value,
+ amount_fraction: amount.fraction,
+ amount_currency: amount.currency,
+ };
+ var url = URI(callback_url).addQuery(q);
+ if (!url.is("absolute")) {
+ throw Error("callback url is not absolute");
+ }
+ console.log("going to", url.href());
+ document.location.href = url.href();
+ }
+ else {
+ _this.reset();
+ _this.errorString = ("Oops, something went wrong." +
+ ("The wallet responded with error status (" + rawResp.error + ")."));
+ }
+ };
+ chrome.runtime.sendMessage({ type: 'create-reserve', detail: d }, cb);
+ };
+ Controller.prototype.onUrlChanged = function (url) {
+ this.reset();
+ this.url = url;
+ this.timer.bump();
+ };
+ return Controller;
+ }());
}
}
});
diff --git a/extension/pages/confirm-create-reserve.tsx b/extension/pages/confirm-create-reserve.tsx
index 6a130eeff..8cb46559b 100644
--- a/extension/pages/confirm-create-reserve.tsx
+++ b/extension/pages/confirm-create-reserve.tsx
@@ -14,40 +14,107 @@
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
*/
-import {amountToPretty} from "../lib/web-common";
-import {AmountJson, CreateReserveResponse} from "../lib/wallet/wallet";
+import {amountToPretty, canonicalizeBaseUrl} from "../lib/wallet/helpers";
+import {AmountJson, CreateReserveResponse} from "../lib/wallet/types";
+
"use strict";
+declare var m: any;
-export function main() {
- function updateAmount() {
- let showAmount = document.getElementById("show-amount");
- console.log("Query is " + JSON.stringify(query));
- let amount = AmountJson.checked(JSON.parse(query.amount));
- showAmount.textContent = amountToPretty(amount);
+
+/**
+ * Execute something after a delay, with the possibility
+ * to reset the delay.
+ */
+class DelayTimer {
+ ms: number;
+ f;
+ timerId: number = null;
+
+ constructor(ms: number, f) {
+ this.f = f;
+ this.ms = ms;
+ }
+
+ bump() {
+ if (this.timerId !== null) {
+ window.clearTimeout(this.timerId);
+ }
+ const handler = () => {
+ this.f();
+ };
+ this.timerId = window.setTimeout(handler, this.ms);
}
+}
- let url = URI(document.location.href);
- let query: any = URI.parseQuery(url.query());
- updateAmount();
+class Controller {
+ url = null;
+ errorString = null;
+ isValidMint = false;
+ private timer: DelayTimer;
+ private request: XMLHttpRequest;
- document.getElementById("confirm").addEventListener("click", (e) => {
- const d = {
- mint: (document.getElementById('mint-url') as HTMLInputElement).value,
- amount: JSON.parse(query.amount)
+ constructor() {
+ this.update();
+ this.timer = new DelayTimer(800, () => this.update());
+ }
+
+ update() {
+ const doUpdate = () => {
+ if (!this.url) {
+ this.errorString = i18n`Please enter a URL`;
+ return;
+ }
+ this.errorString = null;
+ let parsedUrl = URI(this.url);
+ if (parsedUrl.is("relative")) {
+ this.errorString = i18n`The URL you've entered is not valid (must be absolute)`;
+ return;
+ }
+
+ const keysUrl = URI("/keys").absoluteTo(canonicalizeBaseUrl(this.url));
+
+ console.log(`requesting keys from '${keysUrl}'`);
+
+ this.request = new XMLHttpRequest();
+ this.request.onreadystatechange = () => {
+ if (this.request.readyState == XMLHttpRequest.DONE) {
+ switch (this.request.status) {
+ case 200:
+ this.isValidMint = true;
+ break;
+ case 0:
+ this.errorString = `unknown request error`;
+ break;
+ default:
+ this.errorString = `request failed with status ${this.request.status}`;
+ break;
+ }
+ m.redraw();
+ }
+ };
+ this.request.open("get", keysUrl.href());
+ this.request.send();
};
- if (!d.mint) {
- // FIXME: indicate error instead!
- throw Error("mint missing");
- }
+ doUpdate();
+ m.redraw();
+ console.log("got update");
+ }
- if (!d.amount) {
- // FIXME: indicate error instead!
- throw Error("amount missing");
+ reset() {
+ this.isValidMint = false;
+ this.errorString = null;
+ if (this.request) {
+ this.request.abort();
+ this.request = null;
}
+ m.redraw();
+ }
+ confirmReserve(mint: string, amount: AmountJson, callback_url: string) {
+ const d = {mint, amount};
const cb = (rawResp) => {
if (!rawResp) {
throw Error("empty response");
@@ -57,20 +124,72 @@ export function main() {
let q = {
mint: resp.mint,
reserve_pub: resp.reservePub,
- amount: query.amount,
+ amount_value: amount.value,
+ amount_fraction: amount.fraction,
+ amount_currency: amount.currency,
};
- let url = URI(query.callback_url).addQuery(q);
+ let url = URI(callback_url).addQuery(q);
if (!url.is("absolute")) {
throw Error("callback url is not absolute");
}
+ console.log("going to", url.href());
document.location.href = url.href();
} else {
- document.body.innerHTML =
- `Oops, something went wrong. It looks like the bank could not
- transfer funds to the mint. Please go back to your bank's website
- to check what happened.`;
+ this.reset();
+ this.errorString = (
+ `Oops, something went wrong.` +
+ `The wallet responded with error status (${rawResp.error}).`);
}
};
chrome.runtime.sendMessage({type: 'create-reserve', detail: d}, cb);
- });
+ }
+
+ onUrlChanged(url: string) {
+ this.reset();
+ this.url = url;
+ this.timer.bump();
+ }
+}
+
+
+export function main() {
+ const url = URI(document.location.href);
+ const query: any = URI.parseQuery(url.query());
+ const amount = AmountJson.checked(JSON.parse(query.amount));
+ const callback_url = query.callback_url;
+
+ var MintSelection = {
+ controller: () => new Controller(),
+ view(ctrl: Controller) {
+ let controls = [];
+ let mx = (...args) => controls.push(m(...args));
+
+ mx("p",
+ i18n`The bank wants to create a reserve over ${amountToPretty(
+ amount)}.`);
+ mx("input.url",
+ {
+ type: "text",
+ spellcheck: false,
+ oninput: m.withAttr("value", ctrl.onUrlChanged.bind(ctrl)),
+ });
+
+ if (ctrl.isValidMint) {
+ mx("button", {
+ onclick: () => ctrl.confirmReserve(ctrl.url,
+ amount,
+ callback_url)
+ },
+ "Confirm mint selection");
+ }
+
+ if (ctrl.errorString) {
+ mx("p", ctrl.errorString);
+ }
+
+ return m("div", controls);
+ }
+ };
+
+ m.mount(document.getElementById("mint-selection"), MintSelection);
} \ No newline at end of file