diff --git a/lib/agent/actions.js b/lib/agent/actions.js
index d92b488ba..d364c0ef3 100644
--- a/lib/agent/actions.js
+++ b/lib/agent/actions.js
@@ -116,7 +116,6 @@ actions.stop = function(name) {
} else {
action.stop();
}
-
}
actions.stop_all = function() {
diff --git a/lib/agent/actions/alarm/lib/alarm.mp3 b/lib/agent/actions/alarm/lib/alarm.mp3
index 8a3bf0016..843468c59 100644
Binary files a/lib/agent/actions/alarm/lib/alarm.mp3 and b/lib/agent/actions/alarm/lib/alarm.mp3 differ
diff --git a/lib/agent/cli.js b/lib/agent/cli.js
index 4c2b455c3..974d784a6 100644
--- a/lib/agent/cli.js
+++ b/lib/agent/cli.js
@@ -37,24 +37,19 @@ var common = require('./common'),
logger = common.logger,
pidfile; // null unless we do set one.
-var write = function(str) {
+function warn(str, code) {
if (process.stdout.writable)
process.stdout.write(str + '\n');
-}
-if (program.nodeVersion) {
- return logger.write(process.version);
-} else if (!common.config.present()) {
- write('\nLooks like there\'s no config file yet. Glad to see you\'re getting started. :)');
- write('To finish setting up Prey, please run `prey config hooks post_install` as root.\n');
- return process.exit(1);
+ if (typeof code != 'undefined')
+ process.exit(code);
}
/////////////////////////////////////////////////////////////
// event, signal handlers
/////////////////////////////////////////////////////////////
-var shutdown = function(code, wait) {
+function shutdown(code, wait) {
var wait = wait || 10000;
var die = function(graceful) {
@@ -79,91 +74,107 @@ var shutdown = function(code, wait) {
}
}
-process.on('exit', function(code) {
- shutdown(code);
-});
-
-// sent by other instance when updating config
-// SIGHUP is the default signal sent by Upstart when reloading a job.
-process.on('SIGHUP', function() {
- logger.warn('Got SIGHUP signal!');
- agent.reload();
-})
-
-// sent by Upstart
-process.on('SIGQUIT', function() {
- logger.warn('Got QUIT signal.');
- shutdown(0, 10000);
-});
-
-// sent by LaunchDaemon
-// we cannot exit with code 0 as LaunchDaemon
-// will assume the process exited normally.
-process.on('SIGTERM', function() {
- logger.warn('Got TERM signal.');
- shutdown(11, 10000);
-});
-
-// sent when developing. :)
-// 130 is the 'official' exit code in Bash for SIGINTs
-process.on('SIGINT', function() {
- if (!agent.running()) {
- logger.warn('Ok, ok, whatever you say.');
- return process.exit(2);
- }
+function trap_signals() {
+
+ process.on('exit', function(code) {
+ shutdown(code);
+ });
+
+ // sent by other instance when updating config
+ // SIGHUP is the default signal sent by Upstart when reloading a job.
+ process.on('SIGHUP', function() {
+ logger.warn('Got SIGHUP signal!');
+ agent.reload();
+ })
+
+ // sent by Upstart
+ process.on('SIGQUIT', function() {
+ logger.warn('Got QUIT signal.');
+ shutdown(0, 10000);
+ });
+
+ // sent by LaunchDaemon
+ // we cannot exit with code 0 as LaunchDaemon
+ // will assume the process exited normally.
+ process.on('SIGTERM', function() {
+ logger.warn('Got TERM signal.');
+ shutdown(11, 10000);
+ });
- logger.warn('Got INT signal.');
- shutdown(130, 5000);
-});
+ // sent when developing. :)
+ // 130 is the 'official' exit code in Bash for SIGINTs
+ process.on('SIGINT', function() {
+ if (!agent.running()) {
+ logger.warn('Ok, ok, whatever you say.');
+ return process.exit(2);
+ }
+
+ logger.warn('Got INT signal.');
+ shutdown(130, 5000);
+ });
-process.on('uncaughtException', function (err) {
- logger.critical('UNCAUGHT EXCEPTION: ' + (err.message || err));
- logger.debug(err.stack);
+ process.on('uncaughtException', function (err) {
+ logger.critical('UNCAUGHT EXCEPTION: ' + (err.message || err));
+ logger.debug(err.stack);
- if (!common.config.get('send_crash_reports'))
- return shutdown(1, 5000);
+ if (!common.config.get('send_crash_reports'))
+ return shutdown(1, 5000);
- common.exceptions.send(err, function() {
- shutdown(1, 5000);
+ common.exceptions.send(err, function() {
+ shutdown(1, 5000);
+ });
});
-});
+
+}
////////////////////////////////////////////////////////////
// launcher
/////////////////////////////////////////////////////////////
-if (process.argv[2] == 'console')
- program.mode = 'console';
+(function() {
-if (program.allowOther || program.run || program.mode == 'console') {
- return agent.run();
-}
+ if (program.nodeVersion) {
+ return warn(process.version, 0);
+ } else if (!common.config.present()) {
+ warn('\nLooks like there\'s no config file yet. Glad to see you\'re getting started. :)');
+ return warn('To finish setting up Prey, please run `prey config hooks post_install` as root.\n', 1);
+ }
+
+ trap_signals();
-// if running in console mode, or using -a or -r, pidfile won't
-// be available for them to remove on process.exit().
-pidfile = common.pid_file;
+ if (process.argv[2] == 'console')
+ program.mode = 'console';
-pid.store(pidfile, function(err, running) {
- if (err) {
- var msg = err.code == 'EPERM' ? 'No write access to pidfile: ' + pidfile : err.message;
- write('Cannot continue: ' + msg);
- return process.exit(1);
+ if (program.allowOther || program.run || program.mode == 'console') {
+ return agent.run();
}
- if (!running) return agent.run();
+ // if running in console mode, or using -a or -r, pidfile won't
+ // be available for them to remove on process.exit().
+ pidfile = common.pid_file;
- if (process.stdout.writable) {
- write('\n The Prey agent is running. Good job!');
+ pid.store(pidfile, function(err, running) {
+ if (err) {
+ var msg = err.code == 'EPERM' ? 'No write access to pidfile: ' + pidfile : err.message;
+ return warn('Cannot continue: ' + msg, 1);
+ }
+
+ if (!running) return agent.run();
+
+ if (process.stdout.writable) {
+ warn('\n The Prey agent is running. Good job!');
- if (running.stat && running.stat.ctime) {
- var run_time = (new Date() - running.stat.ctime)/(60 * 1000);
- var run_time_str = run_time.toString().substring(0,5);
- write(' It has been live for ' + run_time_str + ' minutes, under process ID ' + running.pid + '.');
+ if (running.stat && running.stat.ctime) {
+ var run_time = (new Date() - running.stat.ctime)/(60 * 1000);
+ var run_time_str = run_time.toString().substring(0,5);
+ warn(' It has been live for ' + run_time_str + ' minutes, under process ID ' + running.pid + '.');
+ }
+
+ warn(' To trigger actions or retrieve information, log in to your Prey account at https://preyproject.com');
+ warn(' For additional configuration options, please run `prey config`.\n');
}
- write(' To trigger actions or retrieve information, log in to your Prey account at https://preyproject.com');
- write(' For additional configuration options, please run `prey config`.\n');
- }
+ process.exit(10);
+ });
- process.exit(10);
-});
+})();
diff --git a/lib/agent/hooks.js b/lib/agent/hooks.js
index 9f3ac0948..7cc6657d6 100644
--- a/lib/agent/hooks.js
+++ b/lib/agent/hooks.js
@@ -1,6 +1,5 @@
var logger = require('./common').logger.prefix('hooks'),
Emitter = require('events').EventEmitter,
- hooks = {},
emitter = new Emitter();
var trigger = function(event) {
diff --git a/lib/agent/plugins/control-panel/api/accounts.js b/lib/agent/plugins/control-panel/api/accounts.js
index fd3889430..7c1313b1a 100644
--- a/lib/agent/plugins/control-panel/api/accounts.js
+++ b/lib/agent/plugins/control-panel/api/accounts.js
@@ -33,10 +33,10 @@ exports.authorize = function(opts, cb) {
if (resp.statusCode == 401) {
cb(errors.get('INVALID_CREDENTIALS'))
- } else if (body.user && parseInt(body.user.available_slots) <= 0) {
+ } else if (body && body.user && parseInt(body.user.available_slots) <= 0) {
cb(errors.get('NO_AVAILABLE_SLOTS'));
- } else if (body && body.key || (body.user && body.user.key)) {
+ } else if (body && body.key || (body && body.user && body.user.key)) {
cb(null, set(body.key || body.user.key));
} else {
diff --git a/lib/agent/plugins/control-panel/index.js b/lib/agent/plugins/control-panel/index.js
index 83d788ba0..004c51915 100644
--- a/lib/agent/plugins/control-panel/index.js
+++ b/lib/agent/plugins/control-panel/index.js
@@ -40,18 +40,20 @@ var wait_for_config = function() {
var attempts = 0;
var timer = setInterval(function() {
+
logger.info('Reloading config...');
config.reload();
if (config.get('api_key') && config.get('device_key')) {
+
clearInterval(timer);
// set the new keys in the api before booting
- init_api(config.all(), function() {
- boot();
- })
+ init_api(config.all(), function() { boot() });
+
} else if (++attempts > 30) { // five mins total
throw new Error('Not configured. Stopping.');
}
+
}, 10000); // 10 seconds
}
@@ -250,7 +252,7 @@ exports.unload = function(cb) {
}
// export API for conf module
-exports.load_api = function(opts) {
- init_api(opts);
+exports.load_api = function(opts, cb) {
+ init_api(opts, cb);
return api;
};
diff --git a/lib/agent/plugins/control-panel/sender.js b/lib/agent/plugins/control-panel/sender.js
index 65d5c22d2..b579f0414 100644
--- a/lib/agent/plugins/control-panel/sender.js
+++ b/lib/agent/plugins/control-panel/sender.js
@@ -14,9 +14,7 @@ var make_request = function(what, data, opts, cb) {
what = what.replace(/s$/, '');
opts.multipart = what == 'report';
-
- var msg = 'Posting ' + what;
- logger.info(msg);
+ logger.info('Posting ' + what);
api.push[what](data, opts, function(err, resp) {
bus.emit('response', what, err, resp);
@@ -28,7 +26,7 @@ var send = function(what, data, opts, cb) {
var opts = opts || {};
var done = function(err, resp) {
- var str = err ? 'Got error: ' + err.message : 'Got ' + resp.statusCode + ' response: ' + resp.body.toString();
+ var str = err ? 'Got error: ' + err.message : 'Got ' + resp.statusCode + ' response: ' + resp.body;
logger.info(str);
cb && cb(err, resp);
}
diff --git a/lib/agent/plugins/control-panel/test/main_load.js b/lib/agent/plugins/control-panel/test/main_load.js
index 3b8459e55..dec0fafbb 100644
--- a/lib/agent/plugins/control-panel/test/main_load.js
+++ b/lib/agent/plugins/control-panel/test/main_load.js
@@ -24,6 +24,7 @@ describe('main.load', function() {
// insert default values to config
config.set('host', 'destination.com');
config.set('protocol', 'https');
+ config.global = { get: function() {} }
var background = false;
@@ -391,4 +392,4 @@ describe('main.load', function() {
})
-})
\ No newline at end of file
+})
diff --git a/lib/agent/providers.js b/lib/agent/providers.js
index 86768f75a..feb62a9af 100644
--- a/lib/agent/providers.js
+++ b/lib/agent/providers.js
@@ -71,17 +71,18 @@ var get = exports.get = function(name, cb) {
callback = cb || function(){ /* noop */ };
var fire_callbacks = function(name, err, result) {
- callbacks[name].forEach(function(fn){
+ var list = callbacks[name];
+ callbacks[name] = [];
+
+ list.forEach(function(fn){
fn(err, result, name);
});
- callbacks[name] = [];
}
if (name == 'report')
name = 'stolen';
map(function(err, getters) {
-
if (err) return callback(err);
if (getters[name]) {
@@ -89,12 +90,15 @@ var get = exports.get = function(name, cb) {
callbacks[name] = callbacks[name] || [];
callbacks[name].push(callback);
- if (callbacks[name].length > 1)
+ if (callbacks[name].length > 1) {
return logger.info(name + ' already in progress.');
+ }
logger.debug('Fetching ' + name);
getters[name](function(err, result) {
+ fire_callbacks(name, err, result);
+
if (!cb) { // only emit when no callback passed
if (err)
hooks.trigger('error', err);
@@ -106,7 +110,6 @@ var get = exports.get = function(name, cb) {
files.push(result.file); // keep a record so we remove it afterwards
}
- fire_callbacks(name, err, result);
});
} else {
diff --git a/lib/agent/transports/http/index.js b/lib/agent/transports/http/index.js
index f46c07769..ea25b70e7 100644
--- a/lib/agent/transports/http/index.js
+++ b/lib/agent/transports/http/index.js
@@ -15,17 +15,17 @@ exports.defaults = function(opts) {
}
exports.get = function(url, opts, cb) {
- return exports.request('GET', url, null, opts, cb)
+ return request('GET', url, null, opts, cb)
}
exports.post = function(url, data, opts, cb) {
- return exports.request('POST', url, data, opts, cb)
+ return request('POST', url, data, opts, cb)
}
exports.put = function(url, data, opts, cb) {
- return exports.request('PUT', url, data, opts, cb)
+ return request('PUT', url, data, opts, cb)
}
exports.del = function(url, data, opts, cb) {
- return exports.request('DELETE', url, data, opts, cb)
+ return request('DELETE', url, data, opts, cb)
}
diff --git a/lib/agent/triggers/power/index.js b/lib/agent/triggers/power/index.js
index a258a2c18..52c8e391a 100644
--- a/lib/agent/triggers/power/index.js
+++ b/lib/agent/triggers/power/index.js
@@ -9,7 +9,7 @@ var emitter,
var check_battery_status = function() {
- providers.get('battery_status', function(err, current){
+ providers.get('battery_status', function(err, current) {
if (err || !emitter) return;
// console.log('Current: ' + current.state);
@@ -31,7 +31,7 @@ exports.start = function(opts, cb){
if (err) return cb(err);
power.on('state_changed', function(info){
- check_battery_status(info);
+ setTimeout(check_battery_status, 1500);
});
power.on('low_power', function(info){
diff --git a/lib/conf/gui/linux/prey-config.glade b/lib/conf/gui/linux/prey-config.glade
index fe5a37fe3..fb161411f 100644
--- a/lib/conf/gui/linux/prey-config.glade
+++ b/lib/conf/gui/linux/prey-config.glade
@@ -470,6 +470,19 @@
120
+
+
+
+ 150
+ 160
+
+
3
diff --git a/lib/conf/gui/mac/PreyConfig.app/Contents/MacOS/prey-config.py b/lib/conf/gui/mac/PreyConfig.app/Contents/MacOS/prey-config.py
index 7c0510f24..85c111a82 100755
--- a/lib/conf/gui/mac/PreyConfig.app/Contents/MacOS/prey-config.py
+++ b/lib/conf/gui/mac/PreyConfig.app/Contents/MacOS/prey-config.py
@@ -48,7 +48,7 @@
}
################################################
-# paths and such
+# paths and such
SCRIPT_PATH = sys.path[0]
@@ -60,7 +60,7 @@ def find_in_path(file):
full_path = os.path.join('/'.join(segments), file)
# print "Checking %s" % full_path
if os.path.exists(full_path):
- return full_path
+ return full_path
else:
path = segments.pop()
@@ -421,6 +421,10 @@ def run_command(self, cmd):
self.out = "Exception! %s" % e
self.code = 1
+ def open_pass_recovery_url(self):
+ url = "https://panel.preyproject.com/forgot"
+ res = NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_(url))
+
######################################################
# tab clicks
@@ -466,7 +470,8 @@ def drawExistingUser(self, tab, name):
elements = []
elements.append(self.drawTextInput('existing_email', 'Email', 15, 140))
elements.append(self.drawPasswordInput('existing_pass', 'Password', 15, 85))
-
+ elements.append(self.drawButton(NSMakeRect(15, 20, 420, 50), 'Forgot your password?', 'open_pass_recovery_url'))
+
for element in flatten(elements):
tab.view().addSubview_(element)
diff --git a/lib/conf/gui/windows/prey-config.exe b/lib/conf/gui/windows/prey-config.exe
index 5040e7a1a..c60044a2e 100644
Binary files a/lib/conf/gui/windows/prey-config.exe and b/lib/conf/gui/windows/prey-config.exe differ
diff --git a/lib/plugins.js b/lib/plugins.js
index c1eef15b5..af14dd09d 100644
--- a/lib/plugins.js
+++ b/lib/plugins.js
@@ -14,7 +14,7 @@ var filter = function(arr) {
// exports
// init the loader. this provides all(), get(), require() and invoke()
-var plugins = wink.init(__dirname + '/agent/plugins');
+var plugins = wink.init(__dirname + '/agent/plugins');
// called from common lib after config is loaded
plugins.init = function(config_obj) {
@@ -33,7 +33,7 @@ plugins.get_enabled = function() {
var obj = config.get(config_key);
- if (obj && obj.length)
+ if (obj && typeof obj == 'object')
return filter(obj);
return filter((obj || '').split(', '))
diff --git a/package.json b/package.json
index 832a1492e..5ca0ea679 100644
--- a/package.json
+++ b/package.json
@@ -57,7 +57,7 @@
"scrambler": "0.0.1",
"serve-static": "^1.7.0",
"sudoer": "^0.1.1",
- "triggers": "^0.2.0",
+ "triggers": "^0.3.0",
"tuna": "0.0.2",
"underscore": "",
"whenever": "0.0.3",
diff --git a/test/bin_spec.js b/test/bin_spec.js
index e3f96826c..a8c5a688a 100644
--- a/test/bin_spec.js
+++ b/test/bin_spec.js
@@ -1,7 +1,6 @@
var should = require('should'),
path = require('path'),
fs = require('fs'),
- os = require('os'),
exec = require('child_process').exec,
spawn = require('child_process').spawn,
is_windows = process.platform == 'win32';
@@ -11,7 +10,6 @@ var exec_env = process.env, // so we can override it later
bin_path = path.join(__dirname, '..', 'bin'),
bin_prey = path.join(bin_path, 'prey'),
node_bin = path.join(bin_path, 'node'),
- fake_log_file = path.join(os.tmpDir(), 'fake_test_log_file.log'),
local_present = fs.existsSync(node_bin);
if (is_windows) {
@@ -40,22 +38,6 @@ function run_bin_prey(args, cb) {
}, 1500);
}
-/*
-
-function mask_bin_prey(){
- var bin_prey_content = fs.readFileSync(bin_prey,'utf8');
- fs.renameSync(bin_prey, bin_prey + '.tmp');
- var fake_prey_content = bin_prey_content.replace('if (scr',
- 'var require=function(str){console.log(str);console.log(process.argv);return 0;}\nif (scr');
- fs.writeFileSync(bin_prey, fake_prey_content, {mode: 0755});
-}
-
-function unmask_bin_prey(){
- fs.renameSync(bin_prey + '.tmp', bin_prey);
-}
-
-*/
-
describe('bin/prey', function(){
before(function(done) {
@@ -77,19 +59,10 @@ describe('bin/prey', function(){
});
});
- after(function(done){
- fs.unlink(fake_log_file, done);
- });
-
- // we use a fake log file since when running via mocha
- // the spawned process does not have a tty attached, so
- // it assumes that it is running on background and prints
- // any output to the default log file (/var/log/prey.log)
it('uses local node binary', function(done){
- run_bin_prey(['-l', fake_log_file, '-N'], function(code) {
+ run_bin_prey(['-N'], function(code, out, err) {
code.should.equal(0);
- var read_version = fs.readFileSync(fake_log_file, 'utf8');
- read_version.should.containEql(node_versions.local);
+ out.should.containEql(node_versions.local);
done();
})
});
@@ -107,7 +80,6 @@ describe('bin/prey', function(){
it('calls lib/agent/cli.js', function(done){
run_bin_prey(['-h'], function(code, out, err){
- // out.should.containEql('spreads its wings');
out.should.containEql('--logfile');
done();
});
@@ -135,34 +107,6 @@ describe('bin/prey', function(){
});
});
-/*
-
- describe('when called with `test` argument', function(){
- it('calls mocha', function(done){
- run_bin_prey(' test', function(err, out){
- var out_command =
- is_windows ? 'node_modules\\.bin\\_mocha'
- : 'node_modules/.bin/_mocha'
- out.should.containEql(out_command);
- done();
- });
- });
-
- it('passes any other arguments too (eg. `--reporter nyan`)', function(done){
- run_bin_prey(' test --reporter nyan', function(err, out){
- var out_command =
- is_windows ? 'node_modules\\.bin\\_mocha'
- : 'node_modules/.bin/_mocha';
- out.should.containEql(out_command);
- out.should.containEql('--reporter');
- out.should.containEql('nyan');
- done();
- });
- });
- });
-
-*/
-
describe('when called with unknown argument', function(){
it('returns unknown option', function(done){
run_bin_prey(['--hellomyfriend'], function(err, out, stderr){
diff --git a/test/lib/package.js b/test/lib/package.js
index bec58d073..0da202023 100644
--- a/test/lib/package.js
+++ b/test/lib/package.js
@@ -6,6 +6,7 @@ var fs = require('fs'),
sinon = require('sinon'),
should = require('should'),
rmdir = require('rimraf'),
+ buckle = require('buckle'),
child_process = require('child_process'),
helpers = require('../helpers');