Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

argon2-pass

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

argon2-pass - npm Package Compare versions

Comparing version 0.2.1 to 0.2.2

6

CHANGELOG.md
# Changelog
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.2.2] - 2018-09-10
### Added
- Added convenience functions to test if a VerificationResult is a specific type. These are; `isInvalidOrUnrecognized()`, `isInvalid()`, `isValid()` and `isValidNeedsRehash()`. These functions will return true if the enumeration value matches the tested value.
## [0.2.1] - 2018-09-09

@@ -11,2 +16,3 @@ ### Removed

### Added
- Added JSDoc comments to all functions and important objects. This was then used with the TypeDoc module to generate a documentation site for the package.

@@ -13,0 +19,0 @@ - Added synchronous versions of hash and verify. `hashPasswordSync()` and `verifyHashSync()`.

10

dist/__tests__/base64.js

@@ -6,3 +6,3 @@ "use strict";

describe('bufferFromSafeBase64', () => {
test('Should convert a valid base64 string into a buffer.', () => {
test('Should convert a valid url-safe base64 string into a buffer.', () => {
const expected = Buffer.from('TestString');

@@ -14,7 +14,9 @@ const buffer = __1.bufferFromSafeBase64('VGVzdFN0cmluZw');

describe('bufferToSafeBase64', () => {
const expected = 'VGVzdFN0cmluZw';
const base64 = __1.bufferToSafeBase64(Buffer.from('TestString'));
expect(base64).toEqual(expected);
test('Should convert a buffer into a valid url-safe base64 string.', () => {
const expected = 'VGVzdFN0cmluZw';
const base64 = __1.bufferToSafeBase64(Buffer.from('TestString'));
expect(base64).toEqual(expected);
});
});
});
//# sourceMappingURL=base64.js.map

407

dist/__tests__/index.js

@@ -10,27 +10,14 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sodium_native_1 = __importDefault(require("sodium-native"));
const __1 = require("..");
const error_1 = require("../error");
describe('SecurePass - Constants', () => {
test('PasswordBytes* Constants should be defined.', () => {
describe('SecurePass', () => {
test('static readonly constants should be defined.', () => {
expect(__1.SecurePass.PasswordBytesMin).toBeDefined();
expect(__1.SecurePass.PasswordBytesMax).toBeDefined();
expect(__1.SecurePass.PasswordBytesMin).toBeDefined();
});
test('HashBytes Constant should be defined.', () => {
expect(__1.SecurePass.HashBytes).toBeDefined();
});
test('SaltBytes Constant should be defined', () => {
expect(__1.SecurePass.SaltBytes).toBeDefined();
});
test('MacBytes Constant should be defined.', () => {
expect(__1.SecurePass.MacBytes).toBeDefined();
});
test('KeyBytes Constant should be defined.', () => {
expect(__1.SecurePass.KeyBytes).toBeDefined();
});
test('MemLimit* Constants should be defined.', () => {
// Memory Limit Constants
expect(__1.SecurePass.MemLimitDefault).toBeDefined();

@@ -42,4 +29,3 @@ expect(__1.SecurePass.MemLimitInteractive).toBeDefined();

expect(__1.SecurePass.MemLimitMaximum).toBeDefined();
});
test('OpsLimit* Constants should be defined.', () => {
// Operations Limit Constants
expect(__1.SecurePass.OpsLimitDefault).toBeDefined();

@@ -52,144 +38,180 @@ expect(__1.SecurePass.OpsLimitInteractive).toBeDefined();

});
test('VerificationResult.* Enum Constants should be defined.', () => {
expect(__1.VerificationResult.InvalidOrUnrecognized).toEqual(0);
expect(__1.VerificationResult.Invalid).toEqual(1);
expect(__1.VerificationResult.Valid).toEqual(2);
expect(__1.VerificationResult.ValidNeedsRehash).toEqual(3);
test('static readonly constants should have the correct values.', () => {
expect(__1.SecurePass.PasswordBytesMin).toEqual(1);
expect(__1.SecurePass.PasswordBytesMax).toEqual(2147483647);
expect(__1.SecurePass.HashBytes).toEqual(128);
expect(__1.SecurePass.SaltBytes).toEqual(16);
expect(__1.SecurePass.MacBytes).toEqual(16);
expect(__1.SecurePass.KeyBytes).toEqual(32);
// Memory Limit Constants
expect(__1.SecurePass.MemLimitDefault).toEqual(67108864);
expect(__1.SecurePass.MemLimitInteractive).toEqual(67108864);
expect(__1.SecurePass.MemLimitModerate).toEqual(268435456);
expect(__1.SecurePass.MemLimitSensitive).toEqual(1073741824);
expect(__1.SecurePass.MemLimitMinimum).toEqual(8192);
expect(__1.SecurePass.MemLimitMaximum).toEqual(4398046510080);
// Operations Limit Constants
expect(__1.SecurePass.OpsLimitDefault).toEqual(2);
expect(__1.SecurePass.OpsLimitInteractive).toEqual(2);
expect(__1.SecurePass.OpsLimitModerate).toEqual(3);
expect(__1.SecurePass.OpsLimitSensitive).toEqual(4);
expect(__1.SecurePass.OpsLimitMinimum).toEqual(1);
expect(__1.SecurePass.OpsLimitMaximum).toEqual(4294967295);
});
});
describe('SecurePass - Options', () => {
test('Passing no configuration should create a new instance with the default options.', () => {
const sp = new __1.SecurePass();
expect(sp.MemLimit).toEqual(sodium_native_1.default.crypto_pwhash_MEMLIMIT_INTERACTIVE);
expect(sp.OpsLimit).toEqual(sodium_native_1.default.crypto_pwhash_OPSLIMIT_INTERACTIVE);
});
test('Passing in an empty object should create a new instance with the default options.', () => {
const sp = new __1.SecurePass({});
expect(sp.MemLimit).toEqual(sodium_native_1.default.crypto_pwhash_MEMLIMIT_INTERACTIVE);
expect(sp.OpsLimit).toEqual(sodium_native_1.default.crypto_pwhash_OPSLIMIT_INTERACTIVE);
});
test('A valid value for memLimit should be set correctly. And opsLimit should be set to the default value.', () => {
const sp = new __1.SecurePass({
memLimit: 16384
describe('VerificationResult', () => {
test('VerificationResult enumeration has the right values.', () => {
expect(__1.VerificationResult.InvalidOrUnrecognized).toEqual(0);
expect(__1.VerificationResult.Invalid).toEqual(1);
expect(__1.VerificationResult.Valid).toEqual(2);
expect(__1.VerificationResult.ValidNeedsRehash).toEqual(3);
});
expect(sp.MemLimit).toEqual(16384);
expect(sp.OpsLimit).toEqual(sodium_native_1.default.crypto_pwhash_OPSLIMIT_INTERACTIVE);
});
test('A valid value for opsLimit should be set correctly. And memLimit should be set to the default value.', () => {
const sp = new __1.SecurePass({
opsLimit: 12
test.each([
[__1.VerificationResult.InvalidOrUnrecognized, true],
[__1.VerificationResult.Invalid, false],
[__1.VerificationResult.Valid, false],
[__1.VerificationResult.ValidNeedsRehash, false]
])('isInvalidOrUnrecognized should return the correct result when called with %i.', (vr, b) => {
expect(__1.SecurePass.isInvalidOrUnrecognized(vr)).toEqual(b);
});
expect(sp.MemLimit).toEqual(sodium_native_1.default.crypto_pwhash_MEMLIMIT_INTERACTIVE);
expect(sp.OpsLimit).toEqual(12);
});
test('A lower bounds value for memLimit should still be considered valid.', () => {
const sp = new __1.SecurePass({
memLimit: __1.SecurePass.MemLimitMinimum
test.each([
[__1.VerificationResult.InvalidOrUnrecognized, false],
[__1.VerificationResult.Invalid, true],
[__1.VerificationResult.Valid, false],
[__1.VerificationResult.ValidNeedsRehash, false]
])('isInvalid should return the correct result when called with %i.', (vr, b) => {
expect(__1.SecurePass.isInvalid(vr)).toEqual(b);
});
expect(sp.MemLimit).toEqual(__1.SecurePass.MemLimitMinimum);
});
test('An upper bounds value for memLimit should still be considered valid.', () => {
const sp = new __1.SecurePass({
memLimit: __1.SecurePass.MemLimitMaximum
test.each([
[__1.VerificationResult.InvalidOrUnrecognized, false],
[__1.VerificationResult.Invalid, false],
[__1.VerificationResult.Valid, true],
[__1.VerificationResult.ValidNeedsRehash, false]
])('isValid should return the correct result when called with %i.', (vr, b) => {
expect(__1.SecurePass.isValid(vr)).toEqual(b);
});
expect(sp.MemLimit).toEqual(__1.SecurePass.MemLimitMaximum);
});
test('A lower bounds value for opsLimit should still be considered valid.', () => {
const sp = new __1.SecurePass({
opsLimit: __1.SecurePass.OpsLimitMinimum
test.each([
[__1.VerificationResult.InvalidOrUnrecognized, false],
[__1.VerificationResult.Invalid, false],
[__1.VerificationResult.Valid, false],
[__1.VerificationResult.ValidNeedsRehash, true]
])('isValidNeedsRehash should return the correct result when called with %i.', (vr, b) => {
expect(__1.SecurePass.isValidNeedsRehash(vr)).toEqual(b);
});
expect(sp.OpsLimit).toEqual(__1.SecurePass.OpsLimitMinimum);
});
test('An upper bounds value for opsLimit should still be considered valid.', () => {
const sp = new __1.SecurePass({
opsLimit: __1.SecurePass.OpsLimitMaximum
describe('SecurePass MemLimit and OpsLimit Options', () => {
test('Passing no configuration to SecurePass, should create a new instance with the default values', () => {
const sp1 = new __1.SecurePass();
expect(sp1.MemLimit).toEqual(__1.SecurePass.MemLimitDefault);
expect(sp1.OpsLimit).toEqual(__1.SecurePass.OpsLimitDefault);
const sp2 = new __1.SecurePass({});
expect(sp2.MemLimit).toEqual(__1.SecurePass.MemLimitDefault);
expect(sp2.OpsLimit).toEqual(__1.SecurePass.OpsLimitDefault);
});
expect(sp.OpsLimit).toEqual(__1.SecurePass.OpsLimitMaximum);
});
test('An invalid value for memLimit should throw an error.', () => {
try {
test('Passing no value for memLimit, should result in the default value being set.', () => {
const sp = new __1.SecurePass({
memLimit: 1
opsLimit: 6
});
}
catch (e) {
expect(e).toBeDefined();
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
});
test('An invalid value for opsLimit should throw an error.', () => {
try {
expect(sp.MemLimit).toEqual(__1.SecurePass.MemLimitDefault);
});
test('Passing no value for opsLimit, should result in the default value being set.', () => {
const sp = new __1.SecurePass({
opsLimit: __1.SecurePass.OpsLimitMaximum + 1
memLimit: 16 * 1024
});
}
catch (e) {
expect(e).toBeDefined();
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
});
describe('get and set - MemLimit', () => {
test('MemLimit should return the currently configured Memory Limit.', () => {
const sp = new __1.SecurePass({
memLimit: __1.SecurePass.MemLimitSensitive
expect(sp.OpsLimit).toEqual(__1.SecurePass.OpsLimitDefault);
});
// Test Valid Values for MemLimit, Including Upper and Lower Bounds.
describe.each([__1.SecurePass.MemLimitInteractive, __1.SecurePass.MemLimitMinimum, __1.SecurePass.MemLimitMaximum])('Valid and Edge Case values for MemLimit.', m => {
test(`${m} should be a valid value for MemLimit, when passed in the constructor.`, () => {
const sp = new __1.SecurePass({
memLimit: m
});
expect(sp.MemLimit).toEqual(m);
});
expect(sp.MemLimit).toEqual(__1.SecurePass.MemLimitSensitive);
test(`${m} should be a valid value for MemLimit, when set with the accessor.`, () => {
const sp = new __1.SecurePass();
sp.MemLimit = m;
expect(sp.MemLimit).toEqual(m);
});
});
test('MemLimit should set the configured Memory Limit to the new limit.', () => {
const sp = new __1.SecurePass();
sp.MemLimit = __1.SecurePass.MemLimitModerate;
expect(sp.MemLimit).toEqual(__1.SecurePass.MemLimitModerate);
// Test Valid Values for OpsLimit, Including Upper and Lower Bounds.
describe.each([__1.SecurePass.OpsLimitInteractive, __1.SecurePass.OpsLimitMinimum, __1.SecurePass.OpsLimitMaximum])('Valid and Edge Case values for OpsLimit.', o => {
test(`${o} should be a valid value for OpsLimit, when passed in the constructor.`, () => {
const sp = new __1.SecurePass({
opsLimit: o
});
expect(sp.OpsLimit).toEqual(o);
});
test(`${o} should be a valid value for OpsLimit, when set with the accessor.`, () => {
const sp = new __1.SecurePass();
sp.OpsLimit = o;
expect(sp.OpsLimit).toEqual(o);
});
});
test('MemLimit should throw an error if set with an invalid memory limit.', () => {
const sp = new __1.SecurePass();
try {
sp.MemLimit = 1024;
}
catch (e) {
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
// Test Invalid Values for MemLimit.
describe.each([__1.SecurePass.MemLimitMinimum - 1, __1.SecurePass.MemLimitMaximum + 1])('Invalid Values for MemLimit.', m => {
test(`${m} should be an invalid value for MemLimit, when passed in the constructor.`, () => {
try {
const sp = new __1.SecurePass({
memLimit: m
});
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
}
catch (e) {
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
});
test(`${m} should be an invalid value for MemLimit, when set with the accessor.`, () => {
try {
const sp = new __1.SecurePass();
sp.MemLimit = m;
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
}
catch (e) {
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
});
});
});
describe('get and set - OpsLimit', () => {
test('OpsLimit should return the currently configured Memory Limit.', () => {
const sp = new __1.SecurePass({
opsLimit: __1.SecurePass.OpsLimitSensitive
// Test Invalid Values for OpsLimit.
describe.each([__1.SecurePass.OpsLimitMinimum - 1, __1.SecurePass.OpsLimitMaximum + 1])('Invalid Values for OpsLimit.', o => {
test(`${o} should be an invalid value for OpsLimit, when passed in the constructor.`, () => {
try {
const sp = new __1.SecurePass({
opsLimit: o
});
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
}
catch (e) {
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
});
expect(sp.OpsLimit).toEqual(__1.SecurePass.OpsLimitSensitive);
test(`${o} should be an invalid value for OpsLimit, when set with the accessor.`, () => {
try {
const sp = new __1.SecurePass();
sp.OpsLimit = o;
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
}
catch (e) {
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
});
});
test('OpsLimit should set the configured Memory Limit to the new limit.', () => {
const sp = new __1.SecurePass();
sp.OpsLimit = __1.SecurePass.OpsLimitModerate;
expect(sp.OpsLimit).toEqual(__1.SecurePass.OpsLimitModerate);
});
test('OpsLimit should throw an error if set with an invalid memory limit.', () => {
const sp = new __1.SecurePass();
try {
sp.OpsLimit = __1.SecurePass.OpsLimitMaximum + 1;
}
catch (e) {
expect(e instanceof error_1.SecurePassOptionsError).toBeTruthy();
}
});
});
});
describe('SecurePass - Static Functions', () => {
describe('generateOneTimeAuth()', () => {
test('Should return a mac, key and the original message.', () => {
test('Should return a mac, random key and the original message.', () => {
const message = Buffer.from('ExampleMessage');
const result = __1.SecurePass.generateOneTimeAuth(message);
expect(result.mac).toBeDefined();
expect(result.mac.length).toEqual(sodium_native_1.default.crypto_onetimeauth_BYTES);
expect(result.message).toBeDefined();
expect(result.mac.length).toEqual(__1.SecurePass.MacBytes);
expect(result.message.compare(message)).toEqual(0);
expect(result.key).toBeDefined();
expect(result.key.length).toEqual(sodium_native_1.default.crypto_onetimeauth_KEYBYTES);
expect(result.key.length).toEqual(__1.SecurePass.KeyBytes);
});
});
describe('verifyOneTimeAuth()', () => {
test('Should return true if the message, mac and key match.', () => {
test('Should return true if the message, mac and random key match.', () => {
const message = Buffer.from('ExampleMessage');
const ota = __1.SecurePass.generateOneTimeAuth(message);
const result = __1.SecurePass.verifyOneTimeAuth(ota.mac, message, ota.key);
expect(result).toBeDefined();
expect(result).toBeTruthy();

@@ -200,5 +222,4 @@ });

const ota = __1.SecurePass.generateOneTimeAuth(message);
const badMessage = Buffer.from('ExampleBad');
const badMessage = Buffer.from('ExampleMessageBad');
const result = __1.SecurePass.verifyOneTimeAuth(ota.mac, badMessage, ota.key);
expect(result).toBeDefined();
expect(result).toBeFalsy();

@@ -209,13 +230,11 @@ });

const ota = __1.SecurePass.generateOneTimeAuth(message);
const badMac = Buffer.alloc(sodium_native_1.default.crypto_onetimeauth_BYTES);
const badMac = Buffer.alloc(__1.SecurePass.MacBytes);
const result = __1.SecurePass.verifyOneTimeAuth(badMac, message, ota.key);
expect(result).toBeDefined();
expect(result).toBeFalsy();
});
test('Should return false if the key does not match the message and mac.', () => {
test('Should return false if the random key does not match the message and mac.', () => {
const message = Buffer.from('ExampleMessage');
const ota = __1.SecurePass.generateOneTimeAuth(message);
const badKey = Buffer.alloc(sodium_native_1.default.crypto_onetimeauth_KEYBYTES);
const badKey = Buffer.alloc(__1.SecurePass.KeyBytes);
const result = __1.SecurePass.verifyOneTimeAuth(ota.mac, message, badKey);
expect(result).toBeDefined();
expect(result).toBeFalsy();

@@ -225,31 +244,26 @@ });

describe('generateOneTimeAuthCode()', () => {
test('Should return a code string and a key buffer.', () => {
test('Should return a valid code and a key buffer.', () => {
const message = Buffer.from('ExampleMessage');
const result = __1.SecurePass.generateOneTimeAuthCode(message);
expect(typeof result.code).toEqual('string');
expect(result.code.length > 0).toBeTruthy();
expect(result.code.indexOf('~')).toBeTruthy();
expect(result.key instanceof Buffer).toBeTruthy();
expect(result.key.length).toEqual(sodium_native_1.default.crypto_onetimeauth_KEYBYTES);
const otac = __1.SecurePass.generateOneTimeAuthCode(message);
expect(otac.code.indexOf('~')).not.toEqual(-1);
expect(otac.key.length).toEqual(__1.SecurePass.KeyBytes);
});
});
describe('verifyOneTimeAuthCode()', () => {
test('Should return true when used with a valid code and key.', () => {
test('Should return true when called with a valid code and key.', () => {
const message = Buffer.from('ExampleMessage');
const ota = __1.SecurePass.generateOneTimeAuthCode(message);
const result = __1.SecurePass.verifyOneTimeAuthCode(ota.code, ota.key);
const otac = __1.SecurePass.generateOneTimeAuthCode(message);
const result = __1.SecurePass.verifyOneTimeAuthCode(otac.code, otac.key);
expect(result).toBeTruthy();
});
test('Should return false when used with an invalid key.', () => {
test('Should return false if called with an invalid key.', () => {
const message = Buffer.from('ExampleMessage');
const ota = __1.SecurePass.generateOneTimeAuthCode(message);
const badKey = Buffer.alloc(sodium_native_1.default.crypto_onetimeauth_KEYBYTES);
const result = __1.SecurePass.verifyOneTimeAuthCode(ota.code, badKey);
const otac = __1.SecurePass.generateOneTimeAuthCode(message);
const badKey = Buffer.alloc(__1.SecurePass.KeyBytes);
const result = __1.SecurePass.verifyOneTimeAuthCode(otac.code, badKey);
expect(result).toBeFalsy();
});
});
});
describe('SecurePass - Functions', () => {
describe('async/promise hashPassword()', () => {
test('Should return a string if given a valid password buffer.', () => __awaiter(this, void 0, void 0, function* () {
test('Should return a hash if given a valid password.', (done) => __awaiter(this, void 0, void 0, function* () {
const sp = new __1.SecurePass();

@@ -259,14 +273,24 @@ const password = Buffer.from('SecurePass');

expect(hash.length).toEqual(__1.SecurePass.HashBytes);
expect(hash.toString().length > 0).toBeTruthy();
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
}));
test('Should return an error if given a blank password buffer.', () => __awaiter(this, void 0, void 0, function* () {
test.each([__1.SecurePass.PasswordBytesMin, __1.SecurePass.PasswordBytesMax])('Should return a hash if given a password buffer of length %1.', (p, done) => __awaiter(this, void 0, void 0, function* () {
const sp = new __1.SecurePass();
const password = Buffer.alloc(p, 'f');
const hash = yield sp.hashPassword(password);
expect(hash.length).toEqual(__1.SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
}));
test.each([__1.SecurePass.PasswordBytesMin - 1, __1.SecurePass.PasswordBytesMax + 1])('Should throw an error if given a password buffer of length %i.', (p, done) => __awaiter(this, void 0, void 0, function* () {
try {
const password = Buffer.from('');
const sp = new __1.SecurePass();
const password = Buffer.alloc(p, 'f');
const hash = yield sp.hashPassword(password);
expect(false).toBeTruthy();
done();
}
catch (e) {
expect(e).toBeDefined();
expect(e instanceof error_1.SecurePassError).toBeTruthy();
done();
}

@@ -276,24 +300,46 @@ }));

describe('callback hashPassword()', () => {
test('Should return a string if given a valid password buffer.', done => {
test('Should return a hash if given a valid password.', done => {
const sp = new __1.SecurePass();
const password = Buffer.from('SecurePass');
sp.hashPassword(password, (err, hash) => {
expect(err).toBeNull();
expect(hash).toBeDefined();
if (err || hash == undefined) {
expect(false).toBeTruthy();
return;
}
expect(hash.length).toEqual(__1.SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
});
});
test('Should return an error if given a blank password buffer.', done => {
test.each([__1.SecurePass.PasswordBytesMin, __1.SecurePass.PasswordBytesMax])('Should return a hash if given a password buffer of length %1.', (p, done) => __awaiter(this, void 0, void 0, function* () {
const sp = new __1.SecurePass();
const password = Buffer.from('');
const password = Buffer.alloc(p, 'f');
sp.hashPassword(password, (err, hash) => {
expect(err).toBeDefined();
expect(err instanceof error_1.SecurePassError).toBeTruthy();
expect(hash).toBeUndefined();
if (err || hash == undefined) {
expect(false).toBeTruthy();
return;
}
expect(hash.length).toEqual(__1.SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
});
});
}));
test.each([__1.SecurePass.PasswordBytesMin - 1, __1.SecurePass.PasswordBytesMax + 1])('Should throw an error if given a password buffer of length %i.', (p, done) => __awaiter(this, void 0, void 0, function* () {
const sp = new __1.SecurePass();
try {
const password = Buffer.alloc(p, 'f');
sp.hashPassword(password, (err, hash) => {
expect(err instanceof error_1.SecurePassError).toBeTruthy();
expect(hash).toBeUndefined();
done();
});
}
catch (e) {
expect(e).toBeDefined();
done();
}
}));
});
describe('hashPasswordSync', () => {
test('Should return a valid hash if given a valid password.', done => {
describe('hashPasswordSync()', () => {
test('Should return a hash if given a valid password.', done => {
const sp = new __1.SecurePass();

@@ -303,16 +349,25 @@ const password = Buffer.from('SecurePass');

expect(hash.length).toEqual(__1.SecurePass.HashBytes);
expect(sp.verifyHashSync(password, hash)).toEqual(__1.VerificationResult.Valid);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
});
test('Should throw an error if given a blank password buffer.', done => {
test.each([__1.SecurePass.PasswordBytesMin, __1.SecurePass.PasswordBytesMax])('Should return a hash if given a password buffer of length %1.', (p, done) => {
const sp = new __1.SecurePass();
const password = Buffer.from('');
const password = Buffer.alloc(p, 'f');
const hash = sp.hashPasswordSync(password);
expect(hash.length).toEqual(__1.SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
});
test.each([__1.SecurePass.PasswordBytesMin - 1, __1.SecurePass.PasswordBytesMax + 1])('Should throw an error if given a password buffer of length %i.', (p, done) => {
try {
const sp = new __1.SecurePass();
const password = Buffer.alloc(p, 'f');
const hash = sp.hashPasswordSync(password);
expect(false).toBeTruthy();
done();
}
catch (e) {
expect(e).toBeDefined();
expect(e instanceof error_1.SecurePassError).toBeTruthy();
done();
}
done();
});

@@ -319,0 +374,0 @@ });

@@ -108,2 +108,3 @@ /**

* Use of this option requires a minimum of 1024 MiB of dedicated RAM.
* @readonly
*/

@@ -147,2 +148,3 @@ static readonly MemLimitSensitive: number;

* Using this option it takes around 3.5 seconds to derrive a hash on a 2.8Ghz Core i7 CPU.
* @readonly
*/

@@ -187,2 +189,22 @@ static readonly OpsLimitSensitive: number;

/**
* Tests a VerificationResult enumeration and returns true if the value is InvalidOrUnrecognized.
* @param vr - The VerificationResult to Test.
*/
static isInvalidOrUnrecognized(vr: VerificationResult): boolean;
/**
* Tests a VerificationResult enumeration and returns true if the value is Invalid.
* @param vr - The VerificationResult to Test.
*/
static isInvalid(vr: VerificationResult): boolean;
/**
* Tests a VerificationResult enumeration and returns true if the value is Valid.
* @param vr - The VerificationResult to Test.
*/
static isValid(vr: VerificationResult): boolean;
/**
* Tests a VerificationResult enumeration and returns true if the value is ValidNeedsRehash.
* @param vr - The VerificationResult to Test.
*/
static isValidNeedsRehash(vr: VerificationResult): boolean;
/**
* Configured memory limit for Argon2ID.

@@ -189,0 +211,0 @@ */

@@ -117,2 +117,30 @@ "use strict";

/**
* Tests a VerificationResult enumeration and returns true if the value is InvalidOrUnrecognized.
* @param vr - The VerificationResult to Test.
*/
static isInvalidOrUnrecognized(vr) {
return vr == VerificationResult.InvalidOrUnrecognized;
}
/**
* Tests a VerificationResult enumeration and returns true if the value is Invalid.
* @param vr - The VerificationResult to Test.
*/
static isInvalid(vr) {
return vr == VerificationResult.Invalid;
}
/**
* Tests a VerificationResult enumeration and returns true if the value is Valid.
* @param vr - The VerificationResult to Test.
*/
static isValid(vr) {
return vr == VerificationResult.Valid;
}
/**
* Tests a VerificationResult enumeration and returns true if the value is ValidNeedsRehash.
* @param vr - The VerificationResult to Test.
*/
static isValidNeedsRehash(vr) {
return vr == VerificationResult.ValidNeedsRehash;
}
/**
* Returns the currently configured Memory Limit.

@@ -167,3 +195,3 @@ */

hashPasswordSync(password) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
throw new error_1.SecurePassError(`Length of Password Buffer must be between ${SecurePass.PasswordBytesMin} and ${SecurePass.PasswordBytesMax}`);

@@ -190,3 +218,3 @@ }

verifyHashSync(password, hash) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
throw new error_1.SecurePassError(`Length of Password Buffer must be between ${SecurePass.PasswordBytesMin} and ${SecurePass.PasswordBytesMax}`);

@@ -211,3 +239,3 @@ }

return new Promise((resolve, reject) => {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
reject(new error_1.SecurePassError(`Length of Password Buffer must be between ${SecurePass.PasswordBytesMin} and ${SecurePass.PasswordBytesMax}`));

@@ -231,3 +259,3 @@ }

return new Promise((resolve, reject) => {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
reject(new error_1.SecurePassError(`Length of Password Buffer must be between ${SecurePass.PasswordBytesMin} and ${SecurePass.PasswordBytesMax}`));

@@ -270,3 +298,3 @@ }

*/
SecurePass.PasswordBytesMax = 4294967295;
SecurePass.PasswordBytesMax = 2147483647;
/**

@@ -318,2 +346,3 @@ * Length of the Password Hash output buffer.

* Use of this option requires a minimum of 1024 MiB of dedicated RAM.
* @readonly
*/

@@ -357,2 +386,3 @@ SecurePass.MemLimitSensitive = 1073741824;

* Using this option it takes around 3.5 seconds to derrive a hash on a 2.8Ghz Core i7 CPU.
* @readonly
*/

@@ -359,0 +389,0 @@ SecurePass.OpsLimitSensitive = 4;

{
"name": "argon2-pass",
"version": "0.2.1",
"version": "0.2.2",
"description": "State of the art password hashing and one time password reset token generation module written in TypeScript for nodejs.",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

@@ -5,3 +5,3 @@ import { bufferFromSafeBase64, bufferToSafeBase64 } from '..';

describe('bufferFromSafeBase64', () => {
test('Should convert a valid base64 string into a buffer.', () => {
test('Should convert a valid url-safe base64 string into a buffer.', () => {
const expected = Buffer.from('TestString');

@@ -14,6 +14,8 @@ const buffer = bufferFromSafeBase64('VGVzdFN0cmluZw');

describe('bufferToSafeBase64', () => {
const expected = 'VGVzdFN0cmluZw';
const base64 = bufferToSafeBase64(Buffer.from('TestString'));
expect(base64).toEqual(expected);
test('Should convert a buffer into a valid url-safe base64 string.', () => {
const expected = 'VGVzdFN0cmluZw';
const base64 = bufferToSafeBase64(Buffer.from('TestString'));
expect(base64).toEqual(expected);
});
});
});

@@ -5,25 +5,12 @@ import sodium from 'sodium-native';

describe('SecurePass - Constants', () => {
test('PasswordBytes* Constants should be defined.', () => {
describe('SecurePass', () => {
test('static readonly constants should be defined.', () => {
expect(SecurePass.PasswordBytesMin).toBeDefined();
expect(SecurePass.PasswordBytesMax).toBeDefined();
expect(SecurePass.PasswordBytesMin).toBeDefined();
});
test('HashBytes Constant should be defined.', () => {
expect(SecurePass.HashBytes).toBeDefined();
});
test('SaltBytes Constant should be defined', () => {
expect(SecurePass.SaltBytes).toBeDefined();
});
test('MacBytes Constant should be defined.', () => {
expect(SecurePass.MacBytes).toBeDefined();
});
test('KeyBytes Constant should be defined.', () => {
expect(SecurePass.KeyBytes).toBeDefined();
});
test('MemLimit* Constants should be defined.', () => {
// Memory Limit Constants
expect(SecurePass.MemLimitDefault).toBeDefined();

@@ -35,5 +22,4 @@ expect(SecurePass.MemLimitInteractive).toBeDefined();

expect(SecurePass.MemLimitMaximum).toBeDefined();
});
test('OpsLimit* Constants should be defined.', () => {
// Operations Limit Constants
expect(SecurePass.OpsLimitDefault).toBeDefined();

@@ -47,157 +33,206 @@ expect(SecurePass.OpsLimitInteractive).toBeDefined();

test('VerificationResult.* Enum Constants should be defined.', () => {
expect(VerificationResult.InvalidOrUnrecognized).toEqual(0);
expect(VerificationResult.Invalid).toEqual(1);
expect(VerificationResult.Valid).toEqual(2);
expect(VerificationResult.ValidNeedsRehash).toEqual(3);
});
});
test('static readonly constants should have the correct values.', () => {
expect(SecurePass.PasswordBytesMin).toEqual(1);
expect(SecurePass.PasswordBytesMax).toEqual(2147483647);
expect(SecurePass.HashBytes).toEqual(128);
expect(SecurePass.SaltBytes).toEqual(16);
expect(SecurePass.MacBytes).toEqual(16);
expect(SecurePass.KeyBytes).toEqual(32);
describe('SecurePass - Options', () => {
test('Passing no configuration should create a new instance with the default options.', () => {
const sp = new SecurePass();
expect(sp.MemLimit).toEqual(sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE);
expect(sp.OpsLimit).toEqual(sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE);
});
// Memory Limit Constants
expect(SecurePass.MemLimitDefault).toEqual(67108864);
expect(SecurePass.MemLimitInteractive).toEqual(67108864);
expect(SecurePass.MemLimitModerate).toEqual(268435456);
expect(SecurePass.MemLimitSensitive).toEqual(1073741824);
expect(SecurePass.MemLimitMinimum).toEqual(8192);
expect(SecurePass.MemLimitMaximum).toEqual(4398046510080);
test('Passing in an empty object should create a new instance with the default options.', () => {
const sp = new SecurePass({});
expect(sp.MemLimit).toEqual(sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE);
expect(sp.OpsLimit).toEqual(sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE);
// Operations Limit Constants
expect(SecurePass.OpsLimitDefault).toEqual(2);
expect(SecurePass.OpsLimitInteractive).toEqual(2);
expect(SecurePass.OpsLimitModerate).toEqual(3);
expect(SecurePass.OpsLimitSensitive).toEqual(4);
expect(SecurePass.OpsLimitMinimum).toEqual(1);
expect(SecurePass.OpsLimitMaximum).toEqual(4294967295);
});
test('A valid value for memLimit should be set correctly. And opsLimit should be set to the default value.', () => {
const sp = new SecurePass({
memLimit: 16384
describe('VerificationResult', () => {
test('VerificationResult enumeration has the right values.', () => {
expect(VerificationResult.InvalidOrUnrecognized).toEqual(0);
expect(VerificationResult.Invalid).toEqual(1);
expect(VerificationResult.Valid).toEqual(2);
expect(VerificationResult.ValidNeedsRehash).toEqual(3);
});
expect(sp.MemLimit).toEqual(16384);
expect(sp.OpsLimit).toEqual(sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE);
});
test('A valid value for opsLimit should be set correctly. And memLimit should be set to the default value.', () => {
const sp = new SecurePass({
opsLimit: 12
test.each([
[VerificationResult.InvalidOrUnrecognized, true],
[VerificationResult.Invalid, false],
[VerificationResult.Valid, false],
[VerificationResult.ValidNeedsRehash, false]
])('isInvalidOrUnrecognized should return the correct result when called with %i.', (vr, b) => {
expect(SecurePass.isInvalidOrUnrecognized(vr)).toEqual(b);
});
expect(sp.MemLimit).toEqual(sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE);
expect(sp.OpsLimit).toEqual(12);
});
test('A lower bounds value for memLimit should still be considered valid.', () => {
const sp = new SecurePass({
memLimit: SecurePass.MemLimitMinimum
test.each([
[VerificationResult.InvalidOrUnrecognized, false],
[VerificationResult.Invalid, true],
[VerificationResult.Valid, false],
[VerificationResult.ValidNeedsRehash, false]
])('isInvalid should return the correct result when called with %i.', (vr, b) => {
expect(SecurePass.isInvalid(vr)).toEqual(b);
});
expect(sp.MemLimit).toEqual(SecurePass.MemLimitMinimum);
});
test('An upper bounds value for memLimit should still be considered valid.', () => {
const sp = new SecurePass({
memLimit: SecurePass.MemLimitMaximum
test.each([
[VerificationResult.InvalidOrUnrecognized, false],
[VerificationResult.Invalid, false],
[VerificationResult.Valid, true],
[VerificationResult.ValidNeedsRehash, false]
])('isValid should return the correct result when called with %i.', (vr, b) => {
expect(SecurePass.isValid(vr)).toEqual(b);
});
expect(sp.MemLimit).toEqual(SecurePass.MemLimitMaximum);
});
test('A lower bounds value for opsLimit should still be considered valid.', () => {
const sp = new SecurePass({
opsLimit: SecurePass.OpsLimitMinimum
test.each([
[VerificationResult.InvalidOrUnrecognized, false],
[VerificationResult.Invalid, false],
[VerificationResult.Valid, false],
[VerificationResult.ValidNeedsRehash, true]
])('isValidNeedsRehash should return the correct result when called with %i.', (vr, b) => {
expect(SecurePass.isValidNeedsRehash(vr)).toEqual(b);
});
expect(sp.OpsLimit).toEqual(SecurePass.OpsLimitMinimum);
});
test('An upper bounds value for opsLimit should still be considered valid.', () => {
const sp = new SecurePass({
opsLimit: SecurePass.OpsLimitMaximum
describe('SecurePass MemLimit and OpsLimit Options', () => {
test('Passing no configuration to SecurePass, should create a new instance with the default values', () => {
const sp1 = new SecurePass();
expect(sp1.MemLimit).toEqual(SecurePass.MemLimitDefault);
expect(sp1.OpsLimit).toEqual(SecurePass.OpsLimitDefault);
const sp2 = new SecurePass({});
expect(sp2.MemLimit).toEqual(SecurePass.MemLimitDefault);
expect(sp2.OpsLimit).toEqual(SecurePass.OpsLimitDefault);
});
expect(sp.OpsLimit).toEqual(SecurePass.OpsLimitMaximum);
});
test('An invalid value for memLimit should throw an error.', () => {
try {
test('Passing no value for memLimit, should result in the default value being set.', () => {
const sp = new SecurePass({
memLimit: 1
opsLimit: 6
});
} catch (e) {
expect(e).toBeDefined();
expect(e instanceof SecurePassOptionsError).toBeTruthy();
}
});
expect(sp.MemLimit).toEqual(SecurePass.MemLimitDefault);
});
test('An invalid value for opsLimit should throw an error.', () => {
try {
test('Passing no value for opsLimit, should result in the default value being set.', () => {
const sp = new SecurePass({
opsLimit: SecurePass.OpsLimitMaximum + 1
memLimit: 16 * 1024
});
} catch (e) {
expect(e).toBeDefined();
expect(e instanceof SecurePassOptionsError).toBeTruthy();
}
});
describe('get and set - MemLimit', () => {
test('MemLimit should return the currently configured Memory Limit.', () => {
const sp = new SecurePass({
memLimit: SecurePass.MemLimitSensitive
});
expect(sp.MemLimit).toEqual(SecurePass.MemLimitSensitive);
expect(sp.OpsLimit).toEqual(SecurePass.OpsLimitDefault);
});
test('MemLimit should set the configured Memory Limit to the new limit.', () => {
const sp = new SecurePass();
// Test Valid Values for MemLimit, Including Upper and Lower Bounds.
describe.each([SecurePass.MemLimitInteractive, SecurePass.MemLimitMinimum, SecurePass.MemLimitMaximum])(
'Valid and Edge Case values for MemLimit.',
m => {
test(`${m} should be a valid value for MemLimit, when passed in the constructor.`, () => {
const sp = new SecurePass({
memLimit: m
});
expect(sp.MemLimit).toEqual(m);
});
sp.MemLimit = SecurePass.MemLimitModerate;
test(`${m} should be a valid value for MemLimit, when set with the accessor.`, () => {
const sp = new SecurePass();
sp.MemLimit = m;
expect(sp.MemLimit).toEqual(m);
});
}
);
expect(sp.MemLimit).toEqual(SecurePass.MemLimitModerate);
});
// Test Valid Values for OpsLimit, Including Upper and Lower Bounds.
describe.each([SecurePass.OpsLimitInteractive, SecurePass.OpsLimitMinimum, SecurePass.OpsLimitMaximum])(
'Valid and Edge Case values for OpsLimit.',
o => {
test(`${o} should be a valid value for OpsLimit, when passed in the constructor.`, () => {
const sp = new SecurePass({
opsLimit: o
});
expect(sp.OpsLimit).toEqual(o);
});
test('MemLimit should throw an error if set with an invalid memory limit.', () => {
const sp = new SecurePass();
try {
sp.MemLimit = 1024;
} catch (e) {
expect(e instanceof SecurePassOptionsError).toBeTruthy();
test(`${o} should be a valid value for OpsLimit, when set with the accessor.`, () => {
const sp = new SecurePass();
sp.OpsLimit = o;
expect(sp.OpsLimit).toEqual(o);
});
}
});
});
);
describe('get and set - OpsLimit', () => {
test('OpsLimit should return the currently configured Memory Limit.', () => {
const sp = new SecurePass({
opsLimit: SecurePass.OpsLimitSensitive
});
// Test Invalid Values for MemLimit.
describe.each([SecurePass.MemLimitMinimum - 1, SecurePass.MemLimitMaximum + 1])(
'Invalid Values for MemLimit.',
m => {
test(`${m} should be an invalid value for MemLimit, when passed in the constructor.`, () => {
try {
const sp = new SecurePass({
memLimit: m
});
expect(sp.OpsLimit).toEqual(SecurePass.OpsLimitSensitive);
});
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
} catch (e) {
expect(e instanceof SecurePassOptionsError).toBeTruthy();
}
});
test('OpsLimit should set the configured Memory Limit to the new limit.', () => {
const sp = new SecurePass();
test(`${m} should be an invalid value for MemLimit, when set with the accessor.`, () => {
try {
const sp = new SecurePass();
sp.MemLimit = m;
sp.OpsLimit = SecurePass.OpsLimitModerate;
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
} catch (e) {
expect(e instanceof SecurePassOptionsError).toBeTruthy();
}
});
}
);
expect(sp.OpsLimit).toEqual(SecurePass.OpsLimitModerate);
});
// Test Invalid Values for OpsLimit.
describe.each([SecurePass.OpsLimitMinimum - 1, SecurePass.OpsLimitMaximum + 1])(
'Invalid Values for OpsLimit.',
o => {
test(`${o} should be an invalid value for OpsLimit, when passed in the constructor.`, () => {
try {
const sp = new SecurePass({
opsLimit: o
});
test('OpsLimit should throw an error if set with an invalid memory limit.', () => {
const sp = new SecurePass();
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
} catch (e) {
expect(e instanceof SecurePassOptionsError).toBeTruthy();
}
});
try {
sp.OpsLimit = SecurePass.OpsLimitMaximum + 1;
} catch (e) {
expect(e instanceof SecurePassOptionsError).toBeTruthy();
test(`${o} should be an invalid value for OpsLimit, when set with the accessor.`, () => {
try {
const sp = new SecurePass();
sp.OpsLimit = o;
// Makes sure that the error is thrown.
expect(true).toBeFalsy();
} catch (e) {
expect(e instanceof SecurePassOptionsError).toBeTruthy();
}
});
}
});
);
});
});
describe('SecurePass - Static Functions', () => {
describe('generateOneTimeAuth()', () => {
test('Should return a mac, key and the original message.', () => {
test('Should return a mac, random key and the original message.', () => {
const message = Buffer.from('ExampleMessage');
const result = SecurePass.generateOneTimeAuth(message);
expect(result.mac).toBeDefined();
expect(result.mac.length).toEqual(sodium.crypto_onetimeauth_BYTES);
expect(result.message).toBeDefined();
expect(result.mac.length).toEqual(SecurePass.MacBytes);
expect(result.message.compare(message)).toEqual(0);
expect(result.key).toBeDefined();
expect(result.key.length).toEqual(sodium.crypto_onetimeauth_KEYBYTES);
expect(result.key.length).toEqual(SecurePass.KeyBytes);
});

@@ -207,3 +242,3 @@ });

describe('verifyOneTimeAuth()', () => {
test('Should return true if the message, mac and key match.', () => {
test('Should return true if the message, mac and random key match.', () => {
const message = Buffer.from('ExampleMessage');

@@ -213,3 +248,3 @@ const ota = SecurePass.generateOneTimeAuth(message);

const result = SecurePass.verifyOneTimeAuth(ota.mac, message, ota.key);
expect(result).toBeDefined();
expect(result).toBeTruthy();

@@ -222,5 +257,5 @@ });

const badMessage = Buffer.from('ExampleBad');
const badMessage = Buffer.from('ExampleMessageBad');
const result = SecurePass.verifyOneTimeAuth(ota.mac, badMessage, ota.key);
expect(result).toBeDefined();
expect(result).toBeFalsy();

@@ -233,15 +268,15 @@ });

const badMac = Buffer.alloc(sodium.crypto_onetimeauth_BYTES);
const badMac = Buffer.alloc(SecurePass.MacBytes);
const result = SecurePass.verifyOneTimeAuth(badMac, message, ota.key);
expect(result).toBeDefined();
expect(result).toBeFalsy();
});
test('Should return false if the key does not match the message and mac.', () => {
test('Should return false if the random key does not match the message and mac.', () => {
const message = Buffer.from('ExampleMessage');
const ota = SecurePass.generateOneTimeAuth(message);
const badKey = Buffer.alloc(sodium.crypto_onetimeauth_KEYBYTES);
const badKey = Buffer.alloc(SecurePass.KeyBytes);
const result = SecurePass.verifyOneTimeAuth(ota.mac, message, badKey);
expect(result).toBeDefined();
expect(result).toBeFalsy();

@@ -252,10 +287,8 @@ });

describe('generateOneTimeAuthCode()', () => {
test('Should return a code string and a key buffer.', () => {
test('Should return a valid code and a key buffer.', () => {
const message = Buffer.from('ExampleMessage');
const result = SecurePass.generateOneTimeAuthCode(message);
expect(typeof result.code).toEqual('string');
expect(result.code.length > 0).toBeTruthy();
expect(result.code.indexOf('~')).toBeTruthy();
expect(result.key instanceof Buffer).toBeTruthy();
expect(result.key.length).toEqual(sodium.crypto_onetimeauth_KEYBYTES);
const otac = SecurePass.generateOneTimeAuthCode(message);
expect(otac.code.indexOf('~')).not.toEqual(-1);
expect(otac.key.length).toEqual(SecurePass.KeyBytes);
});

@@ -265,24 +298,22 @@ });

describe('verifyOneTimeAuthCode()', () => {
test('Should return true when used with a valid code and key.', () => {
test('Should return true when called with a valid code and key.', () => {
const message = Buffer.from('ExampleMessage');
const ota = SecurePass.generateOneTimeAuthCode(message);
const otac = SecurePass.generateOneTimeAuthCode(message);
const result = SecurePass.verifyOneTimeAuthCode(ota.code, ota.key);
const result = SecurePass.verifyOneTimeAuthCode(otac.code, otac.key);
expect(result).toBeTruthy();
});
test('Should return false when used with an invalid key.', () => {
test('Should return false if called with an invalid key.', () => {
const message = Buffer.from('ExampleMessage');
const ota = SecurePass.generateOneTimeAuthCode(message);
const otac = SecurePass.generateOneTimeAuthCode(message);
const badKey = Buffer.alloc(sodium.crypto_onetimeauth_KEYBYTES);
const result = SecurePass.verifyOneTimeAuthCode(ota.code, badKey);
const badKey = Buffer.alloc(SecurePass.KeyBytes);
const result = SecurePass.verifyOneTimeAuthCode(otac.code, badKey);
expect(result).toBeFalsy();
});
});
});
describe('SecurePass - Functions', () => {
describe('async/promise hashPassword()', () => {
test('Should return a string if given a valid password buffer.', async () => {
test('Should return a hash if given a valid password.', async done => {
const sp = new SecurePass();

@@ -294,21 +325,41 @@

expect(hash.length).toEqual(SecurePass.HashBytes);
expect(hash.toString().length > 0).toBeTruthy();
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
});
test('Should return an error if given a blank password buffer.', async () => {
const sp = new SecurePass();
test.each([SecurePass.PasswordBytesMin, SecurePass.PasswordBytesMax])(
'Should return a hash if given a password buffer of length %1.',
async (p, done) => {
const sp = new SecurePass();
const password = Buffer.alloc(p, 'f');
const hash = await sp.hashPassword(password);
try {
const password = Buffer.from('');
const hash = await sp.hashPassword(password);
} catch (e) {
expect(e).toBeDefined();
expect(e instanceof SecurePassError).toBeTruthy();
expect(hash.length).toEqual(SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
}
});
);
test.each([SecurePass.PasswordBytesMin - 1, SecurePass.PasswordBytesMax + 1])(
'Should throw an error if given a password buffer of length %i.',
async (p, done) => {
try {
const sp = new SecurePass();
const password = Buffer.alloc(p, 'f');
const hash = await sp.hashPassword(password);
expect(false).toBeTruthy();
done();
} catch (e) {
expect(e).toBeDefined();
done();
}
}
);
});
describe('callback hashPassword()', () => {
test('Should return a string if given a valid password buffer.', done => {
test('Should return a hash if given a valid password.', done => {
const sp = new SecurePass();

@@ -318,5 +369,10 @@

sp.hashPassword(password, (err: SecurePassError | null, hash?: Buffer) => {
expect(err).toBeNull();
expect(hash).toBeDefined();
if (err || hash == undefined) {
expect(false).toBeTruthy();
return;
}
expect(hash.length).toEqual(SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();

@@ -326,18 +382,45 @@ });

test('Should return an error if given a blank password buffer.', done => {
const sp = new SecurePass();
test.each([SecurePass.PasswordBytesMin, SecurePass.PasswordBytesMax])(
'Should return a hash if given a password buffer of length %1.',
async (p, done) => {
const sp = new SecurePass();
const password = Buffer.alloc(p, 'f');
sp.hashPassword(password, (err: SecurePassError | null, hash?: Buffer) => {
if (err || hash == undefined) {
expect(false).toBeTruthy();
return;
}
const password = Buffer.from('');
sp.hashPassword(password, (err: SecurePassError | null, hash?: Buffer) => {
expect(err).toBeDefined();
expect(err instanceof SecurePassError).toBeTruthy();
expect(hash).toBeUndefined();
expect(hash.length).toEqual(SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
done();
});
});
done();
});
}
);
test.each([SecurePass.PasswordBytesMin - 1, SecurePass.PasswordBytesMax + 1])(
'Should throw an error if given a password buffer of length %i.',
async (p, done) => {
const sp = new SecurePass();
try {
const password = Buffer.alloc(p, 'f');
sp.hashPassword(password, (err: SecurePassError | null, hash?: Buffer) => {
expect(err instanceof SecurePassError).toBeTruthy();
expect(hash).toBeUndefined();
done();
});
} catch (e) {
expect(e).toBeDefined();
done();
}
}
);
});
describe('hashPasswordSync', () => {
test('Should return a valid hash if given a valid password.', done => {
describe('hashPasswordSync()', () => {
test('Should return a hash if given a valid password.', done => {
const sp = new SecurePass();

@@ -349,3 +432,3 @@

expect(hash.length).toEqual(SecurePass.HashBytes);
expect(sp.verifyHashSync(password, hash)).toEqual(VerificationResult.Valid);
expect(hash.indexOf('$argon2id')).toEqual(0);

@@ -355,16 +438,32 @@ done();

test('Should throw an error if given a blank password buffer.', done => {
const sp = new SecurePass();
test.each([SecurePass.PasswordBytesMin, SecurePass.PasswordBytesMax])(
'Should return a hash if given a password buffer of length %1.',
(p, done) => {
const sp = new SecurePass();
const password = Buffer.alloc(p, 'f');
const hash = sp.hashPasswordSync(password);
const password = Buffer.from('');
expect(hash.length).toEqual(SecurePass.HashBytes);
expect(hash.indexOf('$argon2id')).toEqual(0);
try {
const hash = sp.hashPasswordSync(password);
} catch (e) {
expect(e).toBeDefined();
expect(e instanceof SecurePassError).toBeTruthy();
done();
}
);
done();
});
test.each([SecurePass.PasswordBytesMin - 1, SecurePass.PasswordBytesMax + 1])(
'Should throw an error if given a password buffer of length %i.',
(p, done) => {
try {
const sp = new SecurePass();
const password = Buffer.alloc(p, 'f');
const hash = sp.hashPasswordSync(password);
expect(false).toBeTruthy();
done();
} catch (e) {
expect(e).toBeDefined();
done();
}
}
);
});

@@ -371,0 +470,0 @@

@@ -73,3 +73,3 @@ /**

*/
public static readonly PasswordBytesMax: number = 4294967295;
public static readonly PasswordBytesMax: number = 2147483647;

@@ -129,2 +129,3 @@ /**

* Use of this option requires a minimum of 1024 MiB of dedicated RAM.
* @readonly
*/

@@ -174,2 +175,3 @@ public static readonly MemLimitSensitive: number = 1073741824;

* Using this option it takes around 3.5 seconds to derrive a hash on a 2.8Ghz Core i7 CPU.
* @readonly
*/

@@ -242,2 +244,34 @@ public static readonly OpsLimitSensitive: number = 4;

/**
* Tests a VerificationResult enumeration and returns true if the value is InvalidOrUnrecognized.
* @param vr - The VerificationResult to Test.
*/
public static isInvalidOrUnrecognized(vr: VerificationResult): boolean {
return vr == VerificationResult.InvalidOrUnrecognized;
}
/**
* Tests a VerificationResult enumeration and returns true if the value is Invalid.
* @param vr - The VerificationResult to Test.
*/
public static isInvalid(vr: VerificationResult): boolean {
return vr == VerificationResult.Invalid;
}
/**
* Tests a VerificationResult enumeration and returns true if the value is Valid.
* @param vr - The VerificationResult to Test.
*/
public static isValid(vr: VerificationResult): boolean {
return vr == VerificationResult.Valid;
}
/**
* Tests a VerificationResult enumeration and returns true if the value is ValidNeedsRehash.
* @param vr - The VerificationResult to Test.
*/
public static isValidNeedsRehash(vr: VerificationResult): boolean {
return vr == VerificationResult.ValidNeedsRehash;
}
/**
* Configured memory limit for Argon2ID.

@@ -363,3 +397,3 @@ */

public hashPasswordSync(password: Buffer): Buffer {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
throw new SecurePassError(

@@ -399,3 +433,3 @@ `Length of Password Buffer must be between ${SecurePass.PasswordBytesMin} and ${SecurePass.PasswordBytesMax}`

public verifyHashSync(password: Buffer, hash: Buffer): VerificationResult {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
throw new SecurePassError(

@@ -427,3 +461,3 @@ `Length of Password Buffer must be between ${SecurePass.PasswordBytesMin} and ${SecurePass.PasswordBytesMax}`

return new Promise<Buffer>((resolve, reject) => {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
reject(

@@ -452,3 +486,3 @@ new SecurePassError(

return new Promise<VerificationResult>((resolve, reject) => {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length < SecurePass.PasswordBytesMax)) {
if (!(password.length >= SecurePass.PasswordBytesMin && password.length <= SecurePass.PasswordBytesMax)) {
reject(

@@ -455,0 +489,0 @@ new SecurePassError(

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc