diff --git a/lib/server/auth.js b/lib/server/auth.js index e07174c6c5..c6d7a948d0 100644 --- a/lib/server/auth.js +++ b/lib/server/auth.js @@ -41,7 +41,7 @@ module.exports.setupEveryauth = function(everyauth) { q = model.query('users').withEveryauth('facebook', fbUserMetadata.id); model.fetch(q, function(err, user) { var id; - id = user && user.get() && user.get()[0].id; + id = user && user.get().length > 0 && user.get()[0].id; console.log({ err: err, id: id, diff --git a/lib/server/serverRoutes.js b/lib/server/serverRoutes.js index 440b27ad01..5c32403e4c 100644 --- a/lib/server/serverRoutes.js +++ b/lib/server/serverRoutes.js @@ -4,44 +4,60 @@ var scoring; scoring = require('../app/scoring'); module.exports = function(expressApp, root, derby) { - var staticPages; + var deprecatedMessage, staticPages; staticPages = derby.createStatic(root); - expressApp.get('/:uid/up/:score?', function(req, res) { - var model, score; - score = parseInt(req.params.score) || 1; - model = req.getModel(); - model.fetch("users." + req.params.uid, function(err, user) { - if (err || !user.get()) { - return; - } - scoring.setModel(model); - return scoring.score({ - direction: 'up' - }); - }); - return res.send(200); - }); - expressApp.get('/:uid/down/:score?', function(req, res) { - var model, score; - score = parseInt(req.params.score) || 1; - model = req.getModel(); - model.fetch("users." + req.params.uid, function(err, user) { - if (err || !user.get()) { - return; - } - scoring.setModel(model); - return scoring.score({ - direction: 'down' - }); - }); - return res.send(200); - }); expressApp.get('/privacy', function(req, res) { return staticPages.render('privacy', res); }); expressApp.get('/terms', function(req, res) { return staticPages.render('terms', res); }); + deprecatedMessage = 'This REST resource is no longer supported, use /users/:uid/tasks/:taskId/:direction instead.'; + expressApp.get('/:uid/up/:score?', function(req, res) { + return res.send(200, deprecatedMessage); + }); + expressApp.get('/:uid/down/:score?', function(req, res) { + return res.send(200, deprecatedMessage); + }); + expressApp.post('/users/:uid/tasks/:taskId/:direction', function(req, res) { + var direction, icon, model, service, taskId, title, uid, _ref, _ref1; + _ref = req.params, uid = _ref.uid, taskId = _ref.taskId, direction = _ref.direction; + _ref1 = req.body, title = _ref1.title, service = _ref1.service, icon = _ref1.icon; + console.log({ + params: req.params, + body: req.body + }); + if (direction !== 'up' && direction !== 'down') { + return res.send(500, ":direction must be 'up' or 'down'"); + } + model = req.getModel(); + model.session.userId = uid; + return model.fetch("users." + uid, function(err, user) { + var delta, result; + if (err || !user.get()) { + err || (err = 'No user with that ID'); + return res.send(500, err); + } + model.ref('_user', user); + if (!model.get("_user.tasks." + taskId)) { + model.refList("_habitList", "_user.tasks", "_user.habitIds"); + model.at('_habitList').push({ + id: taskId, + type: 'habit', + text: (title || taskId) + ' *', + value: 0, + up: true, + down: true, + notes: "This task was created by a third-party service. Feel free to edit, it won't harm the connection to that service. Additionally, multiple services may piggy-back off this task." + }); + } + scoring.setModel(model); + delta = scoring.score(taskId, direction); + result = model.get('_user.stats'); + result.delta = delta; + return res.send(result); + }); + }); expressApp.post('/', function(req) { return require('../app/reroll').stripeResponse(req); }); diff --git a/src/app/scoring.coffee b/src/app/scoring.coffee index 0a1a1e1100..cbae0e8396 100644 --- a/src/app/scoring.coffee +++ b/src/app/scoring.coffee @@ -133,7 +133,7 @@ updateStats = (stats) -> # {taskId} task you want to score # {direction} 'up' or 'down' -# {cron} is this function being called by cron? (this will usually be false) +# {options} will usually be passed in via cron or tests, safe to ignore this param score = (taskId, direction, options={cron:false, times:1}) -> taskPath = "_user.tasks.#{taskId}" [task, taskObj] = [model.at(taskPath), model.get(taskPath)] diff --git a/src/server/auth.coffee b/src/server/auth.coffee index 68f42aae94..b9a0e11925 100644 --- a/src/server/auth.coffee +++ b/src/server/auth.coffee @@ -49,7 +49,7 @@ module.exports.setupEveryauth = (everyauth) -> model = req.getModel() q = model.query('users').withEveryauth('facebook', fbUserMetadata.id) model.fetch q, (err, user) -> - id = user && user.get() && user.get()[0].id + id = user && user.get().length>0 && user.get()[0].id console.log {err:err, id:id, fbUserMetadata:fbUserMetadata} # Has user been tied to facebook account already? if (id && id!=session.userId) diff --git a/src/server/serverRoutes.coffee b/src/server/serverRoutes.coffee index ee99101ff3..59649f0aee 100644 --- a/src/server/serverRoutes.coffee +++ b/src/server/serverRoutes.coffee @@ -2,25 +2,8 @@ scoring = require('../app/scoring') module.exports = (expressApp, root, derby) -> + # ---------- Static Pages ------------ staticPages = derby.createStatic root - - expressApp.get '/:uid/up/:score?', (req, res) -> - score = parseInt(req.params.score) || 1 - model = req.getModel() - model.fetch "users.#{req.params.uid}", (err, user) -> - return if err || !user.get() - scoring.setModel(model) - scoring.score({direction:'up'}) - res.send(200) - - expressApp.get '/:uid/down/:score?', (req, res) -> - score = parseInt(req.params.score) || 1 - model = req.getModel() - model.fetch "users.#{req.params.uid}", (err, user) -> - return if err || !user.get() - scoring.setModel(model) - scoring.score({direction:'down'}) - res.send(200) expressApp.get '/privacy', (req, res) -> staticPages.render 'privacy', res @@ -28,8 +11,55 @@ module.exports = (expressApp, root, derby) -> expressApp.get '/terms', (req, res) -> staticPages.render 'terms', res + # ---------- REST API ------------ + + # Deprecated API (will remove soon) + deprecatedMessage = 'This REST resource is no longer supported, use /users/:uid/tasks/:taskId/:direction instead.' + expressApp.get '/:uid/up/:score?', (req, res) -> + res.send(200, deprecatedMessage) + expressApp.get '/:uid/down/:score?', (req, res) -> + res.send(200, deprecatedMessage) + + # New API + expressApp.post '/users/:uid/tasks/:taskId/:direction', (req, res) -> + {uid, taskId, direction} = req.params + {title, service, icon} = req.body + console.log {params:req.params, body:req.body} + return res.send(500, ":direction must be 'up' or 'down'") unless direction in ['up','down'] + model = req.getModel() + model.session.userId = uid + model.fetch "users.#{uid}", (err, user) -> + if err || !user.get() + err ||= 'No user with that ID' + return res.send(500, err) + model.ref('_user', user) + + # Create task if doesn't exist + # TODO add service & icon to task + unless model.get("_user.tasks.#{taskId}") + model.refList "_habitList", "_user.tasks", "_user.habitIds" + model.at('_habitList').push { + id: taskId + type: 'habit' + text: (title || taskId) + ' *' + value: 0 + up: true + down: true + notes: "This task was created by a third-party service. Feel free to edit, it won't harm the connection to that service. Additionally, multiple services may piggy-back off this task." + } + + scoring.setModel(model) + delta = scoring.score(taskId, direction) + result = model.get ('_user.stats') + result.delta = delta + res.send(result) + + # ---------- Stripe ------------ + expressApp.post '/', (req) -> require('../app/reroll').stripeResponse(req) + # ---------- Errors ------------ + expressApp.all '*', (req) -> throw "404: #{req.url}" diff --git a/test/rest.casper.coffee b/test/rest.casper.coffee index 3abc8b149b..d7bacf6c7e 100644 --- a/test/rest.casper.coffee +++ b/test/rest.casper.coffee @@ -7,16 +7,29 @@ uid = undefined casper.start url, -> uid = @evaluate -> window.DERBY.model.get("_user.id") - utils.dump uid -# ---------- REST API ------------ + # ---------- REST API ------------ - casper.thenOpen "#{url}/users/#{uid}" - casper.thenOpen "#{url}/users/#{uid}/tasks" - casper.thenOpen "#{url}/users/#{uid}/tasks/{taskId}" - casper.thenOpen "#{url}/users/#{uid}/tasks/{taskId}" + # casper.thenOpen "#{url}/users/#{uid}" + # casper.thenOpen "#{url}/users/#{uid}/tasks" + # casper.thenOpen "#{url}/users/#{uid}/tasks/{taskId}" - casper.thenOpen "#{url}/users/#{uid}/score" + taskId = 'productivity' + pomodoro = { + 'title': 'Stay Focused', + 'service': 'pomodoro', + 'icon': 'http://www.veryicon.com/icon/16/Food%20%26%20Drinks/Paradise%20Fruits/Tomato.png' + } + + @thenOpen "#{url}/users/#{uid}/tasks/#{taskId}/up", { + method: 'post', + data: pomodoro + } + + @thenOpen "#{url}/users/#{uid}/tasks/#{taskId}/down", { + method: 'post', + data: pomodoro + } # ---------- Run ------------