Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b6a96d5
Showing
4 changed files
with
193 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/** | ||
* Password reset module | ||
* | ||
* @author James Brumond | ||
*/ | ||
|
||
var uuid = require('uuid-v4'); | ||
|
||
/** | ||
* Stored requests that have not yet been fulfilled | ||
*/ | ||
var storage = (function() { | ||
var tokens = { }; | ||
return { | ||
create: function(id) { | ||
var token = uuid(); | ||
tokens[token] = { | ||
id: id, | ||
timer: setTimeout( | ||
function() { | ||
storage.destroy(token); | ||
}, | ||
expireTimeout | ||
) | ||
}; | ||
return token; | ||
}, | ||
lookup: function(token) { | ||
if (tokens[token]) { | ||
return tokens[token].id; | ||
} | ||
}, | ||
destroy: function(token) { | ||
if (tokens[token]) { | ||
clearTimeout(tokens[token].timer); | ||
delete tokens[token]; | ||
} | ||
} | ||
}; | ||
}()); | ||
|
||
/** | ||
* Set the expire timeout | ||
* | ||
* Defaults to 43200000, or 12 hours | ||
*/ | ||
var expireTimeout = 43200000; | ||
exports.expireTimeout = function(milliseconds) { | ||
if (typeof milliseconds === 'number' && ! isNaN(milliseconds)) { | ||
expireTimeout = milliseconds; | ||
} | ||
}; | ||
|
||
/** | ||
* User lookup routine | ||
* | ||
* Should result in an object containing a unique id and email. | ||
*/ | ||
var lookupUser = function(login, callback) { | ||
callback(null, null); | ||
}; | ||
exports.lookupUser = function(func) { | ||
if (typeof func === 'function') { | ||
lookupUser = func; | ||
} | ||
}; | ||
|
||
/** | ||
* Password setting routine | ||
* | ||
* Should take a unique id (as returned from the user lookup | ||
* routine) and a new password. | ||
*/ | ||
var setPassword = function(id, password, callback) { | ||
callback(null, false, null); | ||
}; | ||
exports.setPassword = function(func) { | ||
if (typeof func === 'function') { | ||
setPassword = func; | ||
} | ||
}; | ||
|
||
/** | ||
* Email sending routine | ||
* | ||
* Should take an email address and tokens. | ||
*/ | ||
var sendEmail = function(email, tokens, callback) { | ||
callback(null, false); | ||
}; | ||
exports.sendEmail = function(func) { | ||
if (typeof func === 'function') { | ||
sendEmail = func; | ||
} | ||
}; | ||
|
||
/** | ||
* The route that takes reset requests | ||
* | ||
* eg. POST /password/reset | ||
* | ||
* TODO Needs to be able to handle multiple accounts with one email | ||
*/ | ||
exports.requestResetToken = function(opts) { | ||
opts = merge({ | ||
error: null, | ||
success: null, | ||
loginParam: 'login' | ||
}, opts); | ||
return function(req, res, next) { | ||
var fail = getFailer(opts, req, res, next); | ||
var login = req.body[opts.loginParam]; | ||
if (! login) {return fail();} | ||
lookupUser(login, function(err, user) { | ||
if (err) {return fail();} | ||
|
||
}); | ||
}; | ||
}; | ||
|
||
exports.resetPassword = function(opts) { | ||
opts = merge({ | ||
error: null, | ||
success: null, | ||
tokenParam: 'token', | ||
passwordParam: 'password', | ||
confirmParam: 'confirm' | ||
}, opts); | ||
return function(req, res, next) { | ||
var fail = getFailer(opts, req, res, next); | ||
|
||
}; | ||
}; | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// ------------------------------------------------------------------ | ||
// Utilities | ||
|
||
function getFailer(opts, req, res, next) { | ||
return function() { | ||
if (typeof opts.error === 'string') { | ||
res.redirect(opts.error); | ||
} else if (typeof opts.error === 'function') { | ||
opts.error(req, res, next); | ||
} else { | ||
next(); | ||
} | ||
}; | ||
} | ||
|
||
function merge(host) { | ||
host = isMutable(host) ? host : { }; | ||
for (var i = 1, c = arguments.length; i < c; i++) { | ||
if (isMutable(arguments[i])) { | ||
Object.keys(arguments[i]).forEach(function(prop) { | ||
host[prop] = arguments[i][prop]; | ||
}); | ||
} | ||
} | ||
return host; | ||
} | ||
|
||
function isMutable(value) { | ||
return (typeof value === 'object' && value) || typeof value === 'function'; | ||
} | ||
|
||
/* End of file index.js */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"author": "James Brumond <james@sportzing.com> (http://jbrumond.me)", | ||
"name": "pass-reset", | ||
"description": "A drop-in password reseting module", | ||
"version": "0.0.1", | ||
"main": "index.js", | ||
"dependencies": { | ||
"uuid-v4": "latest" | ||
}, | ||
"devDependencies": {}, | ||
"optionalDependencies": {}, | ||
"engines": { | ||
"node": "*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Password Reseting Module | ||
|
||
|
||
|
||
|