Code Snippets: Part 3

Now that b4YouGo has been launched, it’s time for my next project. As a result of this new endeavour, I’ll be learning much more about developing on Meteor.

1. Setting up an accounts system

An accounts system can be complicated, but it needn’t be. By installing the following packages, I was able to get up and running pretty fast (with some tweaking, see below):

accounts-password

useraccounts:foundation

useraccounts:core

useraccounts:core is actually a dependency that will get automatically downloaded when you install the useraccounts:foundation package, but due to some of the tweaking I had to do, I had to download it as a custom package.

Templates

At the minimum, you’ll need to create a login and registration template. And if you are doing a webapp, I suggest also a dashboard (or home) template so that your logged-in users can get redirected there instead of your main landing page.

In your login template, make sure you have this:

{{>atFormstate='signIn'}}

In your registration template, make sure you have this:

{{>atFormstate='signUp'}}

In the nav bar, if you want a smart sign-in/sign-out button, then you’ll need to add this:

{{>atNavButton}}

Routing

Great, now comes the hard part. We have to set up the actual routes like this in our router.js:

Notice that I make use of an AccountsTemplates.ensureSignedIn function hook to make sure the user is signed in before being able to access the dashboard.

Tweaking the packages

As of 2015-01-31, there seems to be something odd in the useraccounts:core package that prevents the navbar login/logout button from finding the correct sign-in link. As a result, in the at_nav_button.js template helper file, I replaced that particular line with AccountsTemplates.linkClick("signIn");. See example below:

AT.prototype.atNavButtonEvents={'click #at-nav-button':function(event){if(Meteor.user())AccountsTemplates.logout();elseAccountsTemplates.linkClick("signIn");// this is correct},};

Another curious thing about the nav button template is that it (by default) comes wrapped in an <li> element. To see what I mean, take a look at at_nav_button.html inside the useraccounts:foundation package. I replaced:

This way, I can make sure that it will fit with however I wanted to style the nav bar.

Other settings

There will likely be other settings you’ll want to set. For that, you should create an accounts.js file in the server folder. Then, you can have a look at what the documentation says here about what options you have.

2. Getting email verification up and running

1. Install the email package

This is pretty self-explanatory, but I also recommend that you add the houston admin console so you can easily check to see if your user’s e-mails are verified. This step would just require you to type the following into the command line:

meteor add email houston:admin

2. Acquiring an SMTP Server

For this step, I simply signed up for a free account on mail-gun. There are a lot of options out there, particularly if you don’t mind paying for it. On the free side, there’s mail-gun’s free-level offering which is sufficient for testing at this early stage. Apparently there’s also Gmail’s own SMTP server that you can use for free if you have a Gmail account, but I was not able to get that running. Besides, it was a lot more simple to use mail-gun so I recommend them.

We make sure to only publish the entries where the userId matches the current user’s userId.

Removing Insecure

Run command: meteor remove insecure

This means that we want to set restrictions on who can insert/update/remove items in a collection. First let’s define a function that we can use to make sure the user owns a particular document in the collection:

Now we write allow statements in to let Meteor know under what circumstances the insert/update/remove functions are allowed:

// lib/collections/dailyEntries.jsDailyEntries.allow({// only allow insertion if you are logged ininsert:function(userId,doc){return!!userId;},// only allow update/remove if the user owns the documentupdate:function(userId,doc){returnownsDocument(userId,doc);},remove:function(userId,doc){returnownsDocument(userId,doc);},});