npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

brph-mean-auth

v0.3.1

Published

An auth solution for the MEAN stack.

Downloads

6

Readme

brph-mean-auth v0.3.1

An auth solution for the MEAN stack.

This module is an attempt at managing authentication and authorization of users in single-page apps using M ongoDB (specifically, mongoose), E xpress, and A ngular on top of N ode.

Usage

meanAuth always returns the following object:

{
  passport: ...     //The configured passport instance; exposed for further configuration
  router: ...       //See "API Endpoints" below,
  authenticate: ... //See "The Authenticate Middleware" below
}

For example:

var express = require('express'),
  mongoose = require('mongoose'),
  meanAuth = require('brph-mean-auth-server');

var app = express();

// Setup mongoose models, express routes, etc. here

//Instantiate meanAuth with the already configured User model
var auth = meanAuth(mongoose.model('User'));

//Mount the auth router on /auth
app.use('/auth', auth.router);

//In order to make any requests to /members/*, a user must be authenticated
app.use('/members', auth.authenticate, function(req, res, next){ ... });

brph-mean-auth also serves an angular module you can use on the client side to more easily interact with the API. Using the example configuration above:

<script type="text/javascript" src="/auth/angular-brph-mean-auth.js"></script>
<script>
    angular.module('myapp', ['brph.mean-auth'])
      .config(function(MeanAuthServiceProvider){
      
        //Tell the service where you mounted `meanAuth.router`
        MeanAuthServiceProvider.setPath('/auth');
        
      })
      .controller('MyAccountController', function($scope, MeanAuthService){
      
        console.log(MeanAuthService.user); // false
        MeanAuthService.login('[email protected]', 'password123#', function(){
            console.log(MeanAuthService.user); // {_id: '...', local: {...}} 
        });
      
      });
</script>

See "The Angular Module" below for details.

Parameters

meanAuth takes 3 parameters:

| Parameter | Required | Description | | --------- | -------- | ----------- | | User | Yes | The mongoose model used for users. See The Database Model below. | | passport | No | The app's current instance of Passport.JS. This must only be supplied if you have custom passport strategies already configured. If this is not supplied, meanAuth will initialize its own isntance of passport. | | options | No | Various configuration options to control meanAuth's behavior. See Options below |

Options

You can optionally pass an options object as the third parameter passed to meanAuth. Here are all possible options and their defaults:

var defaults = {
  local: {
    fields: {}                  //See "Custom Fields" below
  },
  tokenBytes: 24,               //The size of the token in bytes before it's converted to a hex string
  tokenTTL: 1000*60*60*24*14    //The number of milliseconds that generated tokens should remain valid
};

The options object is broken down into a local set of options to allow for future support of other non-local auth strategies.

The Authenticate Middleware

In order to protect your own custom API endpoints, auth.authenticate is exposed. It's standard express middleware that will only allow requests accomodated with a valid login token proceed down the middleware chain. See the usage example above.

The Database Model

meanAuth requires that it be passed the mongoose (or mongoose-like) model so that it doesn't have to instatiate its own instance of mongoose which would contain seperate models than that of the express app it's running on. Unfortunately, it also makes a few assumptions about the structure and interface of said model. The schema for the model must contain the following fields/paths at a minimum:

{
  local: {
    email: String,
    password: String,
    token: {
      value: String,
      expires: Number
    }
  }
}

The purpose of isolating these paths in a subdocument called local is so that in the future, meanAuth can support other auth strategies such as Facebook or Google. Currently, that effort is left up to the developer.

Custom Fields

You are not, however, limited to only storing the user's email and password on signup. To define how the meanAuth is to handle/store other paths available on your model's schema, use the local.fields configuration option. This option should be an object who's keys are paths on the database model and values are objects which define how that path is handled.

These objects can have any of these fields:

| Field | Type | Description | Default | | ----- | ---- | ----------- | ------- | | required | Boolean | Whether or not this field is required | true | | param | String | The name of the HTTP POST parameter that this path should get its value from during /signup | Same as schema path. | | beforeSave | Function | Whatever this function returns, if provided, is saved to the database during /signup. It is passed only the data from the HTTP POST parameter. | function(value){return value;} |

For example:

//I've already defined my app and User model
app.use(meanAuth(User, passport, {
  local: {
    fields: {
      'local.first_name': {
        required: false,
        param: 'fname'
      },
      'local.last_name': {
        required: false,
        param: 'lname'
      },
      'local.weight': {
        required: true,
        param: 'weight',
        beforeSave: function(weight){
          return parseFloat(weight);
        }
      }
    }
  }
}));

API Endpoints

The Router returned by auth.router exposes a few API endpoints that can be used to handle users within the app:

| Endpoint | Method | Description | Input Parameters | | -------- | ------ | ----------- | ---------------- | | /signup | POST | Create a new user | email and password are required but additional fields can be defined. See Custom Fields above. | | /login | POST | Authenticate an existing user by email+password | email and password only | | /logout | POST | Invalidates the user's login token | token | | /check | POST | Authenticate an existing user by token | token |

Responses

/signup, /login, and /check, if successful, respond with a JSON object such as the following:

{
  status: 'ok',
  token: [Valid token],
  user: [User from database]
}

/logout responds simply with:

{status:'ok'}

The user object pulled from the database has its local.password field set to false for security purposes.

Errors

If any of these encounter a handle-able, auth-related error, they will return the following object at a minimum:

{status:'error', error:'Error Message'}

In addition, if there are any fields relevant to the error, their param names (see "Custom Fields" above) will be passed back alongside the error message in the fields array. For example, if the /login endpoint is hit with a mismatched/incorrect email+password pair, it will return the following:

{
  status: 'error',
  error: 'A user does not exist with that email/password.',
  fields: ['email', 'password']
}

Or, considering the custom fields example above, the /signup endpoint will respond with the following if the user did not supply their weight (which was a custom field marked as required):

{
  status: 'error',
  error: 'Missing one or more required fields.',
  fields: ['weight']
}

The Angular Module

As demonstrated, brph-mean-auth also serves an angular module brph.mean-auth in addition to the API Endpoints available. Included in the module is one service (w/ accompanying provider) that will allow easy interaction with the API Endpoints, hold onto the user data/token, and persist the userdata/token using cookies.

Note: The ngCookies module is a dependency of the brph.mean-auth module, so ensure that it's included along with the angular core.

Configuration

Use the provider during the config phase to configure the service (all possible config options shown w/ defaults):

angular.module('myApp', []).config(function(MeanAuthServiceProvider){
  //Set the path to where `meanAuth.router` was mounted on the server
  MeanAuthServiceProvider.setPath('/');
});

Properties

String MeanAuthService.token

The current logged in user's login token.

When no user is logged in, this is false.

Object<String, String> MeanAuthService.user

The database object of the current logged in user with sensitive information obscured.

When no user is logged in, this is false.

Methods

MeanAuthService.login(Object<String, String> loginInfo, Function success, Function error)

Log in a user with an email and a password. loginInfo must be an object with string properties username and password.

success and error are called when the login request is successful or problematic, respectively. They are both passed directly to the $http service's success and error shortcut promise methods (see "General Usage" in the $http documentation).

Sets MeanAuthService.user to the user's database object with sensitive info obscured and MeanAuthService.token to the user's valid login token.

Returns the $http promise.

MeanAuthService.logout(Function done)

Logs out the current user by invalidating their login token.

done is called after the token is invalidated.

Sets both MeanAuthService.user and MeanAuthService.token to false.

Returns the $http promise.

MeanAuthService.signup(Object<String, String> userInfo, Function success, Function error)

Creates a new user from userInfo. userInfo must contain at least username, password, and all of the required fields passed to meanAuth on the server side (See Custom Fields).

Otherwise, behaves the same as MeanAuthService.login.

MeanAuthService.runAsUser(Function func)

Queue func to be ran as soon as a user is logged in. If a user is currently logged in when this function is called, func will be called immediately. func is passed MeanAuthService.user.

TODO

  • [ ] Move errors object into config so that error messages can be extended by developer
  • [ ] /destory endpoint
  • [ ] Flexible, configurable model paths so that the developer doesn't have to stick to a specific db model structure
  • [ ] More callbacks/event-handlers for further expandability
  • [ ] Promise API for Angular Service
  • [ ] Privileges system
  • [ ] Concurrent logins (by allowing users to posess more than one valid token)
  • [ ] Give tokens more info (datetime, location, etc.)

Changelog

  • 0.3.0
    • Combined client and server side components into one npm module.
  • 0.3.1
    • Tested. Working.