Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add hashAlgorithm to options; move hash to object instance property #16

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the biggest change: moving this method from a private "helper" to a public class method, all necessitated by needing access to this.hashAlgorithm.

Is the naming convention to prepend an underscore to indicate private? (which would be great, IMHO -- _hash)

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