make[1]: Entering directory `/home/travis/build/Tivoli/curio' Coverage

Coverage

94%
1311
1238
73

/home/travis/build/Tivoli/curio/server/apps/admin/index.coffee

88%
17
15
2
LineHitsSource
11(function() {
21 var app, express;
3
41 express = require('express');
5
61 app = express();
7
81 module.exports = function(core) {
91 var middleware;
101 middleware = core.get('middleware');
111 _(middleware).extend(require('./middleware')(app));
121 app.set('views', "" + __dirname + "/views");
131 app.set('middleware', middleware);
141 if (app.get('env') === 'development') {
150 app.use(express.logger('dev'));
160 app.use(require('connect-assets')({
17 paths: core.get('assets')
18 }));
19 } else {
201 app.use(require('connect-assets')({
21 paths: core.get('assets'),
22 build: true
23 }));
24 }
251 require('./locals')(app, core);
261 require('./routes')(app);
271 return app;
28 };
29
30}).call(this);
31

/home/travis/build/Tivoli/curio/server/apps/admin/locals.coffee

100%
8
8
0
LineHitsSource
11(function() {
21 module.exports = function(app, core) {
31 app.locals.layout = true;
41 app.locals.env = app.get('env');
51 app.locals.js = js('admin/bundle');
61 app.locals.css = css('admin/index');
71 app.locals.fb = core.get('facebook_config');
81 return app.locals.google = core.get('google_config');
9 };
10
11}).call(this);
12

/home/travis/build/Tivoli/curio/server/apps/admin/middleware.coffee

100%
13
13
0
LineHitsSource
11(function() {
21 module.exports = function(app) {
31 var module;
41 module = {};
51 module.render_index = function(req, res, next) {
68 var cursor, model, root;
78 root = req.route.path.slice(1);
88 model = utils.to_model(root);
98 cursor = model.paginated(req.param('page'), req.param('limit'));
108 return utils.cursorJSON(cursor, function(err, json) {
118 res.locals.collection = json;
128 return res.render("templates/" + root + "/index");
13 });
14 };
151 return module;
16 };
17
18}).call(this);
19

/home/travis/build/Tivoli/curio/server/apps/admin/routes/dashboard/index.coffee

100%
5
5
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 return app.get('/', routes.index);
8 };
9
10}).call(this);
11

/home/travis/build/Tivoli/curio/server/apps/admin/routes/dashboard/routes.coffee

100%
3
3
0
LineHitsSource
11(function() {
21 exports.index = function(req, res, next) {
31 return res.render('templates/dashboard/index');
4 };
5
6}).call(this);
7

/home/travis/build/Tivoli/curio/server/apps/admin/routes/index.coffee

100%
16
16
0
LineHitsSource
11(function() {
21 var fs;
3
41 fs = require('fs');
5
61 module.exports = function(app, mw) {
71 var file, path, _i, _len, _ref, _ref1, _results;
81 mw = app.get('middleware');
91 app.get('*', mw.restricted);
101 _ref = fs.readdirSync(__dirname);
111 _results = [];
121 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
136 file = _ref[_i];
146 path = "" + __dirname + "/" + file;
156 if (!((_ref1 = fs.statSync(path)) != null ? _ref1.isDirectory() : void 0)) {
161 continue;
17 }
185 _results.push(require(path)(app, mw));
19 }
201 return _results;
21 };
22
23}).call(this);
24

/home/travis/build/Tivoli/curio/server/apps/admin/routes/pages/index.coffee

100%
3
3
0
LineHitsSource
11(function() {
21 module.exports = function(app, mw) {
31 return app.get('/pages', mw.render_index);
4 };
5
6}).call(this);
7

/home/travis/build/Tivoli/curio/server/apps/admin/routes/posts/index.coffee

100%
3
3
0
LineHitsSource
11(function() {
21 module.exports = function(app, mw) {
31 return app.get('/posts', mw.render_index);
4 };
5
6}).call(this);
7

/home/travis/build/Tivoli/curio/server/apps/admin/routes/settings/index.coffee

100%
5
5
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 return app.get('/settings', routes.index);
8 };
9
10}).call(this);
11

/home/travis/build/Tivoli/curio/server/apps/admin/routes/settings/routes.coffee

100%
9
9
0
LineHitsSource
11(function() {
21 exports.index = function(req, res, next) {
31 return async.parallel({
4 website: function(done) {
51 return SiteConfig.find('website', done);
6 }
7 }, function(err, results) {
81 var k, v;
91 for (k in results) {
101 v = results[k];
111 res.locals[k] = v.toJSON();
12 }
131 return res.render('templates/settings/index');
14 });
15 };
16
17}).call(this);
18

/home/travis/build/Tivoli/curio/server/apps/admin/routes/users/index.coffee

100%
3
3
0
LineHitsSource
11(function() {
21 module.exports = function(app, mw) {
31 return app.get('/users', mw.render_index);
4 };
5
6}).call(this);
7

/home/travis/build/Tivoli/curio/server/apps/templates/index.coffee

96%
31
30
1
LineHitsSource
11(function() {
21 var app, compiled, express, fs, path;
3
41 fs = require('fs');
5
61 express = require('express');
7
81 app = express();
9
101 path = require('path');
11
121 compiled = {};
13
141 module.exports = function(core) {
151 var compile;
161 compile = function(type) {
172 var data, directory, file, name, regex, templates, _i, _len, _ref;
182 directory = path.join(core.get('apps'), type, 'views', 'templates');
192 regex = new RegExp("" + directory + "/(.*).dust$");
202 templates = [];
212 _ref = utils.walk_dir(directory);
222 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2319 file = _ref[_i];
2419 if (!(/dust$/.test(file))) {
250 continue;
26 }
2719 data = fs.readFileSync(file, 'utf8');
2819 name = file.match(regex)[1];
2919 templates.push(dust.compile(data, "templates/" + name));
30 }
312 return templates.join('');
32 };
331 app.get('/:templates', function(req, res, next) {
3420 var type;
3520 type = path.basename(req.params.templates, '.js');
3620 res.set('Content-Type', 'application/javascript');
3720 if (compiled[type] == null) {
382 compiled[type] = compile(type);
39 }
4020 return res.send(compiled[type]);
41 });
421 return app;
43 };
44
45}).call(this);
46

/home/travis/build/Tivoli/curio/server/apps/uploads/index.coffee

100%
9
9
0
LineHitsSource
11(function() {
21 var app, express;
3
41 express = require('express');
5
61 app = express();
7
81 module.exports = function(core) {
91 app.set('aws_config', core.get('aws_config'));
101 app.set('middleware', core.get('middleware'));
111 require('./routes')(app);
121 return app;
13 };
14
15}).call(this);
16

/home/travis/build/Tivoli/curio/server/apps/uploads/routes/cors.coffee

100%
9
9
0
LineHitsSource
11(function() {
21 var crypto;
3
41 crypto = require('crypto');
5
61 exports.policy = function(aws) {
71 var s3_policy;
81 s3_policy = {
9 expiration: moment().add('minutes', 30).toISOString(),
10 conditions: [
11 {
12 bucket: aws.s3.bucket
13 }, {
14 acl: "public-read"
15 }, {
16 success_action_status: '201'
17 }, ["starts-with", "$key", ""], ["starts-with", "$Content-Type", ""]
18 ]
19 };
201 return new Buffer(JSON.stringify(s3_policy)).toString('base64');
21 };
22
231 exports.signature = function(aws, policy) {
241 return crypto.createHmac('sha1', aws.secret).update(policy).digest('base64');
25 };
26
27}).call(this);
28

/home/travis/build/Tivoli/curio/server/apps/uploads/routes/images.coffee

100%
7
7
0
LineHitsSource
11(function() {
21 var gm;
3
41 gm = require('gm');
5
61 exports.resize = function(width, height, stream, out) {
72 return gm(stream).noProfile().resize(width, height, '>').type('TrueColor').stream('jpg').pipe(out);
8 };
9
101 exports.crop = function(width, height, stream, out) {
111 return gm(stream).noProfile().gravity('Center').resize(width, height, '^>').crop(width, height).type('TrueColor').stream('jpg').pipe(out);
12 };
13
14}).call(this);
15

/home/travis/build/Tivoli/curio/server/apps/uploads/routes/index.coffee

100%
24
24
0
LineHitsSource
11(function() {
21 var cors, images;
3
41 images = require('./images');
5
61 cors = require('./cors');
7
81 module.exports = function(app) {
91 var aws, mw;
101 aws = app.get('aws_config');
111 mw = app.get('middleware');
121 app.get('/cors', mw.restricted, function(req, res, next) {
131 var json;
141 json = {
15 short_id: utils.shortId(),
16 access_key: aws.key,
17 bucket: aws.s3.bucket,
18 policy: cors.policy(aws)
19 };
201 json.signature = cors.signature(aws, json.policy);
211 return res.json(json);
22 });
231 return app.get('/*', function(req, res, next) {
244 var height, stream, width;
254 width = req.param('w');
264 height = req.param('h');
274 res.set('Content-Type', 'image/jpg');
284 res.set('Cache-Control', 'public, max-age=31536000');
294 res.set('Expires', new Date(Date.now() + 31536000000).toUTCString());
304 stream = request.get("http://s3.amazonaws.com/" + aws.s3.bucket + "/" + req.params[0]);
314 if (!((width != null) || (height != null))) {
321 return stream.pipe(res);
33 }
343 return images[req.param('m') || 'resize'](width, height, stream, res);
35 });
36 };
37
38}).call(this);
39

/home/travis/build/Tivoli/curio/server/apps/website/index.coffee

88%
17
15
2
LineHitsSource
11(function() {
21 var app, express;
3
41 express = require('express');
5
61 app = express();
7
81 module.exports = function(core) {
91 var middleware;
101 middleware = core.get('middleware');
111 _(middleware).extend(require('./middleware')(app));
121 app.set('views', "" + __dirname + "/views");
131 app.set('middleware', middleware);
141 if (app.get('env') === 'development') {
150 app.use(express.logger('dev'));
160 app.use(require('connect-assets')({
17 paths: core.get('assets')
18 }));
19 } else {
201 app.use(require('connect-assets')({
21 paths: core.get('assets'),
22 build: true
23 }));
24 }
251 require('./locals')(app, core);
261 require('./routes')(app);
271 return app;
28 };
29
30}).call(this);
31

/home/travis/build/Tivoli/curio/server/apps/website/locals.coffee

100%
8
8
0
LineHitsSource
11(function() {
21 module.exports = function(app, core) {
31 app.locals.layout = true;
41 app.locals.env = app.get('env');
51 app.locals.js = js('website/bundle');
61 app.locals.css = css('website/index');
71 app.locals.fb = core.get('facebook_config');
81 return app.locals.google = core.get('google_config');
9 };
10
11}).call(this);
12

/home/travis/build/Tivoli/curio/server/apps/website/middleware.coffee

92%
13
12
1
LineHitsSource
11(function() {
21 module.exports = function(app) {
31 var module;
41 module = {};
51 module.load_locals = function(req, res, next) {
681 if (app.locals.website != null) {
778 return next();
8 }
93 return SiteConfig.find('website', function(err, config) {
103 if (err != null) {
110 return next();
12 }
133 app.locals.website = config.toJSON();
143 return next();
15 });
16 };
171 return module;
18 };
19
20}).call(this);
21

/home/travis/build/Tivoli/curio/server/apps/website/routes/configs/index.coffee

92%
13
12
1
LineHitsSource
11(function() {
21 module.exports = function(app, mw) {
31 var routes;
41 app.param(':config', function(req, res, next, id) {
55 return SiteConfig.find(id, function(err, config) {
65 if (err != null) {
70 return next(err);
8 }
95 req.resource = config;
105 return next();
11 });
12 });
131 routes = require('./routes')(app);
141 app.all('/configs*', mw.restricted);
151 app.get('/configs/:config', mw.read);
161 return app.put('/configs/:config', routes.update);
17 };
18
19}).call(this);
20

/home/travis/build/Tivoli/curio/server/apps/website/routes/configs/routes.coffee

100%
8
8
0
LineHitsSource
11(function() {
21 module.exports = function(app) {
31 var routes;
41 routes = {
5 update: function(req, res, next) {
62 if (req.param('config') === 'website') {
72 delete app.locals.website;
8 }
92 return utils.save_and_send(req, res, next);
10 }
11 };
121 return routes;
13 };
14
15}).call(this);
16

/home/travis/build/Tivoli/curio/server/apps/website/routes/index.coffee

96%
28
27
1
LineHitsSource
11(function() {
21 var fs;
3
41 fs = require('fs');
5
61 module.exports = function(app) {
71 var file, mw, path, _i, _len, _ref, _ref1;
81 mw = app.get('middleware');
91 app.get(/^((?!png|jpg|js|css|woff|html).)*$/, mw.load_locals, function(req, res, next) {
1081 var _ref;
1181 res.locals.current_user = (_ref = req.session) != null ? _ref.user : void 0;
1281 return next();
13 });
141 _ref = fs.readdirSync(__dirname);
151 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
169 file = _ref[_i];
179 path = "" + __dirname + "/" + file;
189 if (!((_ref1 = fs.statSync(path)) != null ? _ref1.isDirectory() : void 0)) {
191 continue;
20 }
218 require(path)(app, mw);
22 }
231 app.param(':page_or_post', function(req, res, next, id) {
242 return async.parallel({
25 post: function(done) {
262 return Post.find(id, function(err, post) {
272 return done(null, post);
28 });
29 },
30 page: function(done) {
312 return Page.find(id, function(err, page) {
322 return done(null, page);
33 });
34 }
35 }, function(err, results) {
362 if (!((results.post != null) || (results.page != null))) {
370 return next(new NotFound('Page not found'));
38 }
392 req.resource = results.page || results.post;
402 return next();
41 });
42 });
431 return app.get('/:page_or_post', mw.read);
44 };
45
46}).call(this);
47

/home/travis/build/Tivoli/curio/server/apps/website/routes/oauth/index.coffee

100%
13
13
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 app.param(':source', function(req, res, next, source) {
84 var model;
94 model = global[fleck.capitalize(source)];
104 return new model(req.body).validate(function(err, source) {
114 if (err != null) {
122 return next(err);
13 }
142 req.source = source;
152 return next();
16 });
17 });
181 return app.post('/oauth/:source', routes.create);
19 };
20
21}).call(this);
22

/home/travis/build/Tivoli/curio/server/apps/website/routes/oauth/routes.coffee

83%
12
10
2
LineHitsSource
11(function() {
21 exports.create = function(req, res, next) {
32 return req.source.find_or_create_user(function(err, source) {
42 if (err != null) {
50 return next(err);
6 }
72 return source.update_user(function(err, source) {
82 var json;
92 if (err != null) {
100 return next(err);
11 }
122 json = source.user.set_self().toJSON();
132 req.session.user = json;
142 return res.json(json);
15 });
16 });
17 };
18
19}).call(this);
20

/home/travis/build/Tivoli/curio/server/apps/website/routes/pages/index.coffee

100%
15
15
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 app.param(':page', function(req, res, next, id) {
815 return Page.find(id, function(err, page) {
915 if (err != null) {
102 return next(err);
11 }
1213 req.resource = page;
1313 return next();
14 });
15 });
161 app.get('/pages', mw.restricted, mw.get_index);
171 app.post('/pages', mw.restricted, routes.create);
181 app.get('/pages/:page', mw.read);
191 app.put('/pages/:page', mw.restricted, utils.save_and_send);
201 return app["delete"]('/pages/:page', mw.restricted, mw.destroy);
21 };
22
23}).call(this);
24

/home/travis/build/Tivoli/curio/server/apps/website/routes/pages/routes.coffee

100%
4
4
0
LineHitsSource
11(function() {
21 exports.create = function(req, res, next) {
37 req.resource = new Page(req.body);
47 return utils.save_and_send(req, res, next);
5 };
6
7}).call(this);
8

/home/travis/build/Tivoli/curio/server/apps/website/routes/posts/index.coffee

100%
15
15
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 app.param(':post', function(req, res, next, id) {
813 return Post.find(id, function(err, post) {
913 if (err != null) {
102 return next(err);
11 }
1211 req.resource = post;
1311 return next();
14 });
15 });
161 app.get('/posts', routes.index);
171 app.post('/posts', mw.restricted, routes.create);
181 app.get('/posts/:post', mw.read);
191 app.put('/posts/:post', mw.restricted, utils.save_and_send);
201 return app["delete"]('/posts/:post', mw.restricted, mw.destroy);
21 };
22
23}).call(this);
24

/home/travis/build/Tivoli/curio/server/apps/website/routes/posts/routes.coffee

100%
8
8
0
LineHitsSource
11(function() {
21 exports.index = function(req, res, next) {
37 var cursor;
47 cursor = Post.paginated(req.param('page'), req.param('limit'));
57 return utils.streamJSON(req, res, next, cursor);
6 };
7
81 exports.create = function(req, res, next) {
94 req.resource = new Post(req.body).set_user(req.session.user.id);
104 return utils.save_and_send(req, res, next);
11 };
12
13}).call(this);
14

/home/travis/build/Tivoli/curio/server/apps/website/routes/search/index.coffee

100%
5
5
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 return app.get('/search', routes.index);
8 };
9
10}).call(this);
11

/home/travis/build/Tivoli/curio/server/apps/website/routes/search/routes.coffee

100%
14
14
0
LineHitsSource
11(function() {
21 exports.index = function(req, res, next) {
37 var cursor, model, query;
47 if (req.query.q == null) {
51 return next(new BadRequest('Missing Query'));
6 }
76 if (req.query.core == null) {
81 return next(new BadRequest('Missing Core'));
9 }
105 model = global[fleck.inflect(req.query.core, 'singularize', 'capitalize')];
115 query = (function() {
125 switch (req.query.core) {
13 case 'users':
142 return {
15 username: new RegExp("" + req.query.q, 'i')
16 };
17 case 'posts':
183 return {
19 slug: new RegExp(_(req.query.q).toSlug())
20 };
21 }
22 })();
235 cursor = model.search(query, req.query.page, req.query.limit);
245 return utils.streamJSON(req, res, next, cursor);
25 };
26
27}).call(this);
28

/home/travis/build/Tivoli/curio/server/apps/website/routes/sessions/index.coffee

100%
7
7
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 app.post('/sessions', routes.create);
81 app.get('/sessions/token', routes.token);
91 return app.get('/logout', mw.authed, routes.destroy);
10 };
11
12}).call(this);
13

/home/travis/build/Tivoli/curio/server/apps/website/routes/sessions/routes.coffee

95%
22
21
1
LineHitsSource
11(function() {
21 exports.create = function(req, res, next) {
313 var _ref;
413 if (((_ref = req.session) != null ? _ref.user : void 0) != null) {
50 return next();
6 }
713 return User.authenticate(req.body.email, req.body.password, function(err, user) {
813 var json;
913 if (err != null) {
106 return next(err);
11 }
127 json = req.session.user = user.toJSON();
137 return res.json(json);
14 });
15 };
16
171 exports.destroy = function(req, res) {
181 return req.session.destroy(function() {
191 var back;
201 back = req.get('referer') || '/';
211 return res.redirect(back);
22 });
23 };
24
251 exports.token = function(req, res, next) {
263 return User.find_by_token(req.query.token, function(err, user) {
273 if (err != null) {
282 return next(err);
29 }
301 req.session.user = user.set_self().toJSON();
311 return res.redirect('/');
32 });
33 };
34
35}).call(this);
36

/home/travis/build/Tivoli/curio/server/apps/website/routes/site/index.coffee

100%
5
5
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 return app.get('/', routes.index);
8 };
9
10}).call(this);
11

/home/travis/build/Tivoli/curio/server/apps/website/routes/site/routes.coffee

100%
3
3
0
LineHitsSource
11(function() {
21 exports.index = function(req, res, next) {
39 return res.render('templates/home/index');
4 };
5
6}).call(this);
7

/home/travis/build/Tivoli/curio/server/apps/website/routes/users/index.coffee

100%
20
20
0
LineHitsSource
11(function() {
21 var routes;
3
41 routes = require('./routes');
5
61 module.exports = function(app, mw) {
71 app.param(':user', function(req, res, next, id) {
826 return User.find(id, function(err, user) {
926 var _ref, _ref1;
1026 if (err != null) {
111 return next(err);
12 }
1325 req.resource = user;
1425 if (req.resource.id() === ((_ref = req.session) != null ? (_ref1 = _ref.user) != null ? _ref1.id : void 0 : void 0)) {
1511 req.resource.set_self();
16 }
1725 return next();
18 });
19 });
201 app.get('/users', mw.restricted, routes.index);
211 app.post('/users', routes.create);
221 app.get('/users/me', mw.authed, routes.me);
231 app.post('/users/resetpassword', routes.resetpassword);
241 app.get('/users/:user', mw.read);
251 app.put('/users/:user', mw["private"], routes.update);
261 return app.all('/users/:user/roles', mw.restricted, routes.update_role);
27 };
28
29}).call(this);
30

/home/travis/build/Tivoli/curio/server/apps/website/routes/users/routes.coffee

96%
33
32
1
LineHitsSource
11(function() {
21 exports.index = function(req, res, next) {
36 var cursor;
46 cursor = User.paginated(req.query.page, req.query.limit);
56 return utils.streamJSON(req, res, next, cursor);
6 };
7
81 exports.create = function(req, res, next) {
912 req.resource = new User(req.body).set_self();
1012 req.resource.once('saved', function() {
112 return req.session.user = req.resource.toJSON();
12 });
1312 return utils.save_and_send(req, res, next);
14 };
15
161 exports.me = function(req, res, next) {
1717 return res.json(req.session.user);
18 };
19
201 exports.update = function(req, res, next) {
2111 req.resource.once('saved', function() {
226 return req.session.user = req.resource.toJSON();
23 });
2411 return utils.save_and_send(req, res, next);
25 };
26
271 exports.resetpassword = function(req, res, next) {
284 if (!_(req.body.email).isEmail()) {
292 return next(new BadRequest('Missing or Invalid Email'));
30 }
312 return User.find(req.body.email, function(err, user) {
322 if (err != null) {
331 return next(err);
34 }
351 return user.update_token(function(err, token) {
361 if (err != null) {
370 return next(err);
38 }
391 return res.send(200);
40 });
41 });
42 };
43
441 exports.update_role = function(req, res, next) {
457 var method;
467 method = req.method === 'POST' ? 'add' : 'remove';
477 return req.resource.update_role(method, req.body.role, function(err, user) {
487 if (err != null) {
491 return next(err);
50 }
516 return res.json(user.toJSON());
52 });
53 };
54
55}).call(this);
56

/home/travis/build/Tivoli/curio/server/configs/index.coffee

100%
16
16
0
LineHitsSource
11(function() {
21 var fs;
3
41 fs = require('fs');
5
61 module.exports = function(app) {
71 var config, file, json, name, _i, _len, _ref, _results;
81 _ref = fs.readdirSync(__dirname);
91 _results = [];
101 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
115 file = _ref[_i];
125 if (!(/\.json$/.test(file))) {
131 continue;
14 }
154 name = file.replace('.json', '');
164 json = require("/home/travis/build/Tivoli/curio/server/configs/./" + name);
174 config = _.extend({}, json.defaults, json[app.get('env')]);
184 _results.push(app.set("" + name + "_config", config));
19 }
201 return _results;
21 };
22
23}).call(this);
24

/home/travis/build/Tivoli/curio/server/errors.coffee

90%
31
28
3
LineHitsSource
11(function() {
21 var __hasProp = {}.hasOwnProperty,
352 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
4
51 global.BadRequest = (function(_super) {
61 __extends(BadRequest, _super);
7
81 function BadRequest(message) {
932 this.message = message;
1032 this.statusCode = 400;
1132 BadRequest.__super__.constructor.call(this);
12 }
13
141 return BadRequest;
15
16 })(Error);
17
181 global.Unauthorized = (function(_super) {
191 __extends(Unauthorized, _super);
20
211 function Unauthorized() {
2239 this.statusCode = 401;
2339 this.message = 'Unauthorized';
2439 Unauthorized.__super__.constructor.call(this);
25 }
26
271 return Unauthorized;
28
29 })(Error);
30
311 global.NotFound = (function(_super) {
321 __extends(NotFound, _super);
33
341 function NotFound(message) {
3510 this.message = message;
3610 this.statusCode = 404;
3710 NotFound.__super__.constructor.call(this);
38 }
39
401 return NotFound;
41
42 })(Error);
43
441 global.MongoError = (function(_super) {
451 __extends(MongoError, _super);
46
471 function MongoError(message) {
480 this.message = message;
490 this.statusCode = 500;
500 MongoError.__super__.constructor.call(this);
51 }
52
531 return MongoError;
54
55 })(Error);
56
57}).call(this);
58

/home/travis/build/Tivoli/curio/server/index.coffee

81%
66
54
12
LineHitsSource
11(function() {
21 var MongoStore, app, assets, blue, cons, express, mongo, red, reset,
30 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
4
51 express = require('express');
6
71 app = express();
8
91 cons = require('consolidate');
10
111 blue = '\u001b[34m';
12
131 red = '\u001b[31m';
14
151 reset = '\u001b[0m';
16
171 assets = ["" + __dirname + "/assets/js", "" + __dirname + "/shared", "" + __dirname + "/assets/css"];
18
191 global._ = require('underscore');
20
211 global.async = require('async');
22
231 global.fleck = require('fleck');
24
251 global.moment = require('moment');
26
271 global.request = require('request').defaults({
28 _json: true
29 });
30
311 global.dust = require('dustjs-linkedin');
32
331 require('dustjs-helpers');
34
351 global.utils = require('./utilities')(app);
36
371 utils.load_shared("" + __dirname + "/shared");
38
391 require('./errors');
40
411 require('./configs')(app);
42
431 mongo = require('./mongo')(app);
44
451 MongoStore = require('connect-mongo')(express);
46
471 app.engine('dust', cons.dust);
48
491 app.set('port', process.env.PORT || 3000);
50
511 app.set('version', require('../package').version);
52
531 app.set('description', require('../package').description);
54
551 app.set('views', "" + __dirname + "/views");
56
571 app.set('view engine', 'dust');
58
591 app.set('apps', "" + __dirname + "/apps");
60
611 app.set('assets', assets);
62
631 app.set('middleware', require('./middleware')(app));
64
651 app.use(express.favicon("" + __dirname + "/public/favicon.png", {
66 maxAge: 2592000000
67 }));
68
691 app.use(express.compress());
70
711 app.use(express.methodOverride());
72
731 app.use(express.urlencoded());
74
751 app.use(express.json());
76
771 app.use(express.cookieParser());
78
791 mongo.on('open', function() {
801 var server;
811 app.use(express.session({
82 secret: 'curio cookie',
83 cookie: {
84 maxAge: 604800000
85 },
86 store: new MongoStore({
87 db: mongo._db
88 })
89 }));
901 app.use('/templates', require('./apps/templates')(app));
911 app.use('/uploads', require('./apps/uploads')(app));
921 app.use('/admin', require('./apps/admin')(app));
931 app.use('/', require('./apps/website')(app));
941 app.use(app.get('middleware').error);
951 if (app.get('env') === 'development') {
960 app.use(express.logger('dev'));
970 app.use(express["static"]("" + __dirname + "/public"));
98 } else {
991 app.use(express["static"]("" + __dirname + "/public", {
100 maxAge: 86400000
101 }));
102 }
1031 if (__indexOf.call(process.argv, '--seed') < 0) {
1041 server = require('http').createServer(app);
1051 server.listen(app.get("port"), function() {
1061 var timestamp;
1071 if (!process.env.NODE_COV) {
1080 timestamp = moment().format('D MMM H:mm:ss');
1090 return console.log("%s - %s v%s (" + blue + "%s" + reset + ") port " + red + "%d" + reset, timestamp, app.get('description'), app.get('version'), app.get('env'), app.get('port'));
110 }
111 });
112 }
1131 return process.on('SIGINT', function() {
1140 async.series({
115 mongo: function(done) {
1160 return app.mongo.db.close(done);
117 },
118 server: function(done) {
1190 return server.close(done);
120 }
121 }, function(err, results) {
1220 return process.exit(0);
123 });
1240 return setTimeout(function() {
1250 console.error("Forcefully shutting down");
1260 return process.exit(1);
127 }, 30 * 1000);
128 });
129 });
130
1311 module.exports = app;
132
133}).call(this);
134

/home/travis/build/Tivoli/curio/server/middleware.coffee

90%
55
50
5
LineHitsSource
11(function() {
21 var bugsnag;
3
41 bugsnag = require('bugsnag');
5
61 module.exports = function(app) {
71 var module;
81 module = {};
91 bugsnag.register(app.get('bugsnag_config').key);
101 module.authed = function(req, res, next) {
1125 var _ref;
1225 if (((_ref = req.session) != null ? _ref.user : void 0) != null) {
1318 return next();
14 }
157 return next(new Unauthorized);
16 };
171 module["private"] = function(req, res, next) {
1813 var _ref, _ref1, _ref2, _ref3;
1913 if (((_ref = req.session) != null ? (_ref1 = _ref.user) != null ? _ref1.id : void 0 : void 0) === req.resource.id()) {
2010 return next();
21 }
223 if ((_ref2 = req.session) != null ? (_ref3 = _ref2.user) != null ? _ref3.is_admin : void 0 : void 0) {
231 return next();
24 }
252 return next(new Unauthorized);
26 };
271 module.restricted = function(req, res, next) {
2877 var _ref, _ref1;
2977 if ((_ref = req.session) != null ? (_ref1 = _ref.user) != null ? _ref1.is_admin : void 0 : void 0) {
3055 return next();
31 }
3222 return next(new Unauthorized);
33 };
341 module.read = function(req, res) {
3512 var json, name, root;
3612 name = req.resource.constructor.name;
3712 root = fleck.pluralize(name).toLowerCase();
3812 json = req.resource.toJSON();
3912 return res.format({
40 html: function() {
412 return res.render("templates/" + root + "/show", json);
42 },
43 json: function() {
4410 return res.json(json);
45 }
46 });
47 };
481 module.get_index = function(req, res, next) {
493 var cursor, model;
503 if (!utils.is_json_request(req)) {
510 return next();
52 }
533 model = utils.to_model(req.route.path.slice(1));
543 cursor = model.paginated(req.param('page'), req.param('limit'));
553 return utils.streamJSON(req, res, next, cursor);
56 };
571 module.destroy = function(req, res, next) {
582 return req.resource.destroy(function(err) {
592 if (err) {
600 return next(err);
61 }
622 return res.send(200);
63 });
64 };
651 module.error = function(err, req, res, next) {
6674 var _ref;
6774 if ((err.statusCode == null) || /^5\d+/.test(err.statusCode)) {
680 if ((_ref = app.get('env')) !== 'development' && _ref !== 'test') {
690 bugsnag.notify(err);
70 }
71 }
7274 return res.format({
73 html: function() {
742 if (err.statusCode === 401) {
752 return res.redirect('/');
76 }
770 return res.status(err.statusCode || 500).render("error", {
78 url: req.url,
79 error: err.message
80 });
81 },
82 json: function() {
8372 return res.json(err.statusCode || 500, {
84 url: req.url,
85 error: err.message
86 });
87 }
88 });
89 };
901 return module;
91 };
92
93}).call(this);
94

/home/travis/build/Tivoli/curio/server/mongo/collections.coffee

100%
15
15
0
LineHitsSource
11(function() {
21 module.exports = function(app) {
31 var mongo;
41 mongo = app.mongo;
51 mongo.configs = mongo.db.collection('configs');
61 mongo.users = mongo.db.collection('users');
71 mongo.users.ensureIndex('username', {
8 unique: true
9 }, function() {});
101 mongo.users.ensureIndex('email', {
11 unique: true
12 }, function() {});
131 mongo.posts = mongo.db.collection('posts');
141 mongo.posts.ensureIndex('slug', {
15 unique: true
16 }, function() {});
171 mongo.pages = mongo.db.collection('pages');
181 mongo.pages.ensureIndex('path', {
19 unique: true
20 }, function() {});
211 mongo.pages.ensureIndex('title', {
22 unique: true
23 }, function() {});
241 mongo.tokens = mongo.db.collection('tokens');
251 return mongo.tokens.ensureIndex({
26 expires: 1
27 }, {
28 expireAfterSeconds: 86400 * 2
29 }, function() {});
30 };
31
32}).call(this);
33

/home/travis/build/Tivoli/curio/server/mongo/index.coffee

81%
38
31
7
LineHitsSource
11(function() {
21 var MongoClient, ObjectID, mongodb,
30 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
4
51 mongodb = require('mongodb');
6
71 MongoClient = mongodb.MongoClient;
8
91 ObjectID = mongodb.ObjectID;
10
111 module.exports = function(app) {
121 var client, config, seed;
131 config = app.get('mongo_config');
141 seed = require('./seed')(app);
151 app.mongo = {
16 ObjectID: ObjectID,
17 seed: seed.seed,
18 seed_dir: seed.dir,
19 stringToID: function(id) {
20285 var err;
21285 if (id instanceof ObjectID) {
22230 return id;
23 }
2455 try {
2555 return new ObjectID.createFromHexString(id);
26 } catch (_error) {
272 err = _error;
282 return id;
29 }
30 },
31 dateToID: function(date) {
322 date = (function() {
332 switch (true) {
34 case _(date).isDate():
351 return Math.floor(date / 1000);
36 default:
371 return Math.floor(new Date(parseInt(date)) / 1000);
38 }
39 })();
402 return new ObjectID.createFromTime(date);
41 }
42 };
431 client = new MongoClient();
441 client.connect(config.url, config.options, function(err, _db) {
451 if (err != null) {
460 throw new MongoError(err.message);
47 }
481 app.mongo.db = _db;
491 require('./collections')(app);
501 require('./lib')(app);
511 require('./models')(app);
521 if (__indexOf.call(process.argv, '--seed') >= 0) {
530 if (app.get('env') !== 'development') {
540 return process.exit(0);
55 }
560 console.log('=== Seeding local database ===');
570 return app.mongo.seed(function() {
580 return process.exit(0);
59 });
60 }
61 });
621 return client;
63 };
64
65}).call(this);
66

/home/travis/build/Tivoli/curio/server/mongo/lib/index.coffee

100%
12
12
0
LineHitsSource
11(function() {
21 var fs;
3
41 fs = require('fs');
5
61 module.exports = function(app) {
71 var file, _i, _len, _ref, _results;
81 _ref = fs.readdirSync(__dirname);
91 _results = [];
101 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
113 file = _ref[_i];
123 if (/^((?!index).)*$/.test(file)) {
132 _results.push(require("/home/travis/build/Tivoli/curio/server/mongo/lib/./" + file)(app));
14 }
15 }
161 return _results;
17 };
18
19}).call(this);
20

/home/travis/build/Tivoli/curio/server/mongo/lib/model.coffee

98%
130
128
2
LineHitsSource
11(function() {
21 var EventEmitter,
3 __hasProp = {}.hasOwnProperty,
49 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
61 EventEmitter = require("events").EventEmitter;
7
81 module.exports = function(app) {
91 var mongo;
101 mongo = app.mongo;
111 return global.Model = (function(_super) {
121 __extends(Model, _super);
13
141 Model.strToID = function(id) {
15285 return mongo.stringToID(id);
16 };
17
181 Model.dateToID = function(date) {
192 return mongo.dateToID(date);
20 };
21
221 Model.order_by = [['_id', 'desc']];
23
241 Model.find = function(id, fn) {
25302 var query;
26302 query = {
27 $or: []
28 };
29302 if (_(id).isObjectID()) {
30276 query.$or.push({
31 _id: this.strToID(id)
32 });
33 }
34302 if (_(id != null ? typeof id.toLowerCase === "function" ? id.toLowerCase() : void 0 : void 0).isSlug()) {
3559 query.$or.push({
36 slug: id.toLowerCase()
37 });
38 }
39302 if (_(id != null ? typeof id.toLowerCase === "function" ? id.toLowerCase() : void 0 : void 0).isEmail()) {
4012 query.$or.push({
41 email: id.toLowerCase()
42 });
43 }
44302 if (_(id != null ? typeof id.toLowerCase === "function" ? id.toLowerCase() : void 0 : void 0).isUsername()) {
4512 query.$or.push({
46 username: id.toLowerCase()
47 });
48 }
49302 if (_(id).isString() && this.name === 'Page') {
5017 query.$or.push({
51 path: id.toLowerCase()
52 });
53 }
54302 if (!query.$or.length) {
552 return fn(new BadRequest("Missing query param for " + this.name));
56 }
57300 return this.collection.findOne(query, (function(_this) {
58300 return function(err, data) {
59300 if (data == null) {
609 return fn(err || new NotFound("Cannot find " + _this.name));
61 }
62291 return new global[_this.name](data).populate(fn);
63 };
64 })(this));
65 };
66
671 Model.paginated = function(page, limit) {
6824 var opts;
6924 if (page == null) {
7020 page = 1;
71 }
7224 if (limit == null) {
7320 limit = 20;
74 }
7524 opts = {
76 skip: (+page - 1) * limit,
77 limit: limit
78 };
7924 return this.collection.find({}, opts).sort(this.order_by);
80 };
81
821 Model.search = function(query, page, limit) {
835 var opts;
845 if (page == null) {
855 page = 1;
86 }
875 if (limit == null) {
885 limit = 20;
89 }
905 opts = {
91 skip: (+page - 1) * limit,
92 limit: limit
93 };
945 return this.collection.find(query, opts);
95 };
96
971 function Model(model) {
98814 var k, v;
99814 this.model = model != null ? model : {};
100814 this.strToID = Model.strToID;
101814 this.dateToID = Model.dateToID;
102814 this.collection = this.constructor.collection;
103814 if (this._id() == null) {
10425 if (typeof this.defaults === "function") {
10513 this.defaults();
106 }
107 }
108814 for (k in this) {
10930355 v = this[k];
11030355 if (/^populate_/.test(k)) {
111814 this[k] = _(this[k]).bind(this);
112 }
113 }
114814 return this;
115 }
116
1171 Model.prototype._id = function() {
1181078 return this.model._id;
119 };
120
1211 Model.prototype.id = function() {
122801 var _ref;
123801 return (_ref = this.model._id) != null ? _ref.toHexString() : void 0;
124 };
125
1261 Model.prototype.slug = function() {
127223 return this.model.slug;
128 };
129
1301 Model.prototype.created_at = function() {
131223 return new Date(this._id().getTimestamp()).toISOString();
132 };
133
1341 Model.prototype.validate = function(fn) {
1352 return fn(null, this);
136 };
137
1381 Model.prototype.amend = function(values) {
13946 if (this.whitelist != null) {
14044 values = _(values).pick(this.whitelist);
141 }
14246 if (this.blacklist != null) {
1432 values = _(values).omit(this.blacklist);
144 }
14546 return this.set(values);
146 };
147
1481 Model.prototype.set = function(values) {
149102 var key, val;
150102 if (values == null) {
1510 values = {};
152 }
153102 for (key in values) {
154265 val = values[key];
155265 this.model[key] = val;
156 }
157102 return this;
158 };
159
1601 Model.prototype.set_user = function(id) {
1615 return this.set({
162 _user: this.strToID(id)
163 });
164 };
165
1661 Model.prototype.populate_user = function(fn) {
167228 return User.find(this._user(), fn);
168 };
169
1701 Model.prototype.populate = function(fn) {
171796 var field, funcs, k, v, _ref;
172796 funcs = {};
173796 _ref = this.model;
174796 for (k in _ref) {
1755166 v = _ref[k];
1765166 if (!(/^_(?!id)/.test(k))) {
1774938 continue;
178 }
179228 field = k.slice(1);
180228 funcs[field] = this["populate_" + field];
181 }
182796 return async.parallel(funcs, (function(_this) {
183796 return function(err, results) {
184796 _(_this).extend(results);
185796 return fn(null, _this);
186 };
187 })(this));
188 };
189
1901 Model.prototype.save = function(fn) {
19132 return this.collection.save(this.model, {
192 safe: true
193 }, (function(_this) {
19432 return function(err, model) {
19532 var key;
19632 if ((err != null) && /^E11000 duplicate key/.test(err.message)) {
1974 key = _(/\$(.*?)_/.exec(err.message)).last();
1984 err = new BadRequest("Duplicate " + (fleck.capitalize(key)));
199 }
20032 if (err != null) {
2014 return typeof fn === "function" ? fn(err) : void 0;
202 }
20328 _this.emit('saved');
20428 return typeof fn === "function" ? fn(null, _this) : void 0;
205 };
206 })(this));
207 };
208
2091 Model.prototype.update = function(query, fn) {
2106 return this.collection.findAndModify({
211 _id: this._id()
212 }, [], query, {
213 "new": true
214 }, (function(_this) {
2156 return function(err, model) {
2166 if (err != null) {
2170 return typeof fn === "function" ? fn(err) : void 0;
218 }
2196 _this.model = model;
2206 return typeof fn === "function" ? fn(null, _this) : void 0;
221 };
222 })(this));
223 };
224
2251 Model.prototype.destroy = function(fn) {
2262 return this.collection.remove({
227 _id: this._id()
228 }, (function(_this) {
2292 return function(err, model) {
2302 return typeof fn === "function" ? fn(err, _this) : void 0;
231 };
232 })(this));
233 };
234
2351 return Model;
236
237 })(EventEmitter);
238 };
239
240}).call(this);
241

/home/travis/build/Tivoli/curio/server/mongo/lib/social_model.coffee

90%
75
68
7
LineHitsSource
11(function() {
21 module.exports = function(app) {
31 return global.SocialModel = (function() {
41 function SocialModel(model) {
54 var _ref, _ref1;
64 this.model = model != null ? model : {};
74 this.model.uid = (_ref = this.model) != null ? (_ref1 = _ref.uid) != null ? _ref1.toString() : void 0 : void 0;
84 this.model.source = this.constructor.name.toLowerCase();
94 return this;
10 }
11
121 SocialModel.prototype.uid = function() {
139 var _ref;
149 return (_ref = this.model) != null ? _ref.uid : void 0;
15 };
16
171 SocialModel.prototype.token = function() {
186 var _ref;
196 return (_ref = this.model) != null ? _ref.token : void 0;
20 };
21
221 SocialModel.prototype.secret = function() {
230 var _ref;
240 return (_ref = this.model) != null ? _ref.secret : void 0;
25 };
26
271 SocialModel.prototype.name = function() {
282 var _ref;
292 return (_ref = this.model) != null ? _ref.name : void 0;
30 };
31
321 SocialModel.prototype.avatar = function() {
331 var _ref;
341 return (_ref = this.model) != null ? _ref.avatar : void 0;
35 };
36
371 SocialModel.prototype.email = function() {
383 var _ref;
393 return (_ref = this.model) != null ? _ref.email : void 0;
40 };
41
421 SocialModel.prototype.gender = function() {
434 var _ref;
444 return (_ref = this.model) != null ? _ref.gender : void 0;
45 };
46
471 SocialModel.prototype.source = function() {
487 var _ref;
497 return (_ref = this.model) != null ? _ref.source : void 0;
50 };
51
521 SocialModel.prototype.username = function() {
531 var _ref;
541 return (_ref = this.model) != null ? _ref.username : void 0;
55 };
56
571 SocialModel.prototype.find_or_create_user = function(fn) {
582 return User.find_by_auth(this.source(), this.uid(), (function(_this) {
592 return function(err, user) {
602 _this.user = user;
612 if (_this.user != null) {
621 return fn(null, _this);
63 }
641 return _this.fetch(function(err, self) {
651 if (_this.email() == null) {
660 return fn(new NotFound('Cannot find user'));
67 }
681 return User.find(_this.email(), function(err, user) {
691 _this.user = user;
701 if (_this.user != null) {
710 return fn(null, _this);
72 }
731 return _this.create_user(fn);
74 });
75 });
76 };
77 })(this));
78 };
79
801 SocialModel.prototype.update_user = function(fn) {
812 return this.fetch((function(_this) {
822 return function(err, model) {
832 var current, updates;
842 if (err != null) {
850 return fn(err);
86 }
872 current = _(_this.user.authentications()).reject(function(a) {
881 return a.source === _this.source();
89 });
902 current.push(_this.model);
912 updates = {
92 authentications: current
93 };
942 if (_this.user.name() == null) {
950 updates.name = _this.name();
96 }
972 if (_this.user.model.avatar == null) {
981 updates.avatar = _this.avatar();
99 }
1002 if (_this.gender() != null) {
1012 updates.gender = _this.gender();
102 }
1032 if (!_this.user.settings()["share_" + (_this.source())]) {
1042 updates.settings = _this.user.settings();
1052 updates.settings["share_" + (_this.source())] = 0;
106 }
1072 return _this.user.set(updates).save(function(err, user) {
1082 if (err != null) {
1090 return fn(err);
110 }
1112 _this.user = user;
1122 return fn(null, _this);
113 });
114 };
115 })(this));
116 };
117
1181 return SocialModel;
119
120 })();
121 };
122
123}).call(this);
124

/home/travis/build/Tivoli/curio/server/mongo/models/facebook.coffee

75%
54
41
13
LineHitsSource
11(function() {
21 var qs,
3 __hasProp = {}.hasOwnProperty,
47 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5
61 qs = require('querystring');
7
81 module.exports = function(app) {
91 var config;
101 config = app.get('facebook_config');
111 return global.Facebook = (function(_super) {
121 __extends(Facebook, _super);
13
141 function Facebook() {
154 return Facebook.__super__.constructor.apply(this, arguments);
16 }
17
181 Facebook.prototype.validate = function(fn) {
194 if (this.uid() == null) {
201 return fn(new BadRequest('Missing UID'));
21 }
223 if (this.token() == null) {
231 return fn(new BadRequest('Missing Token'));
24 }
252 return fn(null, this);
26 };
27
281 Facebook.prototype.access_token = function(fn) {
290 var opts;
300 opts = {
31 url: "" + config.url + "/oauth/access_token",
32 qs: {
33 client_id: config.app_id,
34 client_secret: config.app_secret,
35 grant_type: 'fb_exchange_token',
36 fb_exchange_token: this.token()
37 }
38 };
390 return request.get(opts, function(err, r, body) {
400 var token;
410 if (err != null) {
420 return fn(err);
43 }
440 token = qs.parse(body).access_token;
450 if (token == null) {
460 return fn(new BadRequest('Missing token'));
47 }
480 return fn(null, token);
49 });
50 };
51
521 Facebook.prototype.fetch = function(fn) {
533 return request.get("" + config.url + "/me?access_token=" + (this.token()), (function(_this) {
543 return function(e, r, body) {
553 if ((r != null ? r.statusCode : void 0) !== 200) {
560 return fn(new BadRequest(body));
57 }
583 _this.model.uid = body.id.toString();
593 _this.model.name = body.name;
603 _this.model.username = body.username;
613 _this.model.avatar = "" + config.url + "/" + (_this.uid()) + "/picture?type=large";
623 _this.model.email = body.email;
633 _this.model.gender = body.gender;
643 return fn(null, _this);
65 };
66 })(this));
67 };
68
691 Facebook.prototype.create_user = function(fn) {
701 var data, username;
711 username = (function() {
721 switch (true) {
73 case this.username() != null:
740 return this.username();
75 default:
761 return this.name().replace(/\s/g, '.').substr(0, 15);
77 }
78 }).call(this);
791 data = {
80 name: this.name(),
81 username: username,
82 email: this.email(),
83 password: utils.randomString()
84 };
851 return new User(data).save((function(_this) {
861 return function(err, user) {
871 if (err != null) {
880 return fn(err);
89 }
901 _this.user = user;
911 return fn(null, _this);
92 };
93 })(this));
94 };
95
961 return Facebook;
97
98 })(SocialModel);
99 };
100
101}).call(this);
102

/home/travis/build/Tivoli/curio/server/mongo/models/index.coffee

100%
12
12
0
LineHitsSource
11(function() {
21 var fs;
3
41 fs = require('fs');
5
61 module.exports = function(app) {
71 var file, _i, _len, _ref, _results;
81 _ref = fs.readdirSync(__dirname);
91 _results = [];
101 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
116 file = _ref[_i];
126 if (/^((?!index).)*$/.test(file)) {
135 _results.push(require("/home/travis/build/Tivoli/curio/server/mongo/models/./" + file)(app));
14 }
15 }
161 return _results;
17 };
18
19}).call(this);
20

/home/travis/build/Tivoli/curio/server/mongo/models/page.coffee

100%
34
34
0
LineHitsSource
11(function() {
21 var __hasProp = {}.hasOwnProperty,
323 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
4
51 module.exports = function(app) {
61 var mongo;
71 mongo = app.mongo;
81 return global.Page = (function(_super) {
91 __extends(Page, _super);
10
111 function Page() {
12145 return Page.__super__.constructor.apply(this, arguments);
13 }
14
151 Page.collection = mongo.pages;
16
171 Page.prototype.whitelist = ['path', 'title', 'context'];
18
191 Page.prototype.title = function() {
20147 return this.model.title;
21 };
22
231 Page.prototype.path = function() {
24148 return this.model.path_original || this.model.path;
25 };
26
271 Page.prototype.context = function() {
28146 return this.model.context;
29 };
30
311 Page.prototype.validate = function(fn) {
3213 var _ref, _ref1, _ref2;
3313 if (!((_ref = this.path()) != null ? _ref.length : void 0)) {
341 return fn(new BadRequest('Missing Path'));
35 }
3612 if (!((_ref1 = this.title()) != null ? _ref1.length : void 0)) {
371 return fn(new BadRequest('Missing Title'));
38 }
3911 if (!((_ref2 = this.context()) != null ? _ref2.length : void 0)) {
401 return fn(new BadRequest('Missing Context'));
41 }
4210 return fn(null, this);
43 };
44
451 Page.prototype.amend = function(values) {
4613 var _ref;
4713 Page.__super__.amend.call(this, values);
4813 return this.set({
49 path: (_ref = values.path) != null ? _ref.toLowerCase() : void 0,
50 path_original: values.path
51 });
52 };
53
541 Page.prototype.toJSON = function() {
55135 return {
56 id: this.id(),
57 path: this.path(),
58 title: this.title(),
59 context: this.context()
60 };
61 };
62
631 return Page;
64
65 })(Model);
66 };
67
68}).call(this);
69

/home/travis/build/Tivoli/curio/server/mongo/models/post.coffee

100%
36
36
0
LineHitsSource
11(function() {
21 var __hasProp = {}.hasOwnProperty,
323 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
4
51 module.exports = function(app) {
61 var mongo;
71 mongo = app.mongo;
81 return global.Post = (function(_super) {
91 __extends(Post, _super);
10
111 function Post() {
12231 return Post.__super__.constructor.apply(this, arguments);
13 }
14
151 Post.collection = mongo.posts;
16
171 Post.prototype.whitelist = ['title', 'context'];
18
191 Post.prototype._user = function() {
20235 return this.model._user;
21 };
22
231 Post.prototype.title = function() {
24232 return this.model.title;
25 };
26
271 Post.prototype.context = function() {
28231 return this.model.context;
29 };
30
311 Post.prototype.validate = function(fn) {
329 var _ref, _ref1;
339 if (!((_ref = this.title()) != null ? _ref.length : void 0)) {
341 return fn(new BadRequest('Missing Title'));
35 }
368 if (!((_ref1 = this.context()) != null ? _ref1.length : void 0)) {
371 return fn(new BadRequest('Missing Context'));
38 }
397 return User.collection.find({
40 _id: this._user()
41 }).count((function(_this) {
427 return function(err, count) {
437 if (!count) {
441 return fn(err || new BadRequest('Invalid User'));
45 }
466 return fn(null, _this);
47 };
48 })(this));
49 };
50
511 Post.prototype.amend = function(values) {
528 Post.__super__.amend.call(this, values);
538 return this.set({
54 slug: _(values.title).toSlug()
55 });
56 };
57
581 Post.prototype.toJSON = function() {
59223 var _ref;
60223 return {
61 id: this.id(),
62 title: this.title(),
63 slug: this.slug(),
64 created_at: this.created_at(),
65 context: this.context(),
66 author: (_ref = this.user) != null ? _ref.toJSON() : void 0
67 };
68 };
69
701 return Post;
71
72 })(Model);
73 };
74
75}).call(this);
76

/home/travis/build/Tivoli/curio/server/mongo/models/site_config.coffee

96%
28
27
1
LineHitsSource
11(function() {
21 var __hasProp = {}.hasOwnProperty,
323 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
4
51 module.exports = function(app) {
61 var mongo;
71 mongo = app.mongo;
81 return global.SiteConfig = (function(_super) {
91 __extends(SiteConfig, _super);
10
111 function SiteConfig() {
129 return SiteConfig.__super__.constructor.apply(this, arguments);
13 }
14
151 SiteConfig.collection = mongo.configs;
16
171 SiteConfig.find = function(id, fn) {
189 id = id.toLowerCase();
199 return this.collection.findOne({
20 _id: id
21 }, function(err, data) {
229 if (err != null) {
230 return fn(err);
24 }
259 if (data != null) {
268 return fn(null, new SiteConfig(data));
27 }
281 return new SiteConfig({
29 _id: id
30 }).save(fn);
31 });
32 };
33
341 SiteConfig.prototype.blacklist = ['id', '_id'];
35
361 SiteConfig.prototype.toJSON = function() {
379 var json;
389 json = _(this.model).clone();
399 json.id = this._id();
409 json.images = this.images;
419 delete json._id;
429 return json;
43 };
44
451 return SiteConfig;
46
47 })(Model);
48 };
49
50}).call(this);
51

/home/travis/build/Tivoli/curio/server/mongo/models/user.coffee

96%
131
127
4
LineHitsSource
11(function() {
21 var bcrypt, blocked, k, _i, _len,
3 __hasProp = {}.hasOwnProperty,
423 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
50 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
6
71 bcrypt = require('bcrypt');
8
91 blocked = require('../data/reserved');
10
111 for (_i = 0, _len = blocked.length; _i < _len; _i++) {
12142 k = blocked[_i];
13142 blocked.push(fleck.pluralize(k));
14 }
15
161 module.exports = function(app) {
171 var mongo;
181 mongo = app.mongo;
191 return global.User = (function(_super) {
201 __extends(User, _super);
21
221 function User() {
23429 return User.__super__.constructor.apply(this, arguments);
24 }
25
261 User.collection = mongo.users;
27
281 User.order_by = [['email', 'asc']];
29
301 User.find_by_auth = function(source, uid, fn) {
312 var query;
322 query = {
33 'authentications.source': source,
34 'authentications.uid': uid
35 };
362 return this.collection.findOne(query, function(err, data) {
372 if (data == null) {
381 return fn(err || new NotFound('User Not Found'));
39 }
401 return new User(data).populate(fn);
41 });
42 };
43
441 User.find_by_token = function(token, fn) {
453 if (!((token != null) && _(token).isString())) {
461 return fn(new Unauthorized);
47 }
482 return mongo.tokens.findOne({
49 _id: token
50 }, function(err, token) {
512 if (token == null) {
521 return fn(err || new Unauthorized);
53 }
541 return User.find(token._user, fn);
55 });
56 };
57
581 User.authenticate = function(email, pass, fn) {
5913 if (!_(email).isEmail()) {
603 return fn(new Unauthorized);
61 }
6210 if (!(_(pass).isString() && pass.length)) {
631 return fn(new Unauthorized);
64 }
659 return this.find(email, function(err, user) {
669 if (err != null) {
670 return fn(err);
68 }
699 return user.set_self().match_password(pass, fn);
70 });
71 };
72
731 User.prototype.whitelist = ['email', 'username', 'password', 'name'];
74
751 User.prototype.email = function() {
76207 return this.model.email;
77 };
78
791 User.prototype.username = function() {
80434 return this.model.username_original || this.model.username;
81 };
82
831 User.prototype.password = function() {
8437 return this.model.password;
85 };
86
871 User.prototype.name = function() {
88435 return this.model.name;
89 };
90
911 User.prototype.avatar = function() {
92404 return this.model.avatar;
93 };
94
951 User.prototype.settings = function() {
96179 return this.model.settings;
97 };
98
991 User.prototype.authentications = function() {
100177 return this.model.authentications;
101 };
102
1031 User.prototype.hashed_password = function() {
1049 return this.model.hashed_password;
105 };
106
1071 User.prototype.is_admin = function() {
108404 var _ref;
109404 return __indexOf.call(((_ref = this.model) != null ? _ref.roles : void 0) || [], 'admin') >= 0;
110 };
111
1121 User.prototype.defaults = function() {
11313 return _(this.model).defaults({
114 settings: {},
115 authentications: []
116 });
117 };
118
1191 User.prototype.set_self = function() {
120185 this.is_self = true;
121185 return this;
122 };
123
1241 User.prototype.validate = function(fn) {
12523 var _ref, _ref1;
12623 if (this._id() == null) {
12712 if (this.email() == null) {
1281 return fn(new BadRequest('Missing Email'));
129 }
13011 if (this.name() == null) {
1311 return fn(new BadRequest('Missing Name'));
132 }
13310 if (this.password() == null) {
1341 return fn(new BadRequest('Missing Password'));
135 }
136 }
13720 if (!_(this.email()).isEmail()) {
1382 return fn(new BadRequest('Invalid Email'));
139 }
14018 if (!_(this.name()).isName()) {
1412 return fn(new BadRequest('Invalid Name'));
142 }
14316 if (!_(this.username()).isUsername()) {
1442 return fn(new BadRequest('Invalid Username'));
145 }
14614 if (_ref = this.username(), __indexOf.call(blocked, _ref) >= 0) {
1472 return fn(new BadRequest('Invalid Username'));
148 }
14912 if (((_ref1 = this.password()) != null ? _ref1.length : void 0) < 6) {
1502 return fn(new BadRequest('Password too short'));
151 }
15210 if (this.password() == null) {
1535 return fn(null, this);
154 }
1555 return this.hash_password(fn);
156 };
157
1581 User.prototype.amend = function(values) {
15923 var _ref, _ref1;
16023 User.__super__.amend.call(this, values);
16123 return this.set({
162 email: (_ref = values.email) != null ? _ref.toLowerCase() : void 0,
163 username: (_ref1 = values.username) != null ? _ref1.toLowerCase() : void 0,
164 username_original: values.username
165 });
166 };
167
1681 User.prototype.hash_password = function(fn) {
1695 return bcrypt.hash(this.password(), 10, (function(_this) {
1705 return function(err, hash) {
1715 if (err != null) {
1720 return fn(err);
173 }
1745 _this.set({
175 hashed_password: hash
176 });
1775 return fn(null, _this);
178 };
179 })(this));
180 };
181
1821 User.prototype.match_password = function(pass, fn) {
1839 return bcrypt.compare(pass, this.hashed_password(), (function(_this) {
1849 return function(err, result) {
1859 if (!result) {
1862 return fn(err || new Unauthorized('Invalid Password'));
187 }
1887 return fn(null, _this);
189 };
190 })(this));
191 };
192
1931 User.prototype.update_role = function(method, role, fn) {
1947 var query;
1957 if (!_(role).isString()) {
1961 return fn(new BadRequest('Missing Role'));
197 }
1986 query = (function() {
1996 switch (method) {
200 case 'add':
2013 return {
202 $addToSet: {
203 roles: role
204 }
205 };
206 default:
2073 return {
208 $pull: {
209 roles: role
210 }
211 };
212 }
213 })();
2146 return this.update(query, fn);
215 };
216
2171 User.prototype.update_token = function(fn) {
2181 var doc;
2191 doc = {
220 _id: "" + (utils.randomString(24)) + "." + (this.id()),
221 _user: this._id(),
222 expires: new Date()
223 };
2241 return mongo.tokens.insert(doc, function(err, doc) {
2251 if (err != null) {
2260 return fn(new MongoError(err.message));
227 }
2281 return fn(null, doc);
229 });
230 };
231
2321 User.prototype.save = function(fn) {
23313 delete this.model.password;
23413 return User.__super__.save.call(this, fn);
235 };
236
2371 User.prototype.toJSON = function() {
238404 var json;
239404 json = {
240 id: this.id(),
241 username: this.username(),
242 name: this.name(),
243 avatar: this.avatar(),
244 is_admin: this.is_admin()
245 };
246404 if (this.is_self) {
247175 _(json).extend({
248 email: this.email(),
249 settings: this.settings(),
250 authentications: this.authentications()
251 });
252 }
253404 return json;
254 };
255
2561 return User;
257
258 })(Model);
259 };
260
261}).call(this);
262

/home/travis/build/Tivoli/curio/server/mongo/seed.coffee

91%
24
22
2
LineHitsSource
11(function() {
21 var fs, json2mongo, path;
3
41 fs = require('fs');
5
61 path = require('path');
7
81 json2mongo = require('json2mongo');
9
101 module.exports = function(app) {
111 var dir_seeds, module;
121 module = {};
131 dir_seeds = module.dir = "" + __dirname + "/data/seeds";
141 module.seed = function(done) {
151 var mongo;
161 mongo = app.mongo;
171 return fs.readdir(dir_seeds, function(err, files) {
181 if (err != null) {
190 return done(err);
20 }
211 return async.each(files, function(file, fn) {
223 var col, docs;
233 col = /^(\w+)\./.exec(file)[1];
243 docs = require(path.join(dir_seeds, file));
253 docs = json2mongo(docs);
263 if (app.get('env') !== 'test') {
270 console.log(' Seeding %s with %d records', col, docs.length);
28 }
293 return mongo[col].insert(docs, {
30 safe: true,
31 keepGoing: true
32 }, fn);
33 }, done);
34 });
35 };
361 return module;
37 };
38
39}).call(this);
40

/home/travis/build/Tivoli/curio/server/shared/dust_helpers.coffee

83%
18
15
3
LineHitsSource
11(function() {
21 var marked, qs;
3
41 marked = typeof exports !== "undefined" && exports !== null ? require('marked') : window.marked;
5
61 qs = typeof exports !== "undefined" && exports !== null ? require('querystring').stringify : $.param;
7
81 dust.helpers.markdown = function(chunk, context, bodies, params) {
92 if (bodies.block) {
102 return chunk.capture(bodies.block, context, function(string, chunk) {
112 return chunk.end(marked(string));
12 });
13 }
140 return chunk;
15 };
16
171 dust.helpers.moment = function(chunk, context, bodies, params) {
1860 if (bodies.block) {
1960 return chunk.capture(bodies.block, context, function(string, chunk) {
2060 var format;
2160 format = 'MMMM Do YYYY, h:mm a';
2260 if (params != null ? params.format : void 0) {
230 format = dust.helpers.tap(params.format, chunk, context);
24 }
2560 return chunk.end(moment(string).format(format));
26 });
27 }
280 return chunk;
29 };
30
31}).call(this);
32

/home/travis/build/Tivoli/curio/server/shared/underscore_mixins.coffee

100%
27
27
0
LineHitsSource
11(function() {
21 _.mixin({
3 isEmail: function(string) {
4355 if (!_(string).isString()) {
5239 return false;
6 }
7116 return /^[a-z0-9_.%+\-]+@[0-9a-z.\-]+\.[a-z]{2,6}$/i.test(string);
8 },
9 isUsername: function(string) {
10333 if (!_(string).isString()) {
11236 return false;
12 }
1397 return /^[\w\d\.-]{2,15}$/i.test(string);
14 },
15 isName: function(string) {
1629 if (!_(string).isString()) {
176 return false;
18 }
1923 return /^[\u00c0-\u01ff'\w\d\s\.\-]{3,}$/i.test(string);
20 },
21 isObjectID: function(string) {
22311 return /[0-9a-f]{24}/.test(string);
23 },
24 isSlug: function(string) {
25315 if (!_(string).isString()) {
26236 return false;
27 }
2879 return /^[a-z0-9-]+$/.test(string);
29 },
30 isISODate: function(string) {
3113 if (!_(string).isString()) {
329 return false;
33 }
344 return /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/.test(string);
35 },
36 toSlug: function(string) {
3716 if (!_(string).isString()) {
381 return;
39 }
4015 return string.trim().toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '').replace(/-+/g, '-');
41 },
42 formatCurrency: function(num) {
433 var cents, dollars;
443 num = num.toString();
453 dollars = num.slice(0, -2);
463 cents = num.slice(-2);
473 dollars = dollars.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
483 return "$" + dollars + "." + cents;
49 }
50 });
51
52}).call(this);
53

/home/travis/build/Tivoli/curio/server/utilities/index.coffee

97%
81
79
2
LineHitsSource
11(function() {
21 var fs;
3
41 fs = require('fs');
5
61 module.exports = function(app) {
71 var module;
81 module = {};
91 module.randomString = function(length) {
102 var str;
112 if (length == null) {
121 length = 32;
13 }
142 str = '';
152 while (str.length < length) {
165 str += Math.random().toString(36).substr(2);
17 }
182 return str.substr(0, length);
19 };
201 module.shortId = function() {
211 var id;
221 id = new app.mongo.ObjectID().toHexString();
231 return id.substr(0, 10);
24 };
251 module.walk_dir = function(dir) {
2614 var file, results, stat, _i, _len, _ref;
2714 results = [];
2814 _ref = fs.readdirSync(dir);
2914 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
3032 file = _ref[_i];
3132 file = "" + dir + "/" + file;
3232 stat = fs.statSync(file);
3332 switch (true) {
34 case stat != null ? stat.isDirectory() : void 0:
3511 results = results.concat(utils.walk_dir(file));
3611 break;
37 default:
3821 results.push(file);
39 }
40 }
4114 return results;
42 };
431 module.is_json_request = function(req) {
443 return req.is('json') || _(req.accepted).any(function(a) {
453 return a.subtype === 'json';
46 });
47 };
481 module.save_and_send = function(req, res, next) {
4946 var model;
5046 model = req.resource;
5146 return async.waterfall([
52 function(done) {
5346 return done(null, model.amend(req.body));
54 }, function(model, done) {
5546 return model.validate(done);
56 }, function(model, done) {
5728 return model.save(done);
58 }, function(model, done) {
5924 return model.populate(done);
60 }
61 ], function(err, model) {
6246 if (err != null) {
6322 return next(err);
64 }
6524 return res.json(model.toJSON());
66 });
67 };
681 module.cursorJSON = function(cursor, fn) {
6929 var data, model, stream;
7029 stream = cursor.stream();
7129 model = this.to_model(stream);
7229 data = [];
7329 stream.on('data', function(item) {
74480 stream.pause();
75480 return new model(item).populate(function(err, item) {
76480 if (item == null) {
770 return stream.resume();
78 }
79480 if (typeof item.set_self === "function") {
80150 item.set_self();
81 }
82480 data.push(item.toJSON());
83480 return stream.resume();
84 });
85 });
8629 return stream.on('close', function() {
8729 return fn(null, data);
88 });
89 };
901 module.streamJSON = function(req, res, next, cursor) {
9121 return utils.cursorJSON(cursor, function(err, data) {
9221 if (err != null) {
930 return next(err);
94 }
9521 return res.json(data);
96 });
97 };
981 module.load_shared = function(dir) {
991 var file, _i, _len, _ref, _results;
1001 _ref = this.walk_dir(dir);
1011 _results = [];
1021 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1032 file = _ref[_i];
1042 _results.push(require(file));
105 }
1061 return _results;
107 };
1081 module.to_model = function(source) {
10940 source = (function() {
11040 switch (source.constructor.name) {
111 case 'CursorStream':
11229 return source._cursor.collection.collectionName;
113 case 'String':
11411 return source;
115 }
116 })();
11740 return global[fleck.inflect(source, 'singularize', 'upperCamelize')];
118 };
1191 return module;
120 };
121
122}).call(this);
123
make[1]: Leaving directory `/home/travis/build/Tivoli/curio'