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

getapper-hapi-session-mongo

v1.0.0

Published

MongoDB Session Store for Hapijs

Downloads

6

Readme

hapi-session-mongo

hapi MongoDB Session Storage

Install

npm install hapi-session-mongo

Breaking changes from v2 to v3:

All login functions now take a user object as follows {'name': username, 'pwd': password}. loginLocal and loginGithub now take a object that will be the information sealed in the cookie. Say you have a user document:

{
   '_id': 'username',
    'local': {
        'name': 'username',
        'pwd': 'supersecretpassword'
    },
    'data': {
        'firstn': 'John',
        'lastn': 'Doe',
        'phone': '012-345-6789',
        'email': '[email protected]'
    } 
}

and you want to seal name, firstn, and email in the cookie you can create a object:

var seal = {
    'username': 'local.name',
    'name': 'data.firstn',
    'email': 'data.email'
}

the keys can be anything you want to refer to the data by, where the value should be the string literal of the data in the user document. If seal is not passed cookie will just seal username.

Usage

A session store plugin for hapi and MongoDB. Must have database already set up with one user that has readWrite role. All other users in database are just for the challenge-response mechanism and require no roles. Requires options:

  • ip - The IP address of the database. Defaults to 127.0.0.1.
  • port - The port number of the database. Defaults to 27017.
  • db - The name of the database. Defaults to test.
  • collectionName - The name of the collection with users name and password data. Defaults to users.
  • nameField - The name or the path (specified like a pointed string) of the field in the collection to use as the name field. Defaults to local.name.
  • pwdField - The name or the path (specified like a pointed string) of the field in the collection to use as the password field. Defaults to local.password.
  • name - The name of the user with readWrite. Defaults to undefined.
  • pwd - The password of the user with readWrite, also signs Iron cookie. Defaults to undefined.
  • ssl - MongoDB ssl. Defaults to false.
  • ttl - Time-to-live for Iron cookie. Defaults to 0.

Also exports functions:

  • user.loginCr(user, callback) - Challenge-response user. Callback is (err, cookie).
  • user.loginLocal(user, seal, callback) - User stored as a document. Callback is (err, cookie). Requires a schema of {_id: username, local: {name: username, pwd: password}}. Password must be stored with bcrypt.
  • user.loginGithub(user, seal, callback) - User stored as a document for Github OAuth. Callback is (err, cookie). Requires a schema of {_id: username, github: {name: username, pwd: token}}.
  • req.auth.session.set(session) - Called with login to set server state.
  • user.get(session, callback) - Session is cookie. Callback is (err, valid). to be called with the validateFunc.
  • user.logout = function(cookie, callback) - Callback is (err, removed).
  • req.auth.session.clear() - Called with logout to clear server state.

During the server.auth.strategy phase validateFunc(session, callback) is required.

Example set up:

var Hapi = require('hapi');

var server = Hapi.createServer('127.0.0.1', 3000);

server.pack.register({
    plugin: require('hapi-session-mongo'),
    options: {
        db: 'users',
        name: 'sessionHandler',
        pwd: 'supersecretpassword',
        ssl: true
    }
}, function (err) {
    if (err) { console.log(err); };

    server.auth.strategy('session', 'mongo', {
        validateFunc: function(session, callback) {
            server.plugins['hapi-session-mongo'].user.get(session, function(err, valid) {
                return callback(err, valid);
            });
        }
    });
});

server.route([
    {
        method: 'POST',
        path: '/logincr',
        handler: function (req, res) {
            server.plugins['hapi-session-mongo'].user.loginCr({'name': req.payload.username,
              'pwd': req.payload.password}, function(err, logged) {
                  if (err) {
                      res('Invalid name or password');
                  }

                  req.auth.session.set(logged);
                  res(logged);
            });
        }
    },
    {
        method: 'POST',
        path: '/loginlocal',
        handler: function (req, res) {

            var user = {
                'name': req.payload.username,
                'pwd': req.payload.password
            };

            var seal = {
                'username': 'local.name',
                'name': 'data.firstn',
                'email': 'data.email'
            };

            server.plugins['hapi-session-mongo'].user.loginLocal(user, seal, function(err, logged) {
                  if (err) {
                      res('Invalid name or password');
                  }

                  req.auth.session.set(logged);
                  res(logged);
            });
        }
    },
    {
        method: 'GET',
        path: '/home',
        config: {
            handler: function(req, res) {
                res('You are now logged in');
            },
            auth: 'session'
        }
    },
    {
        method: 'GET',
        path: '/logout',
        config: {
            handler: function(req, res) {
                server.plugins['hapi-session-mongo'].user.logout(req.headers['cookie'],
                function(err, removed) {
                    if (err) {
                        res(err);
                    }

                    req.auth.session.clear();
                    res('logged out');
                });
            },
            auth: 'session'
        }
    }
]);

server.start();

Removing stale sessions

MongoDB 2.2 and above supports doing this via an index, see http://docs.mongodb.org/manual/tutorial/expire-data/ To enable this, run

db.sessions.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

Mongo will now remove all sessions older than an hour (every 60 seconds).

Testing

Tests are ran using npm test and require the env variables:

  • VALID_CRUSER
  • VALID_CRPASS
  • LOCAL_USER
  • LOCAL_PASS
  • INVALID_USER
  • INVALID_PASS
  • DATABASE
  • DB_USER
  • DB_PASS
  • TTL

with optional env variables:

  • SSL

If testing on travis you can edit the env variables in .travis.yml and edit your mongodb setup under ./tests/setup.sh.