From b5350d10eb3c3b13058c389a6d190fba589f8b7f Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 18 Sep 2016 17:02:05 -0400 Subject: [PATCH 1/3] Lookup for email in username field to match docs if email is undefined --- spec/MockEmailAdapterWithOptions.js | 14 +++++++++- spec/ValidationAndPasswordsReset.spec.js | 35 ++++++++++++++++++++++++ src/Controllers/UserController.js | 2 +- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/spec/MockEmailAdapterWithOptions.js b/spec/MockEmailAdapterWithOptions.js index 8a3095e21f..b9660363c2 100644 --- a/spec/MockEmailAdapterWithOptions.js +++ b/spec/MockEmailAdapterWithOptions.js @@ -2,9 +2,21 @@ module.exports = options => { if (!options) { throw "Options were not provided" } - return { + let adapter = { sendVerificationEmail: () => Promise.resolve(), sendPasswordResetEmail: () => Promise.resolve(), sendMail: () => Promise.resolve() + }; + if (options.sendMail) { + adapter.sendMail = options.sendMail } + if (options.sendPasswordResetEmail) { + adapter.sendPasswordResetEmail = options.sendPasswordResetEmail + } + if (options.sendVerificationEmail) { + adapter.sendVerificationEmail = options.sendVerificationEmail; + } + + + return adapter; } diff --git a/spec/ValidationAndPasswordsReset.spec.js b/spec/ValidationAndPasswordsReset.spec.js index e959f493de..c6aa364ca7 100644 --- a/spec/ValidationAndPasswordsReset.spec.js +++ b/spec/ValidationAndPasswordsReset.spec.js @@ -479,6 +479,41 @@ describe("Custom Pages, Email Verification, Password Reset", () => { }); }); + it('succeeds sending a password reset username if appName, publicServerURL, and email adapter are prodvided', done => { + let adapter = MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + sendPasswordResetEmail: function(options) { + expect(options.user.get('username').toEqual('testValidConfig@parse.com')); + return Promise.resolve(); + } + }); + spyOn(adapter, 'sendPasswordResetEmail').and.callThrough(); + reconfigureServer({ + appName: 'coolapp', + publicServerURL: 'http://localhost:1337/1', + emailAdapter: adapter + }) + .then(() => { + let user = new Parse.User(); + user.setPassword("asdf"); + user.setUsername("testValidConfig@parse.com"); + user.signUp(null) + .then(user => Parse.User.requestPasswordReset("testValidConfig@parse.com")) + .then(result => { + expect(adapter.sendPasswordResetEmail).toHaveBeenCalled(); + done(); + }, error => { + done(error); + }); + }) + .catch(error => { + fail(JSON.stringify(error)); + done(); + }); + }); + it('does not send verification email if email verification is disabled', done => { var emailAdapter = { sendVerificationEmail: () => Promise.resolve(), diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index a5f01e3f34..2514f502dd 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -125,7 +125,7 @@ export class UserController extends AdaptableController { } setPasswordResetToken(email) { - return this.config.database.update('_User', { email }, { _perishable_token: randomString(25) }, {}, true) + return this.config.database.update('_User', { $or: [{email}, {username: email, email: undefined}] }, { _perishable_token: randomString(25) }, {}, true) } sendPasswordResetEmail(email) { From 6b0cc86b02dc450ef259bf101aeae96100c69891 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 18 Sep 2016 17:07:25 -0400 Subject: [PATCH 2/3] Adds support for sendMail option to when email is selected --- spec/MockEmailAdapterWithOptions.js | 1 - spec/ValidationAndPasswordsReset.spec.js | 12 ++++++++---- src/Controllers/UserController.js | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/spec/MockEmailAdapterWithOptions.js b/spec/MockEmailAdapterWithOptions.js index b9660363c2..c8b217129a 100644 --- a/spec/MockEmailAdapterWithOptions.js +++ b/spec/MockEmailAdapterWithOptions.js @@ -17,6 +17,5 @@ module.exports = options => { adapter.sendVerificationEmail = options.sendVerificationEmail; } - return adapter; } diff --git a/spec/ValidationAndPasswordsReset.spec.js b/spec/ValidationAndPasswordsReset.spec.js index c6aa364ca7..62ed514e05 100644 --- a/spec/ValidationAndPasswordsReset.spec.js +++ b/spec/ValidationAndPasswordsReset.spec.js @@ -484,12 +484,16 @@ describe("Custom Pages, Email Verification, Password Reset", () => { fromAddress: 'parse@example.com', apiKey: 'k', domain: 'd', - sendPasswordResetEmail: function(options) { - expect(options.user.get('username').toEqual('testValidConfig@parse.com')); + sendMail: function(options) { + expect(options.to).toEqual('testValidConfig@parse.com'); return Promise.resolve(); } }); - spyOn(adapter, 'sendPasswordResetEmail').and.callThrough(); + + // delete that handler to force using the default + delete adapter.sendPasswordResetEmail; + + spyOn(adapter, 'sendMail').and.callThrough(); reconfigureServer({ appName: 'coolapp', publicServerURL: 'http://localhost:1337/1', @@ -502,7 +506,7 @@ describe("Custom Pages, Email Verification, Password Reset", () => { user.signUp(null) .then(user => Parse.User.requestPasswordReset("testValidConfig@parse.com")) .then(result => { - expect(adapter.sendPasswordResetEmail).toHaveBeenCalled(); + expect(adapter.sendMail).toHaveBeenCalled(); done(); }, error => { done(error); diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index 2514f502dd..6ef6b5ce06 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -181,7 +181,7 @@ export class UserController extends AdaptableController { "You requested to reset your password for " + appName + ".\n\n" + "" + "Click here to reset it:\n" + link; - let to = user.get("email"); + let to = user.get("email") || user.get('username'); let subject = 'Password Reset for ' + appName; return { text, to, subject }; } From 61e5029c51ba1ad08b67ebf22adab47ad0eb5e07 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 18 Sep 2016 17:46:24 -0400 Subject: [PATCH 3/3] Proper does not exists clause --- src/Controllers/UserController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/UserController.js b/src/Controllers/UserController.js index 6ef6b5ce06..fbdf707a4e 100644 --- a/src/Controllers/UserController.js +++ b/src/Controllers/UserController.js @@ -125,7 +125,7 @@ export class UserController extends AdaptableController { } setPasswordResetToken(email) { - return this.config.database.update('_User', { $or: [{email}, {username: email, email: undefined}] }, { _perishable_token: randomString(25) }, {}, true) + return this.config.database.update('_User', { $or: [{email}, {username: email, email: {$exists: false}}] }, { _perishable_token: randomString(25) }, {}, true) } sendPasswordResetEmail(email) {