diff --git a/test/api/anonymized.coffee b/test/api/anonymized.coffee new file mode 100644 index 0000000000..e0bbfa9a6b --- /dev/null +++ b/test/api/anonymized.coffee @@ -0,0 +1,59 @@ +'use strict' + +app = require("../../website/src/server") + +describe "GET /api/v2/user/anonymized", -> + + anon = null + + before (done) -> + # TODO: Seed user with messages, rewards, dailys, checklists, webhooks, etc + registerNewUser -> + request.get(baseURL + "/user/anonymized").set("Accept", "application/json").end (res) -> + expect(res.statusCode).to.be 200 + anon = res.body + expect(anon._id).to.equal user._id + done() + , true + + it 'removes credentials and financial information', (done) -> + expect(anon.apiToken).to.not.exist + expect(anon.auth.local).to.not.exist + expect(anon.auth.facebook).to.not.exist + expect(anon.purchased.plan).to.not.exist + done() + + it 'removes profile information', (done) -> + expect(anon.profile).to.not.exist + expect(anon.contributor).to.not.exist + expect(anon.achievements.challenges).to.not.exist + done() + + it 'removes social information', (done) -> + expect(anon.newMessages).to.not.exist + expect(anon.invitations).to.not.exist + expect(anon.items.special.nyeReceived).to.not.exist + expect(anon.items.special.valentineReceived).to.not.exist + _(anon.inbox.messages).each (msg) -> + expect(msg).to.equal 'inbox message text' + done() + + it 'removes webhooks', (done) -> + expect(anon.webhooks).to.not.exist + done() + + it 'anonymizes task info', (done) -> + _(['habits', 'todos', 'dailys', 'rewards']).each (tasks) -> + _(anon[tasks]).each (task) -> + expect(task.text).to.equal 'task text' + expect(task.notes).to.equal 'task notes' + checklist_count = 0 + _(task.checklist).each (box) -> + box.text = 'item' + checklist_count++ + done() + + it 'anonymizes tags', (done) -> + _(anon.tags).each (tag) -> + expect(tag.name).to.equal 'tag' + expect(tag.challenge).to.equal 'challenge' + done() diff --git a/website/src/controllers/user.js b/website/src/controllers/user.js index 949e4cfb7b..eaab7279b4 100644 --- a/website/src/controllers/user.js +++ b/website/src/controllers/user.js @@ -215,6 +215,78 @@ api.getUser = function(req, res, next) { return res.json(200, user); }; +/** + * Get anonymized User + */ +api.getUserAnonymized = function(req, res, next) { + var user = res.locals.user.toJSON(); + user.stats.toNextLevel = shared.tnl(user.stats.lvl); + user.stats.maxHealth = 50; + user.stats.maxMP = res.locals.user._statsComputed.maxMP; + + delete user.apiToken; + + if (user.auth) { + delete user.auth.local; + delete user.auth.facebook; + } + + delete user.newMessages; + + delete user.profile; + delete user.purchased.plan; + delete user.contributor; + delete user.invitations; + + delete user.items.special.nyeReceived; + delete user.items.special.valentineReceived; + + delete user.webhooks; + delete user.achievements.challenges; + + _.forEach(user.inbox.messages, function(msg){ + msg.text = "inbox message text"; + }); + + _.forEach(user.tags, function(tag){ + tag.name = "tag"; + tag.challenge = "challenge"; + }); + + function cleanChecklist(task){ + var checklistIndex = 0; + + _.forEach(task.checklist, function(c){ + c.text = "item" + checklistIndex++; + }); + } + + _.forEach(user.habits, function(task){ + task.text = "task text"; + task.notes = "task notes"; + }); + + _.forEach(user.rewards, function(task){ + task.text = "task text"; + task.notes = "task notes"; + }); + + _.forEach(user.dailys, function(task){ + task.text = "task text"; + task.notes = "task notes"; + + cleanChecklist(task); + }); + + _.forEach(user.todos, function(task){ + task.text = "task text"; + task.notes = "task notes"; + + cleanChecklist(task); + }); + + return res.json(200, user); +}; /** * This tells us for which paths users can call `PUT /user` (or batch-update equiv, which use `User.set()` on our client). diff --git a/website/src/routes/apiv2.coffee b/website/src/routes/apiv2.coffee index 9694c0f37f..947979c8c2 100644 --- a/website/src/routes/apiv2.coffee +++ b/website/src/routes/apiv2.coffee @@ -227,6 +227,11 @@ module.exports = (swagger, v2) -> description: "Get the full user object" action: user.getUser + "/user/anonymized": + spec: + description: "Get the user object without any personal data" + action: user.getUserAnonymized + "/user:PUT": spec: path: '/user'