csrf-tokens
Advanced tools
Comparing version 1.0.4 to 2.0.0
81
index.js
var crypto = require('crypto') | ||
var rndm = require('rndm') | ||
var scmp = require('scmp') | ||
var uid = require('uid2') | ||
var uid = require('uid-safe') | ||
var crypto = require('crypto') | ||
var escape = require('base64-url').escape | ||
module.exports = function (options) { | ||
module.exports = csrfTokens | ||
function csrfTokens(options) { | ||
options = options || {} | ||
// adjustable lengths | ||
var secretLength = options.secretLength || 24 // the longer the better | ||
var secretLength = options.secretLength || 18 // the longer the better | ||
var saltLength = options.saltLength || 8 // doesn't need to be long | ||
@@ -17,48 +20,40 @@ | ||
// and we use sha1 because sha256 is unnecessarily long for cookies and stuff | ||
var tokenize = options.tokenize || function tokenize(secret, salt) { | ||
return salt + '-' | ||
+ crypto | ||
.createHash('sha1') | ||
.update(salt) | ||
.update('-') | ||
.update(secret) | ||
.digest('base64') | ||
.replace(/\/|\+|=/g, base64safe) | ||
} | ||
var tokenize = options.tokenize || csrfTokens.tokenize | ||
// create a secret key | ||
// this __should__ be cryptographically secure, | ||
// but generally client's can't/shouldn't-be-able-to access this so it really doesn't matter. | ||
// to do: async version | ||
function secret(cb) { | ||
return uid(secretLength, cb) | ||
} | ||
return { | ||
// create a secret key | ||
// this __should__ be cryptographically secure, | ||
// but generally client's can't/shouldn't-be-able-to access this so it really doesn't matter. | ||
secret: function secret(cb) { | ||
return uid(secretLength, cb) | ||
}, | ||
// create a csrf token | ||
function create(secret) { | ||
return tokenize(secret, rndm(saltLength)) | ||
} | ||
// a sync version of secret() | ||
secretSync: function secretSync() { | ||
return uid.sync(secretLength) | ||
}, | ||
// verify whether a token is valid | ||
function verify(secret, token) { | ||
if (!token || typeof token !== 'string') return false | ||
var expected = tokenize(secret, token.split('-')[0]) | ||
return scmp(token, expected) | ||
} | ||
// create a csrf token | ||
create: function create(secret) { | ||
return tokenize(secret, rndm(saltLength)) | ||
}, | ||
return { | ||
secret: secret, | ||
create: create, | ||
verify: verify, | ||
// verify whether a token is valid | ||
verify: function verify(secret, token) { | ||
if (!token || typeof token !== 'string') return false | ||
var expected = tokenize(secret, token.split('-')[0]) | ||
if (!expected) return false | ||
return scmp(token, expected) | ||
}, | ||
} | ||
} | ||
var safemap = { | ||
"/": "_", | ||
"+": "_", | ||
"=": "", | ||
csrfTokens.tokenize = function tokenize(secret, salt) { | ||
var hash = escape(crypto | ||
.createHash('sha1') | ||
.update(salt) | ||
.update('-') | ||
.update(secret) | ||
.digest('base64')) | ||
return salt + '-' + hash | ||
} | ||
function base64safe(char) { | ||
return safemap[char] | ||
} |
{ | ||
"name": "csrf-tokens", | ||
"description": "primary logic behind csrf tokens", | ||
"version": "1.0.4", | ||
"version": "2.0.0", | ||
"author": { | ||
@@ -15,4 +15,5 @@ "name": "Jonathan Ong", | ||
"rndm": "1", | ||
"uid2": "~0.0.2", | ||
"scmp": "~0.0.3" | ||
"scmp": "~0.0.3", | ||
"uid-safe": "1", | ||
"base64-url": "1" | ||
}, | ||
@@ -19,0 +20,0 @@ "devDependencies": { |
@@ -13,3 +13,3 @@ | ||
var secret = tokens.secret() | ||
var secret = tokens.secretSync() | ||
var token = tokens.create(secret) | ||
@@ -25,7 +25,22 @@ var valid = tokens.verify(secret, token) | ||
### var secret = tokens.secret() | ||
### tokens.secret([cb]) | ||
Create a new `secret` of length `secretLength`. | ||
Asynchronously create a new `secret` of length `secretLength`. | ||
If `cb` is not defined, a promise is returned. | ||
You don't have to use this. | ||
```js | ||
tokens.secret().then(function (secret) { | ||
}) | ||
tokens.secret(function (err, secret) { | ||
}) | ||
``` | ||
### var secret = tokens.secretSync() | ||
Synchronous version of `tokens.secret()` | ||
### var token = tokens.token(secret) | ||
@@ -32,0 +47,0 @@ |
@@ -11,4 +11,8 @@ | ||
it('should return a string', function () { | ||
secret = csrf.secret() | ||
secret = csrf.secretSync() | ||
assert.equal('string', typeof secret) | ||
return csrf.secret().then(function (secret) { | ||
assert.equal('string', typeof secret) | ||
}) | ||
}) | ||
@@ -50,3 +54,3 @@ | ||
var token = csrf.create(secret) | ||
assert(!csrf.verify(csrf.secret(), token)) | ||
assert(!csrf.verify(csrf.secretSync(), token)) | ||
assert(!csrf.verify('asdfasdfasdf', token)) | ||
@@ -53,0 +57,0 @@ }) |
6443
7
53
4
99
+ Addedbase64-url@1
+ Addeduid-safe@1
+ Addedbase64-url@1.2.11.3.3(transitive)
+ Addednative-or-bluebird@1.1.2(transitive)
+ Addeduid-safe@1.1.0(transitive)
- Removeduid2@~0.0.2
- Removeduid2@0.0.4(transitive)