X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fhotp.js;h=1fa41c9406301f8e2809d04a96bc7b3f6fd17cd7;hb=refs%2Fheads%2Fmaster;hp=90942cc4b4691af0cd05bd9e3c379b92a650caca;hpb=e6793fe68b6066fa5672eda73a5dd76c7c6f48b9;p=squeep-totp diff --git a/lib/hotp.js b/lib/hotp.js index 90942cc..1fa41c9 100644 --- a/lib/hotp.js +++ b/lib/hotp.js @@ -3,18 +3,18 @@ const crypto = require('node:crypto'); const B32 = require('base32.js'); const QRCode = require('qrcode-svg'); -const { promisify } = require('util'); +const { promisify } = require('node:util'); const randomBytesAsync = promisify(crypto.randomBytes); class HMACBasedOneTimePassword { /** * - * @param {Object} options - * @param {Buffer|String} options.key - * @param {String=} options.keyEncoding - * @param {Number=} options.codeLength - * @param {BigInt|Number|String=} options.counter - * @param {String=} options.algorithm + * @param {object} options options + * @param {Buffer|string} options.key key + * @param {string=} options.keyEncoding key encoding + * @param {number=} options.codeLength digits in code + * @param {bigint|number|string=} options.counter initial counter value + * @param {string=} options.algorithm algorithm */ constructor(options) { Object.assign(this, this.constructor._defaultOptions, options); @@ -39,6 +39,7 @@ class HMACBasedOneTimePassword { /** * The type used when constructing the otpauth URI. + * @returns {string} otpauth type */ static get _type() { return 'hotp'; @@ -61,8 +62,8 @@ class HMACBasedOneTimePassword { /** * - * @param {String} algorithm - * @returns {Number} + * @param {string} algorithm algorithm + * @returns {number} bytes */ static _algorithmKeyLength(algorithm) { if (!(this._algorithmKeyLengths[algorithm])) { // eslint-disable-line security/detect-object-injection @@ -83,8 +84,8 @@ class HMACBasedOneTimePassword { /** * - * @param {BigInt} count - * @returns {Buffer} + * @param {bigint} count counter value + * @returns {Buffer} hmac */ _hmac(count) { const counterBuffer = Buffer.alloc(8); @@ -96,8 +97,8 @@ class HMACBasedOneTimePassword { /** * - * @param {BigInt} count - * @returns {Number} + * @param {bigint} count counter value + * @returns {number} partial extracted hmac */ _truncate(count) { const digest = this._hmac(count); @@ -107,8 +108,8 @@ class HMACBasedOneTimePassword { /** * - * @param {BigInt=} count - * @returns {String} + * @param {bigint=} count counter value + * @returns {string} code */ generate(count) { const code = this._truncate(count ?? this.counter); @@ -121,9 +122,9 @@ class HMACBasedOneTimePassword { /** * Check a code against expected. - * @param {String} hotp - * @param {BigInt=} count - * @returns {Boolean} + * @param {string} hotp code to check + * @param {bigint=} count counter value + * @returns {boolean} is valid */ validate(hotp, count) { const codeString = this.generate(count); @@ -132,9 +133,9 @@ class HMACBasedOneTimePassword { /** * Make a new key, of the assigned encoding. - * @param {String=} encoding - * @param {String=} algorithm - * @returns {Promise} + * @param {string=} algorithm algorithm + * @param {string=} encoding encoding + * @returns {Promise} key */ static async createKey(algorithm = 'sha1', encoding = 'hex') { const key = await randomBytesAsync(this._algorithmKeyLength(algorithm)); @@ -149,35 +150,35 @@ class HMACBasedOneTimePassword { } /** - * @typedef {Object} OtpAuthData - * @property {String} secret - * @property {String} svg - * @property {String} uri + * @typedef {object} OtpAuthData + * @property {string} secret secret + * @property {string} svg svg of qr otpauth uri + * @property {string} uri uri */ /** * Given a key, return data suitable for an authenticator client to ingest * it, as a qrcode SVG, the otpauth uri encoded in the qrcode SVG, and the * secret key encoded as base32. - * @param {Object} options - * @param {String} options.accountname - * @param {BigInt=} options.counter - * @param {String=} options.issuer - * @param {String=} options.scheme - * @param {String=} options.type - * @param {String=} options.algorithm - * @param {String=} options.digits - * @param {Number=} options.svgPadding - * @param {Number=} options.svgWidth - * @param {Number=} options.svgHeight - * @param {String=} options.svgFg - * @param {String=} options.svgBg - * @param {String=} options.svgEcl - * @param {Boolean=} options.join - * @param {Boolean=} options.xmlDeclaration - * @param {String=} options.container - * @param {String|Buffer} key - * @param {String=} keyEncoding - * @returns {OtpAuthData} + * @param {object} options options + * @param {string} options.accountname descriptive account name to include in uri + * @param {bigint=} options.counter initial counter value + * @param {string=} options.issuer issuer + * @param {string=} options.scheme scheme + * @param {string=} options.type type + * @param {string=} options.algorithm algorithm + * @param {string=} options.digits digits in code + * @param {number=} options.svgPadding qr svg padding + * @param {number=} options.svgWidth qr svg width + * @param {number=} options.svgHeight qr svg height + * @param {string=} options.svgFg qr svg foreground + * @param {string=} options.svgBg qr svg background + * @param {string=} options.svgEcl qr svg encoding resiliancy + * @param {boolean=} options.join qr svg construction option + * @param {boolean=} options.xmlDeclaration qr svg option + * @param {string=} options.container qr svg option + * @param {string|Buffer} key secret key + * @param {string=} keyEncoding secret key encoding + * @returns {OtpAuthData} otp auth */ static createKeySVG(options, key, keyEncoding = 'hex') { // Normalize key to base32 ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 string (rfc4648) @@ -223,15 +224,16 @@ class HMACBasedOneTimePassword { /** * Render parameters as an otpauth URI. - * @param {Object} options - * @param {String} options.accountname - * @param {String} options.secret base32 - * @param {BigInt=} options.counter - * @param {String=} options.issuer - * @param {String=} options.scheme - * @param {String=} options.type - * @param {String=} options.algorithm - * @param {String=} options.digits + * @param {object} options options + * @param {string} options.accountname account name + * @param {string} options.secret base32 encoded secret + * @param {bigint=} options.counter counter value + * @param {string=} options.issuer issuer + * @param {string=} options.scheme scheme + * @param {string=} options.type otp auth type + * @param {string=} options.algorithm algorithm + * @param {string=} options.digits digits in code + * @returns {string} url */ static _qrURI(options) { const {