+ describe('createKey', function () {
+ const algorithm = 'sha1';
+ it('creates a sha1 key by default', async function () {
+ const key = await HOTP.createKey();
+ assert.strictEqual(key.length, 40);
+ });
+ it('creates a sha1 key', async function () {
+ const key = await HOTP.createKey(algorithm);
+ assert.strictEqual(key.length, 40);
+ });
+ it('creates a sha1 key in base32 encoding', async function () {
+ const key = await HOTP.createKey(algorithm, 'base32');
+ assert.strictEqual(key.length, 32);
+ });
+ it('creates a sha1 key in alternate encoding', async function () {
+ const key = await HOTP.createKey(algorithm, 'base64');
+ assert.strictEqual(key.length, 28);
+ });
+ it('creates a sha1 key as a buffer', async function () {
+ const key = await HOTP.createKey(algorithm, 'buffer');
+ assert(Buffer.isBuffer(key));
+ });
+ it('rejects unknown algorithm', async function () {
+ await assert.rejects(() => HOTP.createKey('md5'), RangeError);
+ });
+ }); // createKey
+
+ describe('createKeySVG', function () {
+ let options, key, keyEncoding;
+ beforeEach(function () {
+ options = {
+ issuer: 'Squeep',
+ accountname: 'test@example.com',
+ counter: 0n,
+ };
+ key = undefined;
+ keyEncoding = undefined;
+ });
+ it('creates an svg from base32 key', function () {
+ key = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ';
+ keyEncoding = 'base32';
+ const { secret, svg, uri } = HOTP.createKeySVG(options, key, keyEncoding);
+ assert(svg);
+ assert(uri.includes('hotp'));
+ assert.strictEqual(secret, 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ');
+ });
+ it('creates an svg from buffer key', function () {
+ key = Buffer.from('12345678901234567890');
+ keyEncoding = 'buffer';
+ const { secret, svg, uri } = HOTP.createKeySVG(options, key, keyEncoding);
+ assert(svg);
+ assert(uri.includes('hotp'));
+ assert.strictEqual(secret, 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ');
+ });
+ it('creates an svg from buffer key', function () {
+ key = Buffer.from('12345678901234567890');
+ const { secret, svg, uri } = HOTP.createKeySVG(options, key, keyEncoding);
+ assert(svg);
+ assert(uri.includes('hotp'));
+ assert.strictEqual(secret, 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ');
+ });
+ it('creates an svg from ascii key', function () {
+ key = '12345678901234567890';
+ keyEncoding = 'ascii';
+ const { secret, svg, uri } = HOTP.createKeySVG(options, key, keyEncoding);
+ assert(svg);
+ assert(uri.includes('hotp'));
+ assert.strictEqual(secret, 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ');
+ });
+ }); // createKeySVG
+
+ describe('_qrURI', function () {
+ let options;
+ beforeEach(function () {
+ options = {
+ secret: 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ',
+ accountname: 'test@example.com',
+ issuer: 'Squeep',
+ counter: 0n,
+ };
+ });
+ it('requires accountname', function () {
+ delete options.accountname;
+ assert.throws(() => HOTP._qrURI(options), RangeError);
+ });
+ it('requires secret', function () {
+ delete options.secret;
+ assert.throws(() => HOTP._qrURI(options), RangeError);
+ });
+ it('requires counter', function () {
+ delete options.counter;
+ assert.throws(() => HOTP._qrURI(options), RangeError);
+ });
+ it('requires secret', function () {
+ delete options.secret;
+ assert.throws(() => HOTP._qrURI(options), RangeError);
+ });
+ it('requires known digits', function () {
+ options.digits = 10;
+ assert.throws(() => HOTP._qrURI(options), RangeError);
+ });
+ it('requires known algorithm', function () {
+ options.algorithm = 'md5';
+ assert.throws(() => HOTP._qrURI(options), RangeError);
+ });
+ it('covers no issuer', function () {
+ delete options.issuer;
+ const uri = HOTP._qrURI(options);
+ assert(!uri.includes('issuer'));
+ });
+ it('covers params', function () {
+ options.digits = 6;
+ options.algorithm = 'sha1';
+ const uri = HOTP._qrURI(options);
+ assert(uri.includes('digits'));
+ assert(uri.includes('SHA1'));
+ });
+ }); // _qrURI
+