diff --git a/spec/MockEmailAdapterWithOptions.js b/spec/MockEmailAdapterWithOptions.js index 8a3095e21f..c8b217129a 100644 --- a/spec/MockEmailAdapterWithOptions.js +++ b/spec/MockEmailAdapterWithOptions.js @@ -2,9 +2,20 @@ 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..62ed514e05 100644 --- a/spec/ValidationAndPasswordsReset.spec.js +++ b/spec/ValidationAndPasswordsReset.spec.js @@ -479,6 +479,45 @@ 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', + sendMail: function(options) { + expect(options.to).toEqual('testValidConfig@parse.com'); + return Promise.resolve(); + } + }); + + // delete that handler to force using the default + delete adapter.sendPasswordResetEmail; + + spyOn(adapter, 'sendMail').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.sendMail).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..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', { email }, { _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) { @@ -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 }; }