diff --git a/test/api/v3/integration/debug/POST-debug_update-user.test.js b/test/api/v3/integration/debug/POST-debug_update-user.test.js new file mode 100644 index 0000000000..851d4c48c9 --- /dev/null +++ b/test/api/v3/integration/debug/POST-debug_update-user.test.js @@ -0,0 +1,53 @@ +import nconf from 'nconf'; +import { + generateUser, +} from '../../../../helpers/api-v3-integration.helper'; + +describe('POST /debug/update-user', () => { + let user; + + before(async () => { + user = await generateUser(); + }); + + after(() => { + nconf.set('IS_PROD', false); + }); + + it('sets protected values', async () => { + let newCron = new Date(2015, 11, 20); + + await user.post('/debug/update-user', { + balance: 100, + lastCron: newCron, + }); + + await user.sync(); + + expect(user.lastCron).to.eql(newCron); + expect(user.balance).to.eql(100); + }); + + it('sets nested values', async () => { + await user.post('/debug/update-user', { + 'contributor.level': 9, + 'purchased.txnCount': 100, + }); + + await user.sync(); + + expect(user.contributor.level).to.eql(9); + expect(user.purchased.txnCount).to.eql(100); + }); + + it('returns error when not in production mode', async () => { + nconf.set('IS_PROD', true); + + await expect(user.post('/debug/update-user')) + .eventually.be.rejected.and.to.deep.equal({ + code: 404, + error: 'NotFound', + message: 'Not found.', + }); + }); +}); diff --git a/website/client/js/controllers/footerCtrl.js b/website/client/js/controllers/footerCtrl.js index 694a2b2b65..bca27a04d8 100644 --- a/website/client/js/controllers/footerCtrl.js +++ b/website/client/js/controllers/footerCtrl.js @@ -78,12 +78,10 @@ function($scope, $rootScope, User, $http, Notification, ApiUrl, Social) { }); }; - //@TODO: Route? $scope.addMissedDay = function(numberOfDays){ if (!confirm("Are you sure you want to reset the day by " + numberOfDays + " day(s)?")) return; - var dayBefore = moment(User.user.lastCron).subtract(numberOfDays, 'days').toDate(); - User.set({'lastCron': dayBefore}); - Notification.text('-' + numberOfDays + ' day(s), remember to refresh'); + + User.setCron(numberOfDays); }; $scope.addTenGems = function(){ @@ -126,5 +124,9 @@ function($scope, $rootScope, User, $http, Notification, ApiUrl, Social) { 'party.quest.progress.up': User.user.party.quest.progress.up + 1000 }); }; + + $scope.makeAdmin = function () { + User.makeAdmin(); + }; } }]) diff --git a/website/client/js/services/userServices.js b/website/client/js/services/userServices.js index 8405b87947..22870aedc3 100644 --- a/website/client/js/services/userServices.js +++ b/website/client/js/services/userServices.js @@ -250,6 +250,35 @@ angular.module('habitrpg') }) }, + setCron: function (numberOfDays) { + var date = moment(user.lastCron).subtract(numberOfDays, 'days').toDate(); + + $http({ + method: "POST", + url: 'api/v3/debug/update-user', + data: { + lastCron: date + } + }) + .then(function (response) { + Notification.text('-' + numberOfDays + ' day(s), remember to refresh'); + }); + }, + + makeAdmin: function () { + $http({ + method: "POST", + url: 'api/v3/debug/update-user', + data: { + 'contributor.admin': true + } + }) + .then(function (response) { + Notification.text('You are now an admin! Go to the Hall of Heroes to change your contributor level.'); + sync() + }); + }, + clearNewMessages: function () { callOpsFunctionAndRequest('markPmsRead', 'mark-pms-read', "POST"); }, diff --git a/website/server/controllers/api-v3/debug.js b/website/server/controllers/api-v3/debug.js index dfd462a7e7..4b1c21477f 100644 --- a/website/server/controllers/api-v3/debug.js +++ b/website/server/controllers/api-v3/debug.js @@ -1,5 +1,6 @@ import { authWithHeaders } from '../../middlewares/api-v3/auth'; import ensureDevelpmentMode from '../../middlewares/api-v3/ensureDevelpmentMode'; +import _ from 'lodash'; let api = {}; @@ -51,4 +52,30 @@ api.addHourglass = { }, }; +/** + * @api {post} /api/v3/debug/set-property Sets properties on user, even protected fields + * @apiDescription Only available in development mode. + * @apiVersion 3.0.0 + * @apiName setCron + * @apiGroup Development + * + * @apiSuccess {Object} data An empty Object + */ +api.setCron = { + method: 'POST', + url: '/debug/update-user', + middlewares: [ensureDevelpmentMode, authWithHeaders()], + async handler (req, res) { + let user = res.locals.user; + + _.each(req.body, (value, key) => { + _.set(user, key, value); + }); + + await user.save(); + + res.respond(200, {}); + }, +}; + module.exports = api; diff --git a/website/views/shared/footer.jade b/website/views/shared/footer.jade index 30570f27b4..6ec84cb79d 100644 --- a/website/views/shared/footer.jade +++ b/website/views/shared/footer.jade @@ -92,6 +92,7 @@ footer.footer(ng-controller='FooterCtrl') a.btn.btn-default(ng-click='addLevelsAndGold()') +Exp +GP +MP a.btn.btn-default(ng-click='addOneLevel()') +1 Level a.btn.btn-default(ng-click='addBossQuestProgressUp()') +1000 Boss Quest Progress Up + a.btn.btn-default(ng-click='makeAdmin()') Make Admin div(ng-init='deferredScripts()')