diff --git a/.nvmrc b/.nvmrc index d0e8c6995..471febd32 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -0.10.32 +0.10.36 diff --git a/lib/agent/plugins/control-panel/api/request.js b/lib/agent/plugins/control-panel/api/request.js index 343889571..67ffc99bf 100644 --- a/lib/agent/plugins/control-panel/api/request.js +++ b/lib/agent/plugins/control-panel/api/request.js @@ -5,27 +5,29 @@ var needle = require('needle'), version = '2'; var defaults = { - client : needle, - protocol : 'https', - host : 'solid.preyproject.com', - user_agent : 'Prey Client API v' + version, - timeout : 90 * 1000 -} + client : needle, + protocol : 'https', + host : 'solid.preyproject.com', + user_agent : 'Prey Client API v' + version, + timeout : 90 * 1000, + retry_timeout : 3 * 1000, + try_proxy : '' +}; https.globalAgent.options.secureProtocol = 'TLSv1_method'; -var api_root = '/api/v2'; -var max_attempts = 3; +var api_root = '/api/v2', + max_attempts = 3; var is_network_down = function(err) { - var codes = ['ENETDOWN', 'ENETUNREACH', 'EADDRINFO', 'ENOTFOUND']; + var codes = ['ENETDOWN', 'ENETUNREACH', 'EADDRINFO', 'ENOTFOUND', 'EHOSTUNREACH']; return codes.indexOf(err.code) !== -1; -} +}; var is_server_down = function(err) { var codes = ['ETIMEDOUT', 'ECONNRESET', 'ECONNREFUSED']; return codes.indexOf(err.code) !== -1; -} +}; var is_temporary_error = function(err, resp) { var retry = false; @@ -36,12 +38,15 @@ var is_temporary_error = function(err, resp) { retry = (resp.statusCode == 502 || resp.statusCode == 503); return retry; -} +}; var send = function(attempt, method, path, data, options, cb) { - if (!defaults.client) - return cb(new Error('No HTTP client set!')) + if (!defaults.client) { + return cb(new Error('No HTTP client set!')); + } + // opts are used for the current request, while options are + // used in the recursive call in case of retry var opts = options || {}; opts.timeout = opts.timeout || defaults.timeout; opts.user_agent = opts.user_agent || defaults.user_agent; @@ -53,18 +58,30 @@ var send = function(attempt, method, path, data, options, cb) { var base = defaults.protocol + '://' + defaults.host, url = base + api_root + path, - start = new Date(); + start = new Date(), + logger_msg; - logger.debug('Sending ' + method + ' request #' + attempt + ' to ' + base); - // console.log(opts); + logger_msg = 'Sending ' + method + ' request #' + attempt + ' to ' + base; + if (opts.proxy) { + logger_msg += " using proxy: " + opts.proxy; + } + logger.debug(logger_msg); defaults.client.request(method, url, data, opts, function(err, resp, body) { - var seconds = (new Date() - start) / 1000; + var seconds = (new Date() - start) / 1000, + retry_without_proxy = function() { + delete options.proxy; + logger.debug('Retrying request without proxy.'); + send(1, method, path, data, options, cb); + }; logger.debug('Attempt #' + attempt + ' took ' + seconds + ' seconds.'); if (err && is_network_down(err)) { err.message = 'Network seems to be down. Check your connection and try again.'; + if(opts.proxy) { + return retry_without_proxy(); + } return cb(err); } else if (is_temporary_error(err, resp)) { @@ -73,7 +90,9 @@ var send = function(attempt, method, path, data, options, cb) { logger.debug('Temporary network error. Retrying...'); return setTimeout(function() { send(attempt + 1, method, path, data, options, cb); - }, 3000); + }, defaults.retry_timeout); + } else if (opts.proxy) { + return retry_without_proxy(); } else if (err) { // maxed out all attempts. tell user to retry in a sec. err.message = err.message + ' - Please try again in a minute.'; } @@ -82,19 +101,27 @@ var send = function(attempt, method, path, data, options, cb) { cb(err, resp, body); }); -} +}; + +var set_proxy_and_send = function (method, path, data, opts, cb) { + if (!opts.hasOwnProperty("proxy") && defaults.try_proxy) { + opts.proxy = defaults.try_proxy; + logger.debug("Setting proxy to " + opts.proxy); + } + send(1, method, path, data, opts, cb); +}; exports.get = function(path, opts, cb) { - send(1, 'GET', path, null, opts, cb); -} + set_proxy_and_send('GET', path, null, opts, cb); +}; exports.post = function(path, data, opts, cb) { - send(1, 'POST', path, data, opts, cb); -} + set_proxy_and_send('POST', path, data, opts, cb); +}; exports.delete = function(path, opts, cb) { - send(1, 'DELETE', path, null, opts, cb); -} + set_proxy_and_send('DELETE', path, null, opts, cb); +}; exports.use = function(obj) { for (var key in obj) { @@ -116,4 +143,4 @@ exports.use = function(obj) { } } return defaults; -} +}; \ No newline at end of file diff --git a/lib/agent/plugins/control-panel/api/test/request_spec.js b/lib/agent/plugins/control-panel/api/test/request_spec.js index ee40021e2..3a7cd6c42 100644 --- a/lib/agent/plugins/control-panel/api/test/request_spec.js +++ b/lib/agent/plugins/control-panel/api/test/request_spec.js @@ -8,85 +8,13 @@ describe('API Request Wrapper', function() { describe('.use', function() { it('overrides defaults', function() { - var defaults = api_req.use({ host: 'http://foobar.com' }); + var defaults = api_req.use({ + host: 'http://foobar.com', + retry_timeout: 100 + }); defaults.host.should.equal('http://foobar.com'); - }) + }); - }) - - describe('get', function() { - - var stub; - - describe('on a 200 response', function() { - - before(function() { - stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { - cb(null, { statusCode: 200 }); - }) - }) - - after(function() { - stub.restore(); - }) - - it('does not retry the request', function(done) { - - api_req.get('/devices/something', {}, function(err, resp, body) { - stub.callCount.should.equal(1); - done(); - }) - - }) - - }) - - describe('on a 503 response', function() { - - before(function() { - stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { - cb(new Error('socket hang up')); - }) - }) - - after(function() { - stub.restore(); - }) - - it('retries the request', function(done) { - - api_req.get('/devices/something', {}, function(err, resp, body) { - stub.callCount.should.equal(3); - done(); - }) - - }) - - }) - - describe('on connection error', function() { - - before(function() { - stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { - cb(new Error('socket hang up')); - }) - }) - - after(function() { - stub.restore(); - }) - - it('retries the request', function(done) { - - api_req.get('/devices/something', {}, function(err, resp, body) { - stub.callCount.should.equal(3); - done(); - }) - - }) - - }) - - }) + }); }); diff --git a/lib/agent/plugins/control-panel/api/test/request_with_proxy_spec.js b/lib/agent/plugins/control-panel/api/test/request_with_proxy_spec.js new file mode 100644 index 000000000..338f44bcb --- /dev/null +++ b/lib/agent/plugins/control-panel/api/test/request_with_proxy_spec.js @@ -0,0 +1,266 @@ +var sinon = require('sinon'), + should = require('should'), + needle = require('needle'), + api_req = require('../request'); + +describe('API Request Wrapper', function() { + + describe('get', function() { + + describe('with proxy', function () { + + before(function () { + + api_req.use({ + try_proxy: "http://127.0.0.1", + retry_timeout: 100 + }); + + }); + + describe('on 200', function () { + + before(function() { + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + cb(null, { statusCode: 200 }); + }); + }); + + after(function() { + stub.restore(); + }); + + it('does not retry the request', function(done) { + + api_req.get('/devices/something', {}, function(err, resp, body) { + resp.statusCode.should.equal(200); + stub.callCount.should.equal(1); + done(); + }); + + }); + + }); + + describe('on temp error + 200 response', function () { + + var proxies = []; + + before(function() { + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + + proxies.push(opts.proxy); + + if(opts.proxy) { + cb(new Error('socket hang up')); + } else { + cb(null, { statusCode: 200 }); + } + }); + }); + + after(function() { + stub.restore(); + }); + + it('tries 3 times with proxy and 1 without proxy', function(done) { + + api_req.get('/devices/something', {}, function(err, resp, body) { + resp.statusCode.should.equal(200); + proxies.should.eql([ + 'http://127.0.0.1', + 'http://127.0.0.1', + 'http://127.0.0.1', + undefined + ]); + stub.callCount.should.equal(4); + done(); + }); + + }); + + }); + + describe('on [temp error + network down] + 200 response', function () { + + var proxies = []; + + before(function() { + + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + + proxies.push(opts.proxy); + + if(opts.proxy) { + + if(this.request.callCount === 3) { + + var err = new Error('EHOSTUNREACH'); + err.code = 'EHOSTUNREACH'; + cb(err); + + } else { + cb(new Error('socket hang up')); + } + + } else { + cb(null, { statusCode: 200 }); + } + + }); + + }); + + after(function() { + stub.restore(); + }); + + it('tries 3 times with proxy and 1 without proxy', function(done) { + + api_req.get('/devices/something', {}, function(err, resp, body) { + resp.statusCode.should.equal(200); + proxies.should.eql([ + 'http://127.0.0.1', + 'http://127.0.0.1', + 'http://127.0.0.1', + undefined + ]); + stub.callCount.should.equal(4); + done(); + }); + + }); + + }); + + describe('on network down + [temp error + 200 response]', function () { + + var proxies = []; + + before(function() { + + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + + proxies.push(opts.proxy); + + if(opts.proxy) { + + var err = new Error('EHOSTUNREACH'); + err.code = 'EHOSTUNREACH'; + cb(err); + + } else { + + if(this.request.callCount === 4) { + cb(null, { statusCode: 200 }); + } else { + cb(new Error('socket hang up')); + } + + } + + }); + + }); + + after(function() { + stub.restore(); + }); + + it('tries once with proxy and 3 without proxy', function(done) { + + api_req.get('/devices/something', {}, function(err, resp, body) { + resp.statusCode.should.equal(200); + proxies.should.eql([ + 'http://127.0.0.1', + undefined, + undefined, + undefined + ]); + stub.callCount.should.equal(4); + done(); + }); + + }); + + }); + + describe('on network down', function () { + + var proxies = []; + + before(function() { + + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + + proxies.push(opts.proxy); + + var err = new Error('EHOSTUNREACH'); + err.code = 'EHOSTUNREACH'; + + cb(err); + }); + }); + + after(function() { + stub.restore(); + }); + + it('tries once with proxy and once without proxy', function(done) { + + api_req.get('/devices/something', {}, function(err, resp, body) { + proxies.should.eql([ + 'http://127.0.0.1', + undefined + ]); + stub.callCount.should.equal(2); + done(); + }); + + }); + + }); + + describe('on temp error', function () { + + var proxies = []; + + before(function() { + + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + + proxies.push(opts.proxy); + + cb(new Error('socket hang up')); + }); + + }); + + after(function() { + stub.restore(); + }); + + it('tries 3 times with proxy and 3 without proxy', function(done) { + + api_req.get('/devices/something', {}, function(err, resp, body) { + proxies.should.eql([ + 'http://127.0.0.1', + 'http://127.0.0.1', + 'http://127.0.0.1', + undefined, + undefined, + undefined + ]); + stub.callCount.should.equal(6); + done(); + }); + + }); + + }); + + }); + + }); + +}); \ No newline at end of file diff --git a/lib/agent/plugins/control-panel/api/test/request_without_proxy_spec.js b/lib/agent/plugins/control-panel/api/test/request_without_proxy_spec.js new file mode 100644 index 000000000..ca30bd9d8 --- /dev/null +++ b/lib/agent/plugins/control-panel/api/test/request_without_proxy_spec.js @@ -0,0 +1,166 @@ +var sinon = require('sinon'), + should = require('should'), + needle = require('needle'), + api_req = require('../request'); + +describe('API Request Wrapper', function() { + + describe('get', function() { + + describe('without proxy', function () { + + // Needed when the running the whole test suit, + // in which case defaults.proxy might have been set + var opts = { + proxy: "" + }; + + before(function () { + + api_req.use({ + retry_timeout: 100 + }); + + }); + + describe('on 200', function () { + + before(function() { + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + cb(null, { statusCode: 200 }); + }); + }); + + after(function() { + stub.restore(); + }); + + it('does not retry the request', function(done) { + + api_req.get('/devices/something', opts, function(err, resp, body) { + resp.statusCode.should.equal(200); + stub.callCount.should.equal(1); + done(); + }); + + }); + + }); + + describe('on network down', function () { + + before(function() { + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + var err = new Error('EHOSTUNREACH'); + err.code = 'EHOSTUNREACH'; + cb(err); + }); + }); + + after(function() { + stub.restore(); + }); + + it('tries once', function(done) { + + api_req.get('/devices/something', opts, function(err, resp, body) { + err.code.should.equal('EHOSTUNREACH'); + stub.callCount.should.equal(1); + done(); + }); + + }); + + }); + + describe('on temp error', function () { + + before(function() { + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + cb(new Error('socket hang up')); + }); + }); + + after(function() { + stub.restore(); + }); + + it('tries 3 times', function(done) { + + api_req.get('/devices/something', opts, function(err, resp, body) { + err.message.should.equal('socket hang up - Please try again in a minute.'); + stub.callCount.should.equal(3); + done(); + }); + + }); + + }); + + describe('on temp error + 200', function () { + + before(function() { + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + + if(this.request.calledThrice) { + cb(null, { statusCode: 200 }); + } else { + cb(new Error('socket hang up')); + } + + }); + }); + + after(function() { + stub.restore(); + }); + + it('tries 3 times', function(done) { + + api_req.get('/devices/something', opts, function(err, resp, body) { + resp.statusCode.should.equal(200); + stub.callCount.should.equal(3); + done(); + }); + + }); + + }); + + describe('on temp error + network down', function () { + + before(function() { + stub = sinon.stub(needle, 'request', function(method, url, data, opts, cb) { + + if(this.request.calledThrice) { + var err = new Error('EHOSTUNREACH'); + err.code = 'EHOSTUNREACH'; + cb(err); + } else { + cb(new Error('socket hang up')); + } + + }); + }); + + after(function() { + stub.restore(); + }); + + it('tries 3 times', function(done) { + + api_req.get('/devices/something', opts, function(err, resp, body) { + err.code.should.equal('EHOSTUNREACH'); + stub.callCount.should.equal(3); + done(); + }); + + }); + + }); + + }); + + }); + +}); \ No newline at end of file diff --git a/lib/agent/plugins/control-panel/index.js b/lib/agent/plugins/control-panel/index.js index 4f7dd49e1..83d788ba0 100644 --- a/lib/agent/plugins/control-panel/index.js +++ b/lib/agent/plugins/control-panel/index.js @@ -20,9 +20,10 @@ var init_api = function(opts, cb) { return cb && cb(new Error('Invalid config.')); api.use({ - host : opts.host, - protocol : opts.protocol - }) + host : opts.host, + protocol : opts.protocol, + try_proxy : opts.try_proxy + }); if (!cb) return; @@ -223,9 +224,12 @@ exports.load = function(cb) { commands = common.commands; if (!config) - return cb && cb(new Error('No config object.')) + return cb && cb(new Error('No config object.')); + + init_opts = common.config.all(); + init_opts.try_proxy = common.config.global.get('try_proxy'); - init_api(common.config.all()); + init_api(init_opts); sender.init(common); setup.start(common, function(err) { diff --git a/lib/agent/plugins/control-panel/interval/index.js b/lib/agent/plugins/control-panel/interval/index.js index 3e41870d1..3dc583e49 100644 --- a/lib/agent/plugins/control-panel/interval/index.js +++ b/lib/agent/plugins/control-panel/interval/index.js @@ -1,6 +1,6 @@ var bus = require('../bus'), api = require('./../api'), - getter = api.devices.get.commands, + getter = api.devices.get, Emitter = require('events').EventEmitter; var hooks, @@ -10,9 +10,9 @@ var hooks, var timer, emitter, requesting, - current_delay, - default_delay = 20 * 1000 * 60, // 20 min - short_delay = 0.5 * 1000 * 60; // 30 secs + long_delay = 20 * 1000 * 60, // 20 min + short_delay = 0.5 * 1000 * 60, // 30 secs + current_delay = long_delay; var parse_cmd = function(str) { try { @@ -21,7 +21,7 @@ var parse_cmd = function(str) { if (hooks) hooks.trigger('error', new Error('Invalid command: ' + str)); } -} +}; var request = function() { if (requesting) @@ -29,7 +29,7 @@ var request = function() { requesting = true; logger.debug('Fetching instructions...'); - getter(function(err, resp) { + getter.commands(function(err, resp) { requesting = false; if (err) @@ -45,45 +45,56 @@ var request = function() { resp.body.forEach(function(el) { var cmd = el.target ? el : parse_cmd(el); if (cmd) emitter.emit('command', cmd); - }) - }) -} + }); -var load_hooks = function() { - // whenever device connects, send a request - hooks.on('connected', request); + schedule_request(); + }); +}; - // whenever reachable state changes, hasten or slowen - bus.on('reachable', set_interval); - bus.on('unreachable', set_faster_interval); +var set_slower_interval = function () { + set_interval(long_delay); +}; - loaded = true; -} +var set_faster_interval = function() { + set_interval(short_delay); +}; // set timer to check on intervals var set_interval = function(delay) { - if (!loaded) return; - if (!delay) delay = default_delay; - - if (delay == current_delay) return; current_delay = delay; logger.info('Queuing check-ins every ' + delay/60000 + ' minutes.'); - if (timer) clearInterval(timer); - timer = setInterval(request, delay); -} + if (timer) { + clearTimeout(timer); + schedule_request(); + } +}; -var set_faster_interval = function() { - set_interval(short_delay); -} +var schedule_request = function (custom_delay) { + var delay = custom_delay || current_delay; + timer = setTimeout(request, delay); +}; + +var load_hooks = function() { + // whenever device connects, send a request + hooks.on('connected', request); + + // whenever reachable state changes, hasten or slowen + bus.on('reachable', set_slower_interval); + bus.on('unreachable', set_faster_interval); + + loaded = true; +}; var unload = function(err) { if (err) logger.error('Failed, unloading: ' + err.message); - hooks.remove('woken', request); hooks.remove('connected', request); - if (timer) clearInterval(timer); + + bus.removeAllListeners(); + + if (timer) clearTimeout(timer); loaded = false; @@ -91,11 +102,11 @@ var unload = function(err) { emitter.removeAllListeners(); emitter = null; } -} +}; exports.check = function() { request(); -} +}; exports.load = function(cb) { if (emitter) @@ -106,14 +117,13 @@ exports.load = function(cb) { logger = common.logger; load_hooks(); - set_interval(); - setTimeout(request, 3000); // wait a bit and fire request + schedule_request(3000); // wait a bit and fire request - emitter = new Emitter; + emitter = new Emitter(); cb(null, emitter); -} +}; exports.unload = function() { if (!hooks) return; // not loaded yet. unload(); -} +}; diff --git a/lib/agent/plugins/control-panel/interval/test/interval_spec.js b/lib/agent/plugins/control-panel/interval/test/interval_spec.js new file mode 100644 index 000000000..28fdcc2d7 --- /dev/null +++ b/lib/agent/plugins/control-panel/interval/test/interval_spec.js @@ -0,0 +1,218 @@ +var assert = require("assert"), + sinon = require('sinon'), + should = require('should'), + api = require('../../api'), + interval = require(".."), + bus = require("../../bus"), + hooks = require('../../../../hooks'), + common = require('../../../../../common'), + common_obj = { + hooks: hooks, + config: common.config, + logger: common.logger + }; + +describe('interval', function () { + + var setTimeout_spy = {}, + clearTimeout_spy = {}; + + var set_spies = function () { + setTimeout_spy = sinon.spy(global, "setTimeout"); + clearTimeout_spy = sinon.spy(global, "clearTimeout"); + }; + + var restore_spies = function () { + setTimeout_spy.restore(); + clearTimeout_spy.restore(); + }; + + var reset_spies = function () { + setTimeout_spy.reset(); + clearTimeout_spy.reset(); + }; + + var load_module = function (cb) { + interval.load.call(common_obj, cb); + }; + + before(function () { + set_spies(); + }); + + after(function () { + restore_spies(); + }); + + describe('on load', function () { + + beforeEach(function () { + interval.unload(); + reset_spies(); + }); + + it('queue a request to be issues in 3 seconds', function () { + + load_module(function (err, emitter) { + setTimeout_spy.calledOnce.should.equal(true); + setTimeout_spy.args[0][1].should.equal(3000); + }); + + }); + + it('sets the hooks', function () { + + load_module(function (err, emitter) { + var hook_emitted = hooks.emit('connected'); + hook_emitted.should.equal(true); + }); + + }); + + it('sets the bus', function () { + + load_module(function (err, emitter) { + var bus_emitted = bus.emit('reachable'); + bus_emitted.should.equal(true); + }); + + }); + + }); + + describe('when reachable or unreachable is trigered', function () { + + beforeEach(function () { + interval.unload(); + reset_spies(); + }); + + it('dequeues the request', function () { + + load_module(function (err, emitter) { + bus.emit("reachable"); + process.nextTick(function () { + clearTimeout_spy.calledOnce.should.equal(true); + }); + }); + + }); + + }); + + describe('when device is reachable', function () { + + beforeEach(function () { + interval.unload(); + reset_spies(); + }); + + it('changes to slower interval', function () { + + load_module(function (err, emitter) { + bus.emit("reachable"); + process.nextTick(function () { + setTimeout_spy.calledTwice.should.equal(true); + setTimeout_spy.args[1][1].should.equal(1200000); + }); + }); + + }); + + it('dequeues the previous request', function () { + + load_module(function (err, emitter) { + bus.emit("reachable"); + process.nextTick(function () { + clearTimeout_spy.calledOnce.should.equal(true); + }); + }); + + }); + + }); + + describe('when device is unreachable', function () { + + beforeEach(function () { + interval.unload(); + reset_spies(); + }); + + it('changes to faster interval', function () { + + load_module(function (err, emitter) { + bus.emit("unreachable"); + process.nextTick(function () { + setTimeout_spy.calledTwice.should.equal(true); + setTimeout_spy.args[1][1].should.equal(30000); + }); + }); + + }); + + it('dequeues the previous request', function () { + + load_module(function (err, emitter) { + bus.emit("unreachable"); + process.nextTick(function () { + clearTimeout_spy.calledOnce.should.equal(true); + }); + }); + + }); + + }); + + describe('on check', function() { + + var api_stub = {}; + + before(function () { + interval.unload(); + api_stub = sinon.stub(api.devices.get, 'commands', function (cb) { + return true; + }); + }); + + it('triggers a request', function(done) { + + load_module(function (err, emitter) { + + interval.check(); + api_stub.calledOnce.should.equal(true); + done(); + + }); + + }); + + }); + + describe('on unload', function (){ + + before(function () { + interval.unload(); + reset_spies(); + }); + + it('unloads the module', function () { + + load_module(function (err, emitter) { + var hook_emitted = hooks.emit('connected'); + hook_emitted.should.equal(true); + }); + + interval.unload(); + + process.nextTick(function () { + var hook_emitted = hooks.emit('connected'); + hook_emitted.should.equal(false); + }); + + }); + + }); + +}); + diff --git a/lib/agent/plugins/control-panel/sender.js b/lib/agent/plugins/control-panel/sender.js index 7d4be44df..65d5c22d2 100644 --- a/lib/agent/plugins/control-panel/sender.js +++ b/lib/agent/plugins/control-panel/sender.js @@ -3,7 +3,6 @@ var api = require('./api'), var logger, providers, - try_proxy, send_status_info = false; var get_status_info = function(cb) { @@ -17,17 +16,9 @@ var make_request = function(what, data, opts, cb) { opts.multipart = what == 'report'; var msg = 'Posting ' + what; - if (opts.proxy) msg += ' using proxy: ' + opts.proxy; logger.info(msg); api.push[what](data, opts, function(err, resp) { - - // if there was an error, lets try connecting via a proxy if possible - if (err && !opts.proxy && (try_proxy || '').match('.')) { - opts.proxy = try_proxy; - return make_request(what, data, opts, cb); - } - bus.emit('response', what, err, resp); cb && cb(err, resp); }); @@ -59,7 +50,6 @@ exports.init = function(common) { providers = common.providers; // TODO: we might retrieve these values when needed, instead of on boot - try_proxy = common.config.global && common.config.global.get('try_proxy'); send_status_info = common.config.get('send_status_info'); } diff --git a/lib/conf/shared/panel.js b/lib/conf/shared/panel.js index f4b30dd10..608114c3b 100644 --- a/lib/conf/shared/panel.js +++ b/lib/conf/shared/panel.js @@ -18,6 +18,8 @@ function setup_api() { return process.exit(1); } + opts.try_proxy = config.get('try_proxy'); + api = panel.load_api(opts); return api; } @@ -25,18 +27,18 @@ function setup_api() { exports.verify_keys = function(keys, cb) { setup_api(); api.keys.verify(keys, cb); -} +}; exports.authorize = function(opts, cb) { setup_api(); api.accounts.authorize(opts, cb); -} +}; exports.signup = function(data, cb) { setup_api(); api.accounts.signup(data, cb); -} +}; exports.link = function(cb) { installed.enabled('control-panel', cb); -} +}; diff --git a/lib/conf/tasks/utils/create_user.sh b/lib/conf/tasks/utils/create_user.sh index 5c72e05d7..13e80f217 100755 --- a/lib/conf/tasks/utils/create_user.sh +++ b/lib/conf/tasks/utils/create_user.sh @@ -9,7 +9,7 @@ USER_NAME="$1" [ -z "$USER_NAME" ] && echo "User name required." && exit 1 FULL_NAME="Prey Anti-Theft" -SHELL="/bin/bash" + SU_CMD=$(command -v su) || SU_CMD="/bin/su" # this means user will be able to run commands as other users except root @@ -20,14 +20,17 @@ if [ "$(uname)" == "Linux" ]; then USERS_PATH="/home" [ -n "$(which dmidecode)" ] && SUDOERS_ARGS="$(which dmidecode), ${SUDOERS_ARGS}" [ -n "$(which iwlist)" ] && SUDOERS_ARGS="$(which iwlist), ${SUDOERS_ARGS}" + # for security reasons, Prey user shouldn't have a login shell defined + # also, since nologin path changes between linux distros, lets use /bin/false instead + SHELL="/bin/false" else USERS_PATH="/Users" + SHELL="/sbin/nologin" fi SUDOERS_LINE="${USER_NAME} ALL = NOPASSWD: ${SUDOERS_ARGS}" if [ "$(uname)" == "Linux" ]; then - # EXISTING_USER=$(find ${USERS_PATH} -maxdepth 1 -not -path "*/\.*" | grep -v ${USER_NAME} | tail -1 | cut -f3 -d "/") EXISTING_USER=$(cat /etc/passwd | grep -E "home.*bash" | tail -1 | cut -d":" -f1) else EXISTING_USER=$(dscl . -list /Users | grep -Ev "^_|daemon|nobody|root|Guest|${USER_NAME}" | tail -1) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index f6d298f1b..ced8e9fa7 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -4,7 +4,7 @@ "dependencies": { "async": { "version": "0.9.0", - "from": "async@0.9.0", + "from": "https://registry.npmjs.org/async/-/async-0.9.0.tgz", "resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz" }, "buckle": { @@ -14,39 +14,39 @@ "dependencies": { "decompress-zip": { "version": "0.0.6", - "from": "git://github.com/tomas/decompress-zip", + "from": "../../../../../var/folders/4k/4wdf3tmn3zl0jnczy79pnyjh0000gp/T/npm-2152-0e06c99d/1425562302520-0.9821321198251098/333c2e9bdb1c64aba70acbb336cf027516b528d9", "resolved": "git://github.com/tomas/decompress-zip#333c2e9bdb1c64aba70acbb336cf027516b528d9", "dependencies": { "q": { "version": "1.0.1", - "from": "q@~1.0.0", + "from": "q@>=1.0.0 <1.1.0", "resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz" }, "mkpath": { "version": "0.1.0", - "from": "mkpath@~0.1.0", + "from": "mkpath@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz" }, "binary": { "version": "0.3.0", - "from": "binary@~0.3.0", + "from": "binary@>=0.3.0 <0.4.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "dependencies": { "chainsaw": { "version": "0.1.0", - "from": "chainsaw@~0.1.0", + "from": "chainsaw@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "dependencies": { "traverse": { "version": "0.3.9", - "from": "traverse@>=0.3.0 <0.4", + "from": "traverse@>=0.3.0 <0.4.0", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz" } } }, "buffers": { "version": "0.1.1", - "from": "buffers@~0.1.1", + "from": "buffers@>=0.1.1 <0.2.0", "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz" } } @@ -58,12 +58,12 @@ "dependencies": { "nopt": { "version": "1.0.10", - "from": "nopt@~1.0.10", + "from": "nopt@>=1.0.10 <1.1.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "dependencies": { "abbrev": { "version": "1.0.5", - "from": "abbrev@1", + "from": "abbrev@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz" } } @@ -72,44 +72,44 @@ }, "nopt": { "version": "2.2.1", - "from": "nopt@~2.2.0", + "from": "nopt@>=2.2.0 <2.3.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz", "dependencies": { "abbrev": { "version": "1.0.5", - "from": "abbrev@1", + "from": "abbrev@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz" } } }, "graceful-fs": { "version": "2.0.3", - "from": "graceful-fs@~2.0.3", + "from": "graceful-fs@>=2.0.3 <2.1.0", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" } } - }, - "async": { - "version": "0.9.0", - "from": "https://registry.npmjs.org/async/-/async-0.9.0.tgz", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz" } } }, "campfire": { "version": "0.2.0", - "from": "git://github.com/tomas/node-campfire", + "from": "../../../../../var/folders/4k/4wdf3tmn3zl0jnczy79pnyjh0000gp/T/npm-2152-0e06c99d/1425562302464-0.6288007630500942/c4b0517ce0e49000a14ba3cedcbd9b8df2d2f8d4", "resolved": "git://github.com/tomas/node-campfire#c4b0517ce0e49000a14ba3cedcbd9b8df2d2f8d4" }, "chela": { "version": "0.0.5", - "from": "chela@0.0.5", + "from": "https://registry.npmjs.org/chela/-/chela-0.0.5.tgz", "resolved": "https://registry.npmjs.org/chela/-/chela-0.0.5.tgz", "dependencies": { "graceful-fs": { "version": "3.0.5", - "from": "graceful-fs@3.0.5", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.5.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.5.tgz" + }, + "uid-number": { + "version": "0.0.5", + "from": "uid-number@0.0.5", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.5.tgz" } } }, @@ -124,80 +124,104 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz" }, "commander": { - "version": "2.3.0", - "from": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz" + "version": "2.6.0", + "from": "commander@2.6.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz" }, "connect": { - "version": "3.2.0", - "from": "https://registry.npmjs.org/connect/-/connect-3.2.0.tgz", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.2.0.tgz", + "version": "3.3.4", + "from": "connect@3.3.4", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.3.4.tgz", "dependencies": { "debug": { - "version": "2.0.0", - "from": "https://registry.npmjs.org/debug/-/debug-2.0.0.tgz", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.0.0.tgz", + "version": "2.1.2", + "from": "debug@>=2.1.0 <2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.1.2.tgz", "dependencies": { "ms": { - "version": "0.6.2", - "from": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz" + "version": "0.7.0", + "from": "ms@0.7.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz" } } }, "finalhandler": { - "version": "0.2.0", - "from": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.2.0.tgz", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.2.0.tgz", + "version": "0.3.3", + "from": "finalhandler@0.3.3", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.3.3.tgz", "dependencies": { "escape-html": { "version": "1.0.1", - "from": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", + "from": "escape-html@1.0.1", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz" + }, + "on-finished": { + "version": "2.2.0", + "from": "on-finished@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.2.0.tgz", + "dependencies": { + "ee-first": { + "version": "1.1.0", + "from": "ee-first@1.1.0", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz" + } + } } } }, "parseurl": { "version": "1.3.0", - "from": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.0.tgz", + "from": "parseurl@>=1.3.0 <1.4.0", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.0.tgz" }, "utils-merge": { "version": "1.0.0", - "from": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "from": "utils-merge@1.0.0", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" } } }, "dialog": { "version": "0.1.8", - "from": "dialog@0.1.8", + "from": "https://registry.npmjs.org/dialog/-/dialog-0.1.8.tgz", "resolved": "https://registry.npmjs.org/dialog/-/dialog-0.1.8.tgz" }, "entry": { "version": "0.3.6", - "from": "entry@0.3.6", + "from": "https://registry.npmjs.org/entry/-/entry-0.3.6.tgz", "resolved": "https://registry.npmjs.org/entry/-/entry-0.3.6.tgz", "dependencies": { + "needle": { + "version": "0.7.11", + "from": "needle@0.7.11", + "resolved": "https://registry.npmjs.org/needle/-/needle-0.7.11.tgz", + "dependencies": { + "iconv-lite": { + "version": "0.4.7", + "from": "iconv-lite@>=0.4.4 <0.5.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.7.tgz" + } + } + }, "xml2js": { - "version": "0.4.4", - "from": "xml2js@^0.4.4", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", + "version": "0.4.5", + "from": "xml2js@0.4.5", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.5.tgz", "dependencies": { "sax": { "version": "0.6.1", - "from": "sax@0.6.1", + "from": "sax@>=0.6.0 <0.7.0", "resolved": "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz" }, "xmlbuilder": { - "version": "2.4.4", + "version": "2.6.1", "from": "xmlbuilder@>=1.0.0", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.4.4.tgz", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.6.1.tgz", "dependencies": { - "lodash-node": { - "version": "2.4.1", - "from": "lodash-node@~2.4.1", - "resolved": "https://registry.npmjs.org/lodash-node/-/lodash-node-2.4.1.tgz" + "lodash": { + "version": "3.3.1", + "from": "lodash@>=3.3.0 <3.4.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.3.1.tgz" } } } @@ -207,45 +231,47 @@ }, "firewall": { "version": "0.0.5", - "from": "firewall@0.0.5", + "from": "https://registry.npmjs.org/firewall/-/firewall-0.0.5.tgz", "resolved": "https://registry.npmjs.org/firewall/-/firewall-0.0.5.tgz", "dependencies": { "spawnx": { "version": "0.0.1", - "from": "spawnx@0.0.1" + "from": "spawnx@0.0.1", + "resolved": "https://registry.npmjs.org/spawnx/-/spawnx-0.0.1.tgz" } } }, "folder": { "version": "0.0.4", - "from": "folder@0.0.4", + "from": "https://registry.npmjs.org/folder/-/folder-0.0.4.tgz", "resolved": "https://registry.npmjs.org/folder/-/folder-0.0.4.tgz", "dependencies": { "negotiator": { "version": "0.4.9", - "from": "negotiator@~0.4.2", + "from": "negotiator@0.4.9", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz" }, "batch": { - "version": "0.5.1", - "from": "batch@~0.5.0", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.1.tgz" + "version": "0.5.2", + "from": "batch@0.5.2", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.2.tgz" } } }, "getset": { "version": "0.6.3", - "from": "getset@0.6.3", + "from": "https://registry.npmjs.org/getset/-/getset-0.6.3.tgz", "resolved": "https://registry.npmjs.org/getset/-/getset-0.6.3.tgz" }, "graceful-fs": { - "version": "2.0.3", - "from": "graceful-fs@2.0.3" + "version": "3.0.5", + "from": "graceful-fs@*", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.5.tgz" }, "linus": { - "version": "0.0.3", - "from": "linus@", - "resolved": "https://registry.npmjs.org/linus/-/linus-0.0.3.tgz", + "version": "0.0.4", + "from": "linus@0.0.4", + "resolved": "https://registry.npmjs.org/linus/-/linus-0.0.4.tgz", "dependencies": { "getos": { "version": "1.0.1", @@ -253,9 +279,9 @@ "resolved": "https://registry.npmjs.org/getos/-/getos-1.0.1.tgz" }, "memorize": { - "version": "0.0.3", - "from": "memorize@0.0.3", - "resolved": "https://registry.npmjs.org/memorize/-/memorize-0.0.3.tgz" + "version": "0.0.4", + "from": "memorize@0.0.4", + "resolved": "https://registry.npmjs.org/memorize/-/memorize-0.0.4.tgz" }, "whenever": { "version": "0.0.2", @@ -276,7 +302,7 @@ }, "nat-pmp": { "version": "0.0.3", - "from": "nat-pmp@", + "from": "https://registry.npmjs.org/nat-pmp/-/nat-pmp-0.0.3.tgz", "resolved": "https://registry.npmjs.org/nat-pmp/-/nat-pmp-0.0.3.tgz", "dependencies": { "debug": { @@ -287,29 +313,31 @@ } }, "needle": { - "version": "0.7.10", - "from": "needle@0.7.10", + "version": "0.8.1", + "from": "needle@>=0.8.0 <0.9.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-0.8.1.tgz", "dependencies": { "iconv-lite": { - "version": "0.4.4", - "from": "iconv-lite@^0.4.4", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.4.tgz" + "version": "0.4.7", + "from": "iconv-lite@>=0.4.4 <0.5.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.7.tgz" } } }, "network": { "version": "0.1.3", - "from": "network@0.1.3", + "from": "https://registry.npmjs.org/network/-/network-0.1.3.tgz", "resolved": "https://registry.npmjs.org/network/-/network-0.1.3.tgz", "dependencies": { "needle": { - "version": "0.7.10", - "from": "needle@^0.7.10", + "version": "0.7.11", + "from": "needle@0.7.11", + "resolved": "https://registry.npmjs.org/needle/-/needle-0.7.11.tgz", "dependencies": { "iconv-lite": { - "version": "0.4.4", - "from": "iconv-lite@^0.4.4", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.4.tgz" + "version": "0.4.7", + "from": "iconv-lite@>=0.4.4 <0.5.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.7.tgz" } } } @@ -321,109 +349,172 @@ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-1.3.0.tgz", "dependencies": { "buildmail": { - "version": "1.2.0", - "from": "buildmail@^1.2.0", - "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-1.2.0.tgz", + "version": "1.2.1", + "from": "buildmail@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-1.2.1.tgz", "dependencies": { "addressparser": { - "version": "0.3.1", - "from": "addressparser@^0.3.1", - "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-0.3.1.tgz" + "version": "0.3.2", + "from": "addressparser@>=0.3.2 <0.4.0", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-0.3.2.tgz" }, "hyperquest": { - "version": "0.3.0", - "from": "hyperquest@0.3.0", - "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-0.3.0.tgz", + "version": "1.0.1", + "from": "hyperquest@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-1.0.1.tgz", "dependencies": { - "through": { - "version": "2.2.7", - "from": "through@~2.2.0", - "resolved": "https://registry.npmjs.org/through/-/through-2.2.7.tgz" + "duplexer2": { + "version": "0.0.2", + "from": "duplexer2@>=0.0.2 <0.1.0", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "dependencies": { + "readable-stream": { + "version": "1.1.13", + "from": "readable-stream@>=1.1.9 <1.2.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + } + } }, - "duplexer": { - "version": "0.1.1", - "from": "duplexer@~0.1.0", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz" + "through2": { + "version": "0.6.3", + "from": "through2@>=0.6.3 <0.7.0", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.3.tgz", + "dependencies": { + "readable-stream": { + "version": "1.0.33", + "from": "readable-stream@>=1.0.33-1 <1.1.0-0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "xtend": { + "version": "4.0.0", + "from": "xtend@>=4.0.0 <4.1.0-0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz" + } + } } } }, "libbase64": { "version": "0.1.0", - "from": "libbase64@^0.1.0", + "from": "libbase64@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz" }, "libqp": { "version": "0.1.1", - "from": "libqp@^0.1.1", + "from": "libqp@>=0.1.1 <0.2.0", "resolved": "https://registry.npmjs.org/libqp/-/libqp-0.1.1.tgz" } } }, "hyperquest": { "version": "0.3.0", - "from": "hyperquest@0.3.0", + "from": "hyperquest@>=0.3.0 <0.4.0", "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-0.3.0.tgz", "dependencies": { "through": { "version": "2.2.7", - "from": "through@~2.2.0", + "from": "through@>=2.2.0 <2.3.0", "resolved": "https://registry.npmjs.org/through/-/through-2.2.7.tgz" }, "duplexer": { "version": "0.1.1", - "from": "duplexer@~0.1.0", + "from": "duplexer@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz" } } }, "libmime": { - "version": "0.1.5", - "from": "libmime@^0.1.5", - "resolved": "https://registry.npmjs.org/libmime/-/libmime-0.1.5.tgz", + "version": "0.1.7", + "from": "libmime@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-0.1.7.tgz", "dependencies": { "iconv-lite": { - "version": "0.4.4", - "from": "iconv-lite@^0.4.4", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.4.tgz" + "version": "0.4.7", + "from": "iconv-lite@>=0.4.4 <0.5.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.7.tgz" }, "libbase64": { "version": "0.1.0", - "from": "libbase64@^0.1.0", + "from": "libbase64@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz" }, "libqp": { "version": "0.1.1", - "from": "libqp@^0.1.1", + "from": "libqp@>=0.1.1 <0.2.0", "resolved": "https://registry.npmjs.org/libqp/-/libqp-0.1.1.tgz" } } }, "nodemailer-direct-transport": { - "version": "1.0.0", - "from": "nodemailer-direct-transport@^1.0.0", - "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-1.0.0.tgz", + "version": "1.0.1", + "from": "nodemailer-direct-transport@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-1.0.1.tgz", "dependencies": { "smtp-connection": { - "version": "0.1.7", - "from": "smtp-connection@0.1.7", - "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-0.1.7.tgz" + "version": "1.1.0", + "from": "smtp-connection@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-1.1.0.tgz" } } }, "nodemailer-smtp-transport": { "version": "0.1.13", - "from": "nodemailer-smtp-transport@^0.1.12", + "from": "nodemailer-smtp-transport@>=0.1.12 <0.2.0", "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-0.1.13.tgz", "dependencies": { "nodemailer-wellknown": { - "version": "0.1.2", - "from": "nodemailer-wellknown@^0.1.1", - "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.2.tgz" + "version": "0.1.5", + "from": "nodemailer-wellknown@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.5.tgz" }, "smtp-connection": { - "version": "1.0.2", - "from": "smtp-connection@1.0.2", - "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-1.0.2.tgz" + "version": "1.1.0", + "from": "smtp-connection@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-1.1.0.tgz" } } } @@ -431,27 +522,28 @@ }, "ocelot": { "version": "0.0.5", - "from": "ocelot@0.0.5", + "from": "https://registry.npmjs.org/ocelot/-/ocelot-0.0.5.tgz", "resolved": "https://registry.npmjs.org/ocelot/-/ocelot-0.0.5.tgz" }, "petit": { "version": "0.0.5", - "from": "https://registry.npmjs.org/petit/-/petit-0.0.5.tgz", + "from": "petit@0.0.5", "resolved": "https://registry.npmjs.org/petit/-/petit-0.0.5.tgz" }, "qs": { - "version": "2.2.4", - "from": "qs@2.2.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.2.4.tgz" + "version": "2.3.3", + "from": "qs@2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" }, "random-ua": { "version": "0.0.6", - "from": "random-ua@", + "from": "https://registry.npmjs.org/random-ua/-/random-ua-0.0.6.tgz", "resolved": "https://registry.npmjs.org/random-ua/-/random-ua-0.0.6.tgz" }, "remover": { "version": "0.0.2", - "from": "remover@0.0.2" + "from": "remover@0.0.2", + "resolved": "https://registry.npmjs.org/remover/-/remover-0.0.2.tgz" }, "reply": { "version": "0.3.1", @@ -459,23 +551,107 @@ "resolved": "https://registry.npmjs.org/reply/-/reply-0.3.1.tgz" }, "rimraf": { - "version": "2.2.8", - "from": "rimraf@2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" + "version": "2.3.1", + "from": "rimraf@2.3.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.3.1.tgz", + "dependencies": { + "glob": { + "version": "4.4.2", + "from": "glob@>=4.4.2 <5.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.4.2.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "2.0.1", + "from": "minimatch@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.1.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.0", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz", + "dependencies": { + "balanced-match": { + "version": "0.2.0", + "from": "balanced-match@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.3.1", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.1.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + } + } }, "satan": { "version": "0.4.2", - "from": "satan@0.4.2", + "from": "https://registry.npmjs.org/satan/-/satan-0.4.2.tgz", "resolved": "https://registry.npmjs.org/satan/-/satan-0.4.2.tgz", "dependencies": { "launchd": { "version": "0.0.5", - "from": "launchd@0.0.5", + "from": "https://registry.npmjs.org/launchd/-/launchd-0.0.5.tgz", "resolved": "https://registry.npmjs.org/launchd/-/launchd-0.0.5.tgz" }, + "linus": { + "version": "0.0.3", + "from": "linus@0.0.3", + "resolved": "https://registry.npmjs.org/linus/-/linus-0.0.3.tgz", + "dependencies": { + "getos": { + "version": "1.0.1", + "from": "getos@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-1.0.1.tgz" + }, + "memorize": { + "version": "0.0.3", + "from": "memorize@0.0.3", + "resolved": "https://registry.npmjs.org/memorize/-/memorize-0.0.3.tgz" + }, + "whenever": { + "version": "0.0.2", + "from": "whenever@0.0.2", + "resolved": "https://registry.npmjs.org/whenever/-/whenever-0.0.2.tgz" + } + } + }, "minstache": { "version": "1.2.0", - "from": "minstache@^1.2.0", + "from": "https://registry.npmjs.org/minstache/-/minstache-1.2.0.tgz", "resolved": "https://registry.npmjs.org/minstache/-/minstache-1.2.0.tgz", "dependencies": { "commander": { @@ -485,7 +661,7 @@ "dependencies": { "keypress": { "version": "0.1.0", - "from": "keypress@0.1.x", + "from": "keypress@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz" } } @@ -494,20 +670,25 @@ }, "whenever": { "version": "0.0.4", - "from": "whenever@0.0.4", + "from": "https://registry.npmjs.org/whenever/-/whenever-0.0.4.tgz", "resolved": "https://registry.npmjs.org/whenever/-/whenever-0.0.4.tgz" + }, + "which": { + "version": "1.0.9", + "from": "which@1.0.9", + "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz" } } }, "scrambler": { "version": "0.0.1", - "from": "scrambler@", + "from": "scrambler@0.0.1", "resolved": "https://registry.npmjs.org/scrambler/-/scrambler-0.0.1.tgz" }, "serve-static": { - "version": "1.7.0", - "from": "serve-static@1.7.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.7.0.tgz", + "version": "1.9.1", + "from": "serve-static@1.9.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.9.1.tgz", "dependencies": { "escape-html": { "version": "1.0.1", @@ -516,22 +697,22 @@ }, "parseurl": { "version": "1.3.0", - "from": "parseurl@~1.3.0", + "from": "parseurl@>=1.3.0 <1.4.0", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.0.tgz" }, "send": { - "version": "0.10.0", - "from": "send@0.10.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.10.0.tgz", + "version": "0.12.1", + "from": "send@0.12.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.12.1.tgz", "dependencies": { "debug": { - "version": "2.1.0", - "from": "debug@~2.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.1.0.tgz" + "version": "2.1.2", + "from": "debug@>=2.1.1 <2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.1.2.tgz" }, "depd": { "version": "1.0.0", - "from": "depd@~1.0.0", + "from": "depd@>=1.0.0 <1.1.0", "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.0.tgz" }, "destroy": { @@ -540,14 +721,14 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" }, "etag": { - "version": "1.5.0", - "from": "etag@~1.5.0", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.5.0.tgz", + "version": "1.5.1", + "from": "etag@>=1.5.1 <1.6.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.5.1.tgz", "dependencies": { "crc": { - "version": "3.0.0", - "from": "crc@3.0.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.0.0.tgz" + "version": "3.2.1", + "from": "crc@3.2.1", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.2.1.tgz" } } }, @@ -557,30 +738,30 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.4.tgz" }, "mime": { - "version": "1.2.11", - "from": "mime@1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" + "version": "1.3.4", + "from": "mime@1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" }, "ms": { - "version": "0.6.2", - "from": "ms@0.6.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz" + "version": "0.7.0", + "from": "ms@0.7.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz" }, "on-finished": { - "version": "2.1.0", - "from": "on-finished@~2.1.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.0.tgz", + "version": "2.2.0", + "from": "on-finished@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.2.0.tgz", "dependencies": { "ee-first": { - "version": "1.0.5", - "from": "ee-first@1.0.5", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.0.5.tgz" + "version": "1.1.0", + "from": "ee-first@1.1.0", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz" } } }, "range-parser": { "version": "1.0.2", - "from": "range-parser@~1.0.2", + "from": "range-parser@>=1.0.2 <1.1.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.2.tgz" } } @@ -594,28 +775,23 @@ }, "sudoer": { "version": "0.1.1", - "from": "sudoer@0.1.1", + "from": "https://registry.npmjs.org/sudoer/-/sudoer-0.1.1.tgz", "resolved": "https://registry.npmjs.org/sudoer/-/sudoer-0.1.1.tgz" }, "triggers": { "version": "0.2.0", - "from": "triggers@0.2.0", + "from": "https://registry.npmjs.org/triggers/-/triggers-0.2.0.tgz", "resolved": "https://registry.npmjs.org/triggers/-/triggers-0.2.0.tgz" }, "tuna": { "version": "0.0.2", - "from": "tuna@0.0.2", + "from": "https://registry.npmjs.org/tuna/-/tuna-0.0.2.tgz", "resolved": "https://registry.npmjs.org/tuna/-/tuna-0.0.2.tgz" }, - "uid-number": { - "version": "0.0.5", - "from": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.5.tgz", - "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.5.tgz" - }, "underscore": { - "version": "1.7.0", - "from": "underscore@1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz" + "version": "1.8.2", + "from": "underscore@1.8.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.2.tgz" }, "whenever": { "version": "0.0.3", @@ -623,30 +799,43 @@ "resolved": "https://registry.npmjs.org/whenever/-/whenever-0.0.3.tgz" }, "which": { - "version": "1.0.5", - "from": "which@" + "version": "1.0.9", + "from": "which@1.0.9", + "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz" }, "wink": { "version": "0.0.1", - "from": "wink@0.0.1", + "from": "https://registry.npmjs.org/wink/-/wink-0.0.1.tgz", "resolved": "https://registry.npmjs.org/wink/-/wink-0.0.1.tgz" }, "winssh": { - "version": "0.0.1", - "from": "winssh@", - "resolved": "https://registry.npmjs.org/winssh/-/winssh-0.0.1.tgz" + "version": "0.0.3", + "from": "winssh@0.0.3", + "resolved": "https://registry.npmjs.org/winssh/-/winssh-0.0.3.tgz", + "dependencies": { + "optimist": { + "version": "0.6.1", + "from": "optimist@>=0.6.1 <0.7.0", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "from": "wordwrap@>=0.0.2 <0.1.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz" + }, + "minimist": { + "version": "0.0.10", + "from": "minimist@0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz" + } + } + } + } }, "wmic": { "version": "0.0.7", "from": "https://registry.npmjs.org/wmic/-/wmic-0.0.7.tgz", - "resolved": "https://registry.npmjs.org/wmic/-/wmic-0.0.7.tgz", - "dependencies": { - "async": { - "version": "0.9.0", - "from": "async@0.9.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz" - } - } + "resolved": "https://registry.npmjs.org/wmic/-/wmic-0.0.7.tgz" } } } diff --git a/package.json b/package.json index 7acd1f034..b0e021d13 100644 --- a/package.json +++ b/package.json @@ -38,11 +38,12 @@ "firewall": "0.0.5", "folder": "0.0.4", "getset": "^0.6.3", + "graceful-fs": "^3.0.5", "linus": "0.0.4", "memorize": "0.0.1", "mime": "1.2.5", "nat-pmp": "", - "needle": "^0.7.9", + "needle": "^0.8.1", "network": "^0.1.3", "nodemailer": "1.3.0", "ocelot": "0.0.5", diff --git a/test/lib/conf/tasks.js b/test/lib/conf/tasks.js index f407b2766..c333b2e7d 100755 --- a/test/lib/conf/tasks.js +++ b/test/lib/conf/tasks.js @@ -295,10 +295,46 @@ describe('tasks', function() { describe('with no versions support', function() { - before(function() { + var old_current; + + before(function(done) { common.system.paths.versions = null; + + old_current = common.system.paths.current; + common.system.paths.current = join(tmpdir, "foobar"); + + var dir = common.system.paths.current; + + var createDirStructure = function (base_dir) { + fs.mkdir(base_dir, function () { + fs.mkdir(join(base_dir, "bin"), function () { + var preyBinDir = join(__dirname, "..", "..", "..","bin", "prey"); + var tempBinDir = join(base_dir, "bin", "prey"); + fs.link(join(__dirname, "..", "..", "..","bin", "prey"), join(base_dir, "bin", "prey"), function (err) { + if (err) { console.log(err) } + done(); + }); + }); + }); + } + + fs.exists(dir, function (exists) { + if (exists) { + rimraf(dir, function () { + createDirStructure(dir); + }); + } else { + createDirStructure(dir); + } + }); + }) + after(function(done) { + rimraf(common.system.paths.current, done) + common.system.paths.current = old_current; + }); + it('does not create a current symlink/dir', function(done) { var spy = sinon.spy(vm, 'set_current'); @@ -326,19 +362,21 @@ describe('tasks', function() { before(function(done) { chmod_stub.restore(); - fs.chmod(common.system.paths.current, '0755', done); + fs.chmod(common.system.paths.current, '0755', function () { + fs.chmod(join(common.system.paths.current, "bin", "prey"), '0644', done); + }); + }) after(stub_chmod); - it('chmods files to 33261 (0755)', function(done) { + it('chmods files to 100755 (0755)', function(done) { tasks.activate({}, function(err) { should.not.exist(err); - fs.readdir(common.system.paths.current, function(err, list) { - var stat = fs.lstatSync(list[0]); - stat.mode.should.eql(33261); - done(); - }) + var stat = fs.lstatSync(join(common.system.paths.current, "bin", "prey")); + var intMode = stat.mode.toString(8); + intMode.should.eql('100755'); // stat -f %p + done(); }); }) @@ -384,12 +422,8 @@ describe('tasks', function() { it('doesnt stop, but shows warning', function(done) { - // var spy = sinon.spy(process.stdout, 'write'); tasks.activate({}, function(err, out) { should.not.exist(err); - // spy.called.should.be.true; - // spy.args[0][0].should.containEql('is already set as current'); - // spy.restore(); done(); }) }) @@ -412,7 +446,6 @@ describe('tasks', function() { before(function(done) { rimraf(dir, done); - // fs.existsSync(dir).should.be.false; }) it('fails miserably', function(done) { @@ -532,18 +565,17 @@ describe('tasks', function() { }) - it('chmods files to 33261 (0755)', function(done) { + it('chmods files to 100755 (0755)', function(done) { chmod_stub.restore(); tasks.activate({}, function(err) { should.not.exist(err); - fs.readdir(common.system.paths.current, function(err, list) { - var stat = fs.lstatSync(list[0]); - stat.mode.should.eql(33261); - stub_chmod(); - done(); - }) + var stat = fs.lstatSync(join(common.system.paths.current, "package.json")); + var intMode = stat.mode.toString(8); + intMode.should.eql('100755'); // stat -f %p + stub_chmod(); + done(); }); })