From 22d25f8be3a7fbab875a219f665ed5798df1b9ad Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Wed, 16 Mar 2016 08:41:56 -0500 Subject: [PATCH 1/6] fix: Change update user routes to use PUT instead of POST --- ...il.test.js => PUT-user_update_email.test.js} | 12 ++++++------ ...test.js => PUT-user_update_password.test.js} | 8 ++++---- ...test.js => PUT-user_update_username.test.js} | 17 +++++++++++------ website/src/controllers/api-v3/user.js | 12 ++++++------ 4 files changed, 27 insertions(+), 22 deletions(-) rename test/api/v3/integration/user/{POST-user_update_email.test.js => PUT-user_update_email.test.js} (87%) rename test/api/v3/integration/user/{POST-user_update_password.test.js => PUT-user_update_password.test.js} (87%) rename test/api/v3/integration/user/{POST-user_update_username.test.js => PUT-user_update_username.test.js} (89%) diff --git a/test/api/v3/integration/user/POST-user_update_email.test.js b/test/api/v3/integration/user/PUT-user_update_email.test.js similarity index 87% rename from test/api/v3/integration/user/POST-user_update_email.test.js rename to test/api/v3/integration/user/PUT-user_update_email.test.js index 5a8392ec1e..38fd7da53e 100644 --- a/test/api/v3/integration/user/POST-user_update_email.test.js +++ b/test/api/v3/integration/user/PUT-user_update_email.test.js @@ -4,7 +4,7 @@ import { } from '../../../../helpers/api-v3-integration.helper'; import { model as User } from '../../../../../website/src/models/user'; -describe('POST /user/update-email', () => { +describe('PUT /user/update-email', () => { let user; let fbUser; let endpoint = '/user/update-email'; @@ -17,7 +17,7 @@ describe('POST /user/update-email', () => { }); it('does not change email if one is not provided', async () => { - await expect(user.post(endpoint)).to.eventually.be.rejected.and.eql({ + await expect(user.put(endpoint)).to.eventually.be.rejected.and.eql({ code: 400, error: 'BadRequest', message: t('invalidReqParams'), @@ -25,7 +25,7 @@ describe('POST /user/update-email', () => { }); it('does not change email if password is not provided', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { newEmail, })).to.eventually.be.rejected.and.eql({ code: 400, @@ -35,7 +35,7 @@ describe('POST /user/update-email', () => { }); it('does not change email if wrong password is provided', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { newEmail, password: 'wrong password', })).to.eventually.be.rejected.and.eql({ @@ -46,7 +46,7 @@ describe('POST /user/update-email', () => { }); it('changes email if new email and existing password are provided', async () => { - let response = await user.post(endpoint, { + let response = await user.put(endpoint, { newEmail, password: thePassword, }); @@ -64,7 +64,7 @@ describe('POST /user/update-email', () => { }); it('does not change email if user.auth.local.email does not exist for this user', async () => { - await expect(fbUser.post(endpoint, { + await expect(fbUser.put(endpoint, { newEmail, password: thePassword, })).to.eventually.be.rejected.and.eql({ diff --git a/test/api/v3/integration/user/POST-user_update_password.test.js b/test/api/v3/integration/user/PUT-user_update_password.test.js similarity index 87% rename from test/api/v3/integration/user/POST-user_update_password.test.js rename to test/api/v3/integration/user/PUT-user_update_password.test.js index 728abb13db..18f17177ab 100644 --- a/test/api/v3/integration/user/POST-user_update_password.test.js +++ b/test/api/v3/integration/user/PUT-user_update_password.test.js @@ -3,7 +3,7 @@ import { translate as t, } from '../../../../helpers/api-integration/v3'; -describe('POST /user/update-password', async () => { +describe('PUT /user/update-password', async () => { let endpoint = '/user/update-password'; let user; let password = 'password'; @@ -16,7 +16,7 @@ describe('POST /user/update-password', async () => { it('successfully changes the password', async () => { let previousHashedPassword = user.auth.local.hashed_password; - let response = await user.post(endpoint, { + let response = await user.put(endpoint, { password, newPassword, confirmPassword: newPassword, @@ -27,7 +27,7 @@ describe('POST /user/update-password', async () => { }); it('new passwords mismatch', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { password, newPassword, confirmPassword: `${newPassword}-wrong-confirmation`, @@ -39,7 +39,7 @@ describe('POST /user/update-password', async () => { }); it('existing password is wrong', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { password: wrongPassword, newPassword, confirmPassword: newPassword, diff --git a/test/api/v3/integration/user/POST-user_update_username.test.js b/test/api/v3/integration/user/PUT-user_update_username.test.js similarity index 89% rename from test/api/v3/integration/user/POST-user_update_username.test.js rename to test/api/v3/integration/user/PUT-user_update_username.test.js index 4e59fcb5b8..b48831c010 100644 --- a/test/api/v3/integration/user/POST-user_update_username.test.js +++ b/test/api/v3/integration/user/PUT-user_update_username.test.js @@ -4,7 +4,7 @@ import { } from '../../../../helpers/api-integration/v3'; import { model as User } from '../../../../../website/src/models/user'; -describe('POST /user/update-username', async () => { +describe('PUT /user/update-username', async () => { let endpoint = '/user/update-username'; let user; let newUsername = 'new-username'; @@ -17,7 +17,7 @@ describe('POST /user/update-username', async () => { }); it('successfully changes username', async () => { - let response = await user.post(endpoint, { + let response = await user.put(endpoint, { username: newUsername, password, }); @@ -32,8 +32,9 @@ describe('POST /user/update-username', async () => { user = await generateUser(); await user.update({'auth.local.username': existingUsername, 'auth.local.lowerCaseUsername': existingUsername }); }); + it('prevents username update', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { username: existingUsername, password, })).to.eventually.be.rejected.and.eql({ @@ -43,8 +44,9 @@ describe('POST /user/update-username', async () => { }); }); }); + it('password is wrong', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { username: newUsername, password: wrongPassword, })).to.eventually.be.rejected.and.eql({ @@ -53,13 +55,15 @@ describe('POST /user/update-username', async () => { message: t('wrongPassword'), }); }); + describe('social-only user', async () => { beforeEach(async () => { user = await generateUser(); await user.update({ 'auth.local': { ok: true } }); }); + it('prevents username update', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { username: newUsername, password, })).to.eventually.be.rejected.and.eql({ @@ -69,8 +73,9 @@ describe('POST /user/update-username', async () => { }); }); }); + it('new username is not provided', async () => { - await expect(user.post(endpoint, { + await expect(user.put(endpoint, { password, })).to.eventually.be.rejected.and.eql({ code: 400, diff --git a/website/src/controllers/api-v3/user.js b/website/src/controllers/api-v3/user.js index 17c37aaf84..896f648d19 100644 --- a/website/src/controllers/api-v3/user.js +++ b/website/src/controllers/api-v3/user.js @@ -43,7 +43,7 @@ api.getUser = { }; /** - * @api {post} /user/update-password + * @api {put} /user/update-password * @apiVersion 3.0.0 * @apiName updatePassword * @apiGroup User @@ -53,7 +53,7 @@ api.getUser = { * @apiSuccess {Object} The success message **/ api.updatePassword = { - method: 'POST', + method: 'PUT', middlewares: [authWithHeaders(), cron], url: '/user/update-password', async handler (req, res) { @@ -82,7 +82,7 @@ api.updatePassword = { }; /** - * @api {post} /user/update-username + * @api {put} /user/update-username * @apiVersion 3.0.0 * @apiName updateUsername * @apiGroup User @@ -91,7 +91,7 @@ api.updatePassword = { * @apiSuccess {Object} The new username **/ api.updateUsername = { - method: 'POST', + method: 'PUT', middlewares: [authWithHeaders(), cron], url: '/user/update-username', async handler (req, res) { @@ -128,7 +128,7 @@ api.updateUsername = { /** - * @api {post} /user/update-email + * @api {put} /user/update-email * @apiVersion 3.0.0 * @apiName UpdateEmail * @apiGroup User @@ -139,7 +139,7 @@ api.updateUsername = { * @apiSuccess {Object} An object containing the new email address */ api.updateEmail = { - method: 'POST', + method: 'PUT', middlewares: [authWithHeaders(), cron], url: '/user/update-email', async handler (req, res) { From d1af7adff68c26460ac474f339e02daf0500ef36 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Wed, 16 Mar 2016 08:58:14 -0500 Subject: [PATCH 2/6] refactor: Update user update routes to be under auth namespace --- .../integration/user/PUT-user_update_email.test.js | 4 ++-- .../user/PUT-user_update_password.test.js | 4 ++-- .../user/PUT-user_update_username.test.js | 4 ++-- website/src/controllers/api-v3/user.js | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/api/v3/integration/user/PUT-user_update_email.test.js b/test/api/v3/integration/user/PUT-user_update_email.test.js index 38fd7da53e..749a16a3d4 100644 --- a/test/api/v3/integration/user/PUT-user_update_email.test.js +++ b/test/api/v3/integration/user/PUT-user_update_email.test.js @@ -4,10 +4,10 @@ import { } from '../../../../helpers/api-v3-integration.helper'; import { model as User } from '../../../../../website/src/models/user'; -describe('PUT /user/update-email', () => { +describe('PUT /user/auth/update-email', () => { let user; let fbUser; - let endpoint = '/user/update-email'; + let endpoint = '/user/auth/update-email'; let newEmail = 'some-new-email_2@example.net'; let thePassword = 'password'; // from habitrpg/test/helpers/api-integration/v3/object-generators.js diff --git a/test/api/v3/integration/user/PUT-user_update_password.test.js b/test/api/v3/integration/user/PUT-user_update_password.test.js index 18f17177ab..f0ae2737d0 100644 --- a/test/api/v3/integration/user/PUT-user_update_password.test.js +++ b/test/api/v3/integration/user/PUT-user_update_password.test.js @@ -3,8 +3,8 @@ import { translate as t, } from '../../../../helpers/api-integration/v3'; -describe('PUT /user/update-password', async () => { - let endpoint = '/user/update-password'; +describe('PUT /user/auth/update-password', async () => { + let endpoint = '/user/auth/update-password'; let user; let password = 'password'; let wrongPassword = 'wrong-password'; diff --git a/test/api/v3/integration/user/PUT-user_update_username.test.js b/test/api/v3/integration/user/PUT-user_update_username.test.js index b48831c010..b105544886 100644 --- a/test/api/v3/integration/user/PUT-user_update_username.test.js +++ b/test/api/v3/integration/user/PUT-user_update_username.test.js @@ -4,8 +4,8 @@ import { } from '../../../../helpers/api-integration/v3'; import { model as User } from '../../../../../website/src/models/user'; -describe('PUT /user/update-username', async () => { - let endpoint = '/user/update-username'; +describe('PUT /user/auth/update-username', async () => { + let endpoint = '/user/auth/update-username'; let user; let newUsername = 'new-username'; let existingUsername = 'existing-username'; diff --git a/website/src/controllers/api-v3/user.js b/website/src/controllers/api-v3/user.js index 896f648d19..d2b1a47721 100644 --- a/website/src/controllers/api-v3/user.js +++ b/website/src/controllers/api-v3/user.js @@ -43,7 +43,7 @@ api.getUser = { }; /** - * @api {put} /user/update-password + * @api {put} /user/auth/update-password * @apiVersion 3.0.0 * @apiName updatePassword * @apiGroup User @@ -55,7 +55,7 @@ api.getUser = { api.updatePassword = { method: 'PUT', middlewares: [authWithHeaders(), cron], - url: '/user/update-password', + url: '/user/auth/update-password', async handler (req, res) { let user = res.locals.user; @@ -82,7 +82,7 @@ api.updatePassword = { }; /** - * @api {put} /user/update-username + * @api {put} /user/auth/update-username * @apiVersion 3.0.0 * @apiName updateUsername * @apiGroup User @@ -93,7 +93,7 @@ api.updatePassword = { api.updateUsername = { method: 'PUT', middlewares: [authWithHeaders(), cron], - url: '/user/update-username', + url: '/user/auth/update-username', async handler (req, res) { let user = res.locals.user; @@ -128,7 +128,7 @@ api.updateUsername = { /** - * @api {put} /user/update-email + * @api {put} /user/auth/update-email * @apiVersion 3.0.0 * @apiName UpdateEmail * @apiGroup User @@ -141,7 +141,7 @@ api.updateUsername = { api.updateEmail = { method: 'PUT', middlewares: [authWithHeaders(), cron], - url: '/user/update-email', + url: '/user/auth/update-email', async handler (req, res) { let user = res.locals.user; From 5c3c8ebb743b563bb0c0cad82e0fefca2ff90dd5 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Wed, 16 Mar 2016 17:26:53 -0500 Subject: [PATCH 3/6] refactor: Move auth update routes from user to auth controller --- website/src/controllers/api-v3/auth.js | 120 ++++++++++++++++++++++++ website/src/controllers/api-v3/user.js | 121 ------------------------- 2 files changed, 120 insertions(+), 121 deletions(-) diff --git a/website/src/controllers/api-v3/auth.js b/website/src/controllers/api-v3/auth.js index ad3c26bbdd..875d8672ca 100644 --- a/website/src/controllers/api-v3/auth.js +++ b/website/src/controllers/api-v3/auth.js @@ -9,6 +9,7 @@ import { import cron from '../../middlewares/api-v3/cron'; import { NotAuthorized, + BadRequest, NotFound, } from '../../libs/api-v3/errors'; import Q from 'q'; @@ -283,6 +284,125 @@ api.loginSocial = { }, }; +/** + * @api {put} /user/auth/update-username + * @apiVersion 3.0.0 + * @apiName updateUsername + * @apiGroup User + * @apiParam {string} password The password + * @apiParam {string} username New username + * @apiSuccess {Object} The new username + **/ +api.updateUsername = { + method: 'PUT', + middlewares: [authWithHeaders(), cron], + url: '/user/auth/update-username', + async handler (req, res) { + let user = res.locals.user; + + req.checkBody({ + password: { + notEmpty: {errorMessage: res.t('missingPassword')}, + }, + username: { + notEmpty: { errorMessage: res.t('missingUsername') }, + }, + }); + + let validationErrors = req.validationErrors(); + if (validationErrors) throw validationErrors; + + if (!user.auth.local.username) throw new BadRequest(res.t('userHasNoLocalRegistration')); + + let oldPassword = passwordUtils.encrypt(req.body.password, user.auth.local.salt); + if (oldPassword !== user.auth.local.hashed_password) throw new NotAuthorized(res.t('wrongPassword')); + + let count = await User.count({ 'auth.local.lowerCaseUsername': req.body.username.toLowerCase() }); + if (count > 0) throw new BadRequest(res.t('usernameTaken')); + + // save username + user.auth.local.lowerCaseUsername = req.body.username.toLowerCase(); + user.auth.local.username = req.body.username; + await user.save(); + + res.respond(200, { username: req.body.username }); + }, +}; + +/** + * @api {put} /user/auth/update-password + * @apiVersion 3.0.0 + * @apiName updatePassword + * @apiGroup User + * @apiParam {string} password The old password + * @apiParam {string} newPassword The new password + * @apiParam {string} confirmPassword Password confirmation + * @apiSuccess {Object} The success message + **/ +api.updatePassword = { + method: 'PUT', + middlewares: [authWithHeaders(), cron], + url: '/user/auth/update-password', + async handler (req, res) { + let user = res.locals.user; + + if (!user.auth.local.hashed_password) throw new BadRequest(res.t('userHasNoLocalRegistration')); + + let oldPassword = passwordUtils.encrypt(req.body.password, user.auth.local.salt); + if (oldPassword !== user.auth.local.hashed_password) throw new NotAuthorized(res.t('wrongPassword')); + + req.checkBody({ + password: { + notEmpty: {errorMessage: res.t('missingNewPassword')}, + }, + newPassword: { + notEmpty: {errorMessage: res.t('missingPassword')}, + }, + }); + + if (req.body.newPassword !== req.body.confirmPassword) throw new NotAuthorized(res.t('passwordConfirmationMatch')); + + user.auth.local.hashed_password = passwordUtils.encrypt(req.body.newPassword, user.auth.local.salt); // eslint-disable-line camelcase + await user.save(); + res.respond(200, {}); + }, +}; + +/** + * @api {put} /user/auth/update-email + * @apiVersion 3.0.0 + * @apiName UpdateEmail + * @apiGroup User + * + * @apiParam {string} newEmail The new email address. + * @apiParam {string} password The user password. + * + * @apiSuccess {Object} An object containing the new email address + */ +api.updateEmail = { + method: 'PUT', + middlewares: [authWithHeaders(), cron], + url: '/user/auth/update-email', + async handler (req, res) { + let user = res.locals.user; + + if (!user.auth.local.email) throw new BadRequest(res.t('userHasNoLocalRegistration')); + + req.checkBody('newEmail', res.t('newEmailRequired')).notEmpty().isEmail(); + req.checkBody('password', res.t('missingPassword')).notEmpty(); + let validationErrors = req.validationErrors(); + if (validationErrors) throw validationErrors; + + let candidatePassword = passwordUtils.encrypt(req.body.password, user.auth.local.salt); + if (candidatePassword !== user.auth.local.hashed_password) throw new NotAuthorized(res.t('wrongPassword')); + + user.auth.local.email = req.body.newEmail; + await user.save(); + + return res.respond(200, { email: user.auth.local.email }); + }, +}; + const firebaseTokenGenerator = new FirebaseTokenGenerator(nconf.get('FIREBASE:SECRET')); // Internal route TODO expose? diff --git a/website/src/controllers/api-v3/user.js b/website/src/controllers/api-v3/user.js index d2b1a47721..cb5b0524ff 100644 --- a/website/src/controllers/api-v3/user.js +++ b/website/src/controllers/api-v3/user.js @@ -11,7 +11,6 @@ import { model as Group } from '../../models/group'; import { model as User } from '../../models/user'; import Q from 'q'; import _ from 'lodash'; -import * as passwordUtils from '../../libs/api-v3/password'; let api = {}; @@ -42,126 +41,6 @@ api.getUser = { }, }; -/** - * @api {put} /user/auth/update-password - * @apiVersion 3.0.0 - * @apiName updatePassword - * @apiGroup User - * @apiParam {string} password The old password - * @apiParam {string} newPassword The new password - * @apiParam {string} confirmPassword Password confirmation - * @apiSuccess {Object} The success message - **/ -api.updatePassword = { - method: 'PUT', - middlewares: [authWithHeaders(), cron], - url: '/user/auth/update-password', - async handler (req, res) { - let user = res.locals.user; - - if (!user.auth.local.hashed_password) throw new BadRequest(res.t('userHasNoLocalRegistration')); - - let oldPassword = passwordUtils.encrypt(req.body.password, user.auth.local.salt); - if (oldPassword !== user.auth.local.hashed_password) throw new NotAuthorized(res.t('wrongPassword')); - - req.checkBody({ - password: { - notEmpty: {errorMessage: res.t('missingNewPassword')}, - }, - newPassword: { - notEmpty: {errorMessage: res.t('missingPassword')}, - }, - }); - - if (req.body.newPassword !== req.body.confirmPassword) throw new NotAuthorized(res.t('passwordConfirmationMatch')); - - user.auth.local.hashed_password = passwordUtils.encrypt(req.body.newPassword, user.auth.local.salt); // eslint-disable-line camelcase - await user.save(); - res.respond(200, {}); - }, -}; - -/** - * @api {put} /user/auth/update-username - * @apiVersion 3.0.0 - * @apiName updateUsername - * @apiGroup User - * @apiParam {string} password The password - * @apiParam {string} username New username - * @apiSuccess {Object} The new username - **/ -api.updateUsername = { - method: 'PUT', - middlewares: [authWithHeaders(), cron], - url: '/user/auth/update-username', - async handler (req, res) { - let user = res.locals.user; - - req.checkBody({ - password: { - notEmpty: {errorMessage: res.t('missingPassword')}, - }, - username: { - notEmpty: { errorMessage: res.t('missingUsername') }, - }, - }); - - let validationErrors = req.validationErrors(); - if (validationErrors) throw validationErrors; - - if (!user.auth.local.username) throw new BadRequest(res.t('userHasNoLocalRegistration')); - - let oldPassword = passwordUtils.encrypt(req.body.password, user.auth.local.salt); - if (oldPassword !== user.auth.local.hashed_password) throw new NotAuthorized(res.t('wrongPassword')); - - let count = await User.count({ 'auth.local.lowerCaseUsername': req.body.username.toLowerCase() }); - if (count > 0) throw new BadRequest(res.t('usernameTaken')); - - // save username - user.auth.local.lowerCaseUsername = req.body.username.toLowerCase(); - user.auth.local.username = req.body.username; - await user.save(); - - res.respond(200, { username: req.body.username }); - }, -}; - - -/** - * @api {put} /user/auth/update-email - * @apiVersion 3.0.0 - * @apiName UpdateEmail - * @apiGroup User - * - * @apiParam {string} newEmail The new email address. - * @apiParam {string} password The user password. - * - * @apiSuccess {Object} An object containing the new email address - */ -api.updateEmail = { - method: 'PUT', - middlewares: [authWithHeaders(), cron], - url: '/user/auth/update-email', - async handler (req, res) { - let user = res.locals.user; - - if (!user.auth.local.email) throw new BadRequest(res.t('userHasNoLocalRegistration')); - - req.checkBody('newEmail', res.t('newEmailRequired')).notEmpty().isEmail(); - req.checkBody('password', res.t('missingPassword')).notEmpty(); - let validationErrors = req.validationErrors(); - if (validationErrors) throw validationErrors; - - let candidatePassword = passwordUtils.encrypt(req.body.password, user.auth.local.salt); - if (candidatePassword !== user.auth.local.hashed_password) throw new NotAuthorized(res.t('wrongPassword')); - - user.auth.local.email = req.body.newEmail; - await user.save(); - - return res.respond(200, { email: user.auth.local.email }); - }, -}; - const partyMembersFields = 'profile.name stats achievements items.special'; /** From 2ef176c6f2d6abc370b48c186c7db8bef84d41f7 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Fri, 18 Mar 2016 07:55:19 -0500 Subject: [PATCH 4/6] refactor: Move auth route tests to auth folder --- .../integration/user/{ => auth}/PUT-user_update_email.test.js | 4 ++-- .../user/{ => auth}/PUT-user_update_password.test.js | 2 +- .../user/{ => auth}/PUT-user_update_username.test.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename test/api/v3/integration/user/{ => auth}/PUT-user_update_email.test.js (94%) rename test/api/v3/integration/user/{ => auth}/PUT-user_update_password.test.js (95%) rename test/api/v3/integration/user/{ => auth}/PUT-user_update_username.test.js (94%) diff --git a/test/api/v3/integration/user/PUT-user_update_email.test.js b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js similarity index 94% rename from test/api/v3/integration/user/PUT-user_update_email.test.js rename to test/api/v3/integration/user/auth/PUT-user_update_email.test.js index 749a16a3d4..b595e213cc 100644 --- a/test/api/v3/integration/user/PUT-user_update_email.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js @@ -1,8 +1,8 @@ import { generateUser, translate as t, -} from '../../../../helpers/api-v3-integration.helper'; -import { model as User } from '../../../../../website/src/models/user'; +} from '../../../../../helpers/api-v3-integration.helper'; +import { model as User } from '../../../../../../website/src/models/user'; describe('PUT /user/auth/update-email', () => { let user; diff --git a/test/api/v3/integration/user/PUT-user_update_password.test.js b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js similarity index 95% rename from test/api/v3/integration/user/PUT-user_update_password.test.js rename to test/api/v3/integration/user/auth/PUT-user_update_password.test.js index f0ae2737d0..3dc4d9dc5d 100644 --- a/test/api/v3/integration/user/PUT-user_update_password.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js @@ -1,7 +1,7 @@ import { generateUser, translate as t, -} from '../../../../helpers/api-integration/v3'; +} from '../../../../../helpers/api-v3-integration.helper'; describe('PUT /user/auth/update-password', async () => { let endpoint = '/user/auth/update-password'; diff --git a/test/api/v3/integration/user/PUT-user_update_username.test.js b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js similarity index 94% rename from test/api/v3/integration/user/PUT-user_update_username.test.js rename to test/api/v3/integration/user/auth/PUT-user_update_username.test.js index b105544886..bcfece8eba 100644 --- a/test/api/v3/integration/user/PUT-user_update_username.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js @@ -1,8 +1,8 @@ import { generateUser, translate as t, -} from '../../../../helpers/api-integration/v3'; -import { model as User } from '../../../../../website/src/models/user'; +} from '../../../../../helpers/api-v3-integration.helper'; +import { model as User } from '../../../../../../website/src/models/user'; describe('PUT /user/auth/update-username', async () => { let endpoint = '/user/auth/update-username'; From f6f5b1a118e9d646affc2deb7e3382d25329bc3c Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Fri, 18 Mar 2016 07:57:42 -0500 Subject: [PATCH 5/6] tests: Remove dependency on mongoose User model in auth tests --- .../v3/integration/user/auth/PUT-user_update_email.test.js | 5 ++--- .../integration/user/auth/PUT-user_update_username.test.js | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js index b595e213cc..4c975390cc 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js @@ -2,7 +2,6 @@ import { generateUser, translate as t, } from '../../../../../helpers/api-v3-integration.helper'; -import { model as User } from '../../../../../../website/src/models/user'; describe('PUT /user/auth/update-email', () => { let user; @@ -51,8 +50,8 @@ describe('PUT /user/auth/update-email', () => { password: thePassword, }); expect(response).to.eql({ email: 'some-new-email_2@example.net' }); - let id = user._id; - user = await User.findOne({ _id: id }); + + await user.sync(); expect(user.auth.local.email).to.eql(newEmail); }); }); diff --git a/test/api/v3/integration/user/auth/PUT-user_update_username.test.js b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js index bcfece8eba..fc308f4cc1 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_username.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js @@ -2,7 +2,6 @@ import { generateUser, translate as t, } from '../../../../../helpers/api-v3-integration.helper'; -import { model as User } from '../../../../../../website/src/models/user'; describe('PUT /user/auth/update-username', async () => { let endpoint = '/user/auth/update-username'; @@ -22,7 +21,7 @@ describe('PUT /user/auth/update-username', async () => { password, }); expect(response).to.eql({ username: newUsername }); - user = await User.findOne({ _id: user._id }); + await user.sync(); expect(user.auth.local.username).to.eql(newUsername); }); From 75ed4080dc55f1060506525998eed18fb3fe8c92 Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Fri, 18 Mar 2016 08:34:13 -0500 Subject: [PATCH 6/6] tests: Clean up styling of auth update tests --- .../user/auth/PUT-user_update_email.test.js | 39 ++++++----- .../auth/PUT-user_update_password.test.js | 15 +++-- .../auth/PUT-user_update_username.test.js | 65 ++++++++----------- 3 files changed, 57 insertions(+), 62 deletions(-) diff --git a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js index 4c975390cc..47357d3c85 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js @@ -3,20 +3,21 @@ import { translate as t, } from '../../../../../helpers/api-v3-integration.helper'; -describe('PUT /user/auth/update-email', () => { - let user; - let fbUser; - let endpoint = '/user/auth/update-email'; - let newEmail = 'some-new-email_2@example.net'; - let thePassword = 'password'; // from habitrpg/test/helpers/api-integration/v3/object-generators.js +const ENDPOINT = '/user/auth/update-email'; + +describe('PUT /user/auth/update-email', () => { + let newEmail = 'some-new-email_2@example.net'; + let oldPassword = 'password'; // from habitrpg/test/helpers/api-integration/v3/object-generators.js + + context('Local Authenticaion User', async () => { + let user; - describe('local user', async () => { beforeEach(async () => { user = await generateUser(); }); - it('does not change email if one is not provided', async () => { - await expect(user.put(endpoint)).to.eventually.be.rejected.and.eql({ + it('does not change email if email is not provided', async () => { + await expect(user.put(ENDPOINT)).to.eventually.be.rejected.and.eql({ code: 400, error: 'BadRequest', message: t('invalidReqParams'), @@ -24,7 +25,7 @@ describe('PUT /user/auth/update-email', () => { }); it('does not change email if password is not provided', async () => { - await expect(user.put(endpoint, { + await expect(user.put(ENDPOINT, { newEmail, })).to.eventually.be.rejected.and.eql({ code: 400, @@ -34,7 +35,7 @@ describe('PUT /user/auth/update-email', () => { }); it('does not change email if wrong password is provided', async () => { - await expect(user.put(endpoint, { + await expect(user.put(ENDPOINT, { newEmail, password: 'wrong password', })).to.eventually.be.rejected.and.eql({ @@ -45,9 +46,9 @@ describe('PUT /user/auth/update-email', () => { }); it('changes email if new email and existing password are provided', async () => { - let response = await user.put(endpoint, { + let response = await user.put(ENDPOINT, { newEmail, - password: thePassword, + password: oldPassword, }); expect(response).to.eql({ email: 'some-new-email_2@example.net' }); @@ -56,16 +57,18 @@ describe('PUT /user/auth/update-email', () => { }); }); - describe('facebook user', async () => { + context('Social Login User', async () => { + let socialUser; + beforeEach(async () => { - fbUser = await generateUser(); - await fbUser.update({ 'auth.local': { ok: true } }); + socialUser = await generateUser(); + await socialUser.update({ 'auth.local': { ok: true } }); }); it('does not change email if user.auth.local.email does not exist for this user', async () => { - await expect(fbUser.put(endpoint, { + await expect(socialUser.put(ENDPOINT, { newEmail, - password: thePassword, + password: oldPassword, })).to.eventually.be.rejected.and.eql({ code: 400, error: 'BadRequest', diff --git a/test/api/v3/integration/user/auth/PUT-user_update_password.test.js b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js index 3dc4d9dc5d..bcc1ac25d3 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_password.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js @@ -3,10 +3,11 @@ import { translate as t, } from '../../../../../helpers/api-v3-integration.helper'; +const ENDPOINT = '/user/auth/update-password'; + describe('PUT /user/auth/update-password', async () => { - let endpoint = '/user/auth/update-password'; let user; - let password = 'password'; + let password = 'password'; // from habitrpg/test/helpers/api-integration/v3/object-generators.js let wrongPassword = 'wrong-password'; let newPassword = 'new-password'; @@ -16,7 +17,7 @@ describe('PUT /user/auth/update-password', async () => { it('successfully changes the password', async () => { let previousHashedPassword = user.auth.local.hashed_password; - let response = await user.put(endpoint, { + let response = await user.put(ENDPOINT, { password, newPassword, confirmPassword: newPassword, @@ -26,8 +27,8 @@ describe('PUT /user/auth/update-password', async () => { expect(user.auth.local.hashed_password).to.not.eql(previousHashedPassword); }); - it('new passwords mismatch', async () => { - await expect(user.put(endpoint, { + it('returns an error when confirmPassword does not match newPassword', async () => { + await expect(user.put(ENDPOINT, { password, newPassword, confirmPassword: `${newPassword}-wrong-confirmation`, @@ -38,8 +39,8 @@ describe('PUT /user/auth/update-password', async () => { }); }); - it('existing password is wrong', async () => { - await expect(user.put(endpoint, { + it('returns an error when existing password is wrong', async () => { + await expect(user.put(ENDPOINT, { password: wrongPassword, newPassword, confirmPassword: newPassword, diff --git a/test/api/v3/integration/user/auth/PUT-user_update_username.test.js b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js index fc308f4cc1..c61e85ab1e 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_username.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js @@ -3,20 +3,19 @@ import { translate as t, } from '../../../../../helpers/api-v3-integration.helper'; +const ENDPOINT = '/user/auth/update-username'; + describe('PUT /user/auth/update-username', async () => { - let endpoint = '/user/auth/update-username'; let user; let newUsername = 'new-username'; - let existingUsername = 'existing-username'; let password = 'password'; // from habitrpg/test/helpers/api-integration/v3/object-generators.js - let wrongPassword = 'wrong-password'; beforeEach(async () => { user = await generateUser(); }); it('successfully changes username', async () => { - let response = await user.put(endpoint, { + let response = await user.put(ENDPOINT, { username: newUsername, password, }); @@ -26,28 +25,24 @@ describe('PUT /user/auth/update-username', async () => { }); context('errors', async () => { - describe('new username is unavailable', async () => { - beforeEach(async () => { - user = await generateUser(); - await user.update({'auth.local.username': existingUsername, 'auth.local.lowerCaseUsername': existingUsername }); - }); + it('prevents username update if new username is already taken', async () => { + let existingUsername = 'existing-username'; + await generateUser({'auth.local.username': existingUsername, 'auth.local.lowerCaseUsername': existingUsername }); - it('prevents username update', async () => { - await expect(user.put(endpoint, { - username: existingUsername, - password, - })).to.eventually.be.rejected.and.eql({ - code: 400, - error: 'BadRequest', - message: t('usernameTaken'), - }); + await expect(user.put(ENDPOINT, { + username: existingUsername, + password, + })).to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('usernameTaken'), }); }); - it('password is wrong', async () => { - await expect(user.put(endpoint, { + it('errors if password is wrong', async () => { + await expect(user.put(ENDPOINT, { username: newUsername, - password: wrongPassword, + password: 'wrong-password', })).to.eventually.be.rejected.and.eql({ code: 401, error: 'NotAuthorized', @@ -55,26 +50,22 @@ describe('PUT /user/auth/update-username', async () => { }); }); - describe('social-only user', async () => { - beforeEach(async () => { - user = await generateUser(); - await user.update({ 'auth.local': { ok: true } }); - }); - it('prevents username update', async () => { - await expect(user.put(endpoint, { - username: newUsername, - password, - })).to.eventually.be.rejected.and.eql({ - code: 400, - error: 'BadRequest', - message: t('userHasNoLocalRegistration'), - }); + it('prevents social-only user from changing username', async () => { + let socialUser = await generateUser({ 'auth.local': { ok: true } }); + + await expect(socialUser.put(ENDPOINT, { + username: newUsername, + password, + })).to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('userHasNoLocalRegistration'), }); }); - it('new username is not provided', async () => { - await expect(user.put(endpoint, { + it('errors if new username is not provided', async () => { + await expect(user.put(ENDPOINT, { password, })).to.eventually.be.rejected.and.eql({ code: 400,