otpauth.node.min.mjs.map 40 KB

1
  1. {"version":3,"file":"otpauth.node.min.mjs","sources":["../src/internal/encoding/uint.js","../src/internal/global-scope.js","../src/internal/encoding/base32.js","../src/internal/encoding/hex.js","../src/internal/encoding/latin1.js","../src/internal/encoding/utf8.js","../src/secret.js","../src/internal/crypto/random-bytes.js","../src/hotp.js","../src/internal/crypto/hmac-digest.js","../src/internal/crypto/timing-safe-equal.js","../src/totp.js","../src/uri.js","../src/version.js"],"sourcesContent":["/**\n * Converts an integer to an Uint8Array.\n * @param {number} num Integer.\n * @returns {Uint8Array} Uint8Array.\n */\nconst uintDecode = (num) => {\n const buf = new ArrayBuffer(8);\n const arr = new Uint8Array(buf);\n let acc = num;\n\n for (let i = 7; i >= 0; i--) {\n if (acc === 0) break;\n arr[i] = acc & 255;\n acc -= arr[i];\n acc /= 256;\n }\n\n return arr;\n};\n\n/**\n * Converts an Uint8Array to an integer.\n * @param {Uint8Array} arr Uint8Array.\n * @returns {number} Integer.\n */\nconst uintEncode = (arr) => {\n let num = 0;\n\n for (let i = 0; i < arr.length; i++) {\n if (arr[i] !== 0) {\n num *= 256;\n num += arr[i];\n }\n }\n\n return num;\n};\n\nexport { uintDecode, uintEncode };\n","/**\n * \"globalThis\" ponyfill.\n * @see [A horrifying globalThis polyfill in universal JavaScript](https://mathiasbynens.be/notes/globalthis)\n * @type {Object.<string, *>}\n */\nconst globalScope = (() => {\n if (typeof globalThis === \"object\") return globalThis;\n else {\n Object.defineProperty(Object.prototype, \"__GLOBALTHIS__\", {\n get() {\n return this;\n },\n configurable: true,\n });\n try {\n // @ts-ignore\n // eslint-disable-next-line no-undef\n if (typeof __GLOBALTHIS__ !== \"undefined\") return __GLOBALTHIS__;\n } finally {\n // @ts-ignore\n delete Object.prototype.__GLOBALTHIS__;\n }\n }\n\n // Still unable to determine \"globalThis\", fall back to a naive method.\n if (typeof self !== \"undefined\") return self;\n else if (typeof window !== \"undefined\") return window;\n else if (typeof global !== \"undefined\") return global;\n\n return undefined;\n})();\n\nexport { globalScope };\n","/**\n * RFC 4648 base32 alphabet without pad.\n * @type {string}\n */\nconst ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\";\n\n/**\n * Converts a base32 string to an Uint8Array (RFC 4648).\n * @see [LinusU/base32-decode](https://github.com/LinusU/base32-decode)\n * @param {string} str Base32 string.\n * @returns {Uint8Array} Uint8Array.\n */\nconst base32Decode = (str) => {\n // Canonicalize to all upper case and remove padding if it exists.\n let end = str.length;\n while (str[end - 1] === \"=\") --end;\n const cstr = (end < str.length ? str.substring(0, end) : str).toUpperCase();\n\n const buf = new ArrayBuffer(((cstr.length * 5) / 8) | 0);\n const arr = new Uint8Array(buf);\n let bits = 0;\n let value = 0;\n let index = 0;\n\n for (let i = 0; i < cstr.length; i++) {\n const idx = ALPHABET.indexOf(cstr[i]);\n if (idx === -1) throw new TypeError(`Invalid character found: ${cstr[i]}`);\n\n value = (value << 5) | idx;\n bits += 5;\n\n if (bits >= 8) {\n bits -= 8;\n arr[index++] = value >>> bits;\n }\n }\n\n return arr;\n};\n\n/**\n * Converts an Uint8Array to a base32 string (RFC 4648).\n * @see [LinusU/base32-encode](https://github.com/LinusU/base32-encode)\n * @param {Uint8Array} arr Uint8Array.\n * @returns {string} Base32 string.\n */\nconst base32Encode = (arr) => {\n let bits = 0;\n let value = 0;\n let str = \"\";\n\n for (let i = 0; i < arr.length; i++) {\n value = (value << 8) | arr[i];\n bits += 8;\n\n while (bits >= 5) {\n str += ALPHABET[(value >>> (bits - 5)) & 31];\n bits -= 5;\n }\n }\n\n if (bits > 0) {\n str += ALPHABET[(value << (5 - bits)) & 31];\n }\n\n return str;\n};\n\nexport { base32Decode, base32Encode };\n","/**\n * Converts a hexadecimal string to an Uint8Array.\n * @param {string} str Hexadecimal string.\n * @returns {Uint8Array} Uint8Array.\n */\nconst hexDecode = (str) => {\n const buf = new ArrayBuffer(str.length / 2);\n const arr = new Uint8Array(buf);\n\n for (let i = 0; i < str.length; i += 2) {\n arr[i / 2] = parseInt(str.substring(i, i + 2), 16);\n }\n\n return arr;\n};\n\n/**\n * Converts an Uint8Array to a hexadecimal string.\n * @param {Uint8Array} arr Uint8Array.\n * @returns {string} Hexadecimal string.\n */\nconst hexEncode = (arr) => {\n let str = \"\";\n\n for (let i = 0; i < arr.length; i++) {\n const hex = arr[i].toString(16);\n if (hex.length === 1) str += \"0\";\n str += hex;\n }\n\n return str.toUpperCase();\n};\n\nexport { hexDecode, hexEncode };\n","/**\n * Converts a Latin-1 string to an Uint8Array.\n * @param {string} str Latin-1 string.\n * @returns {Uint8Array} Uint8Array.\n */\nconst latin1Decode = (str) => {\n const buf = new ArrayBuffer(str.length);\n const arr = new Uint8Array(buf);\n\n for (let i = 0; i < str.length; i++) {\n arr[i] = str.charCodeAt(i) & 0xff;\n }\n\n return arr;\n};\n\n/**\n * Converts an Uint8Array to a Latin-1 string.\n * @param {Uint8Array} arr Uint8Array.\n * @returns {string} Latin-1 string.\n */\nconst latin1Encode = (arr) => {\n let str = \"\";\n\n for (let i = 0; i < arr.length; i++) {\n str += String.fromCharCode(arr[i]);\n }\n\n return str;\n};\n\nexport { latin1Decode, latin1Encode };\n","import { globalScope } from \"../global-scope.js\";\n\n/**\n * TextEncoder instance.\n * @type {TextEncoder|null}\n */\nconst ENCODER = globalScope.TextEncoder ? new globalScope.TextEncoder() : null;\n\n/**\n * TextDecoder instance.\n * @type {TextDecoder|null}\n */\nconst DECODER = globalScope.TextDecoder ? new globalScope.TextDecoder() : null;\n\n/**\n * Converts an UTF-8 string to an Uint8Array.\n * @param {string} str String.\n * @returns {Uint8Array} Uint8Array.\n */\nconst utf8Decode = (str) => {\n if (!ENCODER) {\n throw new Error(\"Encoding API not available\");\n }\n\n return ENCODER.encode(str);\n};\n\n/**\n * Converts an Uint8Array to an UTF-8 string.\n * @param {Uint8Array} arr Uint8Array.\n * @returns {string} String.\n */\nconst utf8Encode = (arr) => {\n if (!DECODER) {\n throw new Error(\"Encoding API not available\");\n }\n\n return DECODER.decode(arr);\n};\n\nexport { utf8Decode, utf8Encode };\n","import { base32Decode, base32Encode } from \"./internal/encoding/base32.js\";\nimport { hexDecode, hexEncode } from \"./internal/encoding/hex.js\";\nimport { latin1Decode, latin1Encode } from \"./internal/encoding/latin1.js\";\nimport { utf8Decode, utf8Encode } from \"./internal/encoding/utf8.js\";\nimport { randomBytes } from \"./internal/crypto/random-bytes.js\";\n\n/**\n * OTP secret key.\n */\nclass Secret {\n /**\n * Creates a secret key object.\n * @param {Object} [config] Configuration options.\n * @param {ArrayBufferLike} [config.buffer] Secret key buffer.\n * @param {number} [config.size=20] Number of random bytes to generate, ignored if 'buffer' is provided.\n */\n constructor({ buffer, size = 20 } = {}) {\n /**\n * Secret key.\n * @type {Uint8Array}\n * @readonly\n */\n this.bytes = typeof buffer === \"undefined\" ? randomBytes(size) : new Uint8Array(buffer);\n\n // Prevent the \"bytes\" property from being modified.\n Object.defineProperty(this, \"bytes\", {\n enumerable: true,\n writable: false,\n configurable: false,\n value: this.bytes,\n });\n }\n\n /**\n * Converts a Latin-1 string to a Secret object.\n * @param {string} str Latin-1 string.\n * @returns {Secret} Secret object.\n */\n static fromLatin1(str) {\n return new Secret({ buffer: latin1Decode(str).buffer });\n }\n\n /**\n * Converts an UTF-8 string to a Secret object.\n * @param {string} str UTF-8 string.\n * @returns {Secret} Secret object.\n */\n static fromUTF8(str) {\n return new Secret({ buffer: utf8Decode(str).buffer });\n }\n\n /**\n * Converts a base32 string to a Secret object.\n * @param {string} str Base32 string.\n * @returns {Secret} Secret object.\n */\n static fromBase32(str) {\n return new Secret({ buffer: base32Decode(str).buffer });\n }\n\n /**\n * Converts a hexadecimal string to a Secret object.\n * @param {string} str Hexadecimal string.\n * @returns {Secret} Secret object.\n */\n static fromHex(str) {\n return new Secret({ buffer: hexDecode(str).buffer });\n }\n\n /**\n * Secret key buffer.\n * @deprecated For backward compatibility, the \"bytes\" property should be used instead.\n * @type {ArrayBufferLike}\n */\n get buffer() {\n return this.bytes.buffer;\n }\n\n /**\n * Latin-1 string representation of secret key.\n * @type {string}\n */\n get latin1() {\n Object.defineProperty(this, \"latin1\", {\n enumerable: true,\n writable: false,\n configurable: false,\n value: latin1Encode(this.bytes),\n });\n\n return this.latin1;\n }\n\n /**\n * UTF-8 string representation of secret key.\n * @type {string}\n */\n get utf8() {\n Object.defineProperty(this, \"utf8\", {\n enumerable: true,\n writable: false,\n configurable: false,\n value: utf8Encode(this.bytes),\n });\n\n return this.utf8;\n }\n\n /**\n * Base32 string representation of secret key.\n * @type {string}\n */\n get base32() {\n Object.defineProperty(this, \"base32\", {\n enumerable: true,\n writable: false,\n configurable: false,\n value: base32Encode(this.bytes),\n });\n\n return this.base32;\n }\n\n /**\n * Hexadecimal string representation of secret key.\n * @type {string}\n */\n get hex() {\n Object.defineProperty(this, \"hex\", {\n enumerable: true,\n writable: false,\n configurable: false,\n value: hexEncode(this.bytes),\n });\n\n return this.hex;\n }\n}\n\nexport { Secret };\n","import * as crypto from \"node:crypto\";\n\nimport { globalScope } from \"../global-scope.js\";\n\n/**\n * Returns random bytes.\n * @param {number} size Size.\n * @returns {Uint8Array} Random bytes.\n */\nconst randomBytes = (size) => {\n if (crypto?.randomBytes) {\n return crypto.randomBytes(size);\n } else {\n if (!globalScope.crypto?.getRandomValues) {\n throw new Error(\"Cryptography API not available\");\n }\n return globalScope.crypto.getRandomValues(new Uint8Array(size));\n }\n};\n\nexport { randomBytes };\n","import { uintDecode } from \"./internal/encoding/uint.js\";\nimport { hmacDigest } from \"./internal/crypto/hmac-digest.js\";\nimport { Secret } from \"./secret.js\";\nimport { timingSafeEqual } from \"./internal/crypto/timing-safe-equal.js\";\n\n/**\n * HOTP: An HMAC-based One-time Password Algorithm.\n * @see [RFC 4226](https://tools.ietf.org/html/rfc4226)\n */\nclass HOTP {\n /**\n * Default configuration.\n * @type {{\n * issuer: string,\n * label: string,\n * issuerInLabel: boolean,\n * algorithm: string,\n * digits: number,\n * counter: number\n * window: number\n * }}\n */\n static get defaults() {\n return {\n issuer: \"\",\n label: \"OTPAuth\",\n issuerInLabel: true,\n algorithm: \"SHA1\",\n digits: 6,\n counter: 0,\n window: 1,\n };\n }\n\n /**\n * Creates an HOTP object.\n * @param {Object} [config] Configuration options.\n * @param {string} [config.issuer=''] Account provider.\n * @param {string} [config.label='OTPAuth'] Account label.\n * @param {boolean} [config.issuerInLabel=true] Include issuer prefix in label.\n * @param {Secret|string} [config.secret=Secret] Secret key.\n * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.\n * @param {number} [config.digits=6] Token length.\n * @param {number} [config.counter=0] Initial counter value.\n */\n constructor({\n issuer = HOTP.defaults.issuer,\n label = HOTP.defaults.label,\n issuerInLabel = HOTP.defaults.issuerInLabel,\n secret = new Secret(),\n algorithm = HOTP.defaults.algorithm,\n digits = HOTP.defaults.digits,\n counter = HOTP.defaults.counter,\n } = {}) {\n /**\n * Account provider.\n * @type {string}\n */\n this.issuer = issuer;\n /**\n * Account label.\n * @type {string}\n */\n this.label = label;\n /**\n * Include issuer prefix in label.\n * @type {boolean}\n */\n this.issuerInLabel = issuerInLabel;\n /**\n * Secret key.\n * @type {Secret}\n */\n this.secret = typeof secret === \"string\" ? Secret.fromBase32(secret) : secret;\n /**\n * HMAC hashing algorithm.\n * @type {string}\n */\n this.algorithm = algorithm.toUpperCase();\n /**\n * Token length.\n * @type {number}\n */\n this.digits = digits;\n /**\n * Initial counter value.\n * @type {number}\n */\n this.counter = counter;\n }\n\n /**\n * Generates an HOTP token.\n * @param {Object} config Configuration options.\n * @param {Secret} config.secret Secret key.\n * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.\n * @param {number} [config.digits=6] Token length.\n * @param {number} [config.counter=0] Counter value.\n * @returns {string} Token.\n */\n static generate({\n secret,\n algorithm = HOTP.defaults.algorithm,\n digits = HOTP.defaults.digits,\n counter = HOTP.defaults.counter,\n }) {\n const digest = hmacDigest(algorithm, secret.bytes, uintDecode(counter));\n const offset = digest[digest.byteLength - 1] & 15;\n const otp =\n (((digest[offset] & 127) << 24) |\n ((digest[offset + 1] & 255) << 16) |\n ((digest[offset + 2] & 255) << 8) |\n (digest[offset + 3] & 255)) %\n 10 ** digits;\n\n return otp.toString().padStart(digits, \"0\");\n }\n\n /**\n * Generates an HOTP token.\n * @param {Object} [config] Configuration options.\n * @param {number} [config.counter=this.counter++] Counter value.\n * @returns {string} Token.\n */\n generate({ counter = this.counter++ } = {}) {\n return HOTP.generate({\n secret: this.secret,\n algorithm: this.algorithm,\n digits: this.digits,\n counter,\n });\n }\n\n /**\n * Validates an HOTP token.\n * @param {Object} config Configuration options.\n * @param {string} config.token Token value.\n * @param {Secret} config.secret Secret key.\n * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.\n * @param {number} config.digits Token length.\n * @param {number} [config.counter=0] Counter value.\n * @param {number} [config.window=1] Window of counter values to test.\n * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.\n */\n static validate({\n token,\n secret,\n algorithm,\n digits,\n counter = HOTP.defaults.counter,\n window = HOTP.defaults.window,\n }) {\n // Return early if the token length does not match the digit number.\n if (token.length !== digits) return null;\n\n let delta = null;\n\n const check = (/** @type {number} */ i) => {\n const generatedToken = HOTP.generate({\n secret,\n algorithm,\n digits,\n counter: i,\n });\n if (timingSafeEqual(token, generatedToken)) {\n delta = i - counter;\n }\n };\n\n check(counter);\n for (let i = 1; i <= window && delta === null; ++i) {\n check(counter - i);\n if (delta !== null) break;\n check(counter + i);\n if (delta !== null) break;\n }\n\n return delta;\n }\n\n /**\n * Validates an HOTP token.\n * @param {Object} config Configuration options.\n * @param {string} config.token Token value.\n * @param {number} [config.counter=this.counter] Counter value.\n * @param {number} [config.window=1] Window of counter values to test.\n * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.\n */\n validate({ token, counter = this.counter, window }) {\n return HOTP.validate({\n token,\n secret: this.secret,\n algorithm: this.algorithm,\n digits: this.digits,\n counter,\n window,\n });\n }\n\n /**\n * Returns a Google Authenticator key URI.\n * @returns {string} URI.\n */\n toString() {\n const e = encodeURIComponent;\n return (\n \"otpauth://hotp/\" +\n `${\n this.issuer.length > 0\n ? this.issuerInLabel\n ? `${e(this.issuer)}:${e(this.label)}?issuer=${e(this.issuer)}&`\n : `${e(this.label)}?issuer=${e(this.issuer)}&`\n : `${e(this.label)}?`\n }` +\n `secret=${e(this.secret.base32)}&` +\n `algorithm=${e(this.algorithm)}&` +\n `digits=${e(this.digits)}&` +\n `counter=${e(this.counter)}`\n );\n }\n}\n\nexport { HOTP };\n","import * as crypto from \"node:crypto\";\nimport { hmac } from \"@noble/hashes/hmac\";\nimport { sha1 } from \"@noble/hashes/sha1\";\nimport { sha224, sha256, sha384, sha512 } from \"@noble/hashes/sha2\";\nimport { sha3_224, sha3_256, sha3_384, sha3_512 } from \"@noble/hashes/sha3\";\nimport { globalScope } from \"../global-scope.js\";\n\n/**\n * OpenSSL-Noble hashes map.\n * @type {Object.<string, sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512>}\n */\nconst OPENSSL_NOBLE_HASHES = {\n SHA1: sha1,\n SHA224: sha224,\n SHA256: sha256,\n SHA384: sha384,\n SHA512: sha512,\n \"SHA3-224\": sha3_224,\n \"SHA3-256\": sha3_256,\n \"SHA3-384\": sha3_384,\n \"SHA3-512\": sha3_512,\n};\n\n/**\n * Calculates an HMAC digest.\n * In Node.js, the command \"openssl list -digest-algorithms\" displays the available digest algorithms.\n * @param {string} algorithm Algorithm.\n * @param {Uint8Array} key Key.\n * @param {Uint8Array} message Message.\n * @returns {Uint8Array} Digest.\n */\nconst hmacDigest = (algorithm, key, message) => {\n if (crypto?.createHmac) {\n const hmac = crypto.createHmac(algorithm, globalScope.Buffer.from(key));\n hmac.update(globalScope.Buffer.from(message));\n return hmac.digest();\n } else if (hmac) {\n const hash = OPENSSL_NOBLE_HASHES[algorithm.toUpperCase()];\n if (!hash) throw new TypeError(\"Unknown hash function\");\n return hmac(hash, key, message);\n } else {\n throw new Error(\"Missing HMAC function\");\n }\n};\n\nexport { hmacDigest };\n","import * as crypto from \"node:crypto\";\n\nimport { globalScope } from \"../global-scope.js\";\n\n/**\n * Returns true if a is equal to b, without leaking timing information that would allow an attacker to guess one of the values.\n * @param {string} a String a.\n * @param {string} b String b.\n * @returns {boolean} Equality result.\n */\nconst timingSafeEqual = (a, b) => {\n if (crypto?.timingSafeEqual) {\n return crypto.timingSafeEqual(globalScope.Buffer.from(a), globalScope.Buffer.from(b));\n } else {\n if (a.length !== b.length) {\n throw new TypeError(\"Input strings must have the same length\");\n }\n let i = -1;\n let out = 0;\n while (++i < a.length) {\n out |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return out === 0;\n }\n};\n\nexport { timingSafeEqual };\n","import { HOTP } from \"./hotp.js\";\nimport { Secret } from \"./secret.js\";\n\n/**\n * TOTP: Time-Based One-Time Password Algorithm.\n * @see [RFC 6238](https://tools.ietf.org/html/rfc6238)\n */\nclass TOTP {\n /**\n * Default configuration.\n * @type {{\n * issuer: string,\n * label: string,\n * issuerInLabel: boolean,\n * algorithm: string,\n * digits: number,\n * period: number\n * window: number\n * }}\n */\n static get defaults() {\n return {\n issuer: \"\",\n label: \"OTPAuth\",\n issuerInLabel: true,\n algorithm: \"SHA1\",\n digits: 6,\n period: 30,\n window: 1,\n };\n }\n\n /**\n * Creates a TOTP object.\n * @param {Object} [config] Configuration options.\n * @param {string} [config.issuer=''] Account provider.\n * @param {string} [config.label='OTPAuth'] Account label.\n * @param {boolean} [config.issuerInLabel=true] Include issuer prefix in label.\n * @param {Secret|string} [config.secret=Secret] Secret key.\n * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.\n * @param {number} [config.digits=6] Token length.\n * @param {number} [config.period=30] Token time-step duration.\n */\n constructor({\n issuer = TOTP.defaults.issuer,\n label = TOTP.defaults.label,\n issuerInLabel = TOTP.defaults.issuerInLabel,\n secret = new Secret(),\n algorithm = TOTP.defaults.algorithm,\n digits = TOTP.defaults.digits,\n period = TOTP.defaults.period,\n } = {}) {\n /**\n * Account provider.\n * @type {string}\n */\n this.issuer = issuer;\n /**\n * Account label.\n * @type {string}\n */\n this.label = label;\n /**\n * Include issuer prefix in label.\n * @type {boolean}\n */\n this.issuerInLabel = issuerInLabel;\n /**\n * Secret key.\n * @type {Secret}\n */\n this.secret = typeof secret === \"string\" ? Secret.fromBase32(secret) : secret;\n /**\n * HMAC hashing algorithm.\n * @type {string}\n */\n this.algorithm = algorithm.toUpperCase();\n /**\n * Token length.\n * @type {number}\n */\n this.digits = digits;\n /**\n * Token time-step duration.\n * @type {number}\n */\n this.period = period;\n }\n\n /**\n * Generates a TOTP token.\n * @param {Object} config Configuration options.\n * @param {Secret} config.secret Secret key.\n * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.\n * @param {number} [config.digits=6] Token length.\n * @param {number} [config.period=30] Token time-step duration.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @returns {string} Token.\n */\n static generate({ secret, algorithm, digits, period = TOTP.defaults.period, timestamp = Date.now() }) {\n return HOTP.generate({\n secret,\n algorithm,\n digits,\n counter: Math.floor(timestamp / 1000 / period),\n });\n }\n\n /**\n * Generates a TOTP token.\n * @param {Object} [config] Configuration options.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @returns {string} Token.\n */\n generate({ timestamp = Date.now() } = {}) {\n return TOTP.generate({\n secret: this.secret,\n algorithm: this.algorithm,\n digits: this.digits,\n period: this.period,\n timestamp,\n });\n }\n\n /**\n * Validates a TOTP token.\n * @param {Object} config Configuration options.\n * @param {string} config.token Token value.\n * @param {Secret} config.secret Secret key.\n * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.\n * @param {number} config.digits Token length.\n * @param {number} [config.period=30] Token time-step duration.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @param {number} [config.window=1] Window of counter values to test.\n * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.\n */\n static validate({ token, secret, algorithm, digits, period = TOTP.defaults.period, timestamp = Date.now(), window }) {\n return HOTP.validate({\n token,\n secret,\n algorithm,\n digits,\n counter: Math.floor(timestamp / 1000 / period),\n window,\n });\n }\n\n /**\n * Validates a TOTP token.\n * @param {Object} config Configuration options.\n * @param {string} config.token Token value.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @param {number} [config.window=1] Window of counter values to test.\n * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.\n */\n validate({ token, timestamp, window }) {\n return TOTP.validate({\n token,\n secret: this.secret,\n algorithm: this.algorithm,\n digits: this.digits,\n period: this.period,\n timestamp,\n window,\n });\n }\n\n /**\n * Returns a Google Authenticator key URI.\n * @returns {string} URI.\n */\n toString() {\n const e = encodeURIComponent;\n return (\n \"otpauth://totp/\" +\n `${\n this.issuer.length > 0\n ? this.issuerInLabel\n ? `${e(this.issuer)}:${e(this.label)}?issuer=${e(this.issuer)}&`\n : `${e(this.label)}?issuer=${e(this.issuer)}&`\n : `${e(this.label)}?`\n }` +\n `secret=${e(this.secret.base32)}&` +\n `algorithm=${e(this.algorithm)}&` +\n `digits=${e(this.digits)}&` +\n `period=${e(this.period)}`\n );\n }\n}\n\nexport { TOTP };\n","import { HOTP } from \"./hotp.js\";\nimport { TOTP } from \"./totp.js\";\n\n/**\n * Key URI regex (otpauth://TYPE/[ISSUER:]LABEL?PARAMETERS).\n * @type {RegExp}\n */\nconst OTPURI_REGEX = /^otpauth:\\/\\/([ht]otp)\\/(.+)\\?([A-Z0-9.~_-]+=[^?&]*(?:&[A-Z0-9.~_-]+=[^?&]*)*)$/i;\n\n/**\n * RFC 4648 base32 alphabet with pad.\n * @type {RegExp}\n */\nconst SECRET_REGEX = /^[2-7A-Z]+=*$/i;\n\n/**\n * Regex for supported algorithms.\n * @type {RegExp}\n */\nconst ALGORITHM_REGEX = /^SHA(?:1|224|256|384|512|3-224|3-256|3-384|3-512)$/i;\n\n/**\n * Integer regex.\n * @type {RegExp}\n */\nconst INTEGER_REGEX = /^[+-]?\\d+$/;\n\n/**\n * Positive integer regex.\n * @type {RegExp}\n */\nconst POSITIVE_INTEGER_REGEX = /^\\+?[1-9]\\d*$/;\n\n/**\n * HOTP/TOTP object/string conversion.\n * @see [Key URI Format](https://github.com/google/google-authenticator/wiki/Key-Uri-Format)\n */\nclass URI {\n /**\n * Parses a Google Authenticator key URI and returns an HOTP/TOTP object.\n * @param {string} uri Google Authenticator Key URI.\n * @returns {HOTP|TOTP} HOTP/TOTP object.\n */\n static parse(uri) {\n let uriGroups;\n\n try {\n uriGroups = uri.match(OTPURI_REGEX);\n // eslint-disable-next-line no-unused-vars\n } catch (_) {\n /* Handled below */\n }\n\n if (!Array.isArray(uriGroups)) {\n throw new URIError(\"Invalid URI format\");\n }\n\n // Extract URI groups.\n const uriType = uriGroups[1].toLowerCase();\n const uriLabel = uriGroups[2].split(/(?::|%3A) *(.+)/i, 2).map(decodeURIComponent);\n /** @type {Object.<string, string>} */\n const uriParams = uriGroups[3].split(\"&\").reduce((acc, cur) => {\n const pairArr = cur.split(/=(.*)/, 2).map(decodeURIComponent);\n const pairKey = pairArr[0].toLowerCase();\n const pairVal = pairArr[1];\n /** @type {Object.<string, string>} */\n const pairAcc = acc;\n\n pairAcc[pairKey] = pairVal;\n return pairAcc;\n }, {});\n\n // 'OTP' will be instantiated with 'config' argument.\n let OTP;\n const config = {};\n\n if (uriType === \"hotp\") {\n OTP = HOTP;\n\n // Counter: required\n if (typeof uriParams.counter !== \"undefined\" && INTEGER_REGEX.test(uriParams.counter)) {\n config.counter = parseInt(uriParams.counter, 10);\n } else {\n throw new TypeError(\"Missing or invalid 'counter' parameter\");\n }\n } else if (uriType === \"totp\") {\n OTP = TOTP;\n\n // Period: optional\n if (typeof uriParams.period !== \"undefined\") {\n if (POSITIVE_INTEGER_REGEX.test(uriParams.period)) {\n config.period = parseInt(uriParams.period, 10);\n } else {\n throw new TypeError(\"Invalid 'period' parameter\");\n }\n }\n } else {\n throw new TypeError(\"Unknown OTP type\");\n }\n\n // Label: required\n // Issuer: optional\n if (typeof uriParams.issuer !== \"undefined\") {\n config.issuer = uriParams.issuer;\n }\n if (uriLabel.length === 2) {\n config.label = uriLabel[1];\n if (typeof config.issuer === \"undefined\" || config.issuer === \"\") {\n config.issuer = uriLabel[0];\n } else if (uriLabel[0] === \"\") {\n config.issuerInLabel = false;\n }\n } else {\n config.label = uriLabel[0];\n if (typeof config.issuer !== \"undefined\" && config.issuer !== \"\") {\n config.issuerInLabel = false;\n }\n }\n\n // Secret: required\n if (typeof uriParams.secret !== \"undefined\" && SECRET_REGEX.test(uriParams.secret)) {\n config.secret = uriParams.secret;\n } else {\n throw new TypeError(\"Missing or invalid 'secret' parameter\");\n }\n\n // Algorithm: optional\n if (typeof uriParams.algorithm !== \"undefined\") {\n if (ALGORITHM_REGEX.test(uriParams.algorithm)) {\n config.algorithm = uriParams.algorithm;\n } else {\n throw new TypeError(\"Invalid 'algorithm' parameter\");\n }\n }\n\n // Digits: optional\n if (typeof uriParams.digits !== \"undefined\") {\n if (POSITIVE_INTEGER_REGEX.test(uriParams.digits)) {\n config.digits = parseInt(uriParams.digits, 10);\n } else {\n throw new TypeError(\"Invalid 'digits' parameter\");\n }\n }\n\n return new OTP(config);\n }\n\n /**\n * Converts an HOTP/TOTP object to a Google Authenticator key URI.\n * @param {HOTP|TOTP} otp HOTP/TOTP object.\n * @returns {string} Google Authenticator Key URI.\n */\n static stringify(otp) {\n if (otp instanceof HOTP || otp instanceof TOTP) {\n return otp.toString();\n }\n\n throw new TypeError(\"Invalid 'HOTP/TOTP' object\");\n }\n}\n\nexport { URI };\n","/**\n * Library version.\n * @type {string}\n */\nconst version = \"__OTPAUTH_VERSION__\";\n\nexport { version };\n"],"names":["globalScope","globalThis","Object","defineProperty","prototype","get","this","configurable","__GLOBALTHIS__","self","window","global","ALPHABET","base32Decode","str","end","length","cstr","substring","toUpperCase","buf","ArrayBuffer","arr","Uint8Array","bits","value","index","i","idx","indexOf","TypeError","base32Encode","hexDecode","parseInt","hexEncode","hex","toString","latin1Decode","charCodeAt","latin1Encode","String","fromCharCode","ENCODER","TextEncoder","DECODER","TextDecoder","utf8Decode","Error","encode","utf8Encode","decode","Secret","fromLatin1","buffer","fromUTF8","fromBase32","fromHex","bytes","latin1","enumerable","writable","utf8","base32","constructor","size","crypto","randomBytes","getRandomValues","HOTP","defaults","issuer","label","issuerInLabel","algorithm","digits","counter","generate","secret","digest","key","message","createHmac","hmac","Buffer","from","update","hmacDigest","num","acc","uintDecode","offset","byteLength","padStart","validate","token","delta","check","generatedToken","a","b","timingSafeEqual","out","e","encodeURIComponent","TOTP","period","timestamp","Date","now","Math","floor","OTPURI_REGEX","SECRET_REGEX","ALGORITHM_REGEX","INTEGER_REGEX","POSITIVE_INTEGER_REGEX","URI","parse","uri","uriGroups","match","_","Array","isArray","URIError","uriType","toLowerCase","uriLabel","split","map","decodeURIComponent","uriParams","reduce","cur","pairArr","pairKey","pairVal","pairAcc","OTP","config","test","stringify","otp","version"],"mappings":"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"}