This is a Meteor package which maintains the registered_emails
array field inside the user object up to date with any account service email used by the user to login into the application.
It exploits the onLogin
hook from the Accounts object to check the user object after every successful login and possibly updates the content of its registered_emails
field.
In particular:
- email addresses used with 3rd-party services are added to the
registered_emails
field - email added with
accounts-password
service which are still not validated but appear inside some 3rd-party service as validated are promotes to validated also inside theregistered_emails
field. - emails which do not appear anymore inside some 3rd-party service are deleted from the
registered_emails
field. In case theaccounts-password
service is used, the first email appearing inside the array, which is the one supposed to belong to theaccounts-password
service is anyway preserved insideregistered_emails
!
Having an up-to-date registered_emails
field should permit to find a registered user by any of its email addresses with a simple function like this:
var findUserByEmail = function(emailAddress){
return Meteor.users.findOne({"registered_emails.address": emailAddress});
};
This should, among other things, permit to check whether a newly registered user has already another account for the application. This could happen when different account services are used at the same time (e.g. accounts-password
, accounts-google
, accounts-github
, etc.) and the user don't remember with which service logged in originally. A simple check on the email address could reveal this uncomfortable scenario and permit the application to warn the user or even propose her to merge the two accounts...
meteor add splendido:accounts-emails-field
Nothing to do... just install it and you're ready to go!
The registered_emails
field that is automatically added to Meteor.users
has the same format than the built-in emails
field:
registered_emails: [
{ address: "[email protected]", verified: true },
{ address: "[email protected]", verified: false }
],
If you use aldeed:collection2 on Meteor.users
, you need to add the following field to your schema or you will get a collection2 exception each time a user logs in:
registered_emails: { type: [Object], blackbox: true, optional: true }
The accounts-emails-field
exports an AccountsEmailsField
object which in
turn makes available the following functions on the server only:
-
AccountsEmailsField.getEmailsFromService(serviceName, serviceObj)
: internally used to extract email informations from OAuth service objects to be found into the user object within theservices
field. -
AccountsEmailsField.updateAllUsersEmails()
: handy function to update theregistered_emails
field for all known users at once. Possibly useful for initial database update in case the packge is added to an already existing application. -
AccountsEmailsField.updateEmails({user: user})
: internally used to create/update theregistered_emails
field of a particular user object. Its signature is designed to match the one required for callbacks to be used with Accounts.onLogin (because it's actually used this way...).
If you need to track changes in the registered_emails
field, declare your own onLogin
hook. It will be called after the one set by accounts-emails-field
and will allow you to update whatever data depending on registered_emails
:
Accounts.onLogin(function (info) {
// If login was not successful, quit
if (! info.user)
return;
// Get the user, including the registered_emails field added by the "splendido:accounts-emails-field"
// package. We cannot rely on info.user here, because modifications to the info object are not
// propagated through onLogin callbacks (so info.user.registered_emails might be inexistent or out
// of date)
var user = Meteor.users.findOne(info.user._id, { fields: { registered_emails: 1, ... } });
// Use user.registered_emails here:
...
});
This project is still Work In Progress: any comments, suggestions, testing efforts, and PRs are very very welcome. Please use the repo page for issues, discussions, etc.
In particular it would be very useful to test the package with as many accounts services as possible to confirm it is correctly functioning.
The major question mark is about the name used by each service to provide the email address (so far email
and emailAddressed
were observed) and the presence of a field telling whether the same address was verified or not (so far only for accounts-google a field called verified_email
was found).
service | let non-verified in | email field | email verified field |
---|---|---|---|
X | |||
X | |||
X | X | X | |
github | X | (may be null) | |
X |
See also these lines for more details.
Please try the following:
meteor create test-accounts-emails-field && cd test-accounts-emails-field
meteor add twbs:bootstrap
meteor add ian:accounts-ui-bootstrap-3
meteor add service-configuration
meteor add accounts-YOUR_PREFERRED_SERVICE
meteor add splendido:accounts-emails-field
mkdir server
touch server/accounts.js
Then add the configuration required for your test app registered for the chosen service and finally run the application with:
meteor
Head your browser to localhost:3000
and try to login with your service. After this open the mongo shell with
meteor mongo
from the same app folder but from a different terminal (while the testing app is still running) and type
db.users.find().pretty()
Please try to confirm that the email you used to register to the service was added to the registered_emails
field and try to see if it is marked as verified or not.
In case something is unexpected, please try to see under user.services.YOUR_PREFERRED_SERVICE
which is the name for the email field (if any!) and whether there is another field stating the verified status of the email address (if any...).
In any case, please comment/add an issue having the same name of the service with the test outcome.
Big Tnx in advance to anyone willing to test accounts-emails-field
!!!