From 862b1e199b0785a8dade9b3ed8bf869fb3ff4d2c Mon Sep 17 00:00:00 2001 From: Anthony Mosca Date: Fri, 31 Mar 2017 11:48:46 +1030 Subject: [PATCH 1/3] Removed hidden keys from users/me. --- src/Routers/UsersRouter.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 39273418b2..0ab0e9e6f8 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -57,6 +57,17 @@ export class UsersRouter extends ClassesRouter { const user = response.results[0].user; // Send token back on the login, because SDKs expect that. user.sessionToken = sessionToken; + + // Remove hidden properties. + for (var key in user) { + if (user.hasOwnProperty(key)) { + // Regexp comes from Parse.Object.prototype.validate + if (key !== "__type" && !(/^[A-Za-z][0-9A-Za-z_]*$/).test(key)) { + delete user[key]; + } + } + } + return { response: user }; } }); From 140272edde76957ca79f733ca9e85c0e71873ff4 Mon Sep 17 00:00:00 2001 From: Anthony Mosca Date: Thu, 13 Apr 2017 10:48:39 +0930 Subject: [PATCH 2/3] Ensured that general users cannot update email verified flag. --- src/RestWrite.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/RestWrite.js b/src/RestWrite.js index 0cdc88bca9..c558a0f806 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -349,6 +349,11 @@ RestWrite.prototype.transformUser = function() { return promise; } + if (!this.auth.isMaster && "emailVerified" in this.data) { + const error = `Clients aren't allowed to manually update email verification.` + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } + if (this.query) { // If we're updating a _User object, we need to clear out the cache for that user. Find all their // session tokens, and remove them from the cache. From c50b34ab010ce43daefad231ff773fc43c053b0f Mon Sep 17 00:00:00 2001 From: Anthony Mosca Date: Thu, 13 Apr 2017 16:49:55 +0930 Subject: [PATCH 3/3] Updated tests to reflect email verification changes. --- spec/ParseUser.spec.js | 117 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 02d90a71dd..5cc85bd128 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -2784,4 +2784,121 @@ describe('Parse.User testing', () => { done(); }); }); + + it('should not allow updates to emailVerified', done => { + var emailAdapter = { + sendVerificationEmail: () => {}, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => Promise.resolve() + } + + const user = new Parse.User(); + user.set({ + username: 'hello', + password: 'world', + email: "test@email.com" + }) + + reconfigureServer({ + appName: 'unused', + verifyUserEmails: true, + emailAdapter: emailAdapter, + publicServerURL: "http://localhost:8378/1" + }).then(() => { + return user.signUp(); + }).then(() => { + return Parse.User.current().set('emailVerified', true).save(); + }).then(() => { + fail("Should not be able to update emailVerified"); + done(); + }).catch((err) => { + expect(err.message).toBe("Clients aren't allowed to manually update email verification."); + done(); + }); + }); + + it('should not retrieve hidden fields', done => { + + var emailAdapter = { + sendVerificationEmail: () => {}, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => Promise.resolve() + } + + const user = new Parse.User(); + user.set({ + username: 'hello', + password: 'world', + email: "test@email.com" + }) + + reconfigureServer({ + appName: 'unused', + verifyUserEmails: true, + emailAdapter: emailAdapter, + publicServerURL: "http://localhost:8378/1" + }).then(() => { + return user.signUp(); + }).then(() => rp({ + method: 'GET', + url: 'http://localhost:8378/1/users/me', + json: true, + headers: { + 'X-Parse-Application-Id': Parse.applicationId, + 'X-Parse-Session-Token': Parse.User.current().getSessionToken(), + 'X-Parse-REST-API-Key': 'rest' + }, + })).then((res) => { + expect(res.emailVerified).toBe(false); + expect(res._email_verify_token).toBeUndefined(); + done() + }).then(() => rp({ + method: 'GET', + url: 'http://localhost:8378/1/users/' + Parse.User.current().id, + json: true, + headers: { + 'X-Parse-Application-Id': Parse.applicationId, + 'X-Parse-REST-API-Key': 'rest' + }, + })).then((res) => { + expect(res.emailVerified).toBe(false); + expect(res._email_verify_token).toBeUndefined(); + done() + }).catch((err) => { + fail(JSON.stringify(err)); + done(); + }); + }); + + it('should not allow updates to hidden fields', done => { + var emailAdapter = { + sendVerificationEmail: () => {}, + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => Promise.resolve() + } + + const user = new Parse.User(); + user.set({ + username: 'hello', + password: 'world', + email: "test@email.com" + }) + + reconfigureServer({ + appName: 'unused', + verifyUserEmails: true, + emailAdapter: emailAdapter, + publicServerURL: "http://localhost:8378/1" + }).then(() => { + return user.signUp(); + }).then(() => { + return Parse.User.current().set('_email_verify_token', 'bad').save(); + }).then(() => { + fail("Should not be able to update email verification token"); + done(); + }).catch((err) => { + expect(err).toBeDefined(); + done(); + }); + }); });