diff --git a/packages/accounts-passwords/email_tests.js b/packages/accounts-passwords/email_tests.js index f6634bebb0..92c1dbad70 100644 --- a/packages/accounts-passwords/email_tests.js +++ b/packages/accounts-passwords/email_tests.js @@ -27,8 +27,8 @@ function (test, expect) { Meteor.call("getInterceptedEmails", email1, expect(function (error, result) { test.notEqual(result, undefined); - test.equal(result.length, 1); - var content = result[0]; + test.equal(result.length, 2); // the first is the email validation + var content = result[1]; var match = content.match( new RegExp(window.location.protocol + "//" + @@ -82,7 +82,7 @@ email2 = Meteor.uuid() + "-intercept@example.com"; email3 = Meteor.uuid() + "-intercept@example.com"; Meteor.createUser( - {email: email2, password: 'foobar', validation: true}, + {email: email2, password: 'foobar'}, expect(function (error) { test.equal(error, undefined); })); @@ -109,7 +109,6 @@ function (test, expect) { Meteor.call( "addEmailForTestAndValidate", email3, - window.location.protocol + "//" + window.location.host + "/" /*appBaseUrl*/, expect(function (error, result) { test.isFalse(error); })); diff --git a/packages/accounts-passwords/email_tests_setup.js b/packages/accounts-passwords/email_tests_setup.js index 78346f63e7..09ff7dc139 100644 --- a/packages/accounts-passwords/email_tests_setup.js +++ b/packages/accounts-passwords/email_tests_setup.js @@ -23,11 +23,11 @@ return interceptedEmails[email]; }, - addEmailForTestAndValidate: function (email, appBaseUrl) { + addEmailForTestAndValidate: function (email) { Meteor.users.update( {_id: this.userId()}, {$push: {emails: {email: email, validated: false}}}); - Meteor.accounts.sendValidationEmail(this.userId(), email, appBaseUrl); + Meteor.accounts.sendValidationEmail(this.userId(), email); }, createUserOnServer: function (email) { diff --git a/packages/accounts-passwords/passwords_client.js b/packages/accounts-passwords/passwords_client.js index 4c676f7b43..36af1955fe 100644 --- a/packages/accounts-passwords/passwords_client.js +++ b/packages/accounts-passwords/passwords_client.js @@ -14,10 +14,6 @@ delete options.password; options.srp = verifier; - if (options.validation) - // needed because we generate a link back to the app - options.baseUrl = appBaseUrl(); - Meteor.apply('createUser', [options, extra], {wait: true}, function (error, result) { if (error || !result) { @@ -138,8 +134,6 @@ Meteor.forgotPassword = function(options, callback) { if (!options.email) throw new Error("Must pass options.email"); - // needed because we generate a link back to the app - options.baseUrl = appBaseUrl(); Meteor.call("forgotPassword", options, callback); }; @@ -215,9 +209,5 @@ callback && callback(); }); }; - - var appBaseUrl = function () { - return window.location.protocol + "//" + window.location.host + "/"; - }; })(); diff --git a/packages/accounts-passwords/passwords_server.js b/packages/accounts-passwords/passwords_server.js index 9340de71f4..7d5a2c37a1 100644 --- a/packages/accounts-passwords/passwords_server.js +++ b/packages/accounts-passwords/passwords_server.js @@ -106,11 +106,8 @@ forgotPassword: function (options) { var email = options.email; - var baseUrl = options.baseUrl; - if (!email) + if (!email) throw new Meteor.Error(400, "Need to set options.email"); - if (!baseUrl) - throw new Meteor.Error(400, "Need to set options.baseUrl"); var user = Meteor.users.findOne({"emails.email": email}); if (!user) @@ -126,7 +123,7 @@ }}); // XXX definitely *not* the final form! - Meteor.mail.send(email, Meteor.accounts.urls.resetPassword(baseUrl, token)); + Meteor.mail.send(email, Meteor.accounts.urls.resetPassword(token)); }, resetPassword: function (token, newVerifier) { @@ -197,7 +194,7 @@ // send the user an email with a link that when opened marks that // address as validated - Meteor.accounts.sendValidationEmail = function (userId, email, appBaseUrl) { + Meteor.accounts.sendValidationEmail = function (userId, email) { var token = Meteor.uuid(); var creationTime = +(new Date); Meteor.accounts._emailValidationTokens.insert({ @@ -212,13 +209,13 @@ // this account. Meteor.mail.send( email, - Meteor.accounts.urls.validateEmail(appBaseUrl, token)); + Meteor.accounts.urls.validateEmail(token)); }; // send the user an email informing them that their account was // created, with a link that when opened both marks their email as // validated and forces them to choose their password - Meteor.accounts.sendEnrollmentEmail = function (userId, email, appBaseUrl) { + Meteor.accounts.sendEnrollmentEmail = function (userId, email) { var token = Meteor.uuid(); var creationTime = +(new Date); Meteor.users.update(userId, {$set: { @@ -230,7 +227,7 @@ Meteor.mail.send( email, - Meteor.accounts.urls.enrollAccount(appBaseUrl, token)); + Meteor.accounts.urls.enrollAccount(token)); }; // handler to login with password @@ -310,12 +307,6 @@ if (!username && !email) throw new Meteor.Error(400, "Need to set a username or email"); - // XXX need to get base url on the server somehow, for welcome - // emails at least. - if (options.validation && !options.baseUrl) - throw new Meteor.Error( - 400, "If options.validation is set, need to pass options.baseUrl"); - if (username && Meteor.users.findOne({username: username})) throw new Meteor.Error(403, "User already exists with username " + username); if (email && Meteor.users.findOne({"emails.email": email})) { @@ -341,12 +332,6 @@ user = Meteor.accounts.onCreateUserHook(options, extra, user); var userId = Meteor.users.insert(user); - - // If `options.validation` is set, register a token to validate - // the user's primary email, and send it to that address. - if (email && options.validation) - Meteor.accounts.sendValidationEmail(userId, email, options.baseUrl); - return userId; }; @@ -362,6 +347,12 @@ if (!userId) throw new Error("createUser failed to insert new user"); + // If `Meteor.accounts._options.validateEmails` is set, register + // a token to validate the user's primary email, and send it to + // that address. + if (options.email && Meteor.accounts._options.validateEmails) + Meteor.accounts.sendValidationEmail(userId, options.email); + // client gets logged in as the new user afterwards. var loginToken = Meteor.accounts._loginTokens.insert({userId: userId}); this.setUserId(userId); @@ -393,13 +384,9 @@ if (!options.email) throw new Error("Meteor.createUser on the server requires email."); - // XXX we don't have a base url, so we don't know how to generate links. - if (options.validation) - throw new Error("Validation email from server not supported yet."); var userId = createUser(options, extra); - /// XXX replace with real root url! - Meteor.accounts.sendEnrollmentEmail(userId, options.email, 'http://localhost:3000/'); + Meteor.accounts.sendEnrollmentEmail(userId, options.email); return userId; }; diff --git a/packages/accounts-passwords/passwords_tests.js b/packages/accounts-passwords/passwords_tests.js index 5981fca7fd..a9e5f33c9a 100644 --- a/packages/accounts-passwords/passwords_tests.js +++ b/packages/accounts-passwords/passwords_tests.js @@ -6,7 +6,8 @@ if (Meteor.is_client) (function () { var username = Meteor.uuid(); var username2 = Meteor.uuid(); var username3 = Meteor.uuid(); - var email = Meteor.uuid() + '@example.com'; + // use -intercept so that we don't print to the console + var email = Meteor.uuid() + '-intercept@example.com'; var password = 'password'; var password2 = 'password2'; var password3 = 'password3'; diff --git a/packages/accounts-passwords/passwords_tests_setup.js b/packages/accounts-passwords/passwords_tests_setup.js index 1fdf3ca4f2..858e0667c4 100644 --- a/packages/accounts-passwords/passwords_tests_setup.js +++ b/packages/accounts-passwords/passwords_tests_setup.js @@ -29,5 +29,6 @@ Meteor.accounts.config({ // The 'accounts - updateOrCreateUser' test needs accounts without // usernames or emails, so we can't test with these on. requireEmail: false, - requireUsername: false + requireUsername: false, + validateEmails: true }); diff --git a/packages/accounts-urls/package.js b/packages/accounts-urls/package.js index 71e31e66dd..3f84ec6f57 100644 --- a/packages/accounts-urls/package.js +++ b/packages/accounts-urls/package.js @@ -4,6 +4,7 @@ Package.describe({ }); Package.on_use(function (api) { + api.use('absolute-url', 'server'); api.add_files('url_client.js', 'client'); api.add_files('url_server.js', 'server'); }); diff --git a/packages/accounts-urls/url_server.js b/packages/accounts-urls/url_server.js index 8b12673611..2b8e991a58 100644 --- a/packages/accounts-urls/url_server.js +++ b/packages/accounts-urls/url_server.js @@ -4,14 +4,14 @@ if (!Meteor.accounts) if (!Meteor.accounts.urls) Meteor.accounts.urls = {}; -Meteor.accounts.urls.resetPassword = function (baseUrl, token) { - return baseUrl + '#?reset-password/' + token; +Meteor.accounts.urls.resetPassword = function (token) { + return Meteor.absoluteUrl('#?reset-password/' + token); }; -Meteor.accounts.urls.validateEmail = function (baseUrl, token) { - return baseUrl + '#?validate-email/' + token; +Meteor.accounts.urls.validateEmail = function (token) { + return Meteor.absoluteUrl('#?validate-email/' + token); }; -Meteor.accounts.urls.enrollAccount = function (baseUrl, token) { - return baseUrl + '#?enroll-account/' + token; +Meteor.accounts.urls.enrollAccount = function (token) { + return Meteor.absoluteUrl('#?enroll-account/' + token); }; diff --git a/packages/accounts/accounts_common.js b/packages/accounts/accounts_common.js index 8472e90dfe..1b5e335d5a 100644 --- a/packages/accounts/accounts_common.js +++ b/packages/accounts/accounts_common.js @@ -10,8 +10,8 @@ if (!Meteor.accounts._options) { // - unsafePasswordChanges {Boolean} allow changing password without the old one // - requireEmail {Boolean} // - requireUsername {Boolean} -// - validateEmail {Boolean} Send validation emails to all new users -// via the signup form +// - validateEmails {Boolean} Send validation emails to all new users +// via the signup form Meteor.accounts.config = function(options) { Meteor.accounts._options = options; };