Skip to content

Commit 51224ed

Browse files
committed
Implement and test sending of signup email
1 parent 4a53faa commit 51224ed

File tree

5 files changed

+58
-22
lines changed

5 files changed

+58
-22
lines changed

spec/ParseUser.spec.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,40 @@ describe('Parse.User testing', () => {
4747
});
4848
});
4949

50+
it('sends verification email if email verification is enabled', done => {
51+
var emailAdapter = {
52+
sendVerificationEmail: () => Promise.resolve()
53+
}
54+
setServerConfiguration({
55+
serverURL: 'http://localhost:8378/1',
56+
appId: 'test',
57+
appName: 'unused',
58+
javascriptKey: 'test',
59+
dotNetKey: 'windows',
60+
clientKey: 'client',
61+
restAPIKey: 'rest',
62+
masterKey: 'test',
63+
collectionPrefix: 'test_',
64+
fileKey: 'test',
65+
verifyUserEmails: true,
66+
emailAdapter: emailAdapter,
67+
});
68+
spyOn(emailAdapter, 'sendVerificationEmail');
69+
var user = new Parse.User();
70+
user.setPassword("asdf");
71+
user.setUsername("zxcv");
72+
user.signUp(null, {
73+
success: function(user) {
74+
expect(emailAdapter.sendVerificationEmail).toHaveBeenCalled();
75+
done();
76+
},
77+
error: function(userAgain, error) {
78+
fail('Failed to save user');
79+
done();
80+
}
81+
});
82+
});
83+
5084
it("user login wrong username", (done) => {
5185
Parse.User.signUp("asdf", "zxcv", null, {
5286
success: function(user) {
@@ -1628,7 +1662,7 @@ describe('Parse.User testing', () => {
16281662
done();
16291663
});
16301664
});
1631-
1665+
16321666
it('test parse user become', (done) => {
16331667
var sessionToken = null;
16341668
Parse.Promise.as().then(function() {

src/Adapters/Email/SimpleMailgunAdapter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default (mailgunOptions) => {
2828
"You are being asked to confirm the e-mail address " + user.email + " with " + appName + "\n\n" +
2929
"" +
3030
"Click here to confirm it:\n" + link;
31-
sendMail(user.email, 'Please verify your e-mail for ' + appName, verifyMessage);
31+
return sendMail(user.email, 'Please verify your e-mail for ' + appName, verifyMessage);
3232
}
3333
}
3434
}

src/RestWrite.js

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ RestWrite.prototype.transformUser = function() {
406406
}
407407
if (this.config.verifyUserEmails && this.data.email) {
408408
this.data.emailVerified = false;
409-
this.data._email_verify_token = cryptoUtils.randomString(25);
410409
this.data._perishable_token = cryptoUtils.randomString(25);
411410
}
412411
return Promise.resolve();
@@ -721,23 +720,10 @@ RestWrite.prototype.runDatabaseOperation = function() {
721720
throw new Parse.Error(Parse.Error.INVALID_ACL, 'Invalid ACL.');
722721
}
723722

724-
function sendEmailVerification() {
725-
var hasUserEmail = typeof this.data.email !== 'undefined' && this.className === "_User";
726-
if (hasUserEmail && this.config.verifyUserEmails) {
727-
let link = this.config.mount + "/verify_email?token=" + encodeURIComponent(this.data._email_verify_token) + "&username=" + encodeURIComponent(this.data.username);
728-
this.config.emailAdapter.sendVerificationEmail({
729-
link: link,
730-
user: this.auth.user,
731-
appName: this.co.appName,
732-
});
733-
}
734-
}
735-
736723
if (this.query) {
737724
// Run an update
738725
return this.config.database.update(
739726
this.className, this.query, this.data, this.runOptions).then((resp) => {
740-
sendEmailVerification.call(this);
741727
this.response = resp;
742728
this.response.updatedAt = this.updatedAt;
743729
});
@@ -751,9 +737,6 @@ RestWrite.prototype.runDatabaseOperation = function() {
751737
}
752738
// Run a create
753739
return this.config.database.create(this.className, this.data, this.runOptions)
754-
.then(() => {
755-
sendEmailVerification.call(this);
756-
})
757740
.then(() => {
758741
var resp = {
759742
objectId: this.data.objectId,

src/Routers/UsersRouter.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import rest from '../rest';
88
import Auth from '../Auth';
99
import passwordCrypto from '../password';
1010
import RestWrite from '../RestWrite';
11-
import { newToken } from '../cryptoUtils';
11+
let cryptoUtils = require('../cryptoUtils');
1212

1313
export class UsersRouter extends ClassesRouter {
1414
handleFind(req) {
@@ -25,7 +25,25 @@ export class UsersRouter extends ClassesRouter {
2525
let data = deepcopy(req.body);
2626
req.body = data;
2727
req.params.className = '_User';
28-
return super.handleCreate(req);
28+
29+
if (req.config.verifyUserEmails) {
30+
req.body._email_verify_token = cryptoUtils.randomString(25);
31+
}
32+
33+
let p = super.handleCreate(req);
34+
35+
if (req.config.verifyUserEmails) {
36+
// Send email as fire-and-forget once the user makes it into the DB.
37+
p.then(() => {
38+
let link = req.config.mount + "/verify_email?token=" + encodeURIComponent(req.body._email_verify_token) + "&username=" + encodeURIComponent(req.body.username);
39+
req.config.emailAdapter.sendVerificationEmail({
40+
appName: req.config.appName,
41+
link: link,
42+
user: req.auth.user,
43+
});
44+
});
45+
}
46+
return p;
2947
}
3048

3149
handleUpdate(req) {
@@ -84,7 +102,7 @@ export class UsersRouter extends ClassesRouter {
84102
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid username/password.');
85103
}
86104

87-
let token = 'r:' + newToken();
105+
let token = 'r:' + cryptoUtils.newToken();
88106
user.sessionToken = token;
89107
delete user.password;
90108

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ function ParseServer({
146146
enableAnonymousUsers: enableAnonymousUsers,
147147
oauth: oauth,
148148
verifyUserEmails: verifyUserEmails,
149+
emailAdapter: emailAdapter,
149150
};
150151

151152
// To maintain compatibility. TODO: Remove in v2.1

0 commit comments

Comments
 (0)