diff options
| author | Adam Soltys <[email protected]> | 2015-12-11 11:28:18 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2015-12-11 11:29:30 -0800 |
| commit | f466c6aa4db08d953df9916fad8ba5d03020e0a0 (patch) | |
| tree | 14c139e53929cae7c7e39f5ad298780716be5c9a | |
| parent | 208311023aa6eb433d5e1201eafcd53fab0e6dbd (diff) | |
| download | coinos-server-f466c6aa4db08d953df9916fad8ba5d03020e0a0.tar.gz coinos-server-f466c6aa4db08d953df9916fad8ba5d03020e0a0.zip | |
Proxy blockcypher API requests
| -rw-r--r-- | app.js | 29 | ||||
| -rw-r--r-- | package.json | 2 | ||||
| -rw-r--r-- | public/js/wallet.coffee | 43 | ||||
| -rw-r--r-- | public/js/wallet.js | 47 | ||||
| -rw-r--r-- | src/app.coffee | 20 | ||||
| -rw-r--r-- | views/users/wallet.html | 3 |
6 files changed, 82 insertions, 62 deletions
@@ -1,5 +1,6 @@ (function() { - var RedisStore, app, authorize, bodyParser, cache, config, cookieParser, express, fetchRates, fs, passport, path, request, session, sessionStore, sessions, transactions, users; + var RedisStore, app, authorize, bodyParser, cache, config, cookieParser, express, fetchRates, fs, passport, path, proxy, proxyContext, proxyMiddleware, proxyOptions, request, session, sessionStore, sessions, transactions, users, + __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; request = require('request'); @@ -17,6 +18,8 @@ fs = require('fs'); + proxyMiddleware = require('http-proxy-middleware'); + sessions = require("./routes/sessions")(passport); transactions = require("./routes/transactions"); @@ -31,6 +34,23 @@ ttl: 172800 }); + proxyContext = '/blockcypher'; + + proxyOptions = { + target: 'https://api.blockcypher.com', + changeOrigin: true, + pathRewrite: { + '^/blockcypher/': '/' + }, + onProxyReq: function(proxyReq, req, res) { + var symbol; + symbol = __indexOf.call(proxyReq.path, '?') >= 0 ? '&' : '?'; + return proxyReq.path += "" + symbol + "token=" + config.blockcypher_token; + } + }; + + proxy = proxyMiddleware(proxyContext, proxyOptions); + app = express(); app.enable('trust proxy'); @@ -43,6 +63,8 @@ app.use(express["static"](__dirname + '/public')); + app.use(proxy); + app.use(bodyParser.urlencoded({ extended: true })); @@ -137,11 +159,6 @@ }); }); - app.get('/token', cache, function(req, res) { - res.write(config.blockcypher_token); - return res.end(); - }); - app.get('/tips', cache, function(req, res) { return res.render('tips', { notice: true, diff --git a/package.json b/package.json index d7ec101f..ace1ba6b 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,12 @@ "express": "4.6.1", "express-session": "^1.6.5", "hogan-express": "0.5.2", + "http-proxy-middleware": "^0.9.0", "jquery": "^2.1.4", "jquery-ui": "^1.10.5", "less": "1.7.3", "moment": "^2.10.6", + "node-http-proxy": "^0.2.3", "nodemailer": "~1.2.1", "passport": "0.2.0", "passport-local": "1.0.0", diff --git a/public/js/wallet.coffee b/public/js/wallet.coffee index ebe6826a..cfaac22b 100644 --- a/public/js/wallet.coffee +++ b/public/js/wallet.coffee @@ -1,15 +1,17 @@ g = exports ? this g.proceed = false -g.api = 'https://api.blockcypher.com/v1/btc/main' +g.api = '/blockcypher/v1/btc/main' validators = address: (e) -> + return true if e.val() is '' try bitcoin.address.fromBase58Check(e.val()) catch return false password: (e) -> + return true if e.val() is '' g.master = null try g.master = bitcoin.HDNode.fromBase58(CryptoJS.AES.decrypt($('#privkey').val(), e.val()).toString(CryptoJS.enc.Utf8)) @@ -17,13 +19,13 @@ validators = catch return false - errors = - address: 'Invalid address' - password: 'Wrong password' + address: 'Invalid address.' + password: 'Wrong password.' $(-> - getToken() + getUser() + $('form').validator(custom: validators, errors: errors) $('button[data-toggle=tooltip]').tooltip(trigger: 'hover') @@ -39,7 +41,7 @@ $(-> $.post("/#{g.user.username}", $('#keys form').serializeObject(), -> $.ajax( - url: "#{g.api}/wallets/hd/#{g.user.username}?token=#{g.token}" + url: "#{g.api}/wallets/hd/#{g.user.username}" type: 'DELETE' ).done(-> setTimeout(-> @@ -48,8 +50,8 @@ $(-> extended_public_key: $('#pubkey').val() subchain_indexes: [0,1] - $.post("#{g.api}/wallets/hd?token=#{g.token}", JSON.stringify(data)).always(-> - $.post("#{g.api}/wallets/hd/#{g.user.username}/addresses/derive?token=#{g.token}").always(-> + $.post("#{g.api}/wallets/hd", JSON.stringify(data)).always(-> + $.post("#{g.api}/wallets/hd/#{g.user.username}/addresses/derive").always(-> getBalance() ) ) @@ -79,11 +81,11 @@ $(-> $('#max').click(-> if $('#currency_toggle').html() is g.user.unit - $('#amount').val(g.balance) + $('#amount').val(g.balance).blur() else g.amount = parseFloat(g.balance).toFixed(precision()) amount = (g.balance / multiplier() * g.exchange).toFixed(2) - $('#amount').val(amount) + $('#amount').val(amount).blur() ) $('#amount').change(-> @@ -141,13 +143,6 @@ $(-> $('.close').on('click', -> $(this).closest('.alert').fadeOut()) ) - -getToken = -> - $.get("/token", (token) -> - g.token = token - getUser() - ) - getUser = -> $.getJSON("/#{$('#username').val()}.json", (user) -> g.user = user @@ -168,7 +163,7 @@ getExchangeRate = -> ) createWallet = -> - $.get("#{g.api}/wallets?token=#{g.token}", (data) -> + $.get("#{g.api}/wallets", (data) -> if g.user.username in data.wallet_names getBalance() else @@ -178,7 +173,7 @@ createWallet = -> extended_public_key: g.user.pubkey subchain_indexes: [0,1] - $.post("#{g.api}/wallets/hd?token=#{g.token}", JSON.stringify(data)).always(getBalance) + $.post("#{g.api}/wallets/hd", JSON.stringify(data)).always(getBalance) else # TODO implement this properly $('#balance').html(99) @@ -187,7 +182,7 @@ createWallet = -> getBalance = -> - $.get("#{g.api}/addrs/#{g.user.username}/balance?token=#{g.token}&omitWalletAddresses=true", (data) -> + $.get("#{g.api}/addrs/#{g.user.username}/balance?omitWalletAddresses=true", (data) -> balance = data.final_balance g.balance = balance.toBTC() fiat = balance.toFiat() @@ -227,7 +222,7 @@ sendTransaction = -> outputs: [{addresses: [$('#recipient').val()], value: 1}] preference: $('#priority').val() - $.post("#{g.api}/txs/new?token=#{g.token}", JSON.stringify(params)).done((data) -> + $.post("#{g.api}/txs/new", JSON.stringify(params)).done((data) -> if $('#currency_toggle').html() is g.user.unit amount = $('#amount').val() else @@ -240,7 +235,7 @@ sendTransaction = -> if value > parseFloat(g.balance).toSatoshis() - params.fees params.outputs[0].value -= params.fees - $.post("#{g.api}/txs/new?token=#{g.token}", JSON.stringify(params)).done((data) -> + $.post("#{g.api}/txs/new", JSON.stringify(params)).done((data) -> data.pubkeys = [] data.signatures = data.tosign.map((tosign, i) -> path = data.tx.inputs[i].hd_path.split('/') @@ -265,14 +260,14 @@ sendTransaction = -> dialog.getModalBody().html($('.dialog').html()) dialog.getModal().find('.btn-primary').click(-> - $.post("#{g.api}/txs/send?token=#{g.token}", JSON.stringify(g.data)).then((finaltx) -> + $.post("#{g.api}/txs/send", JSON.stringify(g.data)).then((finaltx) -> $('#transaction_sent').fadeIn() balance = g.balance.toSatoshis() - finaltx.tx.outputs[0].value - finaltx.tx.fees g.balance = balance.toBTC() fiat = balance.toFiat() $('#balance').html(g.balance) $('#fiat').html("#{fiat} #{g.user.currency}") - $('#blockchain').off('click').on('click', -> window.open('https://live.blockcypher.com/btc/main/' + finaltx.tx.hash, '_blank')) + $('#blockchain').off('click').on('click', -> window.open('https://live.blockcypher.com/btc/main/tx/' + finaltx.tx.hash, '_blank')) dialog.close() ) ) diff --git a/public/js/wallet.js b/public/js/wallet.js index d83b764d..cadd6db3 100644 --- a/public/js/wallet.js +++ b/public/js/wallet.js @@ -1,16 +1,19 @@ ;(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0](function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){ (function(){(function() { - var check_address, convertedAmount, createWallet, displayErrors, errors, g, getBalance, getExchangeRate, getToken, getUser, isBip32, multiplier, precision, sendTransaction, validators, + var check_address, convertedAmount, createWallet, displayErrors, errors, g, getBalance, getExchangeRate, getUser, isBip32, multiplier, precision, sendTransaction, validators, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; g = typeof exports !== "undefined" && exports !== null ? exports : this; g.proceed = false; - g.api = 'https://api.blockcypher.com/v1/btc/main'; + g.api = '/blockcypher/v1/btc/main'; validators = { address: function(e) { + if (e.val() === '') { + return true; + } try { return bitcoin.address.fromBase58Check(e.val()); } catch (_error) { @@ -18,6 +21,9 @@ } }, password: function(e) { + if (e.val() === '') { + return true; + } g.master = null; try { g.master = bitcoin.HDNode.fromBase58(CryptoJS.AES.decrypt($('#privkey').val(), e.val()).toString(CryptoJS.enc.Utf8)); @@ -29,12 +35,12 @@ }; errors = { - address: 'Invalid address', - password: 'Wrong password' + address: 'Invalid address.', + password: 'Wrong password.' }; $(function() { - getToken(); + getUser(); $('form').validator({ custom: validators, errors: errors @@ -52,7 +58,7 @@ $('#keys_updated').fadeIn(); $.post("/" + g.user.username, $('#keys form').serializeObject(), function() { return $.ajax({ - url: "" + g.api + "/wallets/hd/" + g.user.username + "?token=" + g.token, + url: "" + g.api + "/wallets/hd/" + g.user.username, type: 'DELETE' }).done(function() { return setTimeout(function() { @@ -62,8 +68,8 @@ extended_public_key: $('#pubkey').val(), subchain_indexes: [0, 1] }; - return $.post("" + g.api + "/wallets/hd?token=" + g.token, JSON.stringify(data)).always(function() { - return $.post("" + g.api + "/wallets/hd/" + g.user.username + "/addresses/derive?token=" + g.token).always(function() { + return $.post("" + g.api + "/wallets/hd", JSON.stringify(data)).always(function() { + return $.post("" + g.api + "/wallets/hd/" + g.user.username + "/addresses/derive").always(function() { return getBalance(); }); }); @@ -92,11 +98,11 @@ $('#max').click(function() { var amount; if ($('#currency_toggle').html() === g.user.unit) { - return $('#amount').val(g.balance); + return $('#amount').val(g.balance).blur(); } else { g.amount = parseFloat(g.balance).toFixed(precision()); amount = (g.balance / multiplier() * g.exchange).toFixed(2); - return $('#amount').val(amount); + return $('#amount').val(amount).blur(); } }); $('#amount').change(function() { @@ -152,13 +158,6 @@ }); }); - getToken = function() { - return $.get("/token", function(token) { - g.token = token; - return getUser(); - }); - }; - getUser = function() { return $.getJSON("/" + ($('#username').val()) + ".json", function(user) { g.user = user; @@ -180,7 +179,7 @@ }; createWallet = function() { - return $.get("" + g.api + "/wallets?token=" + g.token, function(data) { + return $.get("" + g.api + "/wallets", function(data) { var _ref; if (_ref = g.user.username, __indexOf.call(data.wallet_names, _ref) >= 0) { return getBalance(); @@ -191,7 +190,7 @@ extended_public_key: g.user.pubkey, subchain_indexes: [0, 1] }; - return $.post("" + g.api + "/wallets/hd?token=" + g.token, JSON.stringify(data)).always(getBalance); + return $.post("" + g.api + "/wallets/hd", JSON.stringify(data)).always(getBalance); } else { $('#balance').html(99); return $('#amount').val(99); @@ -201,7 +200,7 @@ }; getBalance = function() { - return $.get("" + g.api + "/addrs/" + g.user.username + "/balance?token=" + g.token + "&omitWalletAddresses=true", function(data) { + return $.get("" + g.api + "/addrs/" + g.user.username + "/balance?omitWalletAddresses=true", function(data) { var balance, fiat; balance = data.final_balance; g.balance = balance.toBTC(); @@ -257,7 +256,7 @@ ], preference: $('#priority').val() }; - return $.post("" + g.api + "/txs/new?token=" + g.token, JSON.stringify(params)).done(function(data) { + return $.post("" + g.api + "/txs/new", JSON.stringify(params)).done(function(data) { var amount, value; if ($('#currency_toggle').html() === g.user.unit) { amount = $('#amount').val(); @@ -270,7 +269,7 @@ if (value > parseFloat(g.balance).toSatoshis() - params.fees) { params.outputs[0].value -= params.fees; } - return $.post("" + g.api + "/txs/new?token=" + g.token, JSON.stringify(params)).done(function(data) { + return $.post("" + g.api + "/txs/new", JSON.stringify(params)).done(function(data) { var fee, total; data.pubkeys = []; data.signatures = data.tosign.map(function(tosign, i) { @@ -293,7 +292,7 @@ $('.dialog .address').html(data.tx.outputs[0].addresses[0]); dialog.getModalBody().html($('.dialog').html()); return dialog.getModal().find('.btn-primary').click(function() { - return $.post("" + g.api + "/txs/send?token=" + g.token, JSON.stringify(g.data)).then(function(finaltx) { + return $.post("" + g.api + "/txs/send", JSON.stringify(g.data)).then(function(finaltx) { var balance, fiat; $('#transaction_sent').fadeIn(); balance = g.balance.toSatoshis() - finaltx.tx.outputs[0].value - finaltx.tx.fees; @@ -302,7 +301,7 @@ $('#balance').html(g.balance); $('#fiat').html("" + fiat + " " + g.user.currency); $('#blockchain').off('click').on('click', function() { - return window.open('https://live.blockcypher.com/btc/main/' + finaltx.tx.hash, '_blank'); + return window.open('https://live.blockcypher.com/btc/main/tx/' + finaltx.tx.hash, '_blank'); }); return dialog.close(); }); diff --git a/src/app.coffee b/src/app.coffee index df3c0433..fc1eee37 100644 --- a/src/app.coffee +++ b/src/app.coffee @@ -6,6 +6,7 @@ path = require('path') passport = require('./passport') config = require('./config') fs = require('fs') +proxyMiddleware = require('http-proxy-middleware') sessions = require("./routes/sessions")(passport) transactions = require("./routes/transactions") @@ -15,12 +16,25 @@ session = require('express-session') RedisStore = require('connect-redis')(session) sessionStore = new RedisStore(require('./redis').host, ttl: 172800) +proxyContext = '/blockcypher' +proxyOptions = + target: 'https://api.blockcypher.com' + changeOrigin: true + pathRewrite: + '^/blockcypher/': '/' + onProxyReq: (proxyReq, req, res) -> + symbol = if '?' in proxyReq.path then '&' else '?' + proxyReq.path += "#{symbol}token=#{config.blockcypher_token}" + +proxy = proxyMiddleware(proxyContext, proxyOptions) + app = express() app.enable('trust proxy') app.engine('html', require('hogan-express')) app.set('view engine', 'html') app.set('views', __dirname + '/views') app.use(express.static(__dirname + '/public')) +app.use(proxy) app.use(bodyParser.urlencoded({ extended: true})) app.use(bodyParser.json()) app.use(bodyParser.json({ type: 'application/vnd.api+json' })) @@ -61,6 +75,7 @@ do fetchRates = -> ) setTimeout(fetchRates, 120000) + app.get('/', cache, sessions.new) app.get('/address', cache, (req, res) -> @@ -91,11 +106,6 @@ app.get('/ticker', cache, (req, res) -> ) ) -app.get('/token', cache, (req, res) -> - res.write(config.blockcypher_token) - res.end() -) - app.get('/tips', cache, (req, res) -> res.render('tips', notice: true, diff --git a/views/users/wallet.html b/views/users/wallet.html index 4848eedd..7195f865 100644 --- a/views/users/wallet.html +++ b/views/users/wallet.html @@ -93,7 +93,6 @@ <label for="amount">To Address:</label> <input type="text" id="recipient" name="recipient" class="form-control" data-address="true" required /> </div> - <span class="glyphicon form-control-feedback" aria-hidden="true"></span> <div class="help-block with-errors"></div> </div> @@ -106,7 +105,6 @@ <option value="high">High</option> </select> </div> - <span class="glyphicon form-control-feedback" aria-hidden="true"></span> </div> <div class="form-group has-feedback"> @@ -114,7 +112,6 @@ <label for="password">Password:</label> <input id="password" name="password" type="password" class="form-control" data-password="true" required /> </div> - <span class="glyphicon form-control-feedback" aria-hidden="true"></span> <div class="help-block with-errors"></div> </div> |
