Permalink
Browse files

Upgrade to hapi 0.1.0

  • Loading branch information...
1 parent 79c77da commit 189dc04c8537c02c059ebf1dd2da227a186605ed @hueniverse committed Feb 9, 2012
Showing with 721 additions and 1,061 deletions.
  1. +8 −12 api/batch.js
  2. +44 −45 api/db.js
  3. +19 −28 api/details.js
  4. +23 −25 api/email.js
  5. +61 −6 api/index.js
  6. +8 −9 api/install.js
  7. +18 −29 api/invite.js
  8. +26 −40 api/last.js
  9. +3 −3 api/package.json
  10. +121 −172 api/project.js
  11. +2 −2 api/rules.js
  12. +0 −82 api/server.js
  13. +55 −81 api/session.js
  14. +5 −6 api/sort.js
  15. +41 −61 api/storage.js
  16. +27 −39 api/stream.js
  17. +18 −27 api/suggestions.js
  18. +56 −78 api/task.js
  19. +4 −5 api/tips.js
  20. +157 −248 api/user.js
  21. +12 −30 clients/view/js/mac.js
  22. +1 −2 web/api.js
  23. +0 −1 web/login.js
  24. +1 −1 web/package.json
  25. +11 −29 web/static/scripts/mac.js
View
20 api/batch.js
@@ -5,10 +5,9 @@
// Load modules
+var Hapi = require('hapi');
var Http = require('http');
var MAC = require('mac');
-var Utils = require('hapi').Utils;
-var Err = require('hapi').Error;
var Config = require('./config');
@@ -27,7 +26,7 @@ exports.type = {
// Batch processing
-exports.post = function (req, res, next) {
+exports.post = function (req, reply) {
var requests = [];
var results = [];
@@ -70,12 +69,12 @@ exports.post = function (req, res, next) {
}
};
- for (var i = 0, il = req.body.get.length; i < il; ++i) {
+ for (var i = 0, il = req.hapi.payload.get.length; i < il; ++i) {
// Break into parts
var parts = [];
- var result = req.body.get[i].replace(requestRegex, parseRequest);
+ var result = req.hapi.payload.get[i].replace(requestRegex, parseRequest);
// Make sure entire string was processed (empty)
@@ -96,8 +95,7 @@ exports.post = function (req, res, next) {
}
else {
- res.api.error = Err.badRequest(error);
- next();
+ reply(Hapi.Error.badRequest(error));
}
}
@@ -107,8 +105,7 @@ exports.post = function (req, res, next) {
// Return results
- res.api.result = results;
- next();
+ reply(results);
});
}
@@ -180,7 +177,7 @@ exports.post = function (req, res, next) {
// Make request
- internals.call('GET', path, null, req.api.session, function (data, err) {
+ internals.call('GET', path, null, req.hapi.session, function (data, err) {
if (err === null) {
@@ -228,7 +225,7 @@ internals.call = function (method, path, content, arg1, arg2) { // session, ca
if (session) {
- authorization = MAC.getAuthorizationHeader(method, path, Config.host.api.domain, Config.host.api.port, session, body);
+ authorization = MAC.getAuthorizationHeader(method, path, Config.host.api.domain, Config.host.api.port, session);
if (authorization === null ||
authorization === '') {
@@ -295,7 +292,6 @@ internals.call = function (method, path, content, arg1, arg2) { // session, ca
if (body !== null) {
- hreq.setHeader('Content-Length', body.length);
hreq.setHeader('Content-Type', 'application/json');
hreq.write(body);
}
View
89 api/db.js
@@ -6,8 +6,7 @@
// Load Modules
var MongoDB = require('mongodb');
-var Err = require('hapi').Error;
-var Utils = require('hapi').Utils;
+var Hapi = require('hapi');
var Vault = require('./vault');
var Config = require('./config');
@@ -134,19 +133,19 @@ exports.all = function (collectionName, callback) {
}
else {
- callback(null, Err.database(err, collectionName, 'all'));
+ callback(null, Hapi.Error.database(err, collectionName, 'all'));
}
});
}
else {
- callback(null, Err.database(err, collectionName, 'all'));
+ callback(null, Hapi.Error.database(err, collectionName, 'all'));
}
});
}
else {
- callback(null, Err.database('Collection not found', collectionName, 'all'));
+ callback(null, Hapi.Error.database('Collection not found', collectionName, 'all'));
}
};
@@ -170,7 +169,7 @@ exports.get = function (collectionName, id, callback) {
}
else {
- callback(null, Err.database(err, collectionName, 'get', id));
+ callback(null, Hapi.Error.database(err, collectionName, 'get', id));
}
});
}
@@ -181,7 +180,7 @@ exports.get = function (collectionName, id, callback) {
}
else {
- callback(null, Err.database('Collection not found', collectionName, 'get', id));
+ callback(null, Hapi.Error.database('Collection not found', collectionName, 'get', id));
}
};
@@ -253,13 +252,13 @@ exports.getMany = function (collectionName, ids, callback) {
}
else {
- callback(null, Err.database(err, collectionName, 'getMany', ids), ids);
+ callback(null, Hapi.Error.database(err, collectionName, 'getMany', ids), ids);
}
});
}
else {
- callback(null, Err.database(err, collectionName, 'getMany', ids), ids);
+ callback(null, Hapi.Error.database(err, collectionName, 'getMany', ids), ids);
}
});
}
@@ -270,7 +269,7 @@ exports.getMany = function (collectionName, ids, callback) {
}
else {
- callback(null, Err.database('Collection not found', collectionName, 'getMany', ids), ids);
+ callback(null, Hapi.Error.database('Collection not found', collectionName, 'getMany', ids), ids);
}
};
@@ -296,19 +295,19 @@ exports.query = function (collectionName, criteria, callback) {
}
else {
- callback(null, Err.database(err, collectionName, 'query', criteria));
+ callback(null, Hapi.Error.database(err, collectionName, 'query', criteria));
}
});
}
else {
- callback(null, Err.database(err, collectionName, 'query', criteria));
+ callback(null, Hapi.Error.database(err, collectionName, 'query', criteria));
}
});
}
else {
- callback(null, Err.database('Collection not found', collectionName, 'query', criteria));
+ callback(null, Hapi.Error.database('Collection not found', collectionName, 'query', criteria));
}
};
@@ -341,7 +340,7 @@ exports.queryUnique = function (collectionName, criteria, callback) {
}
else {
- callback(null, Err.database('Found multiple results for unique criteria', collectionName, 'queryUnique', criteria));
+ callback(null, Hapi.Error.database('Found multiple results for unique criteria', collectionName, 'queryUnique', criteria));
}
}
else {
@@ -352,24 +351,24 @@ exports.queryUnique = function (collectionName, criteria, callback) {
}
else {
- callback(null, Err.database('Null result array', collectionName, 'queryUnique', criteria));
+ callback(null, Hapi.Error.database('Null result array', collectionName, 'queryUnique', criteria));
}
}
else {
- callback(null, Err.database(err, collectionName, 'queryUnique', criteria));
+ callback(null, Hapi.Error.database(err, collectionName, 'queryUnique', criteria));
}
});
}
else {
- callback(null, Err.database(err, collectionName, 'queryUnique', criteria));
+ callback(null, Hapi.Error.database(err, collectionName, 'queryUnique', criteria));
}
});
}
else {
- callback(null, Err.database('Collection not found', collectionName, 'queryUnique', criteria));
+ callback(null, Hapi.Error.database('Collection not found', collectionName, 'queryUnique', criteria));
}
};
@@ -390,13 +389,13 @@ exports.count = function (collectionName, criteria, callback) {
}
else {
- callback(null, Err.database(err, collectionName, 'count', criteria));
+ callback(null, Hapi.Error.database(err, collectionName, 'count', criteria));
}
});
}
else {
- callback(null, Err.database('Collection not found', collectionName, 'count', criteria));
+ callback(null, Hapi.Error.database('Collection not found', collectionName, 'count', criteria));
}
};
@@ -408,7 +407,7 @@ exports.insert = function (collectionName, items, callback) {
var collection = internals.collections[collectionName];
if (collection) {
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
if (items instanceof Array) {
@@ -436,18 +435,18 @@ exports.insert = function (collectionName, items, callback) {
}
else {
- callback(null, Err.database('No database insert output', collectionName, 'insert', items));
+ callback(null, Hapi.Error.database('No database insert output', collectionName, 'insert', items));
}
}
else {
- callback(null, Err.database(err, collectionName, 'insert', items));
+ callback(null, Hapi.Error.database(err, collectionName, 'insert', items));
}
});
}
else {
- callback(null, Err.database('Collection not found', collectionName, 'insert', items));
+ callback(null, Hapi.Error.database('Collection not found', collectionName, 'insert', items));
}
};
@@ -459,7 +458,7 @@ exports.replace = function (collectionName, item, callback) {
var collection = internals.collections[collectionName];
if (collection) {
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
if (item.created === undefined) {
item.created = now;
@@ -478,18 +477,18 @@ exports.replace = function (collectionName, item, callback) {
}
else {
- callback(Err.database('No document found to replace', collectionName, 'replace', item));
+ callback(Hapi.Error.database('No document found to replace', collectionName, 'replace', item));
}
}
else {
- callback(Err.database(err, collectionName, 'replace', item));
+ callback(Hapi.Error.database(err, collectionName, 'replace', item));
}
});
}
else {
- callback(Err.database('Collection not found', collectionName, 'replace', item));
+ callback(Hapi.Error.database('Collection not found', collectionName, 'replace', item));
}
};
@@ -504,7 +503,7 @@ exports.update = function (collectionName, id, changes, callback) {
changes = changes || {};
changes.$set = changes.$set || {};
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
changes.$set.modified = now;
var dbId = internals.getDbId(id);
@@ -520,23 +519,23 @@ exports.update = function (collectionName, id, changes, callback) {
}
else {
- callback(Err.database('No document found to update', collectionName, 'update', [id, changes]));
+ callback(Hapi.Error.database('No document found to update', collectionName, 'update', [id, changes]));
}
}
else {
- callback(Err.database(err, collectionName, 'update', [id, changes]));
+ callback(Hapi.Error.database(err, collectionName, 'update', [id, changes]));
}
});
}
else {
- callback(Err.database('Invalid id', collectionName, 'update', [id, changes]));
+ callback(Hapi.Error.database('Invalid id', collectionName, 'update', [id, changes]));
}
}
else {
- callback(Err.database('Collection not found', collectionName, 'update', [id, changes]));
+ callback(Hapi.Error.database('Collection not found', collectionName, 'update', [id, changes]));
}
};
@@ -551,7 +550,7 @@ exports.updateCriteria = function (collectionName, id, itemCriteria, changes, ca
changes = changes || {};
changes.$set = changes.$set || {};
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
changes.$set.modified = now;
var isValid = true;
@@ -591,7 +590,7 @@ exports.updateCriteria = function (collectionName, id, itemCriteria, changes, ca
}
else {
- callback(Err.database('No document found to update', collectionName, 'updateCriteria', [id, itemCriteria, changes, options]));
+ callback(Hapi.Error.database('No document found to update', collectionName, 'updateCriteria', [id, itemCriteria, changes, options]));
}
}
else {
@@ -601,18 +600,18 @@ exports.updateCriteria = function (collectionName, id, itemCriteria, changes, ca
}
else {
- callback(Err.database(err, collectionName, 'updateCriteria', [id, itemCriteria, changes, options]));
+ callback(Hapi.Error.database(err, collectionName, 'updateCriteria', [id, itemCriteria, changes, options]));
}
});
}
else {
- callback(Err.database('Invalid id', collectionName, 'updateCriteria', [id, itemCriteria, changes, options]));
+ callback(Hapi.Error.database('Invalid id', collectionName, 'updateCriteria', [id, itemCriteria, changes, options]));
}
}
else {
- callback(Err.database('Collection not found', collectionName, 'updateCriteria', [id, itemCriteria, changes]));
+ callback(Hapi.Error.database('Collection not found', collectionName, 'updateCriteria', [id, itemCriteria, changes]));
}
};
@@ -633,13 +632,13 @@ exports.remove = function (collectionName, id, callback) {
}
else {
- callback(Err.database(err, collectionName, 'remove', id));
+ callback(Hapi.Error.database(err, collectionName, 'remove', id));
}
});
}
else {
- callback(Err.database('Collection not found', collectionName, 'remove', id));
+ callback(Hapi.Error.database('Collection not found', collectionName, 'remove', id));
}
};
@@ -660,13 +659,13 @@ exports.removeCriteria = function (collectionName, criteria, callback) {
}
else {
- callback(Err.database(err, collectionName, 'remove', id));
+ callback(Hapi.Error.database(err, collectionName, 'remove', id));
}
});
}
else {
- callback(Err.database('Collection not found', collectionName, 'remove', id));
+ callback(Hapi.Error.database('Collection not found', collectionName, 'remove', id));
}
};
@@ -699,18 +698,18 @@ exports.removeMany = function (collectionName, ids, callback) {
}
else {
- callback(Err.database(err, collectionName, 'remove', ids));
+ callback(Hapi.Error.database(err, collectionName, 'remove', ids));
}
});
}
else {
- callback(Err.database('Invalid ids', collectionName, 'remove', ids));
+ callback(Hapi.Error.database('Invalid ids', collectionName, 'remove', ids));
}
}
else {
- callback(Err.database('Collection not found', collectionName, 'remove', ids));
+ callback(Hapi.Error.database('Collection not found', collectionName, 'remove', ids));
}
};
View
47 api/details.js
@@ -5,12 +5,11 @@
// Load modules
+var Hapi = require('hapi');
var Db = require('./db');
-var Utils = require('hapi').Utils;
var Task = require('./task');
var Last = require('./last');
var User = require('./user');
-var Err = require('hapi').Error;
var Stream = require('./stream');
@@ -27,9 +26,9 @@ exports.type = {
// Task details
-exports.get = function (req, res, next) {
+exports.get = function (req, reply) {
- exports.load(req.params.id, req.api.userId, false, function (details, err, task, project) {
+ exports.load(req.params.id, req.hapi.userId, false, function (details, err, task, project) {
details = details || { id: req.params.id, thread: [] };
@@ -73,35 +72,32 @@ exports.get = function (req, res, next) {
details.thread[i].user = usersMap[details.thread[i].user] || { id: details.thread[i].user };
}
- res.api.result = details;
-
- next();
+ reply(details);
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Add task detail
-exports.post = function (req, res, next) {
+exports.post = function (req, reply) {
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
- exports.load(req.params.id, req.api.userId, true, function (details, err, task, project) {
+ exports.load(req.params.id, req.hapi.userId, true, function (details, err, task, project) {
if (task) {
if (err === null) {
- var detail = req.body;
+ var detail = req.hapi.payload;
detail.created = now;
- detail.user = req.api.userId;
+ detail.user = req.hapi.userId;
if (details) {
@@ -111,12 +107,11 @@ exports.post = function (req, res, next) {
if (err === null) {
- reply(task, project);
+ finalize(task, project);
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
@@ -131,40 +126,36 @@ exports.post = function (req, res, next) {
if (err === null) {
- reply(task, project);
+ finalize(task, project);
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
- function reply(task, project) {
+ function finalize(task, project) {
if (req.query.last &&
req.query.last === 'true') {
- Last.setLast(req.api.userId, project, task, function (err) {}); // Ignore response
+ Last.setLast(req.hapi.userId, project, task, function (err) {}); // Ignore response
}
Stream.update({ object: 'details', project: task.project, task: task._id }, req);
- res.api.result = { status: 'ok' };
- next();
+ reply({ status: 'ok' });
}
};
View
48 api/email.js
@@ -5,10 +5,8 @@
// Load modules
+var Hapi = require('hapi');
var Db = require('./db');
-var Utils = require('hapi').Utils;
-var Err = require('hapi').Error;
-var Log = require('hapi').Log;
var Vault = require('./vault');
var User = require('./user');
var Config = require('./config');
@@ -23,9 +21,9 @@ exports.generateTicket = function (user, email, arg1, arg2) {
// Create new ticket
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
var ticketId = now.toString(36); // assuming users cannot generate more than one ticket per msec
- var token = Utils.encrypt(Vault.emailToken.aes256Key, [user._id, ticketId]);
+ var token = Hapi.Utils.encrypt(Vault.emailToken.aes256Key, [user._id, ticketId]);
var ticket = { timestamp: now, email: email };
@@ -98,7 +96,7 @@ exports.loadTicket = function (token, callback) {
// Decode ticket
- var record = Utils.decrypt(Vault.emailToken.aes256Key, token);
+ var record = Hapi.Utils.decrypt(Vault.emailToken.aes256Key, token);
if (record &&
record instanceof Array &&
@@ -119,7 +117,7 @@ exports.loadTicket = function (token, callback) {
user.tickets[ticketId]) {
var ticket = user.tickets[ticketId];
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
// Check expiration
@@ -230,29 +228,29 @@ exports.loadTicket = function (token, callback) {
else {
// Don't cleanup now, do it later
- callback(null, user, Err.notFound('Email token sent to address no longer associated with this account'));
+ callback(null, user, Hapi.Error.notFound('Email token sent to address no longer associated with this account'));
}
}
else {
// Don't cleanup now, do it later
- callback(null, user, Err.notFound('Expired email token'));
+ callback(null, user, Hapi.Error.notFound('Expired email token'));
}
}
else {
- callback(null, user, Err.notFound('Invalid or expired email token'));
+ callback(null, user, Hapi.Error.notFound('Invalid or expired email token'));
}
}
else {
- callback(null, null, Err.notFound('Unknown email token account'));
+ callback(null, null, Hapi.Error.notFound('Unknown email token account'));
}
});
}
else {
- callback(null, null, Err.internal('Invalid email token syntax'));
+ callback(null, null, Hapi.Error.internal('Invalid email token syntax'));
}
};
@@ -276,7 +274,7 @@ exports.sendReminder = function (user, callback) {
'Use this link to sign into ' + Config.product.name + ': \n\n' +
' ' + Config.host.uri('web') + '/t/' + ticket;
- Utils.email(user.emails[0].address, subject, text);
+ Hapi.Utils.email(user.emails[0].address, subject, text);
callback(null);
}
else {
@@ -287,7 +285,7 @@ exports.sendReminder = function (user, callback) {
}
else {
- callback(Err.internal('User has no email address'));
+ callback(Hapi.Error.internal('User has no email address'));
}
};
@@ -308,7 +306,7 @@ exports.sendValidation = function (user, address, callback) {
'Use this link to verify your email address: \n\n' +
' ' + Config.host.uri('web') + '/t/' + ticket;
- Utils.email(address, subject, text);
+ Hapi.Utils.email(address, subject, text);
callback(null);
}
else {
@@ -319,7 +317,7 @@ exports.sendValidation = function (user, address, callback) {
}
else {
- callback(Err.internal('User has no email address'));
+ callback(Hapi.Error.internal('User has no email address'));
}
};
@@ -351,7 +349,7 @@ exports.sendWelcome = function (user, callback) {
text += 'Use this link to verify your email address: \n\n';
text += ' ' + Config.host.uri('web') + '/t/' + ticket + '\n\n';
- Utils.email(address, subject, text);
+ Hapi.Utils.email(address, subject, text);
callback(null);
}
else {
@@ -369,7 +367,7 @@ exports.sendWelcome = function (user, callback) {
text += 'Use this link to sign-into ' + Config.product.name + ': \n\n';
text += ' ' + Config.host.uri('web') + '/\n\n';
- Utils.email(address, subject, text);
+ Hapi.Utils.email(address, subject, text);
callback(null);
}
else {
@@ -384,7 +382,7 @@ exports.sendWelcome = function (user, callback) {
text += 'Since you have not yet linked a Facebook, Twitter, or Yahoo! account, you will need to use this link to sign back into ' + Config.product.name + ': \n\n';
text += ' ' + Config.host.uri('web') + '/t/' + ticket + '\n\n';
- Utils.email(address, subject, text);
+ Hapi.Utils.email(address, subject, text);
callback(null);
}
else {
@@ -396,7 +394,7 @@ exports.sendWelcome = function (user, callback) {
}
else {
- callback(Err.internal('User has no email address'));
+ callback(Hapi.Error.internal('User has no email address'));
}
};
@@ -430,7 +428,7 @@ exports.projectInvite = function (users, pids, project, message, inviter) {
link = 'Use this link to join: \n\n' +
' ' + Config.host.uri('web') + '/view/#project=' + project._id;
- Utils.email(users[i].emails[0].address,
+ Hapi.Utils.email(users[i].emails[0].address,
subject,
'Hi ' + (users[i].name || users[i].username || users[i].emails[0].address) + ',\n\n' + text + link);
}
@@ -449,21 +447,21 @@ exports.projectInvite = function (users, pids, project, message, inviter) {
link = 'Use this link to join: \n\n' +
' ' + Config.host.uri('web') + '/i/' + invite;
- Utils.email(pid.email, subject, 'Hi ' + (pid.display || pid.email) + ',\n\n' + text + link, null, function (err) {
+ Hapi.Utils.email(pid.email, subject, 'Hi ' + (pid.display || pid.email) + ',\n\n' + text + link, null, function (err) {
if (err === null) {
- Log.info('Email sent to: ' + pid.email + ' for project: ' + project._id);
+ Hapi.Log.info('Email sent to: ' + pid.email + ' for project: ' + project._id);
}
else {
- Log.err('Email error: ' + pid.email + ' for project: ' + project._id);
+ Hapi.Log.err('Email error: ' + pid.email + ' for project: ' + project._id);
}
});
}
else {
- Log.err('Email error: project (' + project._id + ') pid (' + pid.pid + ') missing email address');
+ Hapi.Log.err('Email error: project (' + project._id + ') pid (' + pid.pid + ') missing email address');
}
}
}
View
67 api/index.js
@@ -5,19 +5,74 @@
// Load modules
-var Server = require('./server');
+var Hapi = require('hapi');
+var Db = require('./db');
+var Stream = require('./stream');
+var Config = require('./config');
+var Session = require('./session');
var Routes = require('./routes');
var Suggestions = require('./suggestions');
var Tips = require('./tips');
-// Create Server
+// Declare internals
-Server.create(Routes.endpoints, function (server) {
+var internals = {};
- // Load in-memory cache
- Suggestions.initialize();
- Tips.initialize();
+// Create and configure server instance
+
+Hapi.Process.initialize({
+
+ name: Config.product.name + ' API Server',
+ process: Config.process.api,
+ email: Config.email
+});
+
+var configuration = {
+
+ uri: Config.host.uri('api'),
+
+ // Terms of Service
+
+ tos: {
+
+ min: '20110623'
+ },
+
+ // Authentication
+
+ authentication: {
+
+ loadSession: Session.load
+ }
+};
+
+var server = Hapi.Server.create(configuration, Routes.endpoints);
+
+// Initialize database connection
+
+Db.initialize(function (err) {
+
+ if (err === null) {
+
+ // Load in-memory cache
+
+ Suggestions.initialize();
+ Tips.initialize();
+
+ // Start Server
+
+ server.start();
+ Stream.initialize(server.getExpress());
+ Hapi.Process.finalize();
+ }
+ else {
+
+ // Database connection failed
+
+ Hapi.Log.err(err);
+ process.exit(1);
+ }
});
View
17 api/install.js
@@ -1,8 +1,7 @@
// Load modules
-var Utils = require('hapi').Utils;
+var Hapi = require('hapi');
var Db = require('./db');
-var Log = require('hapi').Log;
// Initialize database connection
@@ -11,7 +10,7 @@ Db.initialize(true, function (err) {
if (err === null) {
- Log.info('Database initialized');
+ Hapi.Log.info('Database initialized');
// Create required clients
@@ -20,7 +19,7 @@ Db.initialize(true, function (err) {
{
name: 'postmile.web',
scope: { authorized: true, login: true, reminder: true, signup: true, tos: true },
- secret: Utils.getRandomString(64)
+ secret: Hapi.Utils.getRandomString(64)
},
{
@@ -39,20 +38,20 @@ Db.initialize(true, function (err) {
if (err === null) {
- Log.info('Initial dataset created successfully');
- Log.info('>>>>> postmile.web client secret: ' + clients[0].secret);
+ Hapi.Log.info('Initial dataset created successfully');
+ Hapi.Log.info('>>>>> postmile.web client secret: ' + clients[0].secret);
process.exit(0);
}
else {
- Log.err(err);
+ Hapi.Log.err(err);
process.exit(1);
}
});
}
else {
- Log.err(err);
+ Hapi.Log.err(err);
process.exit(1);
}
});
@@ -61,7 +60,7 @@ Db.initialize(true, function (err) {
// Database connection failed
- Log.err(err);
+ Hapi.Log.err(err);
process.exit(1);
}
});
View
47 api/invite.js
@@ -5,17 +5,16 @@
// Load modules
+var Hapi = require('hapi');
var Db = require('./db');
-var Utils = require('hapi').Utils;
-var Err = require('hapi').Error;
var Project = require('./project');
var User = require('./user');
var Stream = require('./stream');
// Check invitation code
-exports.get = function (req, res, next) {
+exports.get = function (req, reply) {
// Check invitation code type
@@ -72,20 +71,17 @@ exports.get = function (req, res, next) {
about.inviter = inviter.display;
}
- res.api.result = about;
- next();
+ reply(about);
});
}
else {
- res.api.error = Err.badRequest('Invalid invitation code');
- next();
+ reply(Hapi.Error.badRequest('Invalid invitation code'));
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
@@ -97,13 +93,11 @@ exports.get = function (req, res, next) {
if (err === null) {
- res.api.result = invite;
- next();
+ reply(invite);
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
@@ -112,7 +106,7 @@ exports.get = function (req, res, next) {
// Claim a project invitation
-exports.claim = function (req, res, next) {
+exports.claim = function (req, reply) {
var inviteRegex = /^project:([^:]+):([^:]+):([^:]+)$/;
var parts = inviteRegex.exec(req.params.id);
@@ -155,38 +149,33 @@ exports.claim = function (req, res, next) {
if (projectPid) {
- Project.replacePid(project, projectPid.pid, req.api.userId, function (err) {
+ Project.replacePid(project, projectPid.pid, req.hapi.userId, function (err) {
if (err === null) {
Stream.update({ object: 'project', project: projectId }, req);
- res.api.result = { status: 'ok', project: projectId };
- next();
+ reply({ status: 'ok', project: projectId });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.badRequest('Invalid invitation code');
- next();
+ reply(Hapi.Error.badRequest('Invalid invitation code'));
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.badRequest('Invalid invitation format');
- next();
+ reply(Hapi.Error.badRequest('Invalid invitation format'));
}
};
@@ -210,7 +199,7 @@ exports.load = function (code, callback) {
// Check expiration
- if ((invite.expires || Infinity) > Utils.getTimestamp()) {
+ if ((invite.expires || Infinity) > Hapi.Utils.getTimestamp()) {
// Check count
@@ -222,17 +211,17 @@ exports.load = function (code, callback) {
}
else {
- callback(null, Err.badRequest('Invitation code reached limit'));
+ callback(null, Hapi.Error.badRequest('Invitation code reached limit'));
}
}
else {
- callback(null, Err.badRequest('Invitation Code expired'));
+ callback(null, Hapi.Error.badRequest('Invitation Code expired'));
}
}
else {
- callback(null, Err.notFound('Invitation code not found'));
+ callback(null, Hapi.Error.notFound('Invitation code not found'));
}
}
else {
View
66 api/last.js
@@ -5,9 +5,8 @@
// Load modules
+var Hapi = require('hapi');
var Db = require('./db');
-var Err = require('hapi').Error;
-var Utils = require('hapi').Utils;
var Project = require('./project');
var Task = require('./task');
@@ -19,9 +18,9 @@ var internals = {};
// Last information for project (with tasks)
-exports.getProject = function (req, res, next) {
+exports.getProject = function (req, reply) {
- exports.load(req.api.userId, function (last, err) {
+ exports.load(req.hapi.userId, function (last, err) {
if (last &&
last.projects &&
@@ -30,63 +29,57 @@ exports.getProject = function (req, res, next) {
var record = { id: last._id, projects: {} };
record.projects[req.params.id] = last.projects[req.params.id];
- res.api.result = record;
- next();
+ reply(record);
}
else if (err === null) {
- res.api.result = { id: req.api.userId, projects: {} };
- next();
+ reply({ id: req.hapi.userId, projects: {} });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Set last project timestamp
-exports.postProject = function (req, res, next) {
+exports.postProject = function (req, reply) {
- Project.load(req.params.id, req.api.userId, false, function (project, member, err) {
+ Project.load(req.params.id, req.hapi.userId, false, function (project, member, err) {
if (project) {
- exports.setLast(req.api.userId, project, null, function (err) {
+ exports.setLast(req.hapi.userId, project, null, function (err) {
if (err === null) {
- res.api.result = { status: 'ok' };
- next();
+ reply({ status: 'ok' });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Last information for single task
-exports.getTask = function (req, res, next) {
+exports.getTask = function (req, reply) {
- Task.load(req.params.id, req.api.userId, false, function (task, err, project) {
+ Task.load(req.params.id, req.hapi.userId, false, function (task, err, project) {
if (task) {
- exports.load(req.api.userId, function (last, err) {
+ exports.load(req.hapi.userId, function (last, err) {
if (last &&
last.projects &&
@@ -98,56 +91,49 @@ exports.getTask = function (req, res, next) {
record.projects[task.project] = { tasks: {} };
record.projects[task.project].tasks[req.params.id] = last.projects[task.project].tasks[req.params.id];
- res.api.result = record;
- next();
+ reply(record);
}
else if (err === null) {
- res.api.result = { id: req.api.userId, projects: {} };
- next();
+ reply({ id: req.hapi.userId, projects: {} });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Set last task timestamp
-exports.postTask = function (req, res, next) {
+exports.postTask = function (req, reply) {
- Task.load(req.params.id, req.api.userId, false, function (task, err, project) {
+ Task.load(req.params.id, req.hapi.userId, false, function (task, err, project) {
if (task) {
- exports.setLast(req.api.userId, project, task, function (err) {
+ exports.setLast(req.hapi.userId, project, task, function (err) {
if (err === null) {
- res.api.result = { status: 'ok' };
- next();
+ reply({ status: 'ok' });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
@@ -215,7 +201,7 @@ exports.delProject = function (userId, projectId, callback) {
exports.setLast = function (userId, project, task, callback) {
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
exports.load(userId, function (last, err) {
View
6 api/package.json
@@ -1,15 +1,15 @@
{
"name": "postmile.api",
"description": "Postmile API Server",
- "version": "0.0.1",
+ "version": "0.0.2",
"author": "Eran Hammer-Lahav <eran@hammer-lahav.net>",
"private": true,
"dependencies": {
- "hapi": "0.0.x",
+ "hapi": "0.1.x",
"mongodb": "0.9.x",
"oauth": "0.9.x",
"socket.io": "0.8.x",
- "mac": "0.x.x",
+ "mac": "0.1.x",
"opts": "1.x.x"
},
"engines": { "node": "0.6.x" }
View
293 api/project.js
@@ -5,10 +5,9 @@
// Load modules
+var Hapi = require('hapi');
var Db = require('./db');
var User = require('./user');
-var Utils = require('hapi').Utils;
-var Err = require('hapi').Error;
var Tips = require('./tips');
var Suggestions = require('./suggestions');
var Sort = require('./sort');
@@ -39,7 +38,7 @@ exports.type.post = {
participants: { type: 'object', set: false, array: true }
};
-exports.type.put = Utils.clone(exports.type.post);
+exports.type.put = Hapi.Utils.clone(exports.type.post);
exports.type.put.title.required = true;
exports.type.participants = {
@@ -56,34 +55,32 @@ exports.type.uninvite = {
// Get project information
-exports.get = function (req, res, next) {
+exports.get = function (req, reply) {
- exports.load(req.params.id, req.api.userId, false, function (project, member, err) {
+ exports.load(req.params.id, req.hapi.userId, false, function (project, member, err) {
if (project) {
exports.participantsList(project, function (participants) {
project.participants = participants;
- res.api.result = project;
- next();
+ reply(project);
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Get list of projects for current user
-exports.list = function (req, res, next) {
+exports.list = function (req, reply) {
- Sort.list('project', req.api.userId, 'participants.id', function (projects) {
+ Sort.list('project', req.hapi.userId, 'participants.id', function (projects) {
if (projects) {
@@ -94,7 +91,7 @@ exports.list = function (req, res, next) {
for (var p = 0, pl = projects[i].participants.length; p < pl; ++p) {
if (projects[i].participants[p].id &&
- projects[i].participants[p].id === req.api.userId) {
+ projects[i].participants[p].id === req.hapi.userId) {
isPending = projects[i].participants[p].isPending || false;
break;
@@ -111,7 +108,7 @@ exports.list = function (req, res, next) {
list.push(item);
}
- Last.load(req.api.userId, function (last, err) {
+ Last.load(req.hapi.userId, function (last, err) {
if (last &&
last.projects) {
@@ -125,38 +122,36 @@ exports.list = function (req, res, next) {
}
}
- res.api.result = list;
- next();
+ reply(list);
});
}
else {
- res.api.error = Err.notFound();
- next();
+ reply(Hapi.Error.notFound());
}
});
};
// Update project properties
-exports.post = function (req, res, next) {
+exports.post = function (req, reply) {
- exports.load(req.params.id, req.api.userId, true, function (project, member, err) {
+ exports.load(req.params.id, req.hapi.userId, true, function (project, member, err) {
if (project) {
- if (Object.keys(req.body).length > 0) {
+ if (Object.keys(req.hapi.payload).length > 0) {
if (req.query.position === undefined) {
- Db.update('project', project._id, Db.toChanges(req.body), function (err) {
+ Db.update('project', project._id, Db.toChanges(req.hapi.payload), function (err) {
if (err === null) {
Stream.update({ object: 'project', project: project._id }, req);
- if (req.body.title !== project.title) {
+ if (req.hapi.payload.title !== project.title) {
for (var i = 0, il = project.participants.length; i < il; ++i) {
@@ -167,91 +162,80 @@ exports.post = function (req, res, next) {
}
}
- res.api.result = { status: 'ok' };
- next();
+ reply({ status: 'ok' });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.badRequest('Cannot include both position parameter and project object in body');
- next();
+ reply(Hapi.Error.badRequest('Cannot include both position parameter and project object in body'));
}
}
else if (req.query.position) {
- Sort.set('project', req.api.userId, 'participants.id', req.params.id, req.query.position, function (err) {
+ Sort.set('project', req.hapi.userId, 'participants.id', req.params.id, req.query.position, function (err) {
if (err === null) {
- Stream.update({ object: 'projects', user: req.api.userId }, req);
- res.api.result = { status: 'ok' };
- next();
+ Stream.update({ object: 'projects', user: req.hapi.userId }, req);
+ reply({ status: 'ok' });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.badRequest('Missing position parameter or project object in body');
- next();
+ reply(Hapi.Error.badRequest('Missing position parameter or project object in body'));
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Create new project
-exports.put = function (req, res, next) {
+exports.put = function (req, reply) {
- var project = req.body;
- project.participants = [{ id: req.api.userId}];
+ var project = req.hapi.payload;
+ project.participants = [{ id: req.hapi.userId}];
Db.insert('project', project, function (items, err) {
if (err === null) {
- Stream.update({ object: 'projects', user: req.api.userId }, req);
-
- res.api.result = { status: 'ok', id: items[0]._id };
- res.api.created = '/project/' + items[0]._id;
- next();
+ Stream.update({ object: 'projects', user: req.hapi.userId }, req);
+ reply({ status: 'ok', id: items[0]._id }, { created: '/project/' + items[0]._id });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Delete a project
-exports.del = function (req, res, next) {
+exports.del = function (req, reply) {
- exports.load(req.params.id, req.api.userId, false, function (project, member, err) {
+ exports.load(req.params.id, req.hapi.userId, false, function (project, member, err) {
if (project) {
// Check if owner
- if (exports.isOwner(project, req.api.userId)) {
+ if (exports.isOwner(project, req.hapi.userId)) {
// Delete all tasks
@@ -265,7 +249,7 @@ exports.del = function (req, res, next) {
if (err === null) {
- Last.delProject(req.api.userId, project._id, function (err) { });
+ Last.delProject(req.hapi.userId, project._id, function (err) { });
Stream.update({ object: 'project', project: project._id }, req);
@@ -278,20 +262,17 @@ exports.del = function (req, res, next) {
}
}
- res.api.result = { status: 'ok' };
- next();
+ reply({ status: 'ok' });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
@@ -304,86 +285,79 @@ exports.del = function (req, res, next) {
if (err === null) {
Stream.update({ object: 'project', project: project._id }, req);
- Stream.update({ object: 'projects', user: req.api.userId }, req);
- Stream.drop(req.api.userId, project._id);
+ Stream.update({ object: 'projects', user: req.hapi.userId }, req);
+ Stream.drop(req.hapi.userId, project._id);
- res.api.result = { status: 'ok' };
- next();
+ reply({ status: 'ok' });
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Get list of project tips
-exports.tips = function (req, res, next) {
+exports.tips = function (req, reply) {
// Get project
- exports.load(req.params.id, req.api.userId, false, function (project, member, err) {
+ exports.load(req.params.id, req.hapi.userId, false, function (project, member, err) {
if (project) {
// Collect tips
Tips.list(project, function (results) {
- res.api.result = results;
- next();
+ reply(results);
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Get list of project suggestions
-exports.suggestions = function (req, res, next) {
+exports.suggestions = function (req, reply) {
// Get project
- exports.load(req.params.id, req.api.userId, false, function (project, member, err) {
+ exports.load(req.params.id, req.hapi.userId, false, function (project, member, err) {
if (project) {
// Collect tips
- Suggestions.list(project, req.api.userId, function (results) {
+ Suggestions.list(project, req.hapi.userId, function (results) {
- res.api.result = results;
- next();
+ reply(results);
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
};
// Add new participants to a project
-exports.participants = function (req, res, next) {
+exports.participants = function (req, reply) {
if (req.query.message) {
@@ -395,14 +369,12 @@ exports.participants = function (req, res, next) {
}
else {
- res.api.error = Err.badRequest('Message cannot contain links');
- next();
+ reply(Hapi.Error.badRequest('Message cannot contain links'));
}
}
else {
- res.api.error = Err.badRequest('Message length is greater than ' + internals.maxMessageLength);
- next();
+ reply(Hapi.Error.badRequest('Message length is greater than ' + internals.maxMessageLength));
}
}
else {
@@ -412,26 +384,26 @@ exports.participants = function (req, res, next) {
function process() {
- if (req.body.participants ||
- req.body.names) {
+ if (req.hapi.payload.participants ||
+ req.hapi.payload.names) {
- exports.load(req.params.id, req.api.userId, true, function (project, member, err) {
+ exports.load(req.params.id, req.hapi.userId, true, function (project, member, err) {
if (project) {
var change = { $pushAll: { participants: []} };
// Add pids (non-users)
- if (req.body.names) {
+ if (req.hapi.payload.names) {
- for (var i = 0, il = req.body.names.length; i < il; ++i) {
+ for (var i = 0, il = req.hapi.payload.names.length; i < il; ++i) {
- var participant = { pid: Db.generateId(), display: req.body.names[i] };
+ var participant = { pid: Db.generateId(), display: req.hapi.payload.names[i] };
change.$pushAll.participants.push(participant);
}
- if (req.body.participants === undefined) {
+ if (req.hapi.payload.participants === undefined) {
// No user accounts to invite, save project
@@ -441,46 +413,45 @@ exports.participants = function (req, res, next) {
// Return success
- reply();
+ finalize();
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
}
// Add users or emails
- if (req.body.participants) {
+ if (req.hapi.payload.participants) {
// Get user
- User.load(req.api.userId, function (user, err) {
+ User.load(req.hapi.userId, function (user, err) {
if (user) {
// Lookup existing users
- User.find(req.body.participants, function (users, emailsNotFound, err) {
+ User.find(req.hapi.payload.participants, function (users, emailsNotFound, err) {
if (err === null) {
- var prevParticipants = Utils.map(project.participants, 'id');
+ var prevParticipants = Hapi.Utils.map(project.participants, 'id');
// Check for changes
var contactsChange = { $set: {} };
- var now = Utils.getTimestamp();
+ var now = Hapi.Utils.getTimestamp();
var changedUsers = [];
for (var i = 0, il = users.length; i < il; ++i) {
// Add / update contact
- if (users[i]._id !== req.api.userId) {
+ if (users[i]._id !== req.hapi.userId) {
contactsChange.$set['contacts.' + users[i]._id] = { type: 'user', last: now };
}
@@ -494,7 +465,7 @@ exports.participants = function (req, res, next) {
}
}
- var prevPids = Utils.map(project.participants, 'email');
+ var prevPids = Hapi.Utils.map(project.participants, 'email');
var pids = [];
for (i = 0, il = emailsNotFound.length; i < il; ++i) {
@@ -512,7 +483,7 @@ exports.participants = function (req, res, next) {
// Internal fields
email: emailsNotFound[i],
- code: Utils.getRandomString(6),
+ code: Hapi.Utils.getRandomString(6),
inviter: user._id
};
@@ -555,51 +526,45 @@ exports.participants = function (req, res, next) {
// Return success
- reply();
+ finalize();
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.badRequest('All users are already project participants');
- next();
+ reply(Hapi.Error.badRequest('All users are already project participants'));
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.internal(err);
- next();
+ reply(Hapi.Error.internal(err));
}
});
}
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.badRequest('Body must contain a participants or names array');
- next();
+ reply(Hapi.Error.badRequest('Body must contain a participants or names array'));
}
}
- function reply() {
+ function finalize() {
Stream.update({ object: 'project', project: req.params.id }, req);
@@ -613,14 +578,12 @@ exports.participants = function (req, res, next) {
var response = { status: 'ok', participants: participants };
- res.api.result = response;
- next();
+ reply(response);
});
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
@@ -629,25 +592,25 @@ exports.participants = function (req, res, next) {
// Remove participant from project
-exports.uninvite = function (req, res, next) {
+exports.uninvite = function (req, reply) {
// Load project for write
- exports.load(req.params.id, req.api.userId, true, function (project, member, err) {
+ exports.load(req.params.id, req.hapi.userId, true, function (project, member, err) {
if (project) {
// Check if owner
- if (exports.isOwner(project, req.api.userId)) {
+ if (exports.isOwner(project, req.hapi.userId)) {
// Check if single delete or batch
if (req.params.user) {
// Single delete
- if (req.api.userId !== req.params.user) {
+ if (req.hapi.userId !== req.params.user) {
// Lookup user
@@ -663,39 +626,36 @@ exports.uninvite = function (req, res, next) {
Stream.update({ object: 'projects', user: req.params.user }, req);
Stream.drop(req.params.user, project._id);
- reply();
+ finalize();
}
else {
- res.api.error = err;
- next();
+ reply(err);
}
});
}
else {
- res.api.error = Err.notFound('Not a project participant');
- next();
+ reply(Hapi.Error.notFound('Not a project participant'));
}
}
else {
- res.api.error = Err.badRequest('Cannot uninvite self');
- next();
+ reply(Hapi.Error.badRequest('Cannot uninvite self'));
}
}
- else if (req.body.participants) {
+ else if (req.hapi.payload.participants) {
// Batch delete
var error = null;
var uninvitedMembers = [];
- for (var i = 0, il = req.body.participants.length; i < il; ++i) {
+ for (var i = 0, il = req.hapi.payload.participants.length; i < il; ++i) {
- var removeId = req.body.participants[i];
+ var removeId = req.hapi.payload.participants[i];
- if (req.api.userId !== removeId) {
+ if (req.hapi.userId !== removeId) {
// Lookup user
@@ -706,20 +666,20 @@ exports.uninvite = function (req, res, next) {
}
else {
- error = Err.notFound('Not a project participant: ' + removeId);
+ error = Hapi.Error.notFound('Not a project participant: ' + removeId);
break;