Skip to content

Commit

Permalink
Merge cf459a7 into 775fb78
Browse files Browse the repository at this point in the history
  • Loading branch information
buzcarter committed Sep 11, 2019
2 parents 775fb78 + cf459a7 commit 1b0e102
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -59,6 +59,10 @@ The length of the secret to generate, in bytes. Note that the secret is
passed around base-64 encoded and that this length refers to the underlying
bytes, not the length of the base-64 string. Defaults to `18` bytes.

##### hashAlgorithm

The algorithm to be used in generating hash digests. "*The algorithm is dependent on the available algorithms supported by the version of OpenSSL on the platform*" ([see Node crypto.createHash documentation](https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options))

#### tokens.create(secret)

Create a new CSRF token attached to the given `secret`. The `secret` is a
Expand Down
25 changes: 20 additions & 5 deletions index.js
Expand Up @@ -26,6 +26,12 @@ var EQUAL_GLOBAL_REGEXP = /=/g
var PLUS_GLOBAL_REGEXP = /\+/g
var SLASH_GLOBAL_REGEXP = /\//g

var DefaultOptions = {
saltLength: 8,
secretLength: 18,
hashAlgorithm: 'sha1'
}

/**
* Module exports.
* @public
Expand All @@ -51,22 +57,31 @@ function Tokens (options) {

var saltLength = opts.saltLength !== undefined
? opts.saltLength
: 8
: DefaultOptions.saltLength

if (typeof saltLength !== 'number' || !isFinite(saltLength) || saltLength < 1) {
throw new TypeError('option saltLength must be finite number > 1')
}

var secretLength = opts.secretLength !== undefined
? opts.secretLength
: 18
: DefaultOptions.secretLength

if (typeof secretLength !== 'number' || !isFinite(secretLength) || secretLength < 1) {
throw new TypeError('option secretLength must be finite number > 1')
}

var hashAlgorithm = opts.hashAlgorithm !== undefined
? opts.hashAlgorithm
: DefaultOptions.hashAlgorithm

if (typeof hashAlgorithm !== 'string' || !hashAlgorithm) {
throw new TypeError('option hashAlgorithm must be valid hash algorithn')
}

this.saltLength = saltLength
this.secretLength = secretLength
this.hashAlgorithm = hashAlgorithm
}

/**
Expand Down Expand Up @@ -110,7 +125,7 @@ Tokens.prototype.secretSync = function secretSync () {
*/

Tokens.prototype._tokenize = function tokenize (secret, salt) {
return salt + '-' + hash(salt + '-' + secret)
return salt + '-' + this.hash(salt + '-' + secret)
}

/**
Expand Down Expand Up @@ -148,9 +163,9 @@ Tokens.prototype.verify = function verify (secret, token) {
* @private
*/

function hash (str) {
Tokens.prototype.hash = function hash (str) {
return crypto
.createHash('sha1')
.createHash(this.hashAlgorithm)
.update(str, 'ascii')
.digest('base64')
.replace(PLUS_GLOBAL_REGEXP, '-')
Expand Down
12 changes: 12 additions & 0 deletions test/test.js
Expand Up @@ -50,6 +50,18 @@ describe('Tokens', function () {
assert.strictEqual(Tokens({ secretLength: 4 }).secretSync().length, 6)
})
})

describe('hashAlgorithm', function () {
it('should reject non-strings', function () {
assert.throws(Tokens.bind(null, { hashAlgorithm: 256 }),
/option hashAlgorithm/)
})

it('should reject empty strings', function () {
assert.throws(Tokens.bind(null, { hashAlgorithm: '' }),
/option hashAlgorithm/)
})
})
})

describe('.create(secret)', function () {
Expand Down

0 comments on commit 1b0e102

Please sign in to comment.