1 line
46 KiB
Plaintext
1 line
46 KiB
Plaintext
{"version":3,"file":"otpauth.slim.esm.min.js","sources":["../src/internal/encoding/uint.js","../src/internal/global-scope.js","../src/internal/crypto/hmac-digest.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/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 num *= 256;\n num += arr[i];\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-expect-error\n // eslint-disable-next-line no-undef\n if (typeof __GLOBALTHIS__ !== \"undefined\") return __GLOBALTHIS__;\n } finally {\n // @ts-expect-error\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","import * as crypto from \"node:crypto\";\nimport { hmac } from \"@noble/hashes/hmac.js\";\nimport { sha1 } from \"@noble/hashes/legacy.js\";\nimport { sha224, sha256, sha384, sha512 } from \"@noble/hashes/sha2.js\";\nimport { sha3_224, sha3_256, sha3_384, sha3_512 } from \"@noble/hashes/sha3.js\";\nimport { globalScope } from \"../global-scope.js\";\n\n/**\n * @noble/hashes hash functions.\n * @type {Object.<string, sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512>}\n */\nconst nobleHashes = {\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 * Canonicalizes a hash algorithm name.\n * @param {string} algorithm Hash algorithm name.\n * @returns {\"SHA1\"|\"SHA224\"|\"SHA256\"|\"SHA384\"|\"SHA512\"|\"SHA3-224\"|\"SHA3-256\"|\"SHA3-384\"|\"SHA3-512\"} Canonicalized hash algorithm name.\n */\nconst canonicalizeAlgorithm = (algorithm) => {\n switch (true) {\n case /^(?:SHA-?1|SSL3-SHA1)$/i.test(algorithm):\n return \"SHA1\";\n case /^SHA(?:2?-)?224$/i.test(algorithm):\n return \"SHA224\";\n case /^SHA(?:2?-)?256$/i.test(algorithm):\n return \"SHA256\";\n case /^SHA(?:2?-)?384$/i.test(algorithm):\n return \"SHA384\";\n case /^SHA(?:2?-)?512$/i.test(algorithm):\n return \"SHA512\";\n case /^SHA3-224$/i.test(algorithm):\n return \"SHA3-224\";\n case /^SHA3-256$/i.test(algorithm):\n return \"SHA3-256\";\n case /^SHA3-384$/i.test(algorithm):\n return \"SHA3-384\";\n case /^SHA3-512$/i.test(algorithm):\n return \"SHA3-512\";\n default:\n throw new TypeError(`Unknown hash algorithm: ${algorithm}`);\n }\n};\n\n/**\n * Calculates an HMAC digest.\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 = nobleHashes[algorithm] ?? nobleHashes[canonicalizeAlgorithm(algorithm)];\n return hmac(hash, key, message);\n } else {\n throw new Error(\"Missing HMAC function\");\n }\n};\n\nexport { canonicalizeAlgorithm, hmacDigest };\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 // Remove spaces (although they are not allowed by the spec, some issuers add them for readability).\n str = str.replace(/ /g, \"\");\n\n // Canonicalize to all upper case and remove padding if it exists.\n let end = str.length;\n while (str[end - 1] === \"=\") --end;\n str = (end < str.length ? str.substring(0, end) : str).toUpperCase();\n\n const buf = new ArrayBuffer(((str.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 < str.length; i++) {\n const idx = ALPHABET.indexOf(str[i]);\n if (idx === -1) throw new TypeError(`Invalid character found: ${str[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 // Remove spaces (although they are not allowed by the spec, some issuers add them for readability).\n str = str.replace(/ /g, \"\");\n\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 if (globalScope.crypto?.getRandomValues) {\n return globalScope.crypto.getRandomValues(new Uint8Array(size));\n } else {\n throw new Error(\"Cryptography API not available\");\n }\n};\n\nexport { randomBytes };\n","import { uintDecode } from \"./internal/encoding/uint.js\";\nimport { canonicalizeAlgorithm, 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://datatracker.ietf.org/doc/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 * @param {(algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array} [config.hmac] Custom HMAC function.\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 hmac,\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 = hmac ? algorithm : canonicalizeAlgorithm(algorithm);\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 * Custom HMAC function.\n * @type {((algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array)|undefined}\n */\n this.hmac = hmac;\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 * @param {(algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array} [config.hmac] Custom HMAC function.\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 hmac = hmacDigest,\n }) {\n const message = uintDecode(counter);\n const digest = hmac(algorithm, secret.bytes, message);\n if (!digest?.byteLength || digest.byteLength < 19) {\n throw new TypeError(\"Return value must be at least 19 bytes\");\n }\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 hmac: this.hmac,\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=6] Token length.\n * @param {number} [config.counter=0] Counter value.\n * @param {number} [config.window=1] Window of counter values to test.\n * @param {(algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array} [config.hmac] Custom HMAC function.\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 = HOTP.defaults.digits,\n counter = HOTP.defaults.counter,\n window = HOTP.defaults.window,\n hmac = hmacDigest,\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 hmac,\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 hmac: this.hmac,\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\";\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 { canonicalizeAlgorithm } from \"./internal/crypto/hmac-digest.js\";\nimport { HOTP } from \"./hotp.js\";\nimport { Secret } from \"./secret.js\";\n\n/**\n * TOTP: Time-Based One-Time Password Algorithm.\n * @see [RFC 6238](https://datatracker.ietf.org/doc/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 * @param {(algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array} [config.hmac] Custom HMAC function.\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 hmac,\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 = hmac ? algorithm : canonicalizeAlgorithm(algorithm);\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 * Custom HMAC function.\n * @type {((algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array)|undefined}\n */\n this.hmac = hmac;\n }\n\n /**\n * Calculates the counter. i.e. the number of periods since timestamp 0.\n * @param {Object} [config] Configuration options.\n * @param {number} [config.period=30] Token time-step duration.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @returns {number} Counter.\n */\n static counter({ period = TOTP.defaults.period, timestamp = Date.now() } = {}) {\n return Math.floor(timestamp / 1000 / period);\n }\n\n /**\n * Calculates the counter. i.e. the number of periods since timestamp 0.\n * @param {Object} [config] Configuration options.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @returns {number} Counter.\n */\n counter({ timestamp = Date.now() } = {}) {\n return TOTP.counter({\n period: this.period,\n timestamp,\n });\n }\n\n /**\n * Calculates the remaining time in milliseconds until the next token is generated.\n * @param {Object} [config] Configuration options.\n * @param {number} [config.period=30] Token time-step duration.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @returns {number} counter.\n */\n static remaining({ period = TOTP.defaults.period, timestamp = Date.now() } = {}) {\n return period * 1000 - (timestamp % (period * 1000));\n }\n\n /**\n * Calculates the remaining time in milliseconds until the next token is generated.\n * @param {Object} [config] Configuration options.\n * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.\n * @returns {number} counter.\n */\n remaining({ timestamp = Date.now() } = {}) {\n return TOTP.remaining({\n period: this.period,\n timestamp,\n });\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 * @param {(algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array} [config.hmac] Custom HMAC function.\n * @returns {string} Token.\n */\n static generate({ secret, algorithm, digits, period = TOTP.defaults.period, timestamp = Date.now(), hmac }) {\n return HOTP.generate({\n secret,\n algorithm,\n digits,\n counter: TOTP.counter({ period, timestamp }),\n hmac,\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 hmac: this.hmac,\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=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 * @param {number} [config.window=1] Window of counter values to test.\n * @param {(algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array} [config.hmac] Custom HMAC function.\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 period = TOTP.defaults.period,\n timestamp = Date.now(),\n window,\n hmac,\n }) {\n return HOTP.validate({\n token,\n secret,\n algorithm,\n digits,\n counter: TOTP.counter({ period, timestamp }),\n window,\n hmac,\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 hmac: this.hmac,\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 in built-in HMAC function.\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 * Regex for custom algorithms in user-defined HMAC function.\n * @type {RegExp}\n */\nconst ALGORITHM_CUSTOM_REGEX = /^[A-Z0-9]+(?:[_-][A-Z0-9]+)*$/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 * @param {Object} [config] Configuration options.\n * @param {(algorithm: string, key: Uint8Array, message: Uint8Array) => Uint8Array} [config.hmac] Custom HMAC function.\n * @returns {HOTP|TOTP} HOTP/TOTP object.\n */\n static parse(uri, { hmac } = {}) {\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 ((hmac ? ALGORITHM_CUSTOM_REGEX : 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 // HMAC: optional\n if (typeof hmac !== \"undefined\") {\n config.hmac = hmac;\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","nobleHashes","SHA1","sha1","SHA224","sha224","SHA256","sha256","SHA384","sha384","SHA512","sha512","sha3_224","sha3_256","sha3_384","sha3_512","canonicalizeAlgorithm","algorithm","test","TypeError","hmacDigest","key","message","hmac","hash","Error","ALPHABET","base32Decode","str","end","replace","length","substring","toUpperCase","buf","ArrayBuffer","arr","Uint8Array","bits","value","index","i","idx","indexOf","base32Encode","hexDecode","parseInt","hexEncode","hex","toString","latin1Decode","charCodeAt","latin1Encode","String","fromCharCode","ENCODER","TextEncoder","DECODER","TextDecoder","utf8Decode","encode","utf8Encode","decode","Secret","fromLatin1","buffer","fromUTF8","fromBase32","fromHex","bytes","latin1","enumerable","writable","utf8","base32","constructor","size","crypto","getRandomValues","randomBytes","HOTP","defaults","issuer","label","issuerInLabel","digits","counter","generate","secret","num","acc","uintDecode","digest","byteLength","offset","padStart","validate","token","delta","check","generatedToken","a","b","out","timingSafeEqual","e","encodeURIComponent","TOTP","period","timestamp","Date","now","Math","floor","remaining","OTPURI_REGEX","SECRET_REGEX","ALGORITHM_REGEX","ALGORITHM_CUSTOM_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","stringify","otp","version"],"mappings":"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"} |