Move object ID, token, and random string generation into their own module, cryptoUtils. Remove hat dependency, which was used to generate session and some other tokens, because it used non-cryptographic random number generator. Replace it with the cryptographically secure one. The result has the same format (32-character hex string, 128 bits of entropy). Remove randomstring dependency, as we already have this functionality. Add tests.
84 lines
2.3 KiB
JavaScript
84 lines
2.3 KiB
JavaScript
var cryptoUtils = require('../src/cryptoUtils');
|
|
|
|
function givesUniqueResults(fn, iterations) {
|
|
var results = {};
|
|
for (var i = 0; i < iterations; i++) {
|
|
var s = fn();
|
|
if (results[s]) {
|
|
return false;
|
|
}
|
|
results[s] = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
describe('randomString', () => {
|
|
it('returns a string', () => {
|
|
expect(typeof cryptoUtils.randomString(10)).toBe('string');
|
|
});
|
|
|
|
it('returns result of the given length', () => {
|
|
expect(cryptoUtils.randomString(11).length).toBe(11);
|
|
expect(cryptoUtils.randomString(25).length).toBe(25);
|
|
});
|
|
|
|
it('throws if requested length is zero', () => {
|
|
expect(() => cryptoUtils.randomString(0)).toThrow();
|
|
});
|
|
|
|
it('returns unique results', () => {
|
|
expect(givesUniqueResults(() => cryptoUtils.randomString(10), 100)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('randomHexString', () => {
|
|
it('returns a string', () => {
|
|
expect(typeof cryptoUtils.randomHexString(10)).toBe('string');
|
|
});
|
|
|
|
it('returns result of the given length', () => {
|
|
expect(cryptoUtils.randomHexString(10).length).toBe(10);
|
|
expect(cryptoUtils.randomHexString(32).length).toBe(32);
|
|
});
|
|
|
|
it('throws if requested length is zero', () => {
|
|
expect(() => cryptoUtils.randomHexString(0)).toThrow();
|
|
});
|
|
|
|
it('throws if requested length is not even', () => {
|
|
expect(() => cryptoUtils.randomHexString(11)).toThrow();
|
|
});
|
|
|
|
it('returns unique results', () => {
|
|
expect(givesUniqueResults(() => cryptoUtils.randomHexString(20), 100)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('newObjectId', () => {
|
|
it('returns a string', () => {
|
|
expect(typeof cryptoUtils.newObjectId()).toBe('string');
|
|
});
|
|
|
|
it('returns result with at least 10 characters', () => {
|
|
expect(cryptoUtils.newObjectId().length).toBeGreaterThan(9);
|
|
});
|
|
|
|
it('returns unique results', () => {
|
|
expect(givesUniqueResults(() => cryptoUtils.newObjectId(), 100)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('newToken', () => {
|
|
it('returns a string', () => {
|
|
expect(typeof cryptoUtils.newToken()).toBe('string');
|
|
});
|
|
|
|
it('returns result with at least 32 characters', () => {
|
|
expect(cryptoUtils.newToken().length).toBeGreaterThan(31);
|
|
});
|
|
|
|
it('returns unique results', () => {
|
|
expect(givesUniqueResults(() => cryptoUtils.newToken(), 100)).toBe(true);
|
|
});
|
|
});
|