t3db0t / meteor-accounts-invite

A login validation extension for Meteor that supports OAuth services
7 stars 1 forks source link

Accounts-Invite

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.

Features

The Problem

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.

The Solution

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:

API

How it works

Example

// 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);

Known Issues

Acknowledgements

I'm indebted to brettle for his help in figuring out how to make this work.