Skip to content

Commit 8ebcdb4

Browse files
committed
add hashAlgorithm to options; move hash to object instance property
1 parent 775fb78 commit 8ebcdb4

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ The length of the secret to generate, in bytes. Note that the secret is
5959
passed around base-64 encoded and that this length refers to the underlying
6060
bytes, not the length of the base-64 string. Defaults to `18` bytes.
6161

62+
##### hashAlgorithm
63+
64+
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))
65+
6266
#### tokens.create(secret)
6367

6468
Create a new CSRF token attached to the given `secret`. The `secret` is a

index.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ var EQUAL_GLOBAL_REGEXP = /=/g
2626
var PLUS_GLOBAL_REGEXP = /\+/g
2727
var SLASH_GLOBAL_REGEXP = /\//g
2828

29+
var DefaultOptions = {
30+
saltLength: 8,
31+
secretLength: 18,
32+
hashAlgorithm: 'sha1'
33+
}
34+
2935
/**
3036
* Module exports.
3137
* @public
@@ -47,26 +53,29 @@ function Tokens (options) {
4753
return new Tokens(options)
4854
}
4955

50-
var opts = options || {}
56+
var opts = Object.assign({}, DefaultOptions, options || {})
5157

52-
var saltLength = opts.saltLength !== undefined
53-
? opts.saltLength
54-
: 8
58+
var saltLength = opts.saltLength
5559

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

60-
var secretLength = opts.secretLength !== undefined
61-
? opts.secretLength
62-
: 18
64+
var secretLength = opts.secretLength
6365

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

70+
var hashAlgorithm = opts.hashAlgorithm
71+
72+
if (typeof hashAlgorithm !== 'string' || !hashAlgorithm) {
73+
throw new TypeError('option hashAlgorithm must be valid hash algorithn')
74+
}
75+
6876
this.saltLength = saltLength
6977
this.secretLength = secretLength
78+
this.hashAlgorithm = hashAlgorithm
7079
}
7180

7281
/**
@@ -110,7 +119,7 @@ Tokens.prototype.secretSync = function secretSync () {
110119
*/
111120

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

116125
/**
@@ -148,9 +157,9 @@ Tokens.prototype.verify = function verify (secret, token) {
148157
* @private
149158
*/
150159

151-
function hash (str) {
160+
Tokens.prototype.hash = function hash (str) {
152161
return crypto
153-
.createHash('sha1')
162+
.createHash(this.hashAlgorithm)
154163
.update(str, 'ascii')
155164
.digest('base64')
156165
.replace(PLUS_GLOBAL_REGEXP, '-')

test/test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ describe('Tokens', function () {
5050
assert.strictEqual(Tokens({ secretLength: 4 }).secretSync().length, 6)
5151
})
5252
})
53+
54+
describe('hashAlgorithm', function () {
55+
it('should reject non-strings', function () {
56+
assert.throws(Tokens.bind(null, { hashAlgorithm: 256 }),
57+
/option hashAlgorithm/)
58+
})
59+
60+
it('should reject empty strings', function () {
61+
assert.throws(Tokens.bind(null, { hashAlgorithm: '' }),
62+
/option hashAlgorithm/)
63+
})
64+
})
5365
})
5466

5567
describe('.create(secret)', function () {

0 commit comments

Comments
 (0)