pass-reset

A drop-in password reseting module

npm install pass-reset
10 downloads in the last day
32 downloads in the last week
199 downloads in the last month

pass-reset

An express compatable module for creating RESTful password reset endpoints.

Install

$ npm install pass-reset

Configuration

Example expiration
var passReset = require('pass-reset');

// The unit (second param) can be one of the following (or undefined for milliseconds):
//   "secs", "mins", "hours", "days", or "weeks"
passReset.expireTimeout(12, 'hours');
Example user lookup routine
var passReset = require('pass-reset');

passReset.lookupUsers(function(login, callback) {
    User.find({ username: login }, function(err, users) {
        if (err) {return callback(err);}
        if (! users.length) {return callback(null, false);}
        var user = users[0];
        callback(null, {
            email: user.email,
            users: [{
                id: user.id,
                name: user.username
            }]
        });
    });
});
Example set password routine
var passReset = require('pass-reset');

passReset.setPassword(function(id, password, callback) {
    if (password.length < 8) {
        return callback(null, false, 'Password must be at least 8 characters');
    }
    var hash = doHash(password);
    var update = { $set: { password: hash } };
    User.update({ id: id }, update, { }, function(err) {
        if (err) {return callback(err);}
        callback(null, true);
    });
});
Example send email routine
var passReset = require('pass-reset');

var template = handlebars.compile([
    '<p>You requested a password reset for the following account(s).</p>',
    '<ul>',
    '{{#each resets}}',
        '<li>{{name}}: <a href="{{url}}">{{url}}</a></li>',
    '{{/each}}',
    '</ul>'
].join('\n'));

passReset.sendEmail(function(email, resets, callback) {
    mailer.send({
        to: email,
        from: 'noreply@example.com',
        subject: 'password reset',
        body: template({ resets: resets })
    });
    callback(null, true);
});
Example custom storage for tokens
var passReset  = require('pass-reset');
var redis      = require('redis-url').connect(/* ... */);

passReset.storage.setStore({
    create: function(id, token, callback) {
        redis.set(token, id, callback);
        redis.expire(token, Math.round(passReset.expireTimeout() / 1000));
    },
    lookup: function(token, callback) {
        redis.get(token, callback);
    },
    destroy: function(token, callback) {
        redis.del(token, callback);
    }
});

Usage

Route for requesting a new reset token
app.post('/password/reset',
    passReset.requestResetToken()
);

The requestResetToken method can also take an object of configuration values. The following values are supported:

  • loginParam - The name of the param where the login data (username/email) can be found in req.body.
  • callbackURL - The base URL to direct users to actually perform the reset. This value should contain a "{token}" somewhere which will be replaced with the token, eg. "/password/reset/{token}".
  • next - By default, when pass-reset is done generating a token and sending it, an empty 200 OK response will be sent. To change this behavior, this value can be given a few different values. If a string is given, it is treated as a redirect, if a function is given, it will be called with the req, res, and next parameters, and if any other truthy value is given, the next function will simply be called.
app.post('/password/reset',
    passReset.requestResetToken({
        next: true,
        loginParam: 'login',
        callbackURL: '/password/reset/{token}',
    }),
    function(req, res) {
        // ...
    }
);
Route for actually reseting passwords
app.put('/password/reset',
    passReset.resetPassword()
);

The resetPassword method can also take an object of configuration values. The following values are supported:

  • tokenParam/passwordParam/confirmParam - The name of the params where the respective data (token/password/confirm) can be found in req.body.
  • next - By default, after the password is reset, an empty 200 OK response will be sent. To change this behavior, this value can be given a few different values. If a string is given, it is treated as a redirect, if a function is given, it will be called with the req, res, and next parameters, and if any other truthy value is given, the next function will simply be called.
app.put('/password/reset',
    passReset.resetPassword({
        next: true,
        tokenParam: 'token',
        passwordParam: 'password',
        confirmParam: 'confirm'
    }),
    function(req, res) {
        // ...
    }
);
npm loves you