@probolabs/playwright 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1422,6 +1422,33 @@ class OTP {
1422
1422
  throw error;
1423
1423
  }
1424
1424
  }
1425
+ /**
1426
+ * Deletes a specific message by ID
1427
+ * @param messageId - The message ID to delete
1428
+ * @returns Promise<boolean> - True if deleted successfully, false otherwise
1429
+ */
1430
+ static async deleteMessage(messageId) {
1431
+ try {
1432
+ const url = `https://api.mailinator.com/v2/domains/${MAILINATOR_DOMAIN}/messages/${messageId}`;
1433
+ const response = await fetch(url, {
1434
+ method: 'DELETE',
1435
+ headers: {
1436
+ 'Authorization': `Bearer ${MAILINATOR_API_KEY}`,
1437
+ 'Content-Type': 'application/json'
1438
+ }
1439
+ });
1440
+ if (!response.ok) {
1441
+ console.error(`Failed to delete message ${messageId}: ${response.status} ${response.statusText}`);
1442
+ return false;
1443
+ }
1444
+ console.log(`🗑️ [deleteMessage] Deleted message: ${messageId}`);
1445
+ return true;
1446
+ }
1447
+ catch (error) {
1448
+ console.error('Error deleting message from Mailinator:', error);
1449
+ return false;
1450
+ }
1451
+ }
1425
1452
  /**
1426
1453
  * Extracts OTP codes from message content
1427
1454
  * @param message - The message to extract OTP from
@@ -1449,8 +1476,8 @@ class OTP {
1449
1476
  // Last resort: 4-8 digit numbers (but avoid very long ones that are likely tracking IDs)
1450
1477
  /(?:^|\s)(\d{4,8})(?:\s|$)/i
1451
1478
  ];
1452
- // Helper function to check if a number is likely an OTP (not a tracking ID, phone number, etc.)
1453
- const isValidOTP = (number) => {
1479
+ // Helper function to check if a number is likely an OTP (not a tracking ID, phone number, year, etc.)
1480
+ const isValidOTP = (number, text) => {
1454
1481
  // Common OTP lengths
1455
1482
  if (number.length < 4 || number.length > 8)
1456
1483
  return false;
@@ -1461,17 +1488,30 @@ class OTP {
1461
1488
  // Avoid very long numbers that are clearly tracking IDs (but be more lenient)
1462
1489
  if (number.length >= 8 && parseInt(number) > 99999999)
1463
1490
  return false;
1491
+ // Filter out common false positives
1492
+ // Check if this looks like a year (4 digits starting with 19 or 20)
1493
+ if (number.length === 4 && /^(19|20)\d{2}$/.test(number)) {
1494
+ // Check if it appears in copyright context
1495
+ if (text.includes(`© GoSource ${number}`) || text.includes(`©${number}`) || text.match(new RegExp(`©[^\\d]*${number}`, 'i'))) {
1496
+ return false;
1497
+ }
1498
+ }
1464
1499
  return true;
1465
1500
  };
1466
1501
  // Helper function to extract OTP from text content
1467
- const extractFromText = (text) => {
1502
+ const extractFromText = (text, debugContext = '') => {
1468
1503
  if (!text)
1469
1504
  return null;
1470
- for (const pattern of otpPatterns) {
1505
+ for (let i = 0; i < otpPatterns.length; i++) {
1506
+ const pattern = otpPatterns[i];
1471
1507
  const match = text.match(pattern);
1472
- if (match && match[1] && isValidOTP(match[1])) {
1508
+ if (match && match[1] && isValidOTP(match[1], text)) {
1509
+ console.log(`[OTP] Pattern ${i} matched "${match[1]}" in ${debugContext}`);
1473
1510
  return match[1];
1474
1511
  }
1512
+ else if (match && match[1]) {
1513
+ console.log(`[OTP] Pattern ${i} matched "${match[1]}" but rejected by isValidOTP in ${debugContext}`);
1514
+ }
1475
1515
  }
1476
1516
  return null;
1477
1517
  };
@@ -1481,29 +1521,30 @@ class OTP {
1481
1521
  };
1482
1522
  // 1. Try to extract from text body first (preferred)
1483
1523
  if (message.textBody) {
1484
- const otp = extractFromText(message.textBody);
1524
+ const otp = extractFromText(message.textBody, 'textBody');
1485
1525
  if (otp)
1486
1526
  return otp;
1487
1527
  }
1488
1528
  // 2. Try to extract from HTML body (strip HTML tags first)
1489
1529
  if (message.htmlBody) {
1490
1530
  const plainText = stripHtml(message.htmlBody);
1491
- const otp = extractFromText(plainText);
1531
+ const otp = extractFromText(plainText, 'htmlBody');
1492
1532
  if (otp)
1493
1533
  return otp;
1494
1534
  }
1495
1535
  // 3. Try to extract from message parts
1496
1536
  if (message.parts && message.parts.length > 0) {
1497
- for (const part of message.parts) {
1537
+ for (let i = 0; i < message.parts.length; i++) {
1538
+ const part = message.parts[i];
1498
1539
  if (part.body) {
1499
- const otp = extractFromText(part.body);
1540
+ const otp = extractFromText(part.body, `part[${i}]`);
1500
1541
  if (otp)
1501
1542
  return otp;
1502
1543
  }
1503
1544
  }
1504
1545
  }
1505
1546
  // 4. Fallback: try to extract from subject
1506
- const otp = extractFromText(message.subject);
1547
+ const otp = extractFromText(message.subject, 'subject');
1507
1548
  if (otp)
1508
1549
  return otp;
1509
1550
  return null;
@@ -1584,6 +1625,10 @@ class OTP {
1584
1625
  let otp = OTP.extractOTPFromMessage(message);
1585
1626
  if (otp) {
1586
1627
  console.log(`✅ [waitForOTP] Found OTP: ${otp}`);
1628
+ // Delete message if flag is enabled
1629
+ if (OTP.DELETE_MESSAGE_AFTER_OTP_EXTRACTION) {
1630
+ await OTP.deleteMessage(message.id);
1631
+ }
1587
1632
  return otp;
1588
1633
  }
1589
1634
  // If no OTP found in summary, fetch full message details
@@ -1592,6 +1637,10 @@ class OTP {
1592
1637
  otp = OTP.extractOTPFromMessage(fullMessage);
1593
1638
  if (otp) {
1594
1639
  console.log(`✅ [waitForOTP] Found OTP: ${otp}`);
1640
+ // Delete message if flag is enabled
1641
+ if (OTP.DELETE_MESSAGE_AFTER_OTP_EXTRACTION) {
1642
+ await OTP.deleteMessage(fullMessage.id);
1643
+ }
1595
1644
  return otp;
1596
1645
  }
1597
1646
  }
@@ -1620,21 +1669,39 @@ class OTP {
1620
1669
  : await OTP.fetchAllInboxMessages();
1621
1670
  const newMessages = currentMessages.filter(msg => !initialMessageIds.has(msg.id));
1622
1671
  if (newMessages.length > 0) {
1623
- // Get the first new message and try to extract OTP
1624
- const newMessage = newMessages[0];
1625
- // First try to extract OTP from the message summary (faster)
1626
- let otp = OTP.extractOTPFromMessage(newMessage);
1627
- if (otp) {
1628
- console.log(`✅ [waitForOTP] Found OTP: ${otp}`);
1629
- return otp;
1630
- }
1631
- // If no OTP found in summary, fetch full message details
1632
- const fullMessage = await OTP.fetchMessage(newMessage.id);
1633
- otp = OTP.extractOTPFromMessage(fullMessage);
1634
- if (otp) {
1635
- console.log(`✅ [waitForOTP] Found OTP: ${otp}`);
1636
- return otp;
1672
+ // Sort new messages by time (newest first) to handle multiple messages arriving at once
1673
+ const sortedNewMessages = newMessages.sort((a, b) => b.time - a.time);
1674
+ // Check all new messages (not just the first one)
1675
+ for (const newMessage of sortedNewMessages) {
1676
+ // First try to extract OTP from the message summary (faster)
1677
+ let otp = OTP.extractOTPFromMessage(newMessage);
1678
+ if (otp) {
1679
+ console.log(`✅ [waitForOTP] Found OTP: ${otp} in new message`);
1680
+ // Delete message if flag is enabled
1681
+ if (OTP.DELETE_MESSAGE_AFTER_OTP_EXTRACTION) {
1682
+ await OTP.deleteMessage(newMessage.id);
1683
+ }
1684
+ return otp;
1685
+ }
1686
+ // If no OTP found in summary, fetch full message details
1687
+ try {
1688
+ const fullMessage = await OTP.fetchMessage(newMessage.id);
1689
+ otp = OTP.extractOTPFromMessage(fullMessage);
1690
+ if (otp) {
1691
+ console.log(`✅ [waitForOTP] Found OTP: ${otp} in new message (full fetch)`);
1692
+ // Delete message if flag is enabled
1693
+ if (OTP.DELETE_MESSAGE_AFTER_OTP_EXTRACTION) {
1694
+ await OTP.deleteMessage(fullMessage.id);
1695
+ }
1696
+ return otp;
1697
+ }
1698
+ }
1699
+ catch (error) {
1700
+ // Silently continue to next message
1701
+ }
1637
1702
  }
1703
+ // Add all new messages to the set so we don't reprocess them
1704
+ newMessages.forEach(msg => initialMessageIds.add(msg.id));
1638
1705
  }
1639
1706
  }
1640
1707
  catch (error) {
@@ -1645,6 +1712,12 @@ class OTP {
1645
1712
  return null; // Timeout reached or no OTP found
1646
1713
  }
1647
1714
  }
1715
+ /**
1716
+ * Flag to control whether messages should be deleted after OTP extraction
1717
+ * Set to false for debugging purposes to keep messages in the inbox
1718
+ * @default true
1719
+ */
1720
+ OTP.DELETE_MESSAGE_AFTER_OTP_EXTRACTION = true;
1648
1721
 
1649
1722
  /**
1650
1723
  * Global navigation tracker that monitors page navigation events and network activity
@@ -2007,6 +2080,1853 @@ class NavTracker {
2007
2080
  }
2008
2081
  NavTracker.instance = null;
2009
2082
 
2083
+ //! otpauth 9.4.1 | (c) Héctor Molinero Fernández | MIT | https://github.com/hectorm/otpauth
2084
+ //! noble-hashes 1.8.0 | (c) Paul Miller | MIT | https://github.com/paulmillr/noble-hashes
2085
+ /// <reference types="./otpauth.d.ts" />
2086
+ // @ts-nocheck
2087
+ /**
2088
+ * Converts an integer to an Uint8Array.
2089
+ * @param {number} num Integer.
2090
+ * @returns {Uint8Array} Uint8Array.
2091
+ */ const uintDecode = (num)=>{
2092
+ const buf = new ArrayBuffer(8);
2093
+ const arr = new Uint8Array(buf);
2094
+ let acc = num;
2095
+ for(let i = 7; i >= 0; i--){
2096
+ if (acc === 0) break;
2097
+ arr[i] = acc & 255;
2098
+ acc -= arr[i];
2099
+ acc /= 256;
2100
+ }
2101
+ return arr;
2102
+ };
2103
+
2104
+ /**
2105
+ * Utilities for hex, bytes, CSPRNG.
2106
+ * @module
2107
+ */ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
2108
+ // node.js versions earlier than v19 don't declare it in global scope.
2109
+ // For node.js, package.json#exports field mapping rewrites import
2110
+ // from `crypto` to `cryptoNode`, which imports native module.
2111
+ // Makes the utils un-importable in browsers without a bundler.
2112
+ // Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
2113
+ /** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */ function isBytes(a) {
2114
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array';
2115
+ }
2116
+ /** Asserts something is positive integer. */ function anumber(n) {
2117
+ if (!Number.isSafeInteger(n) || n < 0) throw new Error('positive integer expected, got ' + n);
2118
+ }
2119
+ /** Asserts something is Uint8Array. */ function abytes(b, ...lengths) {
2120
+ if (!isBytes(b)) throw new Error('Uint8Array expected');
2121
+ if (lengths.length > 0 && !lengths.includes(b.length)) throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
2122
+ }
2123
+ /** Asserts something is hash */ function ahash(h) {
2124
+ if (typeof h !== 'function' || typeof h.create !== 'function') throw new Error('Hash should be wrapped by utils.createHasher');
2125
+ anumber(h.outputLen);
2126
+ anumber(h.blockLen);
2127
+ }
2128
+ /** Asserts a hash instance has not been destroyed / finished */ function aexists(instance, checkFinished = true) {
2129
+ if (instance.destroyed) throw new Error('Hash instance has been destroyed');
2130
+ if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');
2131
+ }
2132
+ /** Asserts output is properly-sized byte array */ function aoutput(out, instance) {
2133
+ abytes(out);
2134
+ const min = instance.outputLen;
2135
+ if (out.length < min) {
2136
+ throw new Error('digestInto() expects output buffer of length at least ' + min);
2137
+ }
2138
+ }
2139
+ /** Cast u8 / u16 / u32 to u32. */ function u32(arr) {
2140
+ return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
2141
+ }
2142
+ /** Zeroize a byte array. Warning: JS provides no guarantees. */ function clean(...arrays) {
2143
+ for(let i = 0; i < arrays.length; i++){
2144
+ arrays[i].fill(0);
2145
+ }
2146
+ }
2147
+ /** Create DataView of an array for easy byte-level manipulation. */ function createView(arr) {
2148
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
2149
+ }
2150
+ /** The rotate right (circular right shift) operation for uint32 */ function rotr(word, shift) {
2151
+ return word << 32 - shift | word >>> shift;
2152
+ }
2153
+ /** The rotate left (circular left shift) operation for uint32 */ function rotl(word, shift) {
2154
+ return word << shift | word >>> 32 - shift >>> 0;
2155
+ }
2156
+ /** Is current platform little-endian? Most are. Big-Endian platform: IBM */ const isLE = /* @__PURE__ */ (()=>new Uint8Array(new Uint32Array([
2157
+ 0x11223344
2158
+ ]).buffer)[0] === 0x44)();
2159
+ /** The byte swap operation for uint32 */ function byteSwap(word) {
2160
+ return word << 24 & 0xff000000 | word << 8 & 0xff0000 | word >>> 8 & 0xff00 | word >>> 24 & 0xff;
2161
+ }
2162
+ /** In place byte swap for Uint32Array */ function byteSwap32(arr) {
2163
+ for(let i = 0; i < arr.length; i++){
2164
+ arr[i] = byteSwap(arr[i]);
2165
+ }
2166
+ return arr;
2167
+ }
2168
+ const swap32IfBE = isLE ? (u)=>u : byteSwap32;
2169
+ /**
2170
+ * Converts string to bytes using UTF8 encoding.
2171
+ * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
2172
+ */ function utf8ToBytes(str) {
2173
+ if (typeof str !== 'string') throw new Error('string expected');
2174
+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
2175
+ }
2176
+ /**
2177
+ * Normalizes (non-hex) string or Uint8Array to Uint8Array.
2178
+ * Warning: when Uint8Array is passed, it would NOT get copied.
2179
+ * Keep in mind for future mutable operations.
2180
+ */ function toBytes(data) {
2181
+ if (typeof data === 'string') data = utf8ToBytes(data);
2182
+ abytes(data);
2183
+ return data;
2184
+ }
2185
+ /** For runtime check if class implements interface */ class Hash {
2186
+ }
2187
+ /** Wraps hash function, creating an interface on top of it */ function createHasher(hashCons) {
2188
+ const hashC = (msg)=>hashCons().update(toBytes(msg)).digest();
2189
+ const tmp = hashCons();
2190
+ hashC.outputLen = tmp.outputLen;
2191
+ hashC.blockLen = tmp.blockLen;
2192
+ hashC.create = ()=>hashCons();
2193
+ return hashC;
2194
+ }
2195
+
2196
+ class HMAC extends Hash {
2197
+ update(buf) {
2198
+ aexists(this);
2199
+ this.iHash.update(buf);
2200
+ return this;
2201
+ }
2202
+ digestInto(out) {
2203
+ aexists(this);
2204
+ abytes(out, this.outputLen);
2205
+ this.finished = true;
2206
+ this.iHash.digestInto(out);
2207
+ this.oHash.update(out);
2208
+ this.oHash.digestInto(out);
2209
+ this.destroy();
2210
+ }
2211
+ digest() {
2212
+ const out = new Uint8Array(this.oHash.outputLen);
2213
+ this.digestInto(out);
2214
+ return out;
2215
+ }
2216
+ _cloneInto(to) {
2217
+ // Create new instance without calling constructor since key already in state and we don't know it.
2218
+ to || (to = Object.create(Object.getPrototypeOf(this), {}));
2219
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
2220
+ to = to;
2221
+ to.finished = finished;
2222
+ to.destroyed = destroyed;
2223
+ to.blockLen = blockLen;
2224
+ to.outputLen = outputLen;
2225
+ to.oHash = oHash._cloneInto(to.oHash);
2226
+ to.iHash = iHash._cloneInto(to.iHash);
2227
+ return to;
2228
+ }
2229
+ clone() {
2230
+ return this._cloneInto();
2231
+ }
2232
+ destroy() {
2233
+ this.destroyed = true;
2234
+ this.oHash.destroy();
2235
+ this.iHash.destroy();
2236
+ }
2237
+ constructor(hash, _key){
2238
+ super();
2239
+ this.finished = false;
2240
+ this.destroyed = false;
2241
+ ahash(hash);
2242
+ const key = toBytes(_key);
2243
+ this.iHash = hash.create();
2244
+ if (typeof this.iHash.update !== 'function') throw new Error('Expected instance of class which extends utils.Hash');
2245
+ this.blockLen = this.iHash.blockLen;
2246
+ this.outputLen = this.iHash.outputLen;
2247
+ const blockLen = this.blockLen;
2248
+ const pad = new Uint8Array(blockLen);
2249
+ // blockLen can be bigger than outputLen
2250
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
2251
+ for(let i = 0; i < pad.length; i++)pad[i] ^= 0x36;
2252
+ this.iHash.update(pad);
2253
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
2254
+ this.oHash = hash.create();
2255
+ // Undo internal XOR && apply outer XOR
2256
+ for(let i = 0; i < pad.length; i++)pad[i] ^= 0x36 ^ 0x5c;
2257
+ this.oHash.update(pad);
2258
+ clean(pad);
2259
+ }
2260
+ }
2261
+ /**
2262
+ * HMAC: RFC2104 message authentication code.
2263
+ * @param hash - function that would be used e.g. sha256
2264
+ * @param key - message key
2265
+ * @param message - message data
2266
+ * @example
2267
+ * import { hmac } from '@noble/hashes/hmac';
2268
+ * import { sha256 } from '@noble/hashes/sha2';
2269
+ * const mac1 = hmac(sha256, 'key', 'message');
2270
+ */ const hmac = (hash, key, message)=>new HMAC(hash, key).update(message).digest();
2271
+ hmac.create = (hash, key)=>new HMAC(hash, key);
2272
+
2273
+ /** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */ function setBigUint64(view, byteOffset, value, isLE) {
2274
+ if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE);
2275
+ const _32n = BigInt(32);
2276
+ const _u32_max = BigInt(0xffffffff);
2277
+ const wh = Number(value >> _32n & _u32_max);
2278
+ const wl = Number(value & _u32_max);
2279
+ const h = isLE ? 4 : 0;
2280
+ const l = isLE ? 0 : 4;
2281
+ view.setUint32(byteOffset + h, wh, isLE);
2282
+ view.setUint32(byteOffset + l, wl, isLE);
2283
+ }
2284
+ /** Choice: a ? b : c */ function Chi(a, b, c) {
2285
+ return a & b ^ ~a & c;
2286
+ }
2287
+ /** Majority function, true if any two inputs is true. */ function Maj(a, b, c) {
2288
+ return a & b ^ a & c ^ b & c;
2289
+ }
2290
+ /**
2291
+ * Merkle-Damgard hash construction base class.
2292
+ * Could be used to create MD5, RIPEMD, SHA1, SHA2.
2293
+ */ class HashMD extends Hash {
2294
+ update(data) {
2295
+ aexists(this);
2296
+ data = toBytes(data);
2297
+ abytes(data);
2298
+ const { view, buffer, blockLen } = this;
2299
+ const len = data.length;
2300
+ for(let pos = 0; pos < len;){
2301
+ const take = Math.min(blockLen - this.pos, len - pos);
2302
+ // Fast path: we have at least one block in input, cast it to view and process
2303
+ if (take === blockLen) {
2304
+ const dataView = createView(data);
2305
+ for(; blockLen <= len - pos; pos += blockLen)this.process(dataView, pos);
2306
+ continue;
2307
+ }
2308
+ buffer.set(data.subarray(pos, pos + take), this.pos);
2309
+ this.pos += take;
2310
+ pos += take;
2311
+ if (this.pos === blockLen) {
2312
+ this.process(view, 0);
2313
+ this.pos = 0;
2314
+ }
2315
+ }
2316
+ this.length += data.length;
2317
+ this.roundClean();
2318
+ return this;
2319
+ }
2320
+ digestInto(out) {
2321
+ aexists(this);
2322
+ aoutput(out, this);
2323
+ this.finished = true;
2324
+ // Padding
2325
+ // We can avoid allocation of buffer for padding completely if it
2326
+ // was previously not allocated here. But it won't change performance.
2327
+ const { buffer, view, blockLen, isLE } = this;
2328
+ let { pos } = this;
2329
+ // append the bit '1' to the message
2330
+ buffer[pos++] = 0b10000000;
2331
+ clean(this.buffer.subarray(pos));
2332
+ // we have less than padOffset left in buffer, so we cannot put length in
2333
+ // current block, need process it and pad again
2334
+ if (this.padOffset > blockLen - pos) {
2335
+ this.process(view, 0);
2336
+ pos = 0;
2337
+ }
2338
+ // Pad until full block byte with zeros
2339
+ for(let i = pos; i < blockLen; i++)buffer[i] = 0;
2340
+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
2341
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
2342
+ // So we just write lowest 64 bits of that value.
2343
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
2344
+ this.process(view, 0);
2345
+ const oview = createView(out);
2346
+ const len = this.outputLen;
2347
+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
2348
+ if (len % 4) throw new Error('_sha2: outputLen should be aligned to 32bit');
2349
+ const outLen = len / 4;
2350
+ const state = this.get();
2351
+ if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');
2352
+ for(let i = 0; i < outLen; i++)oview.setUint32(4 * i, state[i], isLE);
2353
+ }
2354
+ digest() {
2355
+ const { buffer, outputLen } = this;
2356
+ this.digestInto(buffer);
2357
+ const res = buffer.slice(0, outputLen);
2358
+ this.destroy();
2359
+ return res;
2360
+ }
2361
+ _cloneInto(to) {
2362
+ to || (to = new this.constructor());
2363
+ to.set(...this.get());
2364
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
2365
+ to.destroyed = destroyed;
2366
+ to.finished = finished;
2367
+ to.length = length;
2368
+ to.pos = pos;
2369
+ if (length % blockLen) to.buffer.set(buffer);
2370
+ return to;
2371
+ }
2372
+ clone() {
2373
+ return this._cloneInto();
2374
+ }
2375
+ constructor(blockLen, outputLen, padOffset, isLE){
2376
+ super();
2377
+ this.finished = false;
2378
+ this.length = 0;
2379
+ this.pos = 0;
2380
+ this.destroyed = false;
2381
+ this.blockLen = blockLen;
2382
+ this.outputLen = outputLen;
2383
+ this.padOffset = padOffset;
2384
+ this.isLE = isLE;
2385
+ this.buffer = new Uint8Array(blockLen);
2386
+ this.view = createView(this.buffer);
2387
+ }
2388
+ }
2389
+ /**
2390
+ * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
2391
+ * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
2392
+ */ /** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */ const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
2393
+ 0x6a09e667,
2394
+ 0xbb67ae85,
2395
+ 0x3c6ef372,
2396
+ 0xa54ff53a,
2397
+ 0x510e527f,
2398
+ 0x9b05688c,
2399
+ 0x1f83d9ab,
2400
+ 0x5be0cd19
2401
+ ]);
2402
+ /** Initial SHA224 state. Bits 32..64 of frac part of sqrt of primes 23..53 */ const SHA224_IV = /* @__PURE__ */ Uint32Array.from([
2403
+ 0xc1059ed8,
2404
+ 0x367cd507,
2405
+ 0x3070dd17,
2406
+ 0xf70e5939,
2407
+ 0xffc00b31,
2408
+ 0x68581511,
2409
+ 0x64f98fa7,
2410
+ 0xbefa4fa4
2411
+ ]);
2412
+ /** Initial SHA384 state. Bits 0..64 of frac part of sqrt of primes 23..53 */ const SHA384_IV = /* @__PURE__ */ Uint32Array.from([
2413
+ 0xcbbb9d5d,
2414
+ 0xc1059ed8,
2415
+ 0x629a292a,
2416
+ 0x367cd507,
2417
+ 0x9159015a,
2418
+ 0x3070dd17,
2419
+ 0x152fecd8,
2420
+ 0xf70e5939,
2421
+ 0x67332667,
2422
+ 0xffc00b31,
2423
+ 0x8eb44a87,
2424
+ 0x68581511,
2425
+ 0xdb0c2e0d,
2426
+ 0x64f98fa7,
2427
+ 0x47b5481d,
2428
+ 0xbefa4fa4
2429
+ ]);
2430
+ /** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */ const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
2431
+ 0x6a09e667,
2432
+ 0xf3bcc908,
2433
+ 0xbb67ae85,
2434
+ 0x84caa73b,
2435
+ 0x3c6ef372,
2436
+ 0xfe94f82b,
2437
+ 0xa54ff53a,
2438
+ 0x5f1d36f1,
2439
+ 0x510e527f,
2440
+ 0xade682d1,
2441
+ 0x9b05688c,
2442
+ 0x2b3e6c1f,
2443
+ 0x1f83d9ab,
2444
+ 0xfb41bd6b,
2445
+ 0x5be0cd19,
2446
+ 0x137e2179
2447
+ ]);
2448
+
2449
+ /** Initial SHA1 state */ const SHA1_IV = /* @__PURE__ */ Uint32Array.from([
2450
+ 0x67452301,
2451
+ 0xefcdab89,
2452
+ 0x98badcfe,
2453
+ 0x10325476,
2454
+ 0xc3d2e1f0
2455
+ ]);
2456
+ // Reusable temporary buffer
2457
+ const SHA1_W = /* @__PURE__ */ new Uint32Array(80);
2458
+ /** SHA1 legacy hash class. */ class SHA1 extends HashMD {
2459
+ get() {
2460
+ const { A, B, C, D, E } = this;
2461
+ return [
2462
+ A,
2463
+ B,
2464
+ C,
2465
+ D,
2466
+ E
2467
+ ];
2468
+ }
2469
+ set(A, B, C, D, E) {
2470
+ this.A = A | 0;
2471
+ this.B = B | 0;
2472
+ this.C = C | 0;
2473
+ this.D = D | 0;
2474
+ this.E = E | 0;
2475
+ }
2476
+ process(view, offset) {
2477
+ for(let i = 0; i < 16; i++, offset += 4)SHA1_W[i] = view.getUint32(offset, false);
2478
+ for(let i = 16; i < 80; i++)SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1);
2479
+ // Compression function main loop, 80 rounds
2480
+ let { A, B, C, D, E } = this;
2481
+ for(let i = 0; i < 80; i++){
2482
+ let F, K;
2483
+ if (i < 20) {
2484
+ F = Chi(B, C, D);
2485
+ K = 0x5a827999;
2486
+ } else if (i < 40) {
2487
+ F = B ^ C ^ D;
2488
+ K = 0x6ed9eba1;
2489
+ } else if (i < 60) {
2490
+ F = Maj(B, C, D);
2491
+ K = 0x8f1bbcdc;
2492
+ } else {
2493
+ F = B ^ C ^ D;
2494
+ K = 0xca62c1d6;
2495
+ }
2496
+ const T = rotl(A, 5) + F + E + K + SHA1_W[i] | 0;
2497
+ E = D;
2498
+ D = C;
2499
+ C = rotl(B, 30);
2500
+ B = A;
2501
+ A = T;
2502
+ }
2503
+ // Add the compressed chunk to the current hash value
2504
+ A = A + this.A | 0;
2505
+ B = B + this.B | 0;
2506
+ C = C + this.C | 0;
2507
+ D = D + this.D | 0;
2508
+ E = E + this.E | 0;
2509
+ this.set(A, B, C, D, E);
2510
+ }
2511
+ roundClean() {
2512
+ clean(SHA1_W);
2513
+ }
2514
+ destroy() {
2515
+ this.set(0, 0, 0, 0, 0);
2516
+ clean(this.buffer);
2517
+ }
2518
+ constructor(){
2519
+ super(64, 20, 8, false);
2520
+ this.A = SHA1_IV[0] | 0;
2521
+ this.B = SHA1_IV[1] | 0;
2522
+ this.C = SHA1_IV[2] | 0;
2523
+ this.D = SHA1_IV[3] | 0;
2524
+ this.E = SHA1_IV[4] | 0;
2525
+ }
2526
+ }
2527
+ /** SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. */ const sha1 = /* @__PURE__ */ createHasher(()=>new SHA1());
2528
+
2529
+ /**
2530
+ * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
2531
+ * @todo re-check https://issues.chromium.org/issues/42212588
2532
+ * @module
2533
+ */ const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
2534
+ const _32n = /* @__PURE__ */ BigInt(32);
2535
+ function fromBig(n, le = false) {
2536
+ if (le) return {
2537
+ h: Number(n & U32_MASK64),
2538
+ l: Number(n >> _32n & U32_MASK64)
2539
+ };
2540
+ return {
2541
+ h: Number(n >> _32n & U32_MASK64) | 0,
2542
+ l: Number(n & U32_MASK64) | 0
2543
+ };
2544
+ }
2545
+ function split(lst, le = false) {
2546
+ const len = lst.length;
2547
+ let Ah = new Uint32Array(len);
2548
+ let Al = new Uint32Array(len);
2549
+ for(let i = 0; i < len; i++){
2550
+ const { h, l } = fromBig(lst[i], le);
2551
+ [Ah[i], Al[i]] = [
2552
+ h,
2553
+ l
2554
+ ];
2555
+ }
2556
+ return [
2557
+ Ah,
2558
+ Al
2559
+ ];
2560
+ }
2561
+ // for Shift in [0, 32)
2562
+ const shrSH = (h, _l, s)=>h >>> s;
2563
+ const shrSL = (h, l, s)=>h << 32 - s | l >>> s;
2564
+ // Right rotate for Shift in [1, 32)
2565
+ const rotrSH = (h, l, s)=>h >>> s | l << 32 - s;
2566
+ const rotrSL = (h, l, s)=>h << 32 - s | l >>> s;
2567
+ // Right rotate for Shift in (32, 64), NOTE: 32 is special case.
2568
+ const rotrBH = (h, l, s)=>h << 64 - s | l >>> s - 32;
2569
+ const rotrBL = (h, l, s)=>h >>> s - 32 | l << 64 - s;
2570
+ // Left rotate for Shift in [1, 32)
2571
+ const rotlSH = (h, l, s)=>h << s | l >>> 32 - s;
2572
+ const rotlSL = (h, l, s)=>l << s | h >>> 32 - s;
2573
+ // Left rotate for Shift in (32, 64), NOTE: 32 is special case.
2574
+ const rotlBH = (h, l, s)=>l << s - 32 | h >>> 64 - s;
2575
+ const rotlBL = (h, l, s)=>h << s - 32 | l >>> 64 - s;
2576
+ // JS uses 32-bit signed integers for bitwise operations which means we cannot
2577
+ // simple take carry out of low bit sum by shift, we need to use division.
2578
+ function add(Ah, Al, Bh, Bl) {
2579
+ const l = (Al >>> 0) + (Bl >>> 0);
2580
+ return {
2581
+ h: Ah + Bh + (l / 2 ** 32 | 0) | 0,
2582
+ l: l | 0
2583
+ };
2584
+ }
2585
+ // Addition with more than 2 elements
2586
+ const add3L = (Al, Bl, Cl)=>(Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
2587
+ const add3H = (low, Ah, Bh, Ch)=>Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
2588
+ const add4L = (Al, Bl, Cl, Dl)=>(Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
2589
+ const add4H = (low, Ah, Bh, Ch, Dh)=>Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
2590
+ const add5L = (Al, Bl, Cl, Dl, El)=>(Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
2591
+ const add5H = (low, Ah, Bh, Ch, Dh, Eh)=>Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
2592
+
2593
+ /**
2594
+ * Round constants:
2595
+ * First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
2596
+ */ // prettier-ignore
2597
+ const SHA256_K = /* @__PURE__ */ Uint32Array.from([
2598
+ 0x428a2f98,
2599
+ 0x71374491,
2600
+ 0xb5c0fbcf,
2601
+ 0xe9b5dba5,
2602
+ 0x3956c25b,
2603
+ 0x59f111f1,
2604
+ 0x923f82a4,
2605
+ 0xab1c5ed5,
2606
+ 0xd807aa98,
2607
+ 0x12835b01,
2608
+ 0x243185be,
2609
+ 0x550c7dc3,
2610
+ 0x72be5d74,
2611
+ 0x80deb1fe,
2612
+ 0x9bdc06a7,
2613
+ 0xc19bf174,
2614
+ 0xe49b69c1,
2615
+ 0xefbe4786,
2616
+ 0x0fc19dc6,
2617
+ 0x240ca1cc,
2618
+ 0x2de92c6f,
2619
+ 0x4a7484aa,
2620
+ 0x5cb0a9dc,
2621
+ 0x76f988da,
2622
+ 0x983e5152,
2623
+ 0xa831c66d,
2624
+ 0xb00327c8,
2625
+ 0xbf597fc7,
2626
+ 0xc6e00bf3,
2627
+ 0xd5a79147,
2628
+ 0x06ca6351,
2629
+ 0x14292967,
2630
+ 0x27b70a85,
2631
+ 0x2e1b2138,
2632
+ 0x4d2c6dfc,
2633
+ 0x53380d13,
2634
+ 0x650a7354,
2635
+ 0x766a0abb,
2636
+ 0x81c2c92e,
2637
+ 0x92722c85,
2638
+ 0xa2bfe8a1,
2639
+ 0xa81a664b,
2640
+ 0xc24b8b70,
2641
+ 0xc76c51a3,
2642
+ 0xd192e819,
2643
+ 0xd6990624,
2644
+ 0xf40e3585,
2645
+ 0x106aa070,
2646
+ 0x19a4c116,
2647
+ 0x1e376c08,
2648
+ 0x2748774c,
2649
+ 0x34b0bcb5,
2650
+ 0x391c0cb3,
2651
+ 0x4ed8aa4a,
2652
+ 0x5b9cca4f,
2653
+ 0x682e6ff3,
2654
+ 0x748f82ee,
2655
+ 0x78a5636f,
2656
+ 0x84c87814,
2657
+ 0x8cc70208,
2658
+ 0x90befffa,
2659
+ 0xa4506ceb,
2660
+ 0xbef9a3f7,
2661
+ 0xc67178f2
2662
+ ]);
2663
+ /** Reusable temporary buffer. "W" comes straight from spec. */ const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
2664
+ class SHA256 extends HashMD {
2665
+ get() {
2666
+ const { A, B, C, D, E, F, G, H } = this;
2667
+ return [
2668
+ A,
2669
+ B,
2670
+ C,
2671
+ D,
2672
+ E,
2673
+ F,
2674
+ G,
2675
+ H
2676
+ ];
2677
+ }
2678
+ // prettier-ignore
2679
+ set(A, B, C, D, E, F, G, H) {
2680
+ this.A = A | 0;
2681
+ this.B = B | 0;
2682
+ this.C = C | 0;
2683
+ this.D = D | 0;
2684
+ this.E = E | 0;
2685
+ this.F = F | 0;
2686
+ this.G = G | 0;
2687
+ this.H = H | 0;
2688
+ }
2689
+ process(view, offset) {
2690
+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
2691
+ for(let i = 0; i < 16; i++, offset += 4)SHA256_W[i] = view.getUint32(offset, false);
2692
+ for(let i = 16; i < 64; i++){
2693
+ const W15 = SHA256_W[i - 15];
2694
+ const W2 = SHA256_W[i - 2];
2695
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
2696
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
2697
+ SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
2698
+ }
2699
+ // Compression function main loop, 64 rounds
2700
+ let { A, B, C, D, E, F, G, H } = this;
2701
+ for(let i = 0; i < 64; i++){
2702
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
2703
+ const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
2704
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
2705
+ const T2 = sigma0 + Maj(A, B, C) | 0;
2706
+ H = G;
2707
+ G = F;
2708
+ F = E;
2709
+ E = D + T1 | 0;
2710
+ D = C;
2711
+ C = B;
2712
+ B = A;
2713
+ A = T1 + T2 | 0;
2714
+ }
2715
+ // Add the compressed chunk to the current hash value
2716
+ A = A + this.A | 0;
2717
+ B = B + this.B | 0;
2718
+ C = C + this.C | 0;
2719
+ D = D + this.D | 0;
2720
+ E = E + this.E | 0;
2721
+ F = F + this.F | 0;
2722
+ G = G + this.G | 0;
2723
+ H = H + this.H | 0;
2724
+ this.set(A, B, C, D, E, F, G, H);
2725
+ }
2726
+ roundClean() {
2727
+ clean(SHA256_W);
2728
+ }
2729
+ destroy() {
2730
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
2731
+ clean(this.buffer);
2732
+ }
2733
+ constructor(outputLen = 32){
2734
+ super(64, outputLen, 8, false);
2735
+ // We cannot use array here since array allows indexing by variable
2736
+ // which means optimizer/compiler cannot use registers.
2737
+ this.A = SHA256_IV[0] | 0;
2738
+ this.B = SHA256_IV[1] | 0;
2739
+ this.C = SHA256_IV[2] | 0;
2740
+ this.D = SHA256_IV[3] | 0;
2741
+ this.E = SHA256_IV[4] | 0;
2742
+ this.F = SHA256_IV[5] | 0;
2743
+ this.G = SHA256_IV[6] | 0;
2744
+ this.H = SHA256_IV[7] | 0;
2745
+ }
2746
+ }
2747
+ class SHA224 extends SHA256 {
2748
+ constructor(){
2749
+ super(28);
2750
+ this.A = SHA224_IV[0] | 0;
2751
+ this.B = SHA224_IV[1] | 0;
2752
+ this.C = SHA224_IV[2] | 0;
2753
+ this.D = SHA224_IV[3] | 0;
2754
+ this.E = SHA224_IV[4] | 0;
2755
+ this.F = SHA224_IV[5] | 0;
2756
+ this.G = SHA224_IV[6] | 0;
2757
+ this.H = SHA224_IV[7] | 0;
2758
+ }
2759
+ }
2760
+ // SHA2-512 is slower than sha256 in js because u64 operations are slow.
2761
+ // Round contants
2762
+ // First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409
2763
+ // prettier-ignore
2764
+ const K512 = /* @__PURE__ */ (()=>split([
2765
+ '0x428a2f98d728ae22',
2766
+ '0x7137449123ef65cd',
2767
+ '0xb5c0fbcfec4d3b2f',
2768
+ '0xe9b5dba58189dbbc',
2769
+ '0x3956c25bf348b538',
2770
+ '0x59f111f1b605d019',
2771
+ '0x923f82a4af194f9b',
2772
+ '0xab1c5ed5da6d8118',
2773
+ '0xd807aa98a3030242',
2774
+ '0x12835b0145706fbe',
2775
+ '0x243185be4ee4b28c',
2776
+ '0x550c7dc3d5ffb4e2',
2777
+ '0x72be5d74f27b896f',
2778
+ '0x80deb1fe3b1696b1',
2779
+ '0x9bdc06a725c71235',
2780
+ '0xc19bf174cf692694',
2781
+ '0xe49b69c19ef14ad2',
2782
+ '0xefbe4786384f25e3',
2783
+ '0x0fc19dc68b8cd5b5',
2784
+ '0x240ca1cc77ac9c65',
2785
+ '0x2de92c6f592b0275',
2786
+ '0x4a7484aa6ea6e483',
2787
+ '0x5cb0a9dcbd41fbd4',
2788
+ '0x76f988da831153b5',
2789
+ '0x983e5152ee66dfab',
2790
+ '0xa831c66d2db43210',
2791
+ '0xb00327c898fb213f',
2792
+ '0xbf597fc7beef0ee4',
2793
+ '0xc6e00bf33da88fc2',
2794
+ '0xd5a79147930aa725',
2795
+ '0x06ca6351e003826f',
2796
+ '0x142929670a0e6e70',
2797
+ '0x27b70a8546d22ffc',
2798
+ '0x2e1b21385c26c926',
2799
+ '0x4d2c6dfc5ac42aed',
2800
+ '0x53380d139d95b3df',
2801
+ '0x650a73548baf63de',
2802
+ '0x766a0abb3c77b2a8',
2803
+ '0x81c2c92e47edaee6',
2804
+ '0x92722c851482353b',
2805
+ '0xa2bfe8a14cf10364',
2806
+ '0xa81a664bbc423001',
2807
+ '0xc24b8b70d0f89791',
2808
+ '0xc76c51a30654be30',
2809
+ '0xd192e819d6ef5218',
2810
+ '0xd69906245565a910',
2811
+ '0xf40e35855771202a',
2812
+ '0x106aa07032bbd1b8',
2813
+ '0x19a4c116b8d2d0c8',
2814
+ '0x1e376c085141ab53',
2815
+ '0x2748774cdf8eeb99',
2816
+ '0x34b0bcb5e19b48a8',
2817
+ '0x391c0cb3c5c95a63',
2818
+ '0x4ed8aa4ae3418acb',
2819
+ '0x5b9cca4f7763e373',
2820
+ '0x682e6ff3d6b2b8a3',
2821
+ '0x748f82ee5defb2fc',
2822
+ '0x78a5636f43172f60',
2823
+ '0x84c87814a1f0ab72',
2824
+ '0x8cc702081a6439ec',
2825
+ '0x90befffa23631e28',
2826
+ '0xa4506cebde82bde9',
2827
+ '0xbef9a3f7b2c67915',
2828
+ '0xc67178f2e372532b',
2829
+ '0xca273eceea26619c',
2830
+ '0xd186b8c721c0c207',
2831
+ '0xeada7dd6cde0eb1e',
2832
+ '0xf57d4f7fee6ed178',
2833
+ '0x06f067aa72176fba',
2834
+ '0x0a637dc5a2c898a6',
2835
+ '0x113f9804bef90dae',
2836
+ '0x1b710b35131c471b',
2837
+ '0x28db77f523047d84',
2838
+ '0x32caab7b40c72493',
2839
+ '0x3c9ebe0a15c9bebc',
2840
+ '0x431d67c49c100d4c',
2841
+ '0x4cc5d4becb3e42b6',
2842
+ '0x597f299cfc657e2a',
2843
+ '0x5fcb6fab3ad6faec',
2844
+ '0x6c44198c4a475817'
2845
+ ].map((n)=>BigInt(n))))();
2846
+ const SHA512_Kh = /* @__PURE__ */ (()=>K512[0])();
2847
+ const SHA512_Kl = /* @__PURE__ */ (()=>K512[1])();
2848
+ // Reusable temporary buffers
2849
+ const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
2850
+ const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
2851
+ class SHA512 extends HashMD {
2852
+ // prettier-ignore
2853
+ get() {
2854
+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
2855
+ return [
2856
+ Ah,
2857
+ Al,
2858
+ Bh,
2859
+ Bl,
2860
+ Ch,
2861
+ Cl,
2862
+ Dh,
2863
+ Dl,
2864
+ Eh,
2865
+ El,
2866
+ Fh,
2867
+ Fl,
2868
+ Gh,
2869
+ Gl,
2870
+ Hh,
2871
+ Hl
2872
+ ];
2873
+ }
2874
+ // prettier-ignore
2875
+ set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
2876
+ this.Ah = Ah | 0;
2877
+ this.Al = Al | 0;
2878
+ this.Bh = Bh | 0;
2879
+ this.Bl = Bl | 0;
2880
+ this.Ch = Ch | 0;
2881
+ this.Cl = Cl | 0;
2882
+ this.Dh = Dh | 0;
2883
+ this.Dl = Dl | 0;
2884
+ this.Eh = Eh | 0;
2885
+ this.El = El | 0;
2886
+ this.Fh = Fh | 0;
2887
+ this.Fl = Fl | 0;
2888
+ this.Gh = Gh | 0;
2889
+ this.Gl = Gl | 0;
2890
+ this.Hh = Hh | 0;
2891
+ this.Hl = Hl | 0;
2892
+ }
2893
+ process(view, offset) {
2894
+ // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
2895
+ for(let i = 0; i < 16; i++, offset += 4){
2896
+ SHA512_W_H[i] = view.getUint32(offset);
2897
+ SHA512_W_L[i] = view.getUint32(offset += 4);
2898
+ }
2899
+ for(let i = 16; i < 80; i++){
2900
+ // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
2901
+ const W15h = SHA512_W_H[i - 15] | 0;
2902
+ const W15l = SHA512_W_L[i - 15] | 0;
2903
+ const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
2904
+ const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
2905
+ // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
2906
+ const W2h = SHA512_W_H[i - 2] | 0;
2907
+ const W2l = SHA512_W_L[i - 2] | 0;
2908
+ const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
2909
+ const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
2910
+ // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
2911
+ const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
2912
+ const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
2913
+ SHA512_W_H[i] = SUMh | 0;
2914
+ SHA512_W_L[i] = SUMl | 0;
2915
+ }
2916
+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
2917
+ // Compression function main loop, 80 rounds
2918
+ for(let i = 0; i < 80; i++){
2919
+ // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
2920
+ const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
2921
+ const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
2922
+ //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
2923
+ const CHIh = Eh & Fh ^ ~Eh & Gh;
2924
+ const CHIl = El & Fl ^ ~El & Gl;
2925
+ // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
2926
+ // prettier-ignore
2927
+ const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
2928
+ const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
2929
+ const T1l = T1ll | 0;
2930
+ // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
2931
+ const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
2932
+ const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
2933
+ const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
2934
+ const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
2935
+ Hh = Gh | 0;
2936
+ Hl = Gl | 0;
2937
+ Gh = Fh | 0;
2938
+ Gl = Fl | 0;
2939
+ Fh = Eh | 0;
2940
+ Fl = El | 0;
2941
+ ({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
2942
+ Dh = Ch | 0;
2943
+ Dl = Cl | 0;
2944
+ Ch = Bh | 0;
2945
+ Cl = Bl | 0;
2946
+ Bh = Ah | 0;
2947
+ Bl = Al | 0;
2948
+ const All = add3L(T1l, sigma0l, MAJl);
2949
+ Ah = add3H(All, T1h, sigma0h, MAJh);
2950
+ Al = All | 0;
2951
+ }
2952
+ // Add the compressed chunk to the current hash value
2953
+ ({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
2954
+ ({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
2955
+ ({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
2956
+ ({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
2957
+ ({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
2958
+ ({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
2959
+ ({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
2960
+ ({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
2961
+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
2962
+ }
2963
+ roundClean() {
2964
+ clean(SHA512_W_H, SHA512_W_L);
2965
+ }
2966
+ destroy() {
2967
+ clean(this.buffer);
2968
+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2969
+ }
2970
+ constructor(outputLen = 64){
2971
+ super(128, outputLen, 16, false);
2972
+ // We cannot use array here since array allows indexing by variable
2973
+ // which means optimizer/compiler cannot use registers.
2974
+ // h -- high 32 bits, l -- low 32 bits
2975
+ this.Ah = SHA512_IV[0] | 0;
2976
+ this.Al = SHA512_IV[1] | 0;
2977
+ this.Bh = SHA512_IV[2] | 0;
2978
+ this.Bl = SHA512_IV[3] | 0;
2979
+ this.Ch = SHA512_IV[4] | 0;
2980
+ this.Cl = SHA512_IV[5] | 0;
2981
+ this.Dh = SHA512_IV[6] | 0;
2982
+ this.Dl = SHA512_IV[7] | 0;
2983
+ this.Eh = SHA512_IV[8] | 0;
2984
+ this.El = SHA512_IV[9] | 0;
2985
+ this.Fh = SHA512_IV[10] | 0;
2986
+ this.Fl = SHA512_IV[11] | 0;
2987
+ this.Gh = SHA512_IV[12] | 0;
2988
+ this.Gl = SHA512_IV[13] | 0;
2989
+ this.Hh = SHA512_IV[14] | 0;
2990
+ this.Hl = SHA512_IV[15] | 0;
2991
+ }
2992
+ }
2993
+ class SHA384 extends SHA512 {
2994
+ constructor(){
2995
+ super(48);
2996
+ this.Ah = SHA384_IV[0] | 0;
2997
+ this.Al = SHA384_IV[1] | 0;
2998
+ this.Bh = SHA384_IV[2] | 0;
2999
+ this.Bl = SHA384_IV[3] | 0;
3000
+ this.Ch = SHA384_IV[4] | 0;
3001
+ this.Cl = SHA384_IV[5] | 0;
3002
+ this.Dh = SHA384_IV[6] | 0;
3003
+ this.Dl = SHA384_IV[7] | 0;
3004
+ this.Eh = SHA384_IV[8] | 0;
3005
+ this.El = SHA384_IV[9] | 0;
3006
+ this.Fh = SHA384_IV[10] | 0;
3007
+ this.Fl = SHA384_IV[11] | 0;
3008
+ this.Gh = SHA384_IV[12] | 0;
3009
+ this.Gl = SHA384_IV[13] | 0;
3010
+ this.Hh = SHA384_IV[14] | 0;
3011
+ this.Hl = SHA384_IV[15] | 0;
3012
+ }
3013
+ }
3014
+ /**
3015
+ * SHA2-256 hash function from RFC 4634.
3016
+ *
3017
+ * It is the fastest JS hash, even faster than Blake3.
3018
+ * To break sha256 using birthday attack, attackers need to try 2^128 hashes.
3019
+ * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
3020
+ */ const sha256 = /* @__PURE__ */ createHasher(()=>new SHA256());
3021
+ /** SHA2-224 hash function from RFC 4634 */ const sha224 = /* @__PURE__ */ createHasher(()=>new SHA224());
3022
+ /** SHA2-512 hash function from RFC 4634. */ const sha512 = /* @__PURE__ */ createHasher(()=>new SHA512());
3023
+ /** SHA2-384 hash function from RFC 4634. */ const sha384 = /* @__PURE__ */ createHasher(()=>new SHA384());
3024
+
3025
+ // No __PURE__ annotations in sha3 header:
3026
+ // EVERYTHING is in fact used on every export.
3027
+ // Various per round constants calculations
3028
+ const _0n = BigInt(0);
3029
+ const _1n = BigInt(1);
3030
+ const _2n = BigInt(2);
3031
+ const _7n = BigInt(7);
3032
+ const _256n = BigInt(256);
3033
+ const _0x71n = BigInt(0x71);
3034
+ const SHA3_PI = [];
3035
+ const SHA3_ROTL = [];
3036
+ const _SHA3_IOTA = [];
3037
+ for(let round = 0, R = _1n, x = 1, y = 0; round < 24; round++){
3038
+ // Pi
3039
+ [x, y] = [
3040
+ y,
3041
+ (2 * x + 3 * y) % 5
3042
+ ];
3043
+ SHA3_PI.push(2 * (5 * y + x));
3044
+ // Rotational
3045
+ SHA3_ROTL.push((round + 1) * (round + 2) / 2 % 64);
3046
+ // Iota
3047
+ let t = _0n;
3048
+ for(let j = 0; j < 7; j++){
3049
+ R = (R << _1n ^ (R >> _7n) * _0x71n) % _256n;
3050
+ if (R & _2n) t ^= _1n << (_1n << /* @__PURE__ */ BigInt(j)) - _1n;
3051
+ }
3052
+ _SHA3_IOTA.push(t);
3053
+ }
3054
+ const IOTAS = split(_SHA3_IOTA, true);
3055
+ const SHA3_IOTA_H = IOTAS[0];
3056
+ const SHA3_IOTA_L = IOTAS[1];
3057
+ // Left rotation (without 0, 32, 64)
3058
+ const rotlH = (h, l, s)=>s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s);
3059
+ const rotlL = (h, l, s)=>s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s);
3060
+ /** `keccakf1600` internal function, additionally allows to adjust round count. */ function keccakP(s, rounds = 24) {
3061
+ const B = new Uint32Array(5 * 2);
3062
+ // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)
3063
+ for(let round = 24 - rounds; round < 24; round++){
3064
+ // Theta θ
3065
+ for(let x = 0; x < 10; x++)B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
3066
+ for(let x = 0; x < 10; x += 2){
3067
+ const idx1 = (x + 8) % 10;
3068
+ const idx0 = (x + 2) % 10;
3069
+ const B0 = B[idx0];
3070
+ const B1 = B[idx0 + 1];
3071
+ const Th = rotlH(B0, B1, 1) ^ B[idx1];
3072
+ const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
3073
+ for(let y = 0; y < 50; y += 10){
3074
+ s[x + y] ^= Th;
3075
+ s[x + y + 1] ^= Tl;
3076
+ }
3077
+ }
3078
+ // Rho (ρ) and Pi (π)
3079
+ let curH = s[2];
3080
+ let curL = s[3];
3081
+ for(let t = 0; t < 24; t++){
3082
+ const shift = SHA3_ROTL[t];
3083
+ const Th = rotlH(curH, curL, shift);
3084
+ const Tl = rotlL(curH, curL, shift);
3085
+ const PI = SHA3_PI[t];
3086
+ curH = s[PI];
3087
+ curL = s[PI + 1];
3088
+ s[PI] = Th;
3089
+ s[PI + 1] = Tl;
3090
+ }
3091
+ // Chi (χ)
3092
+ for(let y = 0; y < 50; y += 10){
3093
+ for(let x = 0; x < 10; x++)B[x] = s[y + x];
3094
+ for(let x = 0; x < 10; x++)s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
3095
+ }
3096
+ // Iota (ι)
3097
+ s[0] ^= SHA3_IOTA_H[round];
3098
+ s[1] ^= SHA3_IOTA_L[round];
3099
+ }
3100
+ clean(B);
3101
+ }
3102
+ /** Keccak sponge function. */ class Keccak extends Hash {
3103
+ clone() {
3104
+ return this._cloneInto();
3105
+ }
3106
+ keccak() {
3107
+ swap32IfBE(this.state32);
3108
+ keccakP(this.state32, this.rounds);
3109
+ swap32IfBE(this.state32);
3110
+ this.posOut = 0;
3111
+ this.pos = 0;
3112
+ }
3113
+ update(data) {
3114
+ aexists(this);
3115
+ data = toBytes(data);
3116
+ abytes(data);
3117
+ const { blockLen, state } = this;
3118
+ const len = data.length;
3119
+ for(let pos = 0; pos < len;){
3120
+ const take = Math.min(blockLen - this.pos, len - pos);
3121
+ for(let i = 0; i < take; i++)state[this.pos++] ^= data[pos++];
3122
+ if (this.pos === blockLen) this.keccak();
3123
+ }
3124
+ return this;
3125
+ }
3126
+ finish() {
3127
+ if (this.finished) return;
3128
+ this.finished = true;
3129
+ const { state, suffix, pos, blockLen } = this;
3130
+ // Do the padding
3131
+ state[pos] ^= suffix;
3132
+ if ((suffix & 0x80) !== 0 && pos === blockLen - 1) this.keccak();
3133
+ state[blockLen - 1] ^= 0x80;
3134
+ this.keccak();
3135
+ }
3136
+ writeInto(out) {
3137
+ aexists(this, false);
3138
+ abytes(out);
3139
+ this.finish();
3140
+ const bufferOut = this.state;
3141
+ const { blockLen } = this;
3142
+ for(let pos = 0, len = out.length; pos < len;){
3143
+ if (this.posOut >= blockLen) this.keccak();
3144
+ const take = Math.min(blockLen - this.posOut, len - pos);
3145
+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
3146
+ this.posOut += take;
3147
+ pos += take;
3148
+ }
3149
+ return out;
3150
+ }
3151
+ xofInto(out) {
3152
+ // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF
3153
+ if (!this.enableXOF) throw new Error('XOF is not possible for this instance');
3154
+ return this.writeInto(out);
3155
+ }
3156
+ xof(bytes) {
3157
+ anumber(bytes);
3158
+ return this.xofInto(new Uint8Array(bytes));
3159
+ }
3160
+ digestInto(out) {
3161
+ aoutput(out, this);
3162
+ if (this.finished) throw new Error('digest() was already called');
3163
+ this.writeInto(out);
3164
+ this.destroy();
3165
+ return out;
3166
+ }
3167
+ digest() {
3168
+ return this.digestInto(new Uint8Array(this.outputLen));
3169
+ }
3170
+ destroy() {
3171
+ this.destroyed = true;
3172
+ clean(this.state);
3173
+ }
3174
+ _cloneInto(to) {
3175
+ const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
3176
+ to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
3177
+ to.state32.set(this.state32);
3178
+ to.pos = this.pos;
3179
+ to.posOut = this.posOut;
3180
+ to.finished = this.finished;
3181
+ to.rounds = rounds;
3182
+ // Suffix can change in cSHAKE
3183
+ to.suffix = suffix;
3184
+ to.outputLen = outputLen;
3185
+ to.enableXOF = enableXOF;
3186
+ to.destroyed = this.destroyed;
3187
+ return to;
3188
+ }
3189
+ // NOTE: we accept arguments in bytes instead of bits here.
3190
+ constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24){
3191
+ super();
3192
+ this.pos = 0;
3193
+ this.posOut = 0;
3194
+ this.finished = false;
3195
+ this.destroyed = false;
3196
+ this.enableXOF = false;
3197
+ this.blockLen = blockLen;
3198
+ this.suffix = suffix;
3199
+ this.outputLen = outputLen;
3200
+ this.enableXOF = enableXOF;
3201
+ this.rounds = rounds;
3202
+ // Can be passed from user as dkLen
3203
+ anumber(outputLen);
3204
+ // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes
3205
+ // 0 < blockLen < 200
3206
+ if (!(0 < blockLen && blockLen < 200)) throw new Error('only keccak-f1600 function is supported');
3207
+ this.state = new Uint8Array(200);
3208
+ this.state32 = u32(this.state);
3209
+ }
3210
+ }
3211
+ const gen = (suffix, blockLen, outputLen)=>createHasher(()=>new Keccak(blockLen, suffix, outputLen));
3212
+ /** SHA3-224 hash function. */ const sha3_224 = /* @__PURE__ */ (()=>gen(0x06, 144, 224 / 8))();
3213
+ /** SHA3-256 hash function. Different from keccak-256. */ const sha3_256 = /* @__PURE__ */ (()=>gen(0x06, 136, 256 / 8))();
3214
+ /** SHA3-384 hash function. */ const sha3_384 = /* @__PURE__ */ (()=>gen(0x06, 104, 384 / 8))();
3215
+ /** SHA3-512 hash function. */ const sha3_512 = /* @__PURE__ */ (()=>gen(0x06, 72, 512 / 8))();
3216
+
3217
+ /**
3218
+ * "globalThis" ponyfill.
3219
+ * @see [A horrifying globalThis polyfill in universal JavaScript](https://mathiasbynens.be/notes/globalthis)
3220
+ * @type {Object.<string, *>}
3221
+ */ const globalScope = (()=>{
3222
+ if (typeof globalThis === "object") return globalThis;
3223
+ else {
3224
+ Object.defineProperty(Object.prototype, "__GLOBALTHIS__", {
3225
+ get () {
3226
+ return this;
3227
+ },
3228
+ configurable: true
3229
+ });
3230
+ try {
3231
+ // @ts-expect-error
3232
+ // eslint-disable-next-line no-undef
3233
+ if (typeof __GLOBALTHIS__ !== "undefined") return __GLOBALTHIS__;
3234
+ } finally{
3235
+ // @ts-expect-error
3236
+ delete Object.prototype.__GLOBALTHIS__;
3237
+ }
3238
+ }
3239
+ // Still unable to determine "globalThis", fall back to a naive method.
3240
+ if (typeof self !== "undefined") return self;
3241
+ else if (typeof window !== "undefined") return window;
3242
+ else if (typeof global !== "undefined") return global;
3243
+ return undefined;
3244
+ })();
3245
+
3246
+ /**
3247
+ * @noble/hashes hash functions.
3248
+ * @type {Object.<string, sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512>}
3249
+ */ const nobleHashes = {
3250
+ SHA1: sha1,
3251
+ SHA224: sha224,
3252
+ SHA256: sha256,
3253
+ SHA384: sha384,
3254
+ SHA512: sha512,
3255
+ "SHA3-224": sha3_224,
3256
+ "SHA3-256": sha3_256,
3257
+ "SHA3-384": sha3_384,
3258
+ "SHA3-512": sha3_512
3259
+ };
3260
+ /**
3261
+ * Canonicalizes a hash algorithm name.
3262
+ * @param {string} algorithm Hash algorithm name.
3263
+ * @returns {"SHA1"|"SHA224"|"SHA256"|"SHA384"|"SHA512"|"SHA3-224"|"SHA3-256"|"SHA3-384"|"SHA3-512"} Canonicalized hash algorithm name.
3264
+ */ const canonicalizeAlgorithm = (algorithm)=>{
3265
+ switch(true){
3266
+ case /^(?:SHA-?1|SSL3-SHA1)$/i.test(algorithm):
3267
+ return "SHA1";
3268
+ case /^SHA(?:2?-)?224$/i.test(algorithm):
3269
+ return "SHA224";
3270
+ case /^SHA(?:2?-)?256$/i.test(algorithm):
3271
+ return "SHA256";
3272
+ case /^SHA(?:2?-)?384$/i.test(algorithm):
3273
+ return "SHA384";
3274
+ case /^SHA(?:2?-)?512$/i.test(algorithm):
3275
+ return "SHA512";
3276
+ case /^SHA3-224$/i.test(algorithm):
3277
+ return "SHA3-224";
3278
+ case /^SHA3-256$/i.test(algorithm):
3279
+ return "SHA3-256";
3280
+ case /^SHA3-384$/i.test(algorithm):
3281
+ return "SHA3-384";
3282
+ case /^SHA3-512$/i.test(algorithm):
3283
+ return "SHA3-512";
3284
+ default:
3285
+ throw new TypeError(`Unknown hash algorithm: ${algorithm}`);
3286
+ }
3287
+ };
3288
+ /**
3289
+ * Calculates an HMAC digest.
3290
+ * @param {string} algorithm Algorithm.
3291
+ * @param {Uint8Array} key Key.
3292
+ * @param {Uint8Array} message Message.
3293
+ * @returns {Uint8Array} Digest.
3294
+ */ const hmacDigest = (algorithm, key, message)=>{
3295
+ if (hmac) {
3296
+ const hash = nobleHashes[algorithm] ?? nobleHashes[canonicalizeAlgorithm(algorithm)];
3297
+ return hmac(hash, key, message);
3298
+ } else {
3299
+ throw new Error("Missing HMAC function");
3300
+ }
3301
+ };
3302
+
3303
+ /**
3304
+ * RFC 4648 base32 alphabet without pad.
3305
+ * @type {string}
3306
+ */ const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
3307
+ /**
3308
+ * Converts a base32 string to an Uint8Array (RFC 4648).
3309
+ * @see [LinusU/base32-decode](https://github.com/LinusU/base32-decode)
3310
+ * @param {string} str Base32 string.
3311
+ * @returns {Uint8Array} Uint8Array.
3312
+ */ const base32Decode = (str)=>{
3313
+ // Remove spaces (although they are not allowed by the spec, some issuers add them for readability).
3314
+ str = str.replace(/ /g, "");
3315
+ // Canonicalize to all upper case and remove padding if it exists.
3316
+ let end = str.length;
3317
+ while(str[end - 1] === "=")--end;
3318
+ str = (end < str.length ? str.substring(0, end) : str).toUpperCase();
3319
+ const buf = new ArrayBuffer(str.length * 5 / 8 | 0);
3320
+ const arr = new Uint8Array(buf);
3321
+ let bits = 0;
3322
+ let value = 0;
3323
+ let index = 0;
3324
+ for(let i = 0; i < str.length; i++){
3325
+ const idx = ALPHABET.indexOf(str[i]);
3326
+ if (idx === -1) throw new TypeError(`Invalid character found: ${str[i]}`);
3327
+ value = value << 5 | idx;
3328
+ bits += 5;
3329
+ if (bits >= 8) {
3330
+ bits -= 8;
3331
+ arr[index++] = value >>> bits;
3332
+ }
3333
+ }
3334
+ return arr;
3335
+ };
3336
+ /**
3337
+ * Converts an Uint8Array to a base32 string (RFC 4648).
3338
+ * @see [LinusU/base32-encode](https://github.com/LinusU/base32-encode)
3339
+ * @param {Uint8Array} arr Uint8Array.
3340
+ * @returns {string} Base32 string.
3341
+ */ const base32Encode = (arr)=>{
3342
+ let bits = 0;
3343
+ let value = 0;
3344
+ let str = "";
3345
+ for(let i = 0; i < arr.length; i++){
3346
+ value = value << 8 | arr[i];
3347
+ bits += 8;
3348
+ while(bits >= 5){
3349
+ str += ALPHABET[value >>> bits - 5 & 31];
3350
+ bits -= 5;
3351
+ }
3352
+ }
3353
+ if (bits > 0) {
3354
+ str += ALPHABET[value << 5 - bits & 31];
3355
+ }
3356
+ return str;
3357
+ };
3358
+
3359
+ /**
3360
+ * Converts a hexadecimal string to an Uint8Array.
3361
+ * @param {string} str Hexadecimal string.
3362
+ * @returns {Uint8Array} Uint8Array.
3363
+ */ const hexDecode = (str)=>{
3364
+ // Remove spaces (although they are not allowed by the spec, some issuers add them for readability).
3365
+ str = str.replace(/ /g, "");
3366
+ const buf = new ArrayBuffer(str.length / 2);
3367
+ const arr = new Uint8Array(buf);
3368
+ for(let i = 0; i < str.length; i += 2){
3369
+ arr[i / 2] = parseInt(str.substring(i, i + 2), 16);
3370
+ }
3371
+ return arr;
3372
+ };
3373
+ /**
3374
+ * Converts an Uint8Array to a hexadecimal string.
3375
+ * @param {Uint8Array} arr Uint8Array.
3376
+ * @returns {string} Hexadecimal string.
3377
+ */ const hexEncode = (arr)=>{
3378
+ let str = "";
3379
+ for(let i = 0; i < arr.length; i++){
3380
+ const hex = arr[i].toString(16);
3381
+ if (hex.length === 1) str += "0";
3382
+ str += hex;
3383
+ }
3384
+ return str.toUpperCase();
3385
+ };
3386
+
3387
+ /**
3388
+ * Converts a Latin-1 string to an Uint8Array.
3389
+ * @param {string} str Latin-1 string.
3390
+ * @returns {Uint8Array} Uint8Array.
3391
+ */ const latin1Decode = (str)=>{
3392
+ const buf = new ArrayBuffer(str.length);
3393
+ const arr = new Uint8Array(buf);
3394
+ for(let i = 0; i < str.length; i++){
3395
+ arr[i] = str.charCodeAt(i) & 0xff;
3396
+ }
3397
+ return arr;
3398
+ };
3399
+ /**
3400
+ * Converts an Uint8Array to a Latin-1 string.
3401
+ * @param {Uint8Array} arr Uint8Array.
3402
+ * @returns {string} Latin-1 string.
3403
+ */ const latin1Encode = (arr)=>{
3404
+ let str = "";
3405
+ for(let i = 0; i < arr.length; i++){
3406
+ str += String.fromCharCode(arr[i]);
3407
+ }
3408
+ return str;
3409
+ };
3410
+
3411
+ /**
3412
+ * TextEncoder instance.
3413
+ * @type {TextEncoder|null}
3414
+ */ const ENCODER = globalScope.TextEncoder ? new globalScope.TextEncoder() : null;
3415
+ /**
3416
+ * TextDecoder instance.
3417
+ * @type {TextDecoder|null}
3418
+ */ const DECODER = globalScope.TextDecoder ? new globalScope.TextDecoder() : null;
3419
+ /**
3420
+ * Converts an UTF-8 string to an Uint8Array.
3421
+ * @param {string} str String.
3422
+ * @returns {Uint8Array} Uint8Array.
3423
+ */ const utf8Decode = (str)=>{
3424
+ if (!ENCODER) {
3425
+ throw new Error("Encoding API not available");
3426
+ }
3427
+ return ENCODER.encode(str);
3428
+ };
3429
+ /**
3430
+ * Converts an Uint8Array to an UTF-8 string.
3431
+ * @param {Uint8Array} arr Uint8Array.
3432
+ * @returns {string} String.
3433
+ */ const utf8Encode = (arr)=>{
3434
+ if (!DECODER) {
3435
+ throw new Error("Encoding API not available");
3436
+ }
3437
+ return DECODER.decode(arr);
3438
+ };
3439
+
3440
+ /**
3441
+ * Returns random bytes.
3442
+ * @param {number} size Size.
3443
+ * @returns {Uint8Array} Random bytes.
3444
+ */ const randomBytes = (size)=>{
3445
+ if (globalScope.crypto?.getRandomValues) {
3446
+ return globalScope.crypto.getRandomValues(new Uint8Array(size));
3447
+ } else {
3448
+ throw new Error("Cryptography API not available");
3449
+ }
3450
+ };
3451
+
3452
+ /**
3453
+ * OTP secret key.
3454
+ */ class Secret {
3455
+ /**
3456
+ * Converts a Latin-1 string to a Secret object.
3457
+ * @param {string} str Latin-1 string.
3458
+ * @returns {Secret} Secret object.
3459
+ */ static fromLatin1(str) {
3460
+ return new Secret({
3461
+ buffer: latin1Decode(str).buffer
3462
+ });
3463
+ }
3464
+ /**
3465
+ * Converts an UTF-8 string to a Secret object.
3466
+ * @param {string} str UTF-8 string.
3467
+ * @returns {Secret} Secret object.
3468
+ */ static fromUTF8(str) {
3469
+ return new Secret({
3470
+ buffer: utf8Decode(str).buffer
3471
+ });
3472
+ }
3473
+ /**
3474
+ * Converts a base32 string to a Secret object.
3475
+ * @param {string} str Base32 string.
3476
+ * @returns {Secret} Secret object.
3477
+ */ static fromBase32(str) {
3478
+ return new Secret({
3479
+ buffer: base32Decode(str).buffer
3480
+ });
3481
+ }
3482
+ /**
3483
+ * Converts a hexadecimal string to a Secret object.
3484
+ * @param {string} str Hexadecimal string.
3485
+ * @returns {Secret} Secret object.
3486
+ */ static fromHex(str) {
3487
+ return new Secret({
3488
+ buffer: hexDecode(str).buffer
3489
+ });
3490
+ }
3491
+ /**
3492
+ * Secret key buffer.
3493
+ * @deprecated For backward compatibility, the "bytes" property should be used instead.
3494
+ * @type {ArrayBufferLike}
3495
+ */ get buffer() {
3496
+ return this.bytes.buffer;
3497
+ }
3498
+ /**
3499
+ * Latin-1 string representation of secret key.
3500
+ * @type {string}
3501
+ */ get latin1() {
3502
+ Object.defineProperty(this, "latin1", {
3503
+ enumerable: true,
3504
+ writable: false,
3505
+ configurable: false,
3506
+ value: latin1Encode(this.bytes)
3507
+ });
3508
+ return this.latin1;
3509
+ }
3510
+ /**
3511
+ * UTF-8 string representation of secret key.
3512
+ * @type {string}
3513
+ */ get utf8() {
3514
+ Object.defineProperty(this, "utf8", {
3515
+ enumerable: true,
3516
+ writable: false,
3517
+ configurable: false,
3518
+ value: utf8Encode(this.bytes)
3519
+ });
3520
+ return this.utf8;
3521
+ }
3522
+ /**
3523
+ * Base32 string representation of secret key.
3524
+ * @type {string}
3525
+ */ get base32() {
3526
+ Object.defineProperty(this, "base32", {
3527
+ enumerable: true,
3528
+ writable: false,
3529
+ configurable: false,
3530
+ value: base32Encode(this.bytes)
3531
+ });
3532
+ return this.base32;
3533
+ }
3534
+ /**
3535
+ * Hexadecimal string representation of secret key.
3536
+ * @type {string}
3537
+ */ get hex() {
3538
+ Object.defineProperty(this, "hex", {
3539
+ enumerable: true,
3540
+ writable: false,
3541
+ configurable: false,
3542
+ value: hexEncode(this.bytes)
3543
+ });
3544
+ return this.hex;
3545
+ }
3546
+ /**
3547
+ * Creates a secret key object.
3548
+ * @param {Object} [config] Configuration options.
3549
+ * @param {ArrayBufferLike} [config.buffer] Secret key buffer.
3550
+ * @param {number} [config.size=20] Number of random bytes to generate, ignored if 'buffer' is provided.
3551
+ */ constructor({ buffer, size = 20 } = {}){
3552
+ /**
3553
+ * Secret key.
3554
+ * @type {Uint8Array}
3555
+ * @readonly
3556
+ */ this.bytes = typeof buffer === "undefined" ? randomBytes(size) : new Uint8Array(buffer);
3557
+ // Prevent the "bytes" property from being modified.
3558
+ Object.defineProperty(this, "bytes", {
3559
+ enumerable: true,
3560
+ writable: false,
3561
+ configurable: false,
3562
+ value: this.bytes
3563
+ });
3564
+ }
3565
+ }
3566
+
3567
+ /**
3568
+ * Returns true if a is equal to b, without leaking timing information that would allow an attacker to guess one of the values.
3569
+ * @param {string} a String a.
3570
+ * @param {string} b String b.
3571
+ * @returns {boolean} Equality result.
3572
+ */ const timingSafeEqual = (a, b)=>{
3573
+ {
3574
+ if (a.length !== b.length) {
3575
+ throw new TypeError("Input strings must have the same length");
3576
+ }
3577
+ let i = -1;
3578
+ let out = 0;
3579
+ while(++i < a.length){
3580
+ out |= a.charCodeAt(i) ^ b.charCodeAt(i);
3581
+ }
3582
+ return out === 0;
3583
+ }
3584
+ };
3585
+
3586
+ /**
3587
+ * HOTP: An HMAC-based One-time Password Algorithm.
3588
+ * @see [RFC 4226](https://datatracker.ietf.org/doc/html/rfc4226)
3589
+ */ class HOTP {
3590
+ /**
3591
+ * Default configuration.
3592
+ * @type {{
3593
+ * issuer: string,
3594
+ * label: string,
3595
+ * issuerInLabel: boolean,
3596
+ * algorithm: string,
3597
+ * digits: number,
3598
+ * counter: number
3599
+ * window: number
3600
+ * }}
3601
+ */ static get defaults() {
3602
+ return {
3603
+ issuer: "",
3604
+ label: "OTPAuth",
3605
+ issuerInLabel: true,
3606
+ algorithm: "SHA1",
3607
+ digits: 6,
3608
+ counter: 0,
3609
+ window: 1
3610
+ };
3611
+ }
3612
+ /**
3613
+ * Generates an HOTP token.
3614
+ * @param {Object} config Configuration options.
3615
+ * @param {Secret} config.secret Secret key.
3616
+ * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.
3617
+ * @param {number} [config.digits=6] Token length.
3618
+ * @param {number} [config.counter=0] Counter value.
3619
+ * @returns {string} Token.
3620
+ */ static generate({ secret, algorithm = HOTP.defaults.algorithm, digits = HOTP.defaults.digits, counter = HOTP.defaults.counter }) {
3621
+ const digest = hmacDigest(algorithm, secret.bytes, uintDecode(counter));
3622
+ const offset = digest[digest.byteLength - 1] & 15;
3623
+ const otp = ((digest[offset] & 127) << 24 | (digest[offset + 1] & 255) << 16 | (digest[offset + 2] & 255) << 8 | digest[offset + 3] & 255) % 10 ** digits;
3624
+ return otp.toString().padStart(digits, "0");
3625
+ }
3626
+ /**
3627
+ * Generates an HOTP token.
3628
+ * @param {Object} [config] Configuration options.
3629
+ * @param {number} [config.counter=this.counter++] Counter value.
3630
+ * @returns {string} Token.
3631
+ */ generate({ counter = this.counter++ } = {}) {
3632
+ return HOTP.generate({
3633
+ secret: this.secret,
3634
+ algorithm: this.algorithm,
3635
+ digits: this.digits,
3636
+ counter
3637
+ });
3638
+ }
3639
+ /**
3640
+ * Validates an HOTP token.
3641
+ * @param {Object} config Configuration options.
3642
+ * @param {string} config.token Token value.
3643
+ * @param {Secret} config.secret Secret key.
3644
+ * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.
3645
+ * @param {number} [config.digits=6] Token length.
3646
+ * @param {number} [config.counter=0] Counter value.
3647
+ * @param {number} [config.window=1] Window of counter values to test.
3648
+ * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.
3649
+ */ static validate({ token, secret, algorithm, digits = HOTP.defaults.digits, counter = HOTP.defaults.counter, window = HOTP.defaults.window }) {
3650
+ // Return early if the token length does not match the digit number.
3651
+ if (token.length !== digits) return null;
3652
+ let delta = null;
3653
+ const check = (/** @type {number} */ i)=>{
3654
+ const generatedToken = HOTP.generate({
3655
+ secret,
3656
+ algorithm,
3657
+ digits,
3658
+ counter: i
3659
+ });
3660
+ if (timingSafeEqual(token, generatedToken)) {
3661
+ delta = i - counter;
3662
+ }
3663
+ };
3664
+ check(counter);
3665
+ for(let i = 1; i <= window && delta === null; ++i){
3666
+ check(counter - i);
3667
+ if (delta !== null) break;
3668
+ check(counter + i);
3669
+ if (delta !== null) break;
3670
+ }
3671
+ return delta;
3672
+ }
3673
+ /**
3674
+ * Validates an HOTP token.
3675
+ * @param {Object} config Configuration options.
3676
+ * @param {string} config.token Token value.
3677
+ * @param {number} [config.counter=this.counter] Counter value.
3678
+ * @param {number} [config.window=1] Window of counter values to test.
3679
+ * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.
3680
+ */ validate({ token, counter = this.counter, window }) {
3681
+ return HOTP.validate({
3682
+ token,
3683
+ secret: this.secret,
3684
+ algorithm: this.algorithm,
3685
+ digits: this.digits,
3686
+ counter,
3687
+ window
3688
+ });
3689
+ }
3690
+ /**
3691
+ * Returns a Google Authenticator key URI.
3692
+ * @returns {string} URI.
3693
+ */ toString() {
3694
+ const e = encodeURIComponent;
3695
+ return "otpauth://hotp/" + `${this.issuer.length > 0 ? this.issuerInLabel ? `${e(this.issuer)}:${e(this.label)}?issuer=${e(this.issuer)}&` : `${e(this.label)}?issuer=${e(this.issuer)}&` : `${e(this.label)}?`}` + `secret=${e(this.secret.base32)}&` + `algorithm=${e(this.algorithm)}&` + `digits=${e(this.digits)}&` + `counter=${e(this.counter)}`;
3696
+ }
3697
+ /**
3698
+ * Creates an HOTP object.
3699
+ * @param {Object} [config] Configuration options.
3700
+ * @param {string} [config.issuer=''] Account provider.
3701
+ * @param {string} [config.label='OTPAuth'] Account label.
3702
+ * @param {boolean} [config.issuerInLabel=true] Include issuer prefix in label.
3703
+ * @param {Secret|string} [config.secret=Secret] Secret key.
3704
+ * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.
3705
+ * @param {number} [config.digits=6] Token length.
3706
+ * @param {number} [config.counter=0] Initial counter value.
3707
+ */ constructor({ issuer = HOTP.defaults.issuer, label = HOTP.defaults.label, issuerInLabel = HOTP.defaults.issuerInLabel, secret = new Secret(), algorithm = HOTP.defaults.algorithm, digits = HOTP.defaults.digits, counter = HOTP.defaults.counter } = {}){
3708
+ /**
3709
+ * Account provider.
3710
+ * @type {string}
3711
+ */ this.issuer = issuer;
3712
+ /**
3713
+ * Account label.
3714
+ * @type {string}
3715
+ */ this.label = label;
3716
+ /**
3717
+ * Include issuer prefix in label.
3718
+ * @type {boolean}
3719
+ */ this.issuerInLabel = issuerInLabel;
3720
+ /**
3721
+ * Secret key.
3722
+ * @type {Secret}
3723
+ */ this.secret = typeof secret === "string" ? Secret.fromBase32(secret) : secret;
3724
+ /**
3725
+ * HMAC hashing algorithm.
3726
+ * @type {string}
3727
+ */ this.algorithm = canonicalizeAlgorithm(algorithm);
3728
+ /**
3729
+ * Token length.
3730
+ * @type {number}
3731
+ */ this.digits = digits;
3732
+ /**
3733
+ * Initial counter value.
3734
+ * @type {number}
3735
+ */ this.counter = counter;
3736
+ }
3737
+ }
3738
+
3739
+ /**
3740
+ * TOTP: Time-Based One-Time Password Algorithm.
3741
+ * @see [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238)
3742
+ */ class TOTP {
3743
+ /**
3744
+ * Default configuration.
3745
+ * @type {{
3746
+ * issuer: string,
3747
+ * label: string,
3748
+ * issuerInLabel: boolean,
3749
+ * algorithm: string,
3750
+ * digits: number,
3751
+ * period: number
3752
+ * window: number
3753
+ * }}
3754
+ */ static get defaults() {
3755
+ return {
3756
+ issuer: "",
3757
+ label: "OTPAuth",
3758
+ issuerInLabel: true,
3759
+ algorithm: "SHA1",
3760
+ digits: 6,
3761
+ period: 30,
3762
+ window: 1
3763
+ };
3764
+ }
3765
+ /**
3766
+ * Calculates the counter. i.e. the number of periods since timestamp 0.
3767
+ * @param {Object} [config] Configuration options.
3768
+ * @param {number} [config.period=30] Token time-step duration.
3769
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3770
+ * @returns {number} Counter.
3771
+ */ static counter({ period = TOTP.defaults.period, timestamp = Date.now() } = {}) {
3772
+ return Math.floor(timestamp / 1000 / period);
3773
+ }
3774
+ /**
3775
+ * Calculates the counter. i.e. the number of periods since timestamp 0.
3776
+ * @param {Object} [config] Configuration options.
3777
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3778
+ * @returns {number} Counter.
3779
+ */ counter({ timestamp = Date.now() } = {}) {
3780
+ return TOTP.counter({
3781
+ period: this.period,
3782
+ timestamp
3783
+ });
3784
+ }
3785
+ /**
3786
+ * Calculates the remaining time in milliseconds until the next token is generated.
3787
+ * @param {Object} [config] Configuration options.
3788
+ * @param {number} [config.period=30] Token time-step duration.
3789
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3790
+ * @returns {number} counter.
3791
+ */ static remaining({ period = TOTP.defaults.period, timestamp = Date.now() } = {}) {
3792
+ return period * 1000 - timestamp % (period * 1000);
3793
+ }
3794
+ /**
3795
+ * Calculates the remaining time in milliseconds until the next token is generated.
3796
+ * @param {Object} [config] Configuration options.
3797
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3798
+ * @returns {number} counter.
3799
+ */ remaining({ timestamp = Date.now() } = {}) {
3800
+ return TOTP.remaining({
3801
+ period: this.period,
3802
+ timestamp
3803
+ });
3804
+ }
3805
+ /**
3806
+ * Generates a TOTP token.
3807
+ * @param {Object} config Configuration options.
3808
+ * @param {Secret} config.secret Secret key.
3809
+ * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.
3810
+ * @param {number} [config.digits=6] Token length.
3811
+ * @param {number} [config.period=30] Token time-step duration.
3812
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3813
+ * @returns {string} Token.
3814
+ */ static generate({ secret, algorithm, digits, period = TOTP.defaults.period, timestamp = Date.now() }) {
3815
+ return HOTP.generate({
3816
+ secret,
3817
+ algorithm,
3818
+ digits,
3819
+ counter: TOTP.counter({
3820
+ period,
3821
+ timestamp
3822
+ })
3823
+ });
3824
+ }
3825
+ /**
3826
+ * Generates a TOTP token.
3827
+ * @param {Object} [config] Configuration options.
3828
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3829
+ * @returns {string} Token.
3830
+ */ generate({ timestamp = Date.now() } = {}) {
3831
+ return TOTP.generate({
3832
+ secret: this.secret,
3833
+ algorithm: this.algorithm,
3834
+ digits: this.digits,
3835
+ period: this.period,
3836
+ timestamp
3837
+ });
3838
+ }
3839
+ /**
3840
+ * Validates a TOTP token.
3841
+ * @param {Object} config Configuration options.
3842
+ * @param {string} config.token Token value.
3843
+ * @param {Secret} config.secret Secret key.
3844
+ * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.
3845
+ * @param {number} [config.digits=6] Token length.
3846
+ * @param {number} [config.period=30] Token time-step duration.
3847
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3848
+ * @param {number} [config.window=1] Window of counter values to test.
3849
+ * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.
3850
+ */ static validate({ token, secret, algorithm, digits, period = TOTP.defaults.period, timestamp = Date.now(), window }) {
3851
+ return HOTP.validate({
3852
+ token,
3853
+ secret,
3854
+ algorithm,
3855
+ digits,
3856
+ counter: TOTP.counter({
3857
+ period,
3858
+ timestamp
3859
+ }),
3860
+ window
3861
+ });
3862
+ }
3863
+ /**
3864
+ * Validates a TOTP token.
3865
+ * @param {Object} config Configuration options.
3866
+ * @param {string} config.token Token value.
3867
+ * @param {number} [config.timestamp=Date.now] Timestamp value in milliseconds.
3868
+ * @param {number} [config.window=1] Window of counter values to test.
3869
+ * @returns {number|null} Token delta or null if it is not found in the search window, in which case it should be considered invalid.
3870
+ */ validate({ token, timestamp, window }) {
3871
+ return TOTP.validate({
3872
+ token,
3873
+ secret: this.secret,
3874
+ algorithm: this.algorithm,
3875
+ digits: this.digits,
3876
+ period: this.period,
3877
+ timestamp,
3878
+ window
3879
+ });
3880
+ }
3881
+ /**
3882
+ * Returns a Google Authenticator key URI.
3883
+ * @returns {string} URI.
3884
+ */ toString() {
3885
+ const e = encodeURIComponent;
3886
+ return "otpauth://totp/" + `${this.issuer.length > 0 ? this.issuerInLabel ? `${e(this.issuer)}:${e(this.label)}?issuer=${e(this.issuer)}&` : `${e(this.label)}?issuer=${e(this.issuer)}&` : `${e(this.label)}?`}` + `secret=${e(this.secret.base32)}&` + `algorithm=${e(this.algorithm)}&` + `digits=${e(this.digits)}&` + `period=${e(this.period)}`;
3887
+ }
3888
+ /**
3889
+ * Creates a TOTP object.
3890
+ * @param {Object} [config] Configuration options.
3891
+ * @param {string} [config.issuer=''] Account provider.
3892
+ * @param {string} [config.label='OTPAuth'] Account label.
3893
+ * @param {boolean} [config.issuerInLabel=true] Include issuer prefix in label.
3894
+ * @param {Secret|string} [config.secret=Secret] Secret key.
3895
+ * @param {string} [config.algorithm='SHA1'] HMAC hashing algorithm.
3896
+ * @param {number} [config.digits=6] Token length.
3897
+ * @param {number} [config.period=30] Token time-step duration.
3898
+ */ constructor({ issuer = TOTP.defaults.issuer, label = TOTP.defaults.label, issuerInLabel = TOTP.defaults.issuerInLabel, secret = new Secret(), algorithm = TOTP.defaults.algorithm, digits = TOTP.defaults.digits, period = TOTP.defaults.period } = {}){
3899
+ /**
3900
+ * Account provider.
3901
+ * @type {string}
3902
+ */ this.issuer = issuer;
3903
+ /**
3904
+ * Account label.
3905
+ * @type {string}
3906
+ */ this.label = label;
3907
+ /**
3908
+ * Include issuer prefix in label.
3909
+ * @type {boolean}
3910
+ */ this.issuerInLabel = issuerInLabel;
3911
+ /**
3912
+ * Secret key.
3913
+ * @type {Secret}
3914
+ */ this.secret = typeof secret === "string" ? Secret.fromBase32(secret) : secret;
3915
+ /**
3916
+ * HMAC hashing algorithm.
3917
+ * @type {string}
3918
+ */ this.algorithm = canonicalizeAlgorithm(algorithm);
3919
+ /**
3920
+ * Token length.
3921
+ * @type {number}
3922
+ */ this.digits = digits;
3923
+ /**
3924
+ * Token time-step duration.
3925
+ * @type {number}
3926
+ */ this.period = period;
3927
+ }
3928
+ }
3929
+
2010
3930
  class ProboPlaywright {
2011
3931
  constructor(timeoutConfig = {}, page = null) {
2012
3932
  this.page = null;
@@ -2212,6 +4132,14 @@ class ProboPlaywright {
2212
4132
  throw new Error(`Unhandled action: ${action}`);
2213
4133
  }
2214
4134
  }
4135
+ generateOTP(secret, digits = 6, algorithm = 'SHA1') {
4136
+ const otp = new TOTP({
4137
+ algorithm,
4138
+ digits,
4139
+ secret,
4140
+ });
4141
+ return otp.generate();
4142
+ }
2215
4143
  /**
2216
4144
  * Creates a visual highlight overlay on the target element with optional annotation text.
2217
4145
  * The highlight appears as a red border around the element and can include descriptive text.