Live demo: http://accounts-invite-demo.meteor.com/
Don't you wish you could validate account creation in Meteor more flexibly? accounts-invite
is a login validation extension for Meteor that supports OAuth services, not just accounts-password, and provides basic anonymous account functionality.
All the beta invitation systems for Meteor that I could find (such as this one) make password-based user accounts explicitly. What I wanted was a way for the user to arrive at a special route that allows them to create an account with any service of their choice, including password
. This turns out to be nontrivial because of the limitations of Meteor's built-in validation methods.
What's required is a way to allow Oauth (or accounts-password
) account creation ONLY when we want, i.e. at an acceptInvitation
route with a token, and deny account creation everywhere else, yet still allow registered users to login with the regular login buttons. Meteor's validateLoginAttempt
and validateNewUser
methods are called by the server, which has no way of knowing about your client-side token.
accounts-validate
exposes a special login method (loginWithInvite
) that creates a temporary, anonymous user with a token supplied by your app (i.e. at an acceptInvitation
route). That token can then be verified by login validation callbacks. accounts-invite
depends on these packages:
brettle:accounts-add-service
- Adds a login service to the temporary user accountbrettle:accounts-patch-ui
- Makes loginButtons
act like there isn't a user logged in when the initial, temporary user is createdt3db0t:accounts-multiple
- A fork of [brettle:accounts-multiple
]() that adds an additional callback to handle the case of disallowed logins (noAttemptingUser
)Meteor.loginWithInvite(inviteObject)
(Client)
inviteObject
is an object containing at least a field called inviteToken
inviteToken
can by any string of your choice, i.e. Random.id(n)
validateToken(inviteObject)
(Server)
true
to allow account registrationfalse
to denyonCreatedAccount(attemptingUser, attempt)
(Server)
attemptingUser
, attempt
: same as in brettle:accounts-multiple
, useful for assigning profile name or other infoaccounts-invite
registers a custom login handlerloginWithInvite(token)
is called by host apploginButtons
)accounts-multiple
catches the 'switching' of accounts and calls validateToken()
. If that returns true,accounts-add-service
merges the new service into the existing user recordonCreatedAccount
callback is called so you can, for instance, update an invitation status to "claimed"Accounts.validateNewUser
as normal.Accounts.onLoginFailure
will show some 'failures' as part of the normal operation of this system, due to i.e. brettle:accounts-add-service
. You can safely ignore these.// server
AccountsInvite.register({
validateToken: validateToken,
onCreatedAccount: onCreatedAccount
});
function validateToken(token){
if(InvitesCollection.findOne({"token":token})) return true;
else return false;
}
function onCreatedAccount(token, user){
InvitesCollection.update({"token":token}, {$set:{"status":"claimed"}});
// Here you could also do something like...
// Roles.addUsersToRoles(user._id, ['beta-permissions']);
}
// client
Meteor.loginWithInvite(token);
I'm indebted to brettle
for his help in figuring out how to make this work.