@otplib/v12-adapter 13.1.1 → 13.2.0

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.cjs CHANGED
@@ -40,6 +40,7 @@ var import_hotp = require("@otplib/hotp");
40
40
  var import_plugin_base32_scure = require("@otplib/plugin-base32-scure");
41
41
  var import_plugin_crypto_noble = require("@otplib/plugin-crypto-noble");
42
42
  var import_uri = require("@otplib/uri");
43
+ var import_base = require("@scure/base");
43
44
 
44
45
  // src/types.ts
45
46
  var HashAlgorithms = {
@@ -64,12 +65,12 @@ function secretToBytes(secret, encoding) {
64
65
  return defaultBase32.decode(secret);
65
66
  }
66
67
  if (encoding === KeyEncodings.HEX || encoding === "hex") {
67
- return (0, import_core.hexToBytes)(secret.replace(/\s/g, ""));
68
+ return import_base.hex.decode(secret.replace(/\s/g, ""));
68
69
  }
69
70
  return (0, import_core.stringToBytes)(secret);
70
71
  }
71
72
  function hotpDigestToToken(hexDigest, digits) {
72
- const digestBytes = (0, import_core.hexToBytes)(hexDigest);
73
+ const digestBytes = import_base.hex.decode(hexDigest);
73
74
  const truncated = (0, import_core.dynamicTruncate)(digestBytes);
74
75
  return (0, import_core.truncateDigits)(truncated, digits);
75
76
  }
@@ -83,7 +84,10 @@ var HOTP = class _HOTP {
83
84
  */
84
85
  _defaultOptions = {};
85
86
  constructor(defaultOptions = {}) {
86
- this._defaultOptions = { ...defaultOptions };
87
+ this._defaultOptions = {
88
+ ...defaultOptions,
89
+ guardrails: (0, import_core.createGuardrails)(defaultOptions.guardrails)
90
+ };
87
91
  this._options = {};
88
92
  }
89
93
  /**
@@ -137,7 +141,8 @@ var HOTP = class _HOTP {
137
141
  counter,
138
142
  algorithm: opts.algorithm,
139
143
  digits: opts.digits,
140
- crypto: opts.crypto
144
+ crypto: opts.crypto,
145
+ guardrails: opts.guardrails
141
146
  });
142
147
  }
143
148
  /**
@@ -154,7 +159,8 @@ var HOTP = class _HOTP {
154
159
  algorithm: opts.algorithm,
155
160
  digits: opts.digits,
156
161
  counterTolerance: 0,
157
- crypto: opts.crypto
162
+ crypto: opts.crypto,
163
+ guardrails: opts.guardrails
158
164
  });
159
165
  return result.valid;
160
166
  } catch {
@@ -247,7 +253,8 @@ var TOTP = class _TOTP extends HOTP {
247
253
  period: opts.step,
248
254
  epoch: epochSeconds,
249
255
  t0: 0,
250
- crypto: opts.crypto
256
+ crypto: opts.crypto,
257
+ guardrails: opts.guardrails
251
258
  });
252
259
  }
253
260
  /**
@@ -285,7 +292,8 @@ var TOTP = class _TOTP extends HOTP {
285
292
  epoch: epochSeconds,
286
293
  t0: 0,
287
294
  epochTolerance,
288
- crypto: opts.crypto
295
+ crypto: opts.crypto,
296
+ guardrails: opts.guardrails
289
297
  });
290
298
  if (!result.valid) {
291
299
  return null;
@@ -411,7 +419,8 @@ var Authenticator = class _Authenticator extends TOTP {
411
419
  period: opts.step,
412
420
  epoch: epochSeconds,
413
421
  t0: 0,
414
- crypto: opts.crypto
422
+ crypto: opts.crypto,
423
+ guardrails: opts.guardrails
415
424
  });
416
425
  }
417
426
  /**
@@ -455,7 +464,8 @@ var Authenticator = class _Authenticator extends TOTP {
455
464
  epoch: epochSeconds,
456
465
  t0: 0,
457
466
  epochTolerance,
458
- crypto: opts.crypto
467
+ crypto: opts.crypto,
468
+ guardrails: opts.guardrails
459
469
  });
460
470
  if (!result.valid) {
461
471
  return null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/hotp.ts","../src/types.ts","../src/totp.ts","../src/authenticator.ts"],"sourcesContent":["/**\n * @otplib/v12-adapter\n *\n * Drop-in replacement adapter for migrating from otplib v12 to v13.\n *\n * This package provides the same API as otplib v12, making it easy\n * to migrate existing codebases to v13 without breaking changes.\n *\n * @example Using pre-configured instances (v12 style)\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n *\n * @example Using class instances\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator({ step: 60 });\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * ```\n */\n\n// Classes\nexport { HOTP } from \"./hotp.js\";\nexport { TOTP } from \"./totp.js\";\nexport { Authenticator } from \"./authenticator.js\";\n\n// Functional exports (v12-style)\nexport { hotpDigestToToken } from \"./hotp.js\";\n\n// Constants (v12-style)\nexport { HashAlgorithms, KeyEncodings } from \"./types.js\";\n\n// Types\nexport type {\n HOTPOptions,\n TOTPOptions,\n AuthenticatorOptions,\n SecretKey,\n Base32SecretKey,\n CreateDigest,\n CreateHmacKey,\n CreateRandomBytes,\n KeyEncoder,\n KeyDecoder,\n} from \"./types.js\";\n\n// Pre-configured instances (v12 style)\nimport { Authenticator } from \"./authenticator.js\";\nimport { HOTP } from \"./hotp.js\";\nimport { TOTP } from \"./totp.js\";\n\n/**\n * Pre-configured HOTP instance\n *\n * @example\n * ```typescript\n * import { hotp } from '@otplib/v12-adapter';\n *\n * const token = hotp.generate('JBSWY3DPEHPK3PXP', 0);\n * const isValid = hotp.check(token, 'JBSWY3DPEHPK3PXP', 0);\n * ```\n */\nexport const hotp = new HOTP();\n\n/**\n * Pre-configured TOTP instance\n *\n * @example\n * ```typescript\n * import { totp } from '@otplib/v12-adapter';\n *\n * const token = totp.generate('JBSWY3DPEHPK3PXP');\n * const isValid = totp.check(token, 'JBSWY3DPEHPK3PXP');\n * ```\n */\nexport const totp = new TOTP();\n\n/**\n * Pre-configured Authenticator instance\n *\n * @example\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * ```\n */\nexport const authenticator = new Authenticator();\n\n// Re-export v13 plugins for advanced usage\nexport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nexport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible HOTP class implementation.\n * Provides synchronous API wrapper around v13's HOTP implementation.\n */\n\nimport { stringToBytes, hexToBytes, dynamicTruncate, truncateDigits } from \"@otplib/core\";\nimport { generateSync as hotpGenerateSync, verifySync as hotpVerifySync } from \"@otplib/hotp\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateHOTP as generateHOTPURI } from \"@otplib/uri\";\n\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { HOTPOptions, SecretKey, ResolvedHOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Convert a string secret to bytes based on encoding\n * @internal\n */\nexport function secretToBytes(secret: SecretKey, encoding?: string): Uint8Array {\n if (encoding === KeyEncodingsConst.BASE32 || encoding === \"base32\") {\n return defaultBase32.decode(secret);\n }\n if (encoding === KeyEncodingsConst.HEX || encoding === \"hex\") {\n return hexToBytes(secret.replace(/\\s/g, \"\"));\n }\n // Default: treat as ASCII/UTF-8\n return stringToBytes(secret);\n}\n\n/**\n * Converts a digest to a token of a specified length.\n * Uses dynamicTruncate and truncateDigits from core.\n */\nexport function hotpDigestToToken(hexDigest: string, digits: number): string {\n const digestBytes = hexToBytes(hexDigest);\n const truncated = dynamicTruncate(digestBytes);\n return truncateDigits(truncated, digits);\n}\n\n/**\n * v12-compatible HOTP class\n *\n * Provides the same API as otplib v12 HOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { HOTP } from '@otplib/v12-adapter';\n *\n * const hotp = new HOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = hotp.generate(secret, 0);\n * const isValid = hotp.check(token, secret, 0);\n * ```\n */\nexport class HOTP<T extends HOTPOptions = HOTPOptions> {\n /**\n * Stored options that can be modified\n */\n protected _options: Partial<T> = {};\n\n /**\n * Default options applied to all operations\n */\n protected _defaultOptions: Partial<T> = {};\n\n constructor(defaultOptions: Partial<T> = {}) {\n this._defaultOptions = { ...defaultOptions };\n this._options = {};\n }\n\n /**\n * Get current options (merged with defaults)\n */\n get options(): Partial<T> {\n return { ...this._defaultOptions, ...this._options };\n }\n\n /**\n * Set options (replaces current options)\n */\n set options(value: Partial<T>) {\n this._options = { ...value };\n }\n\n /**\n * Creates a new instance with the specified default options\n */\n create(defaultOptions: Partial<T> = {}): HOTP<T> {\n return new HOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with default values\n */\n allOptions(): Readonly<ResolvedHOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedHOTPOptions>;\n }\n\n /**\n * Reset options to defaults\n */\n resetOptions(): this {\n this._options = {};\n return this;\n }\n\n /**\n * Generate an HOTP token\n */\n generate(secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n return hotpGenerateSync({\n secret: secretBytes,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n crypto: opts.crypto,\n });\n }\n\n /**\n * Check if a token is valid for the given secret and counter\n */\n check(token: string, secret: SecretKey, counter: number): boolean {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n try {\n const result = hotpVerifySync({\n secret: secretBytes,\n token,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counterTolerance: 0,\n crypto: opts.crypto,\n });\n\n return result.valid;\n } catch {\n return false;\n }\n }\n\n /**\n * Verify a token (object-based API)\n */\n verify(opts: { token: string; secret: SecretKey; counter: number }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret, opts.counter);\n }\n\n /**\n * Generate an otpauth:// URI for HOTP\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n\n return generateHOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counter,\n });\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible type definitions for migration adapter.\n * These types mirror the v12 API to provide drop-in compatibility.\n */\n\nimport type { CryptoPlugin, Base32Plugin, HashAlgorithm } from \"@otplib/core\";\n\n/**\n * v12-style hash algorithms constant\n */\nexport const HashAlgorithms = {\n SHA1: \"sha1\",\n SHA256: \"sha256\",\n SHA512: \"sha512\",\n} as const;\n\nexport type HashAlgorithms = (typeof HashAlgorithms)[keyof typeof HashAlgorithms];\n\n/**\n * v12-style key encodings constant\n */\nexport const KeyEncodings = {\n ASCII: \"ascii\",\n HEX: \"hex\",\n BASE32: \"base32\",\n BASE64: \"base64\",\n LATIN1: \"latin1\",\n UTF8: \"utf8\",\n} as const;\n\nexport type KeyEncodings = (typeof KeyEncodings)[keyof typeof KeyEncodings];\n\n/**\n * v12-style secret key type (string-based)\n */\nexport type SecretKey = string;\n\n/**\n * Base32 encoded secret key\n */\nexport type Base32SecretKey = string;\n\n/**\n * v12-style createDigest function signature\n */\nexport type CreateDigest<T = string> = (algorithm: HashAlgorithm, hmacKey: T, counter: T) => T;\n\n/**\n * v12-style createHmacKey function signature\n */\nexport type CreateHmacKey<T = string> = (\n algorithm: HashAlgorithm,\n secret: SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-style createRandomBytes function signature\n */\nexport type CreateRandomBytes<T = string> = (size: number, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyEncoder function signature\n */\nexport type KeyEncoder<T = Base32SecretKey> = (secret: SecretKey, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyDecoder function signature\n */\nexport type KeyDecoder<T = SecretKey> = (\n encodedSecret: Base32SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-compatible HOTP options\n */\nexport type HOTPOptions<T = string> = {\n /** Algorithm for HMAC (default: sha1) */\n algorithm?: HashAlgorithm;\n /** Creates the digest for token generation */\n createDigest?: CreateDigest<T>;\n /** Formats the secret into HMAC key */\n createHmacKey?: CreateHmacKey<T>;\n /** Number of digits in token (default: 6) */\n digits?: number;\n /** Secret encoding (default: ascii) */\n encoding?: KeyEncodings;\n /** Pre-computed digest (use with caution) */\n digest?: string;\n /** v13 crypto plugin (internal use) */\n crypto?: CryptoPlugin;\n /** v13 base32 plugin (internal use) */\n base32?: Base32Plugin;\n};\n\n/**\n * v12-compatible TOTP options\n */\nexport type TOTPOptions<T = string> = HOTPOptions<T> & {\n /** Starting epoch in milliseconds (default: Date.now()) */\n epoch?: number;\n /** Time step in seconds (default: 30) */\n step?: number;\n /** Verification window - number of steps or [past, future] */\n window?: number | [number, number];\n};\n\n/**\n * v12-compatible Authenticator options\n */\nexport type AuthenticatorOptions<T = string> = TOTPOptions<T> & {\n /** Encodes secret to Base32 */\n keyEncoder?: KeyEncoder<T>;\n /** Decodes Base32 secret */\n keyDecoder?: KeyDecoder<T>;\n /** Creates random bytes for secret generation */\n createRandomBytes?: CreateRandomBytes<T>;\n};\n\n/**\n * Resolved HOTP options with guaranteed defaults\n */\nexport type ResolvedHOTPOptions = {\n algorithm: HashAlgorithm;\n digits: number;\n encoding: KeyEncodings;\n crypto: CryptoPlugin;\n base32: Base32Plugin;\n};\n\n/**\n * Resolved TOTP options with guaranteed defaults\n */\nexport type ResolvedTOTPOptions = ResolvedHOTPOptions & {\n epoch: number;\n step: number;\n window: number | [number, number];\n};\n\n/**\n * Resolved Authenticator options with guaranteed defaults\n */\nexport type ResolvedAuthenticatorOptions = ResolvedTOTPOptions & {\n keyEncoder?: KeyEncoder;\n keyDecoder?: KeyDecoder;\n};\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible TOTP class implementation.\n * Provides synchronous API wrapper around v13's TOTP implementation.\n */\n\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport {\n generateSync as totpGenerateSync,\n verifySync as totpVerifySync,\n getRemainingTime,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI } from \"@otplib/uri\";\n\nimport { HOTP, secretToBytes } from \"./hotp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { TOTPOptions, SecretKey, ResolvedTOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Parse window option into epochTolerance\n * v12 uses \"window\" as number of steps, v13 uses epochTolerance in seconds\n */\nfunction parseWindow(\n window: number | [number, number] | undefined,\n step: number,\n): number | [number, number] {\n if (window === undefined || window === 0) {\n return 0;\n }\n if (typeof window === \"number\") {\n return window * step;\n }\n // [past, future] steps → [past, future] seconds\n return [window[0] * step, window[1] * step];\n}\n\n/**\n * v12-compatible TOTP class\n *\n * Provides the same API as otplib v12 TOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { TOTP } from '@otplib/v12-adapter';\n *\n * const totp = new TOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = totp.generate(secret);\n * const isValid = totp.check(token, secret);\n * ```\n */\nexport class TOTP<T extends TOTPOptions = TOTPOptions> extends HOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new TOTP instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): TOTP<T> {\n return new TOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with TOTP default values\n */\n override allOptions(): Readonly<ResolvedTOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedTOTPOptions>;\n }\n\n /**\n * Generate a TOTP token\n *\n * @param secret - The secret key\n * @returns The OTP token\n */\n generate(secret: SecretKey): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n });\n }\n\n /**\n * Check if a token is valid for the given secret\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns true if valid\n */\n check(token: string, secret: SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n checkDelta(token: string, secret: SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n const step = opts.step;\n const window = opts.window;\n\n const epochTolerance = parseWindow(window, step);\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n });\n\n if (!result.valid) {\n return null;\n }\n\n // v13 returns delta directly as time step offset\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n verify(opts: { token: string; secret: SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Generate an otpauth:// URI for TOTP\n *\n * @param accountName - Account name for the URI\n * @param issuer - Issuer name\n * @param secret - The secret key (should be Base32 for QR codes)\n * @returns The otpauth:// URI\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey): string {\n const opts = this.allOptions();\n\n return generateTOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n });\n }\n\n /**\n * Get time used in current step (seconds elapsed in current window)\n *\n * @returns Seconds used in current step\n */\n timeUsed(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return epochSeconds % opts.step;\n }\n\n /**\n * Get time remaining until next token\n *\n * @returns Seconds remaining in current step\n */\n timeRemaining(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return getRemainingTime(epochSeconds, opts.step, 0);\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible Authenticator class implementation.\n * Provides same API as v12 with Base32 encoding support.\n */\n\nimport { generateSecret as generateSecretCore } from \"@otplib/core\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateSync as totpGenerateSync, verifySync as totpVerifySync } from \"@otplib/totp\";\n\nimport { TOTP } from \"./totp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type {\n AuthenticatorOptions,\n Base32SecretKey,\n SecretKey,\n KeyEncodings,\n ResolvedAuthenticatorOptions,\n} from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Default key encoder - encodes raw bytes to Base32\n */\nfunction defaultKeyEncoder(secret: SecretKey, _encoding: KeyEncodings): Base32SecretKey {\n const bytes = new TextEncoder().encode(secret);\n return defaultBase32.encode(bytes);\n}\n\n/**\n * Default key decoder - decodes Base32 to string\n */\nfunction defaultKeyDecoder(encodedSecret: Base32SecretKey, _encoding: KeyEncodings): SecretKey {\n const bytes = defaultBase32.decode(encodedSecret);\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * v12-compatible Authenticator class\n *\n * The Authenticator class is a TOTP variant that uses Base32-encoded secrets\n * by default, making it compatible with Google Authenticator and similar apps.\n *\n * @example\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator();\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n */\nexport class Authenticator<T extends AuthenticatorOptions = AuthenticatorOptions> extends TOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new Authenticator instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): Authenticator<T> {\n return new Authenticator<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with Authenticator default values\n */\n override allOptions(): Readonly<ResolvedAuthenticatorOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.HEX,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n keyEncoder: defaultKeyEncoder,\n keyDecoder: defaultKeyDecoder,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedAuthenticatorOptions>;\n }\n\n /**\n * Generate an OTP token from a Base32 secret\n *\n * @param secret - Base32-encoded secret\n * @returns The OTP token\n */\n override generate(secret: Base32SecretKey): string {\n const opts = this.allOptions();\n\n // Generate using decoded secret (as raw bytes)\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n });\n }\n\n /**\n * Check if a token is valid for the given Base32 secret\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns true if valid\n */\n override check(token: string, secret: Base32SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n override checkDelta(token: string, secret: Base32SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n const step = opts.step;\n const window = opts.window;\n\n // Convert window (steps) to epochTolerance (seconds)\n let epochTolerance: number | [number, number] = 0;\n if (typeof window === \"number\") {\n epochTolerance = window * step;\n } else if (Array.isArray(window)) {\n epochTolerance = [window[0] * step, window[1] * step];\n }\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n });\n\n if (!result.valid) {\n return null;\n }\n\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n override verify(opts: { token: string; secret: Base32SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Encode a raw secret to Base32\n *\n * @param secret - Raw secret string\n * @returns Base32-encoded secret\n */\n encode(secret: SecretKey): Base32SecretKey {\n const opts = this.allOptions();\n if (opts.keyEncoder) {\n return opts.keyEncoder(secret, opts.encoding);\n }\n return defaultKeyEncoder(secret, opts.encoding);\n }\n\n /**\n * Decode a Base32 secret to raw string\n *\n * @param secret - Base32-encoded secret\n * @returns Raw secret string\n */\n decode(secret: Base32SecretKey): SecretKey {\n const opts = this.allOptions();\n if (opts.keyDecoder) {\n return opts.keyDecoder(secret, opts.encoding);\n }\n return defaultKeyDecoder(secret, opts.encoding);\n }\n\n /**\n * Generate a random Base32-encoded secret\n *\n * @param numberOfBytes - Number of bytes for the secret (default: 20)\n * @returns Base32-encoded secret\n */\n generateSecret(numberOfBytes: number = 20): Base32SecretKey {\n const opts = this.allOptions();\n return generateSecretCore({\n crypto: opts.crypto,\n base32: opts.base32,\n length: numberOfBytes,\n });\n }\n}\n"],"mappings":"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","names":["hotpGenerateSync","hotpVerifySync","generateHOTPURI","import_plugin_base32_scure","import_plugin_crypto_noble","import_uri","defaultCrypto","defaultBase32","totpGenerateSync","totpVerifySync","generateTOTPURI","import_core","import_plugin_base32_scure","import_plugin_crypto_noble","import_totp","defaultCrypto","defaultBase32","totpGenerateSync","totpVerifySync","generateSecretCore","import_plugin_crypto_noble","import_plugin_base32_scure"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/hotp.ts","../src/types.ts","../src/totp.ts","../src/authenticator.ts"],"sourcesContent":["/**\n * @otplib/v12-adapter\n *\n * Drop-in replacement adapter for migrating from otplib v12 to v13.\n *\n * This package provides the same API as otplib v12, making it easy\n * to migrate existing codebases to v13 without breaking changes.\n *\n * @example Using pre-configured instances (v12 style)\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n *\n * @example Using class instances\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator({ step: 60 });\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * ```\n */\n\n// Classes\nexport { HOTP } from \"./hotp.js\";\nexport { TOTP } from \"./totp.js\";\nexport { Authenticator } from \"./authenticator.js\";\n\n// Functional exports (v12-style)\nexport { hotpDigestToToken } from \"./hotp.js\";\n\n// Constants (v12-style)\nexport { HashAlgorithms, KeyEncodings } from \"./types.js\";\n\n// Types\nexport type {\n HOTPOptions,\n TOTPOptions,\n AuthenticatorOptions,\n SecretKey,\n Base32SecretKey,\n CreateDigest,\n CreateHmacKey,\n CreateRandomBytes,\n KeyEncoder,\n KeyDecoder,\n} from \"./types.js\";\n\n// Pre-configured instances (v12 style)\nimport { Authenticator } from \"./authenticator.js\";\nimport { HOTP } from \"./hotp.js\";\nimport { TOTP } from \"./totp.js\";\n\n/**\n * Pre-configured HOTP instance\n *\n * @example\n * ```typescript\n * import { hotp } from '@otplib/v12-adapter';\n *\n * const token = hotp.generate('JBSWY3DPEHPK3PXP', 0);\n * const isValid = hotp.check(token, 'JBSWY3DPEHPK3PXP', 0);\n * ```\n */\nexport const hotp = new HOTP();\n\n/**\n * Pre-configured TOTP instance\n *\n * @example\n * ```typescript\n * import { totp } from '@otplib/v12-adapter';\n *\n * const token = totp.generate('JBSWY3DPEHPK3PXP');\n * const isValid = totp.check(token, 'JBSWY3DPEHPK3PXP');\n * ```\n */\nexport const totp = new TOTP();\n\n/**\n * Pre-configured Authenticator instance\n *\n * @example\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * ```\n */\nexport const authenticator = new Authenticator();\n\n// Re-export v13 plugins for advanced usage\nexport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nexport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible HOTP class implementation.\n * Provides synchronous API wrapper around v13's HOTP implementation.\n */\n\nimport { stringToBytes, dynamicTruncate, truncateDigits, createGuardrails } from \"@otplib/core\";\nimport { generateSync as hotpGenerateSync, verifySync as hotpVerifySync } from \"@otplib/hotp\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateHOTP as generateHOTPURI } from \"@otplib/uri\";\nimport { hex } from \"@scure/base\";\n\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { HOTPOptions, SecretKey, ResolvedHOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Convert a string secret to bytes based on encoding\n * @internal\n */\nexport function secretToBytes(secret: SecretKey, encoding?: string): Uint8Array {\n if (encoding === KeyEncodingsConst.BASE32 || encoding === \"base32\") {\n return defaultBase32.decode(secret);\n }\n if (encoding === KeyEncodingsConst.HEX || encoding === \"hex\") {\n return hex.decode(secret.replace(/\\s/g, \"\"));\n }\n // Default: treat as ASCII/UTF-8\n return stringToBytes(secret);\n}\n\n/**\n * Converts a digest to a token of a specified length.\n * Uses dynamicTruncate and truncateDigits from core.\n */\nexport function hotpDigestToToken(hexDigest: string, digits: number): string {\n const digestBytes = hex.decode(hexDigest);\n const truncated = dynamicTruncate(digestBytes);\n return truncateDigits(truncated, digits);\n}\n\n/**\n * v12-compatible HOTP class\n *\n * Provides the same API as otplib v12 HOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { HOTP } from '@otplib/v12-adapter';\n *\n * const hotp = new HOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = hotp.generate(secret, 0);\n * const isValid = hotp.check(token, secret, 0);\n * ```\n */\nexport class HOTP<T extends HOTPOptions = HOTPOptions> {\n /**\n * Stored options that can be modified\n */\n protected _options: Partial<T> = {};\n\n /**\n * Default options applied to all operations\n */\n protected _defaultOptions: Partial<T> = {};\n\n constructor(defaultOptions: Partial<T> = {}) {\n this._defaultOptions = {\n ...defaultOptions,\n guardrails: createGuardrails(defaultOptions.guardrails),\n } as Partial<T>;\n this._options = {};\n }\n\n /**\n * Get current options (merged with defaults)\n */\n get options(): Partial<T> {\n return { ...this._defaultOptions, ...this._options };\n }\n\n /**\n * Set options (replaces current options)\n */\n set options(value: Partial<T>) {\n this._options = { ...value };\n }\n\n /**\n * Creates a new instance with the specified default options\n */\n create(defaultOptions: Partial<T> = {}): HOTP<T> {\n return new HOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with default values\n */\n allOptions(): Readonly<ResolvedHOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedHOTPOptions>;\n }\n\n /**\n * Reset options to defaults\n */\n resetOptions(): this {\n this._options = {};\n return this;\n }\n\n /**\n * Generate an HOTP token\n */\n generate(secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n return hotpGenerateSync({\n secret: secretBytes,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n }\n\n /**\n * Check if a token is valid for the given secret and counter\n */\n check(token: string, secret: SecretKey, counter: number): boolean {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n try {\n const result = hotpVerifySync({\n secret: secretBytes,\n token,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counterTolerance: 0,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n\n return result.valid;\n } catch {\n return false;\n }\n }\n\n /**\n * Verify a token (object-based API)\n */\n verify(opts: { token: string; secret: SecretKey; counter: number }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret, opts.counter);\n }\n\n /**\n * Generate an otpauth:// URI for HOTP\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n\n return generateHOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counter,\n });\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible type definitions for migration adapter.\n * These types mirror the v12 API to provide drop-in compatibility.\n */\n\nimport type { CryptoPlugin, Base32Plugin, HashAlgorithm, OTPGuardrails } from \"@otplib/core\";\n\n/**\n * v12-style hash algorithms constant\n */\nexport const HashAlgorithms = {\n SHA1: \"sha1\",\n SHA256: \"sha256\",\n SHA512: \"sha512\",\n} as const;\n\nexport type HashAlgorithms = (typeof HashAlgorithms)[keyof typeof HashAlgorithms];\n\n/**\n * v12-style key encodings constant\n */\nexport const KeyEncodings = {\n ASCII: \"ascii\",\n HEX: \"hex\",\n BASE32: \"base32\",\n BASE64: \"base64\",\n LATIN1: \"latin1\",\n UTF8: \"utf8\",\n} as const;\n\nexport type KeyEncodings = (typeof KeyEncodings)[keyof typeof KeyEncodings];\n\n/**\n * v12-style secret key type (string-based)\n */\nexport type SecretKey = string;\n\n/**\n * Base32 encoded secret key\n */\nexport type Base32SecretKey = string;\n\n/**\n * v12-style createDigest function signature\n */\nexport type CreateDigest<T = string> = (algorithm: HashAlgorithm, hmacKey: T, counter: T) => T;\n\n/**\n * v12-style createHmacKey function signature\n */\nexport type CreateHmacKey<T = string> = (\n algorithm: HashAlgorithm,\n secret: SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-style createRandomBytes function signature\n */\nexport type CreateRandomBytes<T = string> = (size: number, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyEncoder function signature\n */\nexport type KeyEncoder<T = Base32SecretKey> = (secret: SecretKey, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyDecoder function signature\n */\nexport type KeyDecoder<T = SecretKey> = (\n encodedSecret: Base32SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-compatible HOTP options\n */\nexport type HOTPOptions<T = string> = {\n /** Algorithm for HMAC (default: sha1) */\n algorithm?: HashAlgorithm;\n /** Creates the digest for token generation */\n createDigest?: CreateDigest<T>;\n /** Formats the secret into HMAC key */\n createHmacKey?: CreateHmacKey<T>;\n /** Number of digits in token (default: 6) */\n digits?: number;\n /** Secret encoding (default: ascii) */\n encoding?: KeyEncodings;\n /** Pre-computed digest (use with caution) */\n digest?: string;\n /** v13 crypto plugin (internal use) */\n crypto?: CryptoPlugin;\n /** v13 base32 plugin (internal use) */\n base32?: Base32Plugin;\n /** Validation guardrails */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * v12-compatible TOTP options\n */\nexport type TOTPOptions<T = string> = HOTPOptions<T> & {\n /** Starting epoch in milliseconds (default: Date.now()) */\n epoch?: number;\n /** Time step in seconds (default: 30) */\n step?: number;\n /** Verification window - number of steps or [past, future] */\n window?: number | [number, number];\n};\n\n/**\n * v12-compatible Authenticator options\n */\nexport type AuthenticatorOptions<T = string> = TOTPOptions<T> & {\n /** Encodes secret to Base32 */\n keyEncoder?: KeyEncoder<T>;\n /** Decodes Base32 secret */\n keyDecoder?: KeyDecoder<T>;\n /** Creates random bytes for secret generation */\n createRandomBytes?: CreateRandomBytes<T>;\n};\n\n/**\n * Resolved HOTP options with guaranteed defaults\n */\nexport type ResolvedHOTPOptions = {\n algorithm: HashAlgorithm;\n digits: number;\n encoding: KeyEncodings;\n crypto: CryptoPlugin;\n base32: Base32Plugin;\n guardrails: OTPGuardrails;\n};\n\n/**\n * Resolved TOTP options with guaranteed defaults\n */\nexport type ResolvedTOTPOptions = ResolvedHOTPOptions & {\n epoch: number;\n step: number;\n window: number | [number, number];\n};\n\n/**\n * Resolved Authenticator options with guaranteed defaults\n */\nexport type ResolvedAuthenticatorOptions = ResolvedTOTPOptions & {\n keyEncoder?: KeyEncoder;\n keyDecoder?: KeyDecoder;\n};\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible TOTP class implementation.\n * Provides synchronous API wrapper around v13's TOTP implementation.\n */\n\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport {\n generateSync as totpGenerateSync,\n verifySync as totpVerifySync,\n getRemainingTime,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI } from \"@otplib/uri\";\n\nimport { HOTP, secretToBytes } from \"./hotp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { TOTPOptions, SecretKey, ResolvedTOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Parse window option into epochTolerance\n * v12 uses \"window\" as number of steps, v13 uses epochTolerance in seconds\n */\nfunction parseWindow(\n window: number | [number, number] | undefined,\n step: number,\n): number | [number, number] {\n if (window === undefined || window === 0) {\n return 0;\n }\n if (typeof window === \"number\") {\n return window * step;\n }\n // [past, future] steps → [past, future] seconds\n return [window[0] * step, window[1] * step];\n}\n\n/**\n * v12-compatible TOTP class\n *\n * Provides the same API as otplib v12 TOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { TOTP } from '@otplib/v12-adapter';\n *\n * const totp = new TOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = totp.generate(secret);\n * const isValid = totp.check(token, secret);\n * ```\n */\nexport class TOTP<T extends TOTPOptions = TOTPOptions> extends HOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new TOTP instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): TOTP<T> {\n return new TOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with TOTP default values\n */\n override allOptions(): Readonly<ResolvedTOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedTOTPOptions>;\n }\n\n /**\n * Generate a TOTP token\n *\n * @param secret - The secret key\n * @returns The OTP token\n */\n generate(secret: SecretKey): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n }\n\n /**\n * Check if a token is valid for the given secret\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns true if valid\n */\n check(token: string, secret: SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n checkDelta(token: string, secret: SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n const step = opts.step;\n const window = opts.window;\n\n const epochTolerance = parseWindow(window, step);\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n\n if (!result.valid) {\n return null;\n }\n\n // v13 returns delta directly as time step offset\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n verify(opts: { token: string; secret: SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Generate an otpauth:// URI for TOTP\n *\n * @param accountName - Account name for the URI\n * @param issuer - Issuer name\n * @param secret - The secret key (should be Base32 for QR codes)\n * @returns The otpauth:// URI\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey): string {\n const opts = this.allOptions();\n\n return generateTOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n });\n }\n\n /**\n * Get time used in current step (seconds elapsed in current window)\n *\n * @returns Seconds used in current step\n */\n timeUsed(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return epochSeconds % opts.step;\n }\n\n /**\n * Get time remaining until next token\n *\n * @returns Seconds remaining in current step\n */\n timeRemaining(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return getRemainingTime(epochSeconds, opts.step, 0);\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible Authenticator class implementation.\n * Provides same API as v12 with Base32 encoding support.\n */\n\nimport { generateSecret as generateSecretCore } from \"@otplib/core\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateSync as totpGenerateSync, verifySync as totpVerifySync } from \"@otplib/totp\";\n\nimport { TOTP } from \"./totp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type {\n AuthenticatorOptions,\n Base32SecretKey,\n SecretKey,\n KeyEncodings,\n ResolvedAuthenticatorOptions,\n} from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Default key encoder - encodes raw bytes to Base32\n */\nfunction defaultKeyEncoder(secret: SecretKey, _encoding: KeyEncodings): Base32SecretKey {\n const bytes = new TextEncoder().encode(secret);\n return defaultBase32.encode(bytes);\n}\n\n/**\n * Default key decoder - decodes Base32 to string\n */\nfunction defaultKeyDecoder(encodedSecret: Base32SecretKey, _encoding: KeyEncodings): SecretKey {\n const bytes = defaultBase32.decode(encodedSecret);\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * v12-compatible Authenticator class\n *\n * The Authenticator class is a TOTP variant that uses Base32-encoded secrets\n * by default, making it compatible with Google Authenticator and similar apps.\n *\n * @example\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator();\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n */\nexport class Authenticator<T extends AuthenticatorOptions = AuthenticatorOptions> extends TOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new Authenticator instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): Authenticator<T> {\n return new Authenticator<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with Authenticator default values\n */\n override allOptions(): Readonly<ResolvedAuthenticatorOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.HEX,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n keyEncoder: defaultKeyEncoder,\n keyDecoder: defaultKeyDecoder,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedAuthenticatorOptions>;\n }\n\n /**\n * Generate an OTP token from a Base32 secret\n *\n * @param secret - Base32-encoded secret\n * @returns The OTP token\n */\n override generate(secret: Base32SecretKey): string {\n const opts = this.allOptions();\n\n // Generate using decoded secret (as raw bytes)\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n }\n\n /**\n * Check if a token is valid for the given Base32 secret\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns true if valid\n */\n override check(token: string, secret: Base32SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n override checkDelta(token: string, secret: Base32SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n const step = opts.step;\n const window = opts.window;\n\n // Convert window (steps) to epochTolerance (seconds)\n let epochTolerance: number | [number, number] = 0;\n if (typeof window === \"number\") {\n epochTolerance = window * step;\n } else if (Array.isArray(window)) {\n epochTolerance = [window[0] * step, window[1] * step];\n }\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n\n if (!result.valid) {\n return null;\n }\n\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n override verify(opts: { token: string; secret: Base32SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Encode a raw secret to Base32\n *\n * @param secret - Raw secret string\n * @returns Base32-encoded secret\n */\n encode(secret: SecretKey): Base32SecretKey {\n const opts = this.allOptions();\n if (opts.keyEncoder) {\n return opts.keyEncoder(secret, opts.encoding);\n }\n return defaultKeyEncoder(secret, opts.encoding);\n }\n\n /**\n * Decode a Base32 secret to raw string\n *\n * @param secret - Base32-encoded secret\n * @returns Raw secret string\n */\n decode(secret: Base32SecretKey): SecretKey {\n const opts = this.allOptions();\n if (opts.keyDecoder) {\n return opts.keyDecoder(secret, opts.encoding);\n }\n return defaultKeyDecoder(secret, opts.encoding);\n }\n\n /**\n * Generate a random Base32-encoded secret\n *\n * @param numberOfBytes - Number of bytes for the secret (default: 20)\n * @returns Base32-encoded secret\n */\n generateSecret(numberOfBytes: number = 20): Base32SecretKey {\n const opts = this.allOptions();\n return generateSecretCore({\n crypto: opts.crypto,\n base32: opts.base32,\n length: numberOfBytes,\n });\n }\n}\n"],"mappings":"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","names":["hotpGenerateSync","hotpVerifySync","generateHOTPURI","import_plugin_base32_scure","import_plugin_crypto_noble","import_uri","defaultCrypto","defaultBase32","totpGenerateSync","totpVerifySync","generateTOTPURI","import_core","import_plugin_base32_scure","import_plugin_crypto_noble","import_totp","defaultCrypto","defaultBase32","totpGenerateSync","totpVerifySync","generateSecretCore","import_plugin_crypto_noble","import_plugin_base32_scure"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { HashAlgorithm, CryptoPlugin, Base32Plugin } from '@otplib/core';
1
+ import { HashAlgorithm, CryptoPlugin, Base32Plugin, OTPGuardrails } from '@otplib/core';
2
2
  export { NobleCryptoPlugin } from '@otplib/plugin-crypto-noble';
3
3
  export { ScureBase32Plugin } from '@otplib/plugin-base32-scure';
4
4
 
@@ -78,6 +78,8 @@ type HOTPOptions<T = string> = {
78
78
  crypto?: CryptoPlugin;
79
79
  /** v13 base32 plugin (internal use) */
80
80
  base32?: Base32Plugin;
81
+ /** Validation guardrails */
82
+ guardrails?: OTPGuardrails;
81
83
  };
82
84
  /**
83
85
  * v12-compatible TOTP options
@@ -110,6 +112,7 @@ type ResolvedHOTPOptions = {
110
112
  encoding: KeyEncodings;
111
113
  crypto: CryptoPlugin;
112
114
  base32: Base32Plugin;
115
+ guardrails: OTPGuardrails;
113
116
  };
114
117
  /**
115
118
  * Resolved TOTP options with guaranteed defaults
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { HashAlgorithm, CryptoPlugin, Base32Plugin } from '@otplib/core';
1
+ import { HashAlgorithm, CryptoPlugin, Base32Plugin, OTPGuardrails } from '@otplib/core';
2
2
  export { NobleCryptoPlugin } from '@otplib/plugin-crypto-noble';
3
3
  export { ScureBase32Plugin } from '@otplib/plugin-base32-scure';
4
4
 
@@ -78,6 +78,8 @@ type HOTPOptions<T = string> = {
78
78
  crypto?: CryptoPlugin;
79
79
  /** v13 base32 plugin (internal use) */
80
80
  base32?: Base32Plugin;
81
+ /** Validation guardrails */
82
+ guardrails?: OTPGuardrails;
81
83
  };
82
84
  /**
83
85
  * v12-compatible TOTP options
@@ -110,6 +112,7 @@ type ResolvedHOTPOptions = {
110
112
  encoding: KeyEncodings;
111
113
  crypto: CryptoPlugin;
112
114
  base32: Base32Plugin;
115
+ guardrails: OTPGuardrails;
113
116
  };
114
117
  /**
115
118
  * Resolved TOTP options with guaranteed defaults
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  // src/hotp.ts
2
- import { stringToBytes, hexToBytes, dynamicTruncate, truncateDigits } from "@otplib/core";
2
+ import { stringToBytes, dynamicTruncate, truncateDigits, createGuardrails } from "@otplib/core";
3
3
  import { generateSync as hotpGenerateSync, verifySync as hotpVerifySync } from "@otplib/hotp";
4
4
  import { ScureBase32Plugin } from "@otplib/plugin-base32-scure";
5
5
  import { NobleCryptoPlugin } from "@otplib/plugin-crypto-noble";
6
6
  import { generateHOTP as generateHOTPURI } from "@otplib/uri";
7
+ import { hex } from "@scure/base";
7
8
 
8
9
  // src/types.ts
9
10
  var HashAlgorithms = {
@@ -28,12 +29,12 @@ function secretToBytes(secret, encoding) {
28
29
  return defaultBase32.decode(secret);
29
30
  }
30
31
  if (encoding === KeyEncodings.HEX || encoding === "hex") {
31
- return hexToBytes(secret.replace(/\s/g, ""));
32
+ return hex.decode(secret.replace(/\s/g, ""));
32
33
  }
33
34
  return stringToBytes(secret);
34
35
  }
35
36
  function hotpDigestToToken(hexDigest, digits) {
36
- const digestBytes = hexToBytes(hexDigest);
37
+ const digestBytes = hex.decode(hexDigest);
37
38
  const truncated = dynamicTruncate(digestBytes);
38
39
  return truncateDigits(truncated, digits);
39
40
  }
@@ -47,7 +48,10 @@ var HOTP = class _HOTP {
47
48
  */
48
49
  _defaultOptions = {};
49
50
  constructor(defaultOptions = {}) {
50
- this._defaultOptions = { ...defaultOptions };
51
+ this._defaultOptions = {
52
+ ...defaultOptions,
53
+ guardrails: createGuardrails(defaultOptions.guardrails)
54
+ };
51
55
  this._options = {};
52
56
  }
53
57
  /**
@@ -101,7 +105,8 @@ var HOTP = class _HOTP {
101
105
  counter,
102
106
  algorithm: opts.algorithm,
103
107
  digits: opts.digits,
104
- crypto: opts.crypto
108
+ crypto: opts.crypto,
109
+ guardrails: opts.guardrails
105
110
  });
106
111
  }
107
112
  /**
@@ -118,7 +123,8 @@ var HOTP = class _HOTP {
118
123
  algorithm: opts.algorithm,
119
124
  digits: opts.digits,
120
125
  counterTolerance: 0,
121
- crypto: opts.crypto
126
+ crypto: opts.crypto,
127
+ guardrails: opts.guardrails
122
128
  });
123
129
  return result.valid;
124
130
  } catch {
@@ -215,7 +221,8 @@ var TOTP = class _TOTP extends HOTP {
215
221
  period: opts.step,
216
222
  epoch: epochSeconds,
217
223
  t0: 0,
218
- crypto: opts.crypto
224
+ crypto: opts.crypto,
225
+ guardrails: opts.guardrails
219
226
  });
220
227
  }
221
228
  /**
@@ -253,7 +260,8 @@ var TOTP = class _TOTP extends HOTP {
253
260
  epoch: epochSeconds,
254
261
  t0: 0,
255
262
  epochTolerance,
256
- crypto: opts.crypto
263
+ crypto: opts.crypto,
264
+ guardrails: opts.guardrails
257
265
  });
258
266
  if (!result.valid) {
259
267
  return null;
@@ -379,7 +387,8 @@ var Authenticator = class _Authenticator extends TOTP {
379
387
  period: opts.step,
380
388
  epoch: epochSeconds,
381
389
  t0: 0,
382
- crypto: opts.crypto
390
+ crypto: opts.crypto,
391
+ guardrails: opts.guardrails
383
392
  });
384
393
  }
385
394
  /**
@@ -423,7 +432,8 @@ var Authenticator = class _Authenticator extends TOTP {
423
432
  epoch: epochSeconds,
424
433
  t0: 0,
425
434
  epochTolerance,
426
- crypto: opts.crypto
435
+ crypto: opts.crypto,
436
+ guardrails: opts.guardrails
427
437
  });
428
438
  if (!result.valid) {
429
439
  return null;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hotp.ts","../src/types.ts","../src/totp.ts","../src/authenticator.ts","../src/index.ts"],"sourcesContent":["/**\n * @otplib/v12-adapter\n *\n * v12-compatible HOTP class implementation.\n * Provides synchronous API wrapper around v13's HOTP implementation.\n */\n\nimport { stringToBytes, hexToBytes, dynamicTruncate, truncateDigits } from \"@otplib/core\";\nimport { generateSync as hotpGenerateSync, verifySync as hotpVerifySync } from \"@otplib/hotp\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateHOTP as generateHOTPURI } from \"@otplib/uri\";\n\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { HOTPOptions, SecretKey, ResolvedHOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Convert a string secret to bytes based on encoding\n * @internal\n */\nexport function secretToBytes(secret: SecretKey, encoding?: string): Uint8Array {\n if (encoding === KeyEncodingsConst.BASE32 || encoding === \"base32\") {\n return defaultBase32.decode(secret);\n }\n if (encoding === KeyEncodingsConst.HEX || encoding === \"hex\") {\n return hexToBytes(secret.replace(/\\s/g, \"\"));\n }\n // Default: treat as ASCII/UTF-8\n return stringToBytes(secret);\n}\n\n/**\n * Converts a digest to a token of a specified length.\n * Uses dynamicTruncate and truncateDigits from core.\n */\nexport function hotpDigestToToken(hexDigest: string, digits: number): string {\n const digestBytes = hexToBytes(hexDigest);\n const truncated = dynamicTruncate(digestBytes);\n return truncateDigits(truncated, digits);\n}\n\n/**\n * v12-compatible HOTP class\n *\n * Provides the same API as otplib v12 HOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { HOTP } from '@otplib/v12-adapter';\n *\n * const hotp = new HOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = hotp.generate(secret, 0);\n * const isValid = hotp.check(token, secret, 0);\n * ```\n */\nexport class HOTP<T extends HOTPOptions = HOTPOptions> {\n /**\n * Stored options that can be modified\n */\n protected _options: Partial<T> = {};\n\n /**\n * Default options applied to all operations\n */\n protected _defaultOptions: Partial<T> = {};\n\n constructor(defaultOptions: Partial<T> = {}) {\n this._defaultOptions = { ...defaultOptions };\n this._options = {};\n }\n\n /**\n * Get current options (merged with defaults)\n */\n get options(): Partial<T> {\n return { ...this._defaultOptions, ...this._options };\n }\n\n /**\n * Set options (replaces current options)\n */\n set options(value: Partial<T>) {\n this._options = { ...value };\n }\n\n /**\n * Creates a new instance with the specified default options\n */\n create(defaultOptions: Partial<T> = {}): HOTP<T> {\n return new HOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with default values\n */\n allOptions(): Readonly<ResolvedHOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedHOTPOptions>;\n }\n\n /**\n * Reset options to defaults\n */\n resetOptions(): this {\n this._options = {};\n return this;\n }\n\n /**\n * Generate an HOTP token\n */\n generate(secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n return hotpGenerateSync({\n secret: secretBytes,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n crypto: opts.crypto,\n });\n }\n\n /**\n * Check if a token is valid for the given secret and counter\n */\n check(token: string, secret: SecretKey, counter: number): boolean {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n try {\n const result = hotpVerifySync({\n secret: secretBytes,\n token,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counterTolerance: 0,\n crypto: opts.crypto,\n });\n\n return result.valid;\n } catch {\n return false;\n }\n }\n\n /**\n * Verify a token (object-based API)\n */\n verify(opts: { token: string; secret: SecretKey; counter: number }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret, opts.counter);\n }\n\n /**\n * Generate an otpauth:// URI for HOTP\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n\n return generateHOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counter,\n });\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible type definitions for migration adapter.\n * These types mirror the v12 API to provide drop-in compatibility.\n */\n\nimport type { CryptoPlugin, Base32Plugin, HashAlgorithm } from \"@otplib/core\";\n\n/**\n * v12-style hash algorithms constant\n */\nexport const HashAlgorithms = {\n SHA1: \"sha1\",\n SHA256: \"sha256\",\n SHA512: \"sha512\",\n} as const;\n\nexport type HashAlgorithms = (typeof HashAlgorithms)[keyof typeof HashAlgorithms];\n\n/**\n * v12-style key encodings constant\n */\nexport const KeyEncodings = {\n ASCII: \"ascii\",\n HEX: \"hex\",\n BASE32: \"base32\",\n BASE64: \"base64\",\n LATIN1: \"latin1\",\n UTF8: \"utf8\",\n} as const;\n\nexport type KeyEncodings = (typeof KeyEncodings)[keyof typeof KeyEncodings];\n\n/**\n * v12-style secret key type (string-based)\n */\nexport type SecretKey = string;\n\n/**\n * Base32 encoded secret key\n */\nexport type Base32SecretKey = string;\n\n/**\n * v12-style createDigest function signature\n */\nexport type CreateDigest<T = string> = (algorithm: HashAlgorithm, hmacKey: T, counter: T) => T;\n\n/**\n * v12-style createHmacKey function signature\n */\nexport type CreateHmacKey<T = string> = (\n algorithm: HashAlgorithm,\n secret: SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-style createRandomBytes function signature\n */\nexport type CreateRandomBytes<T = string> = (size: number, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyEncoder function signature\n */\nexport type KeyEncoder<T = Base32SecretKey> = (secret: SecretKey, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyDecoder function signature\n */\nexport type KeyDecoder<T = SecretKey> = (\n encodedSecret: Base32SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-compatible HOTP options\n */\nexport type HOTPOptions<T = string> = {\n /** Algorithm for HMAC (default: sha1) */\n algorithm?: HashAlgorithm;\n /** Creates the digest for token generation */\n createDigest?: CreateDigest<T>;\n /** Formats the secret into HMAC key */\n createHmacKey?: CreateHmacKey<T>;\n /** Number of digits in token (default: 6) */\n digits?: number;\n /** Secret encoding (default: ascii) */\n encoding?: KeyEncodings;\n /** Pre-computed digest (use with caution) */\n digest?: string;\n /** v13 crypto plugin (internal use) */\n crypto?: CryptoPlugin;\n /** v13 base32 plugin (internal use) */\n base32?: Base32Plugin;\n};\n\n/**\n * v12-compatible TOTP options\n */\nexport type TOTPOptions<T = string> = HOTPOptions<T> & {\n /** Starting epoch in milliseconds (default: Date.now()) */\n epoch?: number;\n /** Time step in seconds (default: 30) */\n step?: number;\n /** Verification window - number of steps or [past, future] */\n window?: number | [number, number];\n};\n\n/**\n * v12-compatible Authenticator options\n */\nexport type AuthenticatorOptions<T = string> = TOTPOptions<T> & {\n /** Encodes secret to Base32 */\n keyEncoder?: KeyEncoder<T>;\n /** Decodes Base32 secret */\n keyDecoder?: KeyDecoder<T>;\n /** Creates random bytes for secret generation */\n createRandomBytes?: CreateRandomBytes<T>;\n};\n\n/**\n * Resolved HOTP options with guaranteed defaults\n */\nexport type ResolvedHOTPOptions = {\n algorithm: HashAlgorithm;\n digits: number;\n encoding: KeyEncodings;\n crypto: CryptoPlugin;\n base32: Base32Plugin;\n};\n\n/**\n * Resolved TOTP options with guaranteed defaults\n */\nexport type ResolvedTOTPOptions = ResolvedHOTPOptions & {\n epoch: number;\n step: number;\n window: number | [number, number];\n};\n\n/**\n * Resolved Authenticator options with guaranteed defaults\n */\nexport type ResolvedAuthenticatorOptions = ResolvedTOTPOptions & {\n keyEncoder?: KeyEncoder;\n keyDecoder?: KeyDecoder;\n};\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible TOTP class implementation.\n * Provides synchronous API wrapper around v13's TOTP implementation.\n */\n\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport {\n generateSync as totpGenerateSync,\n verifySync as totpVerifySync,\n getRemainingTime,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI } from \"@otplib/uri\";\n\nimport { HOTP, secretToBytes } from \"./hotp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { TOTPOptions, SecretKey, ResolvedTOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Parse window option into epochTolerance\n * v12 uses \"window\" as number of steps, v13 uses epochTolerance in seconds\n */\nfunction parseWindow(\n window: number | [number, number] | undefined,\n step: number,\n): number | [number, number] {\n if (window === undefined || window === 0) {\n return 0;\n }\n if (typeof window === \"number\") {\n return window * step;\n }\n // [past, future] steps → [past, future] seconds\n return [window[0] * step, window[1] * step];\n}\n\n/**\n * v12-compatible TOTP class\n *\n * Provides the same API as otplib v12 TOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { TOTP } from '@otplib/v12-adapter';\n *\n * const totp = new TOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = totp.generate(secret);\n * const isValid = totp.check(token, secret);\n * ```\n */\nexport class TOTP<T extends TOTPOptions = TOTPOptions> extends HOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new TOTP instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): TOTP<T> {\n return new TOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with TOTP default values\n */\n override allOptions(): Readonly<ResolvedTOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedTOTPOptions>;\n }\n\n /**\n * Generate a TOTP token\n *\n * @param secret - The secret key\n * @returns The OTP token\n */\n generate(secret: SecretKey): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n });\n }\n\n /**\n * Check if a token is valid for the given secret\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns true if valid\n */\n check(token: string, secret: SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n checkDelta(token: string, secret: SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n const step = opts.step;\n const window = opts.window;\n\n const epochTolerance = parseWindow(window, step);\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n });\n\n if (!result.valid) {\n return null;\n }\n\n // v13 returns delta directly as time step offset\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n verify(opts: { token: string; secret: SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Generate an otpauth:// URI for TOTP\n *\n * @param accountName - Account name for the URI\n * @param issuer - Issuer name\n * @param secret - The secret key (should be Base32 for QR codes)\n * @returns The otpauth:// URI\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey): string {\n const opts = this.allOptions();\n\n return generateTOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n });\n }\n\n /**\n * Get time used in current step (seconds elapsed in current window)\n *\n * @returns Seconds used in current step\n */\n timeUsed(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return epochSeconds % opts.step;\n }\n\n /**\n * Get time remaining until next token\n *\n * @returns Seconds remaining in current step\n */\n timeRemaining(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return getRemainingTime(epochSeconds, opts.step, 0);\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible Authenticator class implementation.\n * Provides same API as v12 with Base32 encoding support.\n */\n\nimport { generateSecret as generateSecretCore } from \"@otplib/core\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateSync as totpGenerateSync, verifySync as totpVerifySync } from \"@otplib/totp\";\n\nimport { TOTP } from \"./totp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type {\n AuthenticatorOptions,\n Base32SecretKey,\n SecretKey,\n KeyEncodings,\n ResolvedAuthenticatorOptions,\n} from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Default key encoder - encodes raw bytes to Base32\n */\nfunction defaultKeyEncoder(secret: SecretKey, _encoding: KeyEncodings): Base32SecretKey {\n const bytes = new TextEncoder().encode(secret);\n return defaultBase32.encode(bytes);\n}\n\n/**\n * Default key decoder - decodes Base32 to string\n */\nfunction defaultKeyDecoder(encodedSecret: Base32SecretKey, _encoding: KeyEncodings): SecretKey {\n const bytes = defaultBase32.decode(encodedSecret);\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * v12-compatible Authenticator class\n *\n * The Authenticator class is a TOTP variant that uses Base32-encoded secrets\n * by default, making it compatible with Google Authenticator and similar apps.\n *\n * @example\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator();\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n */\nexport class Authenticator<T extends AuthenticatorOptions = AuthenticatorOptions> extends TOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new Authenticator instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): Authenticator<T> {\n return new Authenticator<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with Authenticator default values\n */\n override allOptions(): Readonly<ResolvedAuthenticatorOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.HEX,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n keyEncoder: defaultKeyEncoder,\n keyDecoder: defaultKeyDecoder,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedAuthenticatorOptions>;\n }\n\n /**\n * Generate an OTP token from a Base32 secret\n *\n * @param secret - Base32-encoded secret\n * @returns The OTP token\n */\n override generate(secret: Base32SecretKey): string {\n const opts = this.allOptions();\n\n // Generate using decoded secret (as raw bytes)\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n });\n }\n\n /**\n * Check if a token is valid for the given Base32 secret\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns true if valid\n */\n override check(token: string, secret: Base32SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n override checkDelta(token: string, secret: Base32SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n const step = opts.step;\n const window = opts.window;\n\n // Convert window (steps) to epochTolerance (seconds)\n let epochTolerance: number | [number, number] = 0;\n if (typeof window === \"number\") {\n epochTolerance = window * step;\n } else if (Array.isArray(window)) {\n epochTolerance = [window[0] * step, window[1] * step];\n }\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n });\n\n if (!result.valid) {\n return null;\n }\n\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n override verify(opts: { token: string; secret: Base32SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Encode a raw secret to Base32\n *\n * @param secret - Raw secret string\n * @returns Base32-encoded secret\n */\n encode(secret: SecretKey): Base32SecretKey {\n const opts = this.allOptions();\n if (opts.keyEncoder) {\n return opts.keyEncoder(secret, opts.encoding);\n }\n return defaultKeyEncoder(secret, opts.encoding);\n }\n\n /**\n * Decode a Base32 secret to raw string\n *\n * @param secret - Base32-encoded secret\n * @returns Raw secret string\n */\n decode(secret: Base32SecretKey): SecretKey {\n const opts = this.allOptions();\n if (opts.keyDecoder) {\n return opts.keyDecoder(secret, opts.encoding);\n }\n return defaultKeyDecoder(secret, opts.encoding);\n }\n\n /**\n * Generate a random Base32-encoded secret\n *\n * @param numberOfBytes - Number of bytes for the secret (default: 20)\n * @returns Base32-encoded secret\n */\n generateSecret(numberOfBytes: number = 20): Base32SecretKey {\n const opts = this.allOptions();\n return generateSecretCore({\n crypto: opts.crypto,\n base32: opts.base32,\n length: numberOfBytes,\n });\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * Drop-in replacement adapter for migrating from otplib v12 to v13.\n *\n * This package provides the same API as otplib v12, making it easy\n * to migrate existing codebases to v13 without breaking changes.\n *\n * @example Using pre-configured instances (v12 style)\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n *\n * @example Using class instances\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator({ step: 60 });\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * ```\n */\n\n// Classes\nexport { HOTP } from \"./hotp.js\";\nexport { TOTP } from \"./totp.js\";\nexport { Authenticator } from \"./authenticator.js\";\n\n// Functional exports (v12-style)\nexport { hotpDigestToToken } from \"./hotp.js\";\n\n// Constants (v12-style)\nexport { HashAlgorithms, KeyEncodings } from \"./types.js\";\n\n// Types\nexport type {\n HOTPOptions,\n TOTPOptions,\n AuthenticatorOptions,\n SecretKey,\n Base32SecretKey,\n CreateDigest,\n CreateHmacKey,\n CreateRandomBytes,\n KeyEncoder,\n KeyDecoder,\n} from \"./types.js\";\n\n// Pre-configured instances (v12 style)\nimport { Authenticator } from \"./authenticator.js\";\nimport { HOTP } from \"./hotp.js\";\nimport { TOTP } from \"./totp.js\";\n\n/**\n * Pre-configured HOTP instance\n *\n * @example\n * ```typescript\n * import { hotp } from '@otplib/v12-adapter';\n *\n * const token = hotp.generate('JBSWY3DPEHPK3PXP', 0);\n * const isValid = hotp.check(token, 'JBSWY3DPEHPK3PXP', 0);\n * ```\n */\nexport const hotp = new HOTP();\n\n/**\n * Pre-configured TOTP instance\n *\n * @example\n * ```typescript\n * import { totp } from '@otplib/v12-adapter';\n *\n * const token = totp.generate('JBSWY3DPEHPK3PXP');\n * const isValid = totp.check(token, 'JBSWY3DPEHPK3PXP');\n * ```\n */\nexport const totp = new TOTP();\n\n/**\n * Pre-configured Authenticator instance\n *\n * @example\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * ```\n */\nexport const authenticator = new Authenticator();\n\n// Re-export v13 plugins for advanced usage\nexport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nexport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\n"],"mappings":";AAOA,SAAS,eAAe,YAAY,iBAAiB,sBAAsB;AAC3E,SAAS,gBAAgB,kBAAkB,cAAc,sBAAsB;AAC/E,SAAS,yBAAyB;AAClC,SAAS,yBAAyB;AAClC,SAAS,gBAAgB,uBAAuB;;;ACCzC,IAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AACV;AAOO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AACR;;;ADTA,IAAM,gBAAgB,IAAI,kBAAkB;AAK5C,IAAM,gBAAgB,IAAI,kBAAkB;AAMrC,SAAS,cAAc,QAAmB,UAA+B;AAC9E,MAAI,aAAa,aAAkB,UAAU,aAAa,UAAU;AAClE,WAAO,cAAc,OAAO,MAAM;AAAA,EACpC;AACA,MAAI,aAAa,aAAkB,OAAO,aAAa,OAAO;AAC5D,WAAO,WAAW,OAAO,QAAQ,OAAO,EAAE,CAAC;AAAA,EAC7C;AAEA,SAAO,cAAc,MAAM;AAC7B;AAMO,SAAS,kBAAkB,WAAmB,QAAwB;AAC3E,QAAM,cAAc,WAAW,SAAS;AACxC,QAAM,YAAY,gBAAgB,WAAW;AAC7C,SAAO,eAAe,WAAW,MAAM;AACzC;AAkBO,IAAM,OAAN,MAAM,MAA0C;AAAA;AAAA;AAAA;AAAA,EAI3C,WAAuB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKxB,kBAA8B,CAAC;AAAA,EAEzC,YAAY,iBAA6B,CAAC,GAAG;AAC3C,SAAK,kBAAkB,EAAE,GAAG,eAAe;AAC3C,SAAK,WAAW,CAAC;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAsB;AACxB,WAAO,EAAE,GAAG,KAAK,iBAAiB,GAAG,KAAK,SAAS;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAQ,OAAmB;AAC7B,SAAK,WAAW,EAAE,GAAG,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,iBAA6B,CAAC,GAAY;AAC/C,WAAO,IAAI,MAAQ,cAAc;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,aAA4C;AAC1C,UAAM,SAAS;AAAA,MACb,WAAW,eAAe;AAAA,MAC1B,QAAQ;AAAA,MACR,UAAU,aAAkB;AAAA,MAC5B,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AACA,WAAO,OAAO,OAAO,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAqB;AACnB,SAAK,WAAW,CAAC;AACjB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,QAAmB,SAAyB;AACnD,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,WAAO,iBAAiB;AAAA,MACtB,QAAQ;AAAA,MACR;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAe,QAAmB,SAA0B;AAChE,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,QAAI;AACF,YAAM,SAAS,eAAe;AAAA,QAC5B,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,kBAAkB;AAAA,QAClB,QAAQ,KAAK;AAAA,MACf,CAAC;AAED,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,MAAsE;AAC3E,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,WAAO,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,aAAqB,QAAgB,QAAmB,SAAyB;AACtF,UAAM,OAAO,KAAK,WAAW;AAE7B,WAAO,gBAAgB;AAAA,MACrB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AE5LA,SAAS,qBAAAA,0BAAyB;AAClC,SAAS,qBAAAC,0BAAyB;AAClC;AAAA,EACE,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd;AAAA,OACK;AACP,SAAS,gBAAgB,uBAAuB;AAWhD,IAAMC,iBAAgB,IAAIC,mBAAkB;AAK5C,IAAMC,iBAAgB,IAAIC,mBAAkB;AAM5C,SAAS,YACP,QACA,MAC2B;AAC3B,MAAI,WAAW,UAAa,WAAW,GAAG;AACxC,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO,CAAC,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,IAAI;AAC5C;AAkBO,IAAM,OAAN,MAAM,cAAkD,KAAQ;AAAA,EACrE,YAAY,iBAA6B,CAAC,GAAG;AAC3C,UAAM,cAAc;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKS,OAAO,iBAA6B,CAAC,GAAY;AACxD,WAAO,IAAI,MAAQ,cAAc;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKS,aAA4C;AACnD,UAAM,SAAS;AAAA,MACb,WAAW,eAAe;AAAA,MAC1B,QAAQ;AAAA,MACR,UAAU,aAAkB;AAAA,MAC5B,OAAO,KAAK,IAAI;AAAA,MAChB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQH;AAAA,MACR,QAAQE;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AACA,WAAO,OAAO,OAAO,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS,QAA2B;AAClC,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AAEjD,WAAO,iBAAiB;AAAA,MACtB,QAAQ;AAAA,MACR,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,OAAO;AAAA,MACP,IAAI;AAAA,MACJ,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAe,QAA4B;AAC/C,UAAM,QAAQ,KAAK,WAAW,OAAO,MAAM;AAC3C,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,OAAe,QAAkC;AAC1D,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AACjD,UAAM,OAAO,KAAK;AAClB,UAAM,SAAS,KAAK;AAEpB,UAAM,iBAAiB,YAAY,QAAQ,IAAI;AAE/C,QAAI;AACF,YAAM,SAAS,eAAe;AAAA,QAC5B,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,IAAI;AAAA,QACJ;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AAED,UAAI,CAAC,OAAO,OAAO;AACjB,eAAO;AAAA,MACT;AAGA,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,MAAqD;AAC1D,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,WAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,aAAqB,QAAgB,QAA2B;AACrE,UAAM,OAAO,KAAK,WAAW;AAE7B,WAAO,gBAAgB;AAAA,MACrB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAmB;AACjB,UAAM,OAAO,KAAK,WAAW;AAE7B,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AACjD,WAAO,eAAe,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAwB;AACtB,UAAM,OAAO,KAAK,WAAW;AAE7B,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AACjD,WAAO,iBAAiB,cAAc,KAAK,MAAM,CAAC;AAAA,EACpD;AACF;;;AC/NA,SAAS,kBAAkB,0BAA0B;AACrD,SAAS,qBAAAE,0BAAyB;AAClC,SAAS,qBAAAC,0BAAyB;AAClC,SAAS,gBAAgBC,mBAAkB,cAAcC,uBAAsB;AAiB/E,IAAMC,iBAAgB,IAAIC,mBAAkB;AAK5C,IAAMC,iBAAgB,IAAIC,mBAAkB;AAK5C,SAAS,kBAAkB,QAAmB,WAA0C;AACtF,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,MAAM;AAC7C,SAAOD,eAAc,OAAO,KAAK;AACnC;AAKA,SAAS,kBAAkB,eAAgC,WAAoC;AAC7F,QAAM,QAAQA,eAAc,OAAO,aAAa;AAChD,SAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AACvC;AAmBO,IAAM,gBAAN,MAAM,uBAA6E,KAAQ;AAAA,EAChG,YAAY,iBAA6B,CAAC,GAAG;AAC3C,UAAM,cAAc;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKS,OAAO,iBAA6B,CAAC,GAAqB;AACjE,WAAO,IAAI,eAAiB,cAAc;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKS,aAAqD;AAC5D,UAAM,SAAS;AAAA,MACb,WAAW,eAAe;AAAA,MAC1B,QAAQ;AAAA,MACR,UAAU,aAAkB;AAAA,MAC5B,OAAO,KAAK,IAAI;AAAA,MAChB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQF;AAAA,MACR,QAAQE;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AACA,WAAO,OAAO,OAAO,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQS,SAAS,QAAiC;AACjD,UAAM,OAAO,KAAK,WAAW;AAG7B,UAAM,cAAcA,eAAc,OAAO,MAAM;AAC/C,UAAM,QAAQ,KAAK;AACnB,UAAM,eAAe,SAAS,OAAO,KAAK,MAAM,QAAQ,GAAI,IAAI;AAEhE,WAAOE,kBAAiB;AAAA,MACtB,QAAQ;AAAA,MACR,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,OAAO;AAAA,MACP,IAAI;AAAA,MACJ,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,MAAM,OAAe,QAAkC;AAC9D,UAAM,QAAQ,KAAK,WAAW,OAAO,MAAM;AAC3C,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,WAAW,OAAe,QAAwC;AACzE,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAcF,eAAc,OAAO,MAAM;AAC/C,UAAM,QAAQ,KAAK;AACnB,UAAM,eAAe,SAAS,OAAO,KAAK,MAAM,QAAQ,GAAI,IAAI;AAChE,UAAM,OAAO,KAAK;AAClB,UAAM,SAAS,KAAK;AAGpB,QAAI,iBAA4C;AAChD,QAAI,OAAO,WAAW,UAAU;AAC9B,uBAAiB,SAAS;AAAA,IAC5B,WAAW,MAAM,QAAQ,MAAM,GAAG;AAChC,uBAAiB,CAAC,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,IAAI;AAAA,IACtD;AAEA,QAAI;AACF,YAAM,SAASG,gBAAe;AAAA,QAC5B,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,IAAI;AAAA,QACJ;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AAED,UAAI,CAAC,OAAO,OAAO;AACjB,eAAO;AAAA,MACT;AAEA,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQS,OAAO,MAA2D;AACzE,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,WAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAAoC;AACzC,UAAM,OAAO,KAAK,WAAW;AAC7B,QAAI,KAAK,YAAY;AACnB,aAAO,KAAK,WAAW,QAAQ,KAAK,QAAQ;AAAA,IAC9C;AACA,WAAO,kBAAkB,QAAQ,KAAK,QAAQ;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAAoC;AACzC,UAAM,OAAO,KAAK,WAAW;AAC7B,QAAI,KAAK,YAAY;AACnB,aAAO,KAAK,WAAW,QAAQ,KAAK,QAAQ;AAAA,IAC9C;AACA,WAAO,kBAAkB,QAAQ,KAAK,QAAQ;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAe,gBAAwB,IAAqB;AAC1D,UAAM,OAAO,KAAK,WAAW;AAC7B,WAAO,mBAAmB;AAAA,MACxB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;;;AC3IA,SAAS,qBAAAC,0BAAyB;AAClC,SAAS,qBAAAC,0BAAyB;AA/B3B,IAAM,OAAO,IAAI,KAAK;AAatB,IAAM,OAAO,IAAI,KAAK;AActB,IAAM,gBAAgB,IAAI,cAAc;","names":["ScureBase32Plugin","NobleCryptoPlugin","defaultCrypto","NobleCryptoPlugin","defaultBase32","ScureBase32Plugin","ScureBase32Plugin","NobleCryptoPlugin","totpGenerateSync","totpVerifySync","defaultCrypto","NobleCryptoPlugin","defaultBase32","ScureBase32Plugin","totpGenerateSync","totpVerifySync","NobleCryptoPlugin","ScureBase32Plugin"]}
1
+ {"version":3,"sources":["../src/hotp.ts","../src/types.ts","../src/totp.ts","../src/authenticator.ts","../src/index.ts"],"sourcesContent":["/**\n * @otplib/v12-adapter\n *\n * v12-compatible HOTP class implementation.\n * Provides synchronous API wrapper around v13's HOTP implementation.\n */\n\nimport { stringToBytes, dynamicTruncate, truncateDigits, createGuardrails } from \"@otplib/core\";\nimport { generateSync as hotpGenerateSync, verifySync as hotpVerifySync } from \"@otplib/hotp\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateHOTP as generateHOTPURI } from \"@otplib/uri\";\nimport { hex } from \"@scure/base\";\n\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { HOTPOptions, SecretKey, ResolvedHOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Convert a string secret to bytes based on encoding\n * @internal\n */\nexport function secretToBytes(secret: SecretKey, encoding?: string): Uint8Array {\n if (encoding === KeyEncodingsConst.BASE32 || encoding === \"base32\") {\n return defaultBase32.decode(secret);\n }\n if (encoding === KeyEncodingsConst.HEX || encoding === \"hex\") {\n return hex.decode(secret.replace(/\\s/g, \"\"));\n }\n // Default: treat as ASCII/UTF-8\n return stringToBytes(secret);\n}\n\n/**\n * Converts a digest to a token of a specified length.\n * Uses dynamicTruncate and truncateDigits from core.\n */\nexport function hotpDigestToToken(hexDigest: string, digits: number): string {\n const digestBytes = hex.decode(hexDigest);\n const truncated = dynamicTruncate(digestBytes);\n return truncateDigits(truncated, digits);\n}\n\n/**\n * v12-compatible HOTP class\n *\n * Provides the same API as otplib v12 HOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { HOTP } from '@otplib/v12-adapter';\n *\n * const hotp = new HOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = hotp.generate(secret, 0);\n * const isValid = hotp.check(token, secret, 0);\n * ```\n */\nexport class HOTP<T extends HOTPOptions = HOTPOptions> {\n /**\n * Stored options that can be modified\n */\n protected _options: Partial<T> = {};\n\n /**\n * Default options applied to all operations\n */\n protected _defaultOptions: Partial<T> = {};\n\n constructor(defaultOptions: Partial<T> = {}) {\n this._defaultOptions = {\n ...defaultOptions,\n guardrails: createGuardrails(defaultOptions.guardrails),\n } as Partial<T>;\n this._options = {};\n }\n\n /**\n * Get current options (merged with defaults)\n */\n get options(): Partial<T> {\n return { ...this._defaultOptions, ...this._options };\n }\n\n /**\n * Set options (replaces current options)\n */\n set options(value: Partial<T>) {\n this._options = { ...value };\n }\n\n /**\n * Creates a new instance with the specified default options\n */\n create(defaultOptions: Partial<T> = {}): HOTP<T> {\n return new HOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with default values\n */\n allOptions(): Readonly<ResolvedHOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedHOTPOptions>;\n }\n\n /**\n * Reset options to defaults\n */\n resetOptions(): this {\n this._options = {};\n return this;\n }\n\n /**\n * Generate an HOTP token\n */\n generate(secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n return hotpGenerateSync({\n secret: secretBytes,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n }\n\n /**\n * Check if a token is valid for the given secret and counter\n */\n check(token: string, secret: SecretKey, counter: number): boolean {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n\n try {\n const result = hotpVerifySync({\n secret: secretBytes,\n token,\n counter,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counterTolerance: 0,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n\n return result.valid;\n } catch {\n return false;\n }\n }\n\n /**\n * Verify a token (object-based API)\n */\n verify(opts: { token: string; secret: SecretKey; counter: number }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret, opts.counter);\n }\n\n /**\n * Generate an otpauth:// URI for HOTP\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey, counter: number): string {\n const opts = this.allOptions();\n\n return generateHOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n counter,\n });\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible type definitions for migration adapter.\n * These types mirror the v12 API to provide drop-in compatibility.\n */\n\nimport type { CryptoPlugin, Base32Plugin, HashAlgorithm, OTPGuardrails } from \"@otplib/core\";\n\n/**\n * v12-style hash algorithms constant\n */\nexport const HashAlgorithms = {\n SHA1: \"sha1\",\n SHA256: \"sha256\",\n SHA512: \"sha512\",\n} as const;\n\nexport type HashAlgorithms = (typeof HashAlgorithms)[keyof typeof HashAlgorithms];\n\n/**\n * v12-style key encodings constant\n */\nexport const KeyEncodings = {\n ASCII: \"ascii\",\n HEX: \"hex\",\n BASE32: \"base32\",\n BASE64: \"base64\",\n LATIN1: \"latin1\",\n UTF8: \"utf8\",\n} as const;\n\nexport type KeyEncodings = (typeof KeyEncodings)[keyof typeof KeyEncodings];\n\n/**\n * v12-style secret key type (string-based)\n */\nexport type SecretKey = string;\n\n/**\n * Base32 encoded secret key\n */\nexport type Base32SecretKey = string;\n\n/**\n * v12-style createDigest function signature\n */\nexport type CreateDigest<T = string> = (algorithm: HashAlgorithm, hmacKey: T, counter: T) => T;\n\n/**\n * v12-style createHmacKey function signature\n */\nexport type CreateHmacKey<T = string> = (\n algorithm: HashAlgorithm,\n secret: SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-style createRandomBytes function signature\n */\nexport type CreateRandomBytes<T = string> = (size: number, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyEncoder function signature\n */\nexport type KeyEncoder<T = Base32SecretKey> = (secret: SecretKey, encoding: KeyEncodings) => T;\n\n/**\n * v12-style keyDecoder function signature\n */\nexport type KeyDecoder<T = SecretKey> = (\n encodedSecret: Base32SecretKey,\n encoding: KeyEncodings,\n) => T;\n\n/**\n * v12-compatible HOTP options\n */\nexport type HOTPOptions<T = string> = {\n /** Algorithm for HMAC (default: sha1) */\n algorithm?: HashAlgorithm;\n /** Creates the digest for token generation */\n createDigest?: CreateDigest<T>;\n /** Formats the secret into HMAC key */\n createHmacKey?: CreateHmacKey<T>;\n /** Number of digits in token (default: 6) */\n digits?: number;\n /** Secret encoding (default: ascii) */\n encoding?: KeyEncodings;\n /** Pre-computed digest (use with caution) */\n digest?: string;\n /** v13 crypto plugin (internal use) */\n crypto?: CryptoPlugin;\n /** v13 base32 plugin (internal use) */\n base32?: Base32Plugin;\n /** Validation guardrails */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * v12-compatible TOTP options\n */\nexport type TOTPOptions<T = string> = HOTPOptions<T> & {\n /** Starting epoch in milliseconds (default: Date.now()) */\n epoch?: number;\n /** Time step in seconds (default: 30) */\n step?: number;\n /** Verification window - number of steps or [past, future] */\n window?: number | [number, number];\n};\n\n/**\n * v12-compatible Authenticator options\n */\nexport type AuthenticatorOptions<T = string> = TOTPOptions<T> & {\n /** Encodes secret to Base32 */\n keyEncoder?: KeyEncoder<T>;\n /** Decodes Base32 secret */\n keyDecoder?: KeyDecoder<T>;\n /** Creates random bytes for secret generation */\n createRandomBytes?: CreateRandomBytes<T>;\n};\n\n/**\n * Resolved HOTP options with guaranteed defaults\n */\nexport type ResolvedHOTPOptions = {\n algorithm: HashAlgorithm;\n digits: number;\n encoding: KeyEncodings;\n crypto: CryptoPlugin;\n base32: Base32Plugin;\n guardrails: OTPGuardrails;\n};\n\n/**\n * Resolved TOTP options with guaranteed defaults\n */\nexport type ResolvedTOTPOptions = ResolvedHOTPOptions & {\n epoch: number;\n step: number;\n window: number | [number, number];\n};\n\n/**\n * Resolved Authenticator options with guaranteed defaults\n */\nexport type ResolvedAuthenticatorOptions = ResolvedTOTPOptions & {\n keyEncoder?: KeyEncoder;\n keyDecoder?: KeyDecoder;\n};\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible TOTP class implementation.\n * Provides synchronous API wrapper around v13's TOTP implementation.\n */\n\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport {\n generateSync as totpGenerateSync,\n verifySync as totpVerifySync,\n getRemainingTime,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI } from \"@otplib/uri\";\n\nimport { HOTP, secretToBytes } from \"./hotp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type { TOTPOptions, SecretKey, ResolvedTOTPOptions } from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Parse window option into epochTolerance\n * v12 uses \"window\" as number of steps, v13 uses epochTolerance in seconds\n */\nfunction parseWindow(\n window: number | [number, number] | undefined,\n step: number,\n): number | [number, number] {\n if (window === undefined || window === 0) {\n return 0;\n }\n if (typeof window === \"number\") {\n return window * step;\n }\n // [past, future] steps → [past, future] seconds\n return [window[0] * step, window[1] * step];\n}\n\n/**\n * v12-compatible TOTP class\n *\n * Provides the same API as otplib v12 TOTP class while using v13's\n * implementation internally.\n *\n * @example\n * ```typescript\n * import { TOTP } from '@otplib/v12-adapter';\n *\n * const totp = new TOTP();\n * const secret = 'JBSWY3DPEHPK3PXP';\n * const token = totp.generate(secret);\n * const isValid = totp.check(token, secret);\n * ```\n */\nexport class TOTP<T extends TOTPOptions = TOTPOptions> extends HOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new TOTP instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): TOTP<T> {\n return new TOTP<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with TOTP default values\n */\n override allOptions(): Readonly<ResolvedTOTPOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.ASCII,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedTOTPOptions>;\n }\n\n /**\n * Generate a TOTP token\n *\n * @param secret - The secret key\n * @returns The OTP token\n */\n generate(secret: SecretKey): string {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n }\n\n /**\n * Check if a token is valid for the given secret\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns true if valid\n */\n check(token: string, secret: SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - The secret key\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n checkDelta(token: string, secret: SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = secretToBytes(secret, opts.encoding);\n // v12 uses epoch in milliseconds, always convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n const step = opts.step;\n const window = opts.window;\n\n const epochTolerance = parseWindow(window, step);\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n\n if (!result.valid) {\n return null;\n }\n\n // v13 returns delta directly as time step offset\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n verify(opts: { token: string; secret: SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Generate an otpauth:// URI for TOTP\n *\n * @param accountName - Account name for the URI\n * @param issuer - Issuer name\n * @param secret - The secret key (should be Base32 for QR codes)\n * @returns The otpauth:// URI\n */\n keyuri(accountName: string, issuer: string, secret: SecretKey): string {\n const opts = this.allOptions();\n\n return generateTOTPURI({\n label: accountName,\n issuer,\n secret,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n });\n }\n\n /**\n * Get time used in current step (seconds elapsed in current window)\n *\n * @returns Seconds used in current step\n */\n timeUsed(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return epochSeconds % opts.step;\n }\n\n /**\n * Get time remaining until next token\n *\n * @returns Seconds remaining in current step\n */\n timeRemaining(): number {\n const opts = this.allOptions();\n // v12 uses epoch in milliseconds, convert to seconds\n const epochSeconds = Math.floor(opts.epoch / 1000);\n return getRemainingTime(epochSeconds, opts.step, 0);\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * v12-compatible Authenticator class implementation.\n * Provides same API as v12 with Base32 encoding support.\n */\n\nimport { generateSecret as generateSecretCore } from \"@otplib/core\";\nimport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\nimport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nimport { generateSync as totpGenerateSync, verifySync as totpVerifySync } from \"@otplib/totp\";\n\nimport { TOTP } from \"./totp.js\";\nimport { HashAlgorithms, KeyEncodings as KeyEncodingsConst } from \"./types.js\";\n\nimport type {\n AuthenticatorOptions,\n Base32SecretKey,\n SecretKey,\n KeyEncodings,\n ResolvedAuthenticatorOptions,\n} from \"./types.js\";\nimport type { Digits } from \"@otplib/core\";\n\n/**\n * Default crypto plugin instance\n */\nconst defaultCrypto = new NobleCryptoPlugin();\n\n/**\n * Default base32 plugin instance\n */\nconst defaultBase32 = new ScureBase32Plugin();\n\n/**\n * Default key encoder - encodes raw bytes to Base32\n */\nfunction defaultKeyEncoder(secret: SecretKey, _encoding: KeyEncodings): Base32SecretKey {\n const bytes = new TextEncoder().encode(secret);\n return defaultBase32.encode(bytes);\n}\n\n/**\n * Default key decoder - decodes Base32 to string\n */\nfunction defaultKeyDecoder(encodedSecret: Base32SecretKey, _encoding: KeyEncodings): SecretKey {\n const bytes = defaultBase32.decode(encodedSecret);\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * v12-compatible Authenticator class\n *\n * The Authenticator class is a TOTP variant that uses Base32-encoded secrets\n * by default, making it compatible with Google Authenticator and similar apps.\n *\n * @example\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator();\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n */\nexport class Authenticator<T extends AuthenticatorOptions = AuthenticatorOptions> extends TOTP<T> {\n constructor(defaultOptions: Partial<T> = {}) {\n super(defaultOptions);\n }\n\n /**\n * Creates a new Authenticator instance with the specified default options\n */\n override create(defaultOptions: Partial<T> = {}): Authenticator<T> {\n return new Authenticator<T>(defaultOptions);\n }\n\n /**\n * Returns class options polyfilled with Authenticator default values\n */\n override allOptions(): Readonly<ResolvedAuthenticatorOptions> {\n const merged = {\n algorithm: HashAlgorithms.SHA1,\n digits: 6,\n encoding: KeyEncodingsConst.HEX,\n epoch: Date.now(),\n step: 30,\n window: 0 as number | [number, number],\n keyEncoder: defaultKeyEncoder,\n keyDecoder: defaultKeyDecoder,\n crypto: defaultCrypto,\n base32: defaultBase32,\n ...this._defaultOptions,\n ...this._options,\n };\n return Object.freeze(merged) as Readonly<ResolvedAuthenticatorOptions>;\n }\n\n /**\n * Generate an OTP token from a Base32 secret\n *\n * @param secret - Base32-encoded secret\n * @returns The OTP token\n */\n override generate(secret: Base32SecretKey): string {\n const opts = this.allOptions();\n\n // Generate using decoded secret (as raw bytes)\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n\n return totpGenerateSync({\n secret: secretBytes,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: opts.step,\n epoch: epochSeconds,\n t0: 0,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n }\n\n /**\n * Check if a token is valid for the given Base32 secret\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns true if valid\n */\n override check(token: string, secret: Base32SecretKey): boolean {\n const delta = this.checkDelta(token, secret);\n return typeof delta === \"number\";\n }\n\n /**\n * Check token and return the time window delta\n *\n * @param token - The token to verify\n * @param secret - Base32-encoded secret\n * @returns Window delta (0 = current, positive = future, negative = past), null if invalid\n */\n override checkDelta(token: string, secret: Base32SecretKey): number | null {\n const opts = this.allOptions();\n const secretBytes = defaultBase32.decode(secret);\n const epoch = opts.epoch;\n const epochSeconds = epoch >= 1e12 ? Math.floor(epoch / 1000) : epoch;\n const step = opts.step;\n const window = opts.window;\n\n // Convert window (steps) to epochTolerance (seconds)\n let epochTolerance: number | [number, number] = 0;\n if (typeof window === \"number\") {\n epochTolerance = window * step;\n } else if (Array.isArray(window)) {\n epochTolerance = [window[0] * step, window[1] * step];\n }\n\n try {\n const result = totpVerifySync({\n secret: secretBytes,\n token,\n algorithm: opts.algorithm,\n digits: opts.digits as Digits,\n period: step,\n epoch: epochSeconds,\n t0: 0,\n epochTolerance,\n crypto: opts.crypto,\n guardrails: opts.guardrails,\n });\n\n if (!result.valid) {\n return null;\n }\n\n return result.delta;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify a token (object-based API)\n *\n * @param opts - Verification options\n * @returns true if valid\n */\n override verify(opts: { token: string; secret: Base32SecretKey }): boolean {\n if (typeof opts !== \"object\") {\n throw new Error(\"Expecting argument 0 of verify to be an object\");\n }\n return this.check(opts.token, opts.secret);\n }\n\n /**\n * Encode a raw secret to Base32\n *\n * @param secret - Raw secret string\n * @returns Base32-encoded secret\n */\n encode(secret: SecretKey): Base32SecretKey {\n const opts = this.allOptions();\n if (opts.keyEncoder) {\n return opts.keyEncoder(secret, opts.encoding);\n }\n return defaultKeyEncoder(secret, opts.encoding);\n }\n\n /**\n * Decode a Base32 secret to raw string\n *\n * @param secret - Base32-encoded secret\n * @returns Raw secret string\n */\n decode(secret: Base32SecretKey): SecretKey {\n const opts = this.allOptions();\n if (opts.keyDecoder) {\n return opts.keyDecoder(secret, opts.encoding);\n }\n return defaultKeyDecoder(secret, opts.encoding);\n }\n\n /**\n * Generate a random Base32-encoded secret\n *\n * @param numberOfBytes - Number of bytes for the secret (default: 20)\n * @returns Base32-encoded secret\n */\n generateSecret(numberOfBytes: number = 20): Base32SecretKey {\n const opts = this.allOptions();\n return generateSecretCore({\n crypto: opts.crypto,\n base32: opts.base32,\n length: numberOfBytes,\n });\n }\n}\n","/**\n * @otplib/v12-adapter\n *\n * Drop-in replacement adapter for migrating from otplib v12 to v13.\n *\n * This package provides the same API as otplib v12, making it easy\n * to migrate existing codebases to v13 without breaking changes.\n *\n * @example Using pre-configured instances (v12 style)\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * const uri = authenticator.keyuri('user@example.com', 'MyApp', secret);\n * ```\n *\n * @example Using class instances\n * ```typescript\n * import { Authenticator } from '@otplib/v12-adapter';\n *\n * const authenticator = new Authenticator({ step: 60 });\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * ```\n */\n\n// Classes\nexport { HOTP } from \"./hotp.js\";\nexport { TOTP } from \"./totp.js\";\nexport { Authenticator } from \"./authenticator.js\";\n\n// Functional exports (v12-style)\nexport { hotpDigestToToken } from \"./hotp.js\";\n\n// Constants (v12-style)\nexport { HashAlgorithms, KeyEncodings } from \"./types.js\";\n\n// Types\nexport type {\n HOTPOptions,\n TOTPOptions,\n AuthenticatorOptions,\n SecretKey,\n Base32SecretKey,\n CreateDigest,\n CreateHmacKey,\n CreateRandomBytes,\n KeyEncoder,\n KeyDecoder,\n} from \"./types.js\";\n\n// Pre-configured instances (v12 style)\nimport { Authenticator } from \"./authenticator.js\";\nimport { HOTP } from \"./hotp.js\";\nimport { TOTP } from \"./totp.js\";\n\n/**\n * Pre-configured HOTP instance\n *\n * @example\n * ```typescript\n * import { hotp } from '@otplib/v12-adapter';\n *\n * const token = hotp.generate('JBSWY3DPEHPK3PXP', 0);\n * const isValid = hotp.check(token, 'JBSWY3DPEHPK3PXP', 0);\n * ```\n */\nexport const hotp = new HOTP();\n\n/**\n * Pre-configured TOTP instance\n *\n * @example\n * ```typescript\n * import { totp } from '@otplib/v12-adapter';\n *\n * const token = totp.generate('JBSWY3DPEHPK3PXP');\n * const isValid = totp.check(token, 'JBSWY3DPEHPK3PXP');\n * ```\n */\nexport const totp = new TOTP();\n\n/**\n * Pre-configured Authenticator instance\n *\n * @example\n * ```typescript\n * import { authenticator } from '@otplib/v12-adapter';\n *\n * const secret = authenticator.generateSecret();\n * const token = authenticator.generate(secret);\n * const isValid = authenticator.check(token, secret);\n * ```\n */\nexport const authenticator = new Authenticator();\n\n// Re-export v13 plugins for advanced usage\nexport { NobleCryptoPlugin } from \"@otplib/plugin-crypto-noble\";\nexport { ScureBase32Plugin } from \"@otplib/plugin-base32-scure\";\n"],"mappings":";AAOA,SAAS,eAAe,iBAAiB,gBAAgB,wBAAwB;AACjF,SAAS,gBAAgB,kBAAkB,cAAc,sBAAsB;AAC/E,SAAS,yBAAyB;AAClC,SAAS,yBAAyB;AAClC,SAAS,gBAAgB,uBAAuB;AAChD,SAAS,WAAW;;;ACAb,IAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AACV;AAOO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AACR;;;ADRA,IAAM,gBAAgB,IAAI,kBAAkB;AAK5C,IAAM,gBAAgB,IAAI,kBAAkB;AAMrC,SAAS,cAAc,QAAmB,UAA+B;AAC9E,MAAI,aAAa,aAAkB,UAAU,aAAa,UAAU;AAClE,WAAO,cAAc,OAAO,MAAM;AAAA,EACpC;AACA,MAAI,aAAa,aAAkB,OAAO,aAAa,OAAO;AAC5D,WAAO,IAAI,OAAO,OAAO,QAAQ,OAAO,EAAE,CAAC;AAAA,EAC7C;AAEA,SAAO,cAAc,MAAM;AAC7B;AAMO,SAAS,kBAAkB,WAAmB,QAAwB;AAC3E,QAAM,cAAc,IAAI,OAAO,SAAS;AACxC,QAAM,YAAY,gBAAgB,WAAW;AAC7C,SAAO,eAAe,WAAW,MAAM;AACzC;AAkBO,IAAM,OAAN,MAAM,MAA0C;AAAA;AAAA;AAAA;AAAA,EAI3C,WAAuB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKxB,kBAA8B,CAAC;AAAA,EAEzC,YAAY,iBAA6B,CAAC,GAAG;AAC3C,SAAK,kBAAkB;AAAA,MACrB,GAAG;AAAA,MACH,YAAY,iBAAiB,eAAe,UAAU;AAAA,IACxD;AACA,SAAK,WAAW,CAAC;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAsB;AACxB,WAAO,EAAE,GAAG,KAAK,iBAAiB,GAAG,KAAK,SAAS;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAQ,OAAmB;AAC7B,SAAK,WAAW,EAAE,GAAG,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,iBAA6B,CAAC,GAAY;AAC/C,WAAO,IAAI,MAAQ,cAAc;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,aAA4C;AAC1C,UAAM,SAAS;AAAA,MACb,WAAW,eAAe;AAAA,MAC1B,QAAQ;AAAA,MACR,UAAU,aAAkB;AAAA,MAC5B,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AACA,WAAO,OAAO,OAAO,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAqB;AACnB,SAAK,WAAW,CAAC;AACjB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,QAAmB,SAAyB;AACnD,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,WAAO,iBAAiB;AAAA,MACtB,QAAQ;AAAA,MACR;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,IACnB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAe,QAAmB,SAA0B;AAChE,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,QAAI;AACF,YAAM,SAAS,eAAe;AAAA,QAC5B,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,kBAAkB;AAAA,QAClB,QAAQ,KAAK;AAAA,QACb,YAAY,KAAK;AAAA,MACnB,CAAC;AAED,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,MAAsE;AAC3E,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,WAAO,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,aAAqB,QAAgB,QAAmB,SAAyB;AACtF,UAAM,OAAO,KAAK,WAAW;AAE7B,WAAO,gBAAgB;AAAA,MACrB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AElMA,SAAS,qBAAAA,0BAAyB;AAClC,SAAS,qBAAAC,0BAAyB;AAClC;AAAA,EACE,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd;AAAA,OACK;AACP,SAAS,gBAAgB,uBAAuB;AAWhD,IAAMC,iBAAgB,IAAIC,mBAAkB;AAK5C,IAAMC,iBAAgB,IAAIC,mBAAkB;AAM5C,SAAS,YACP,QACA,MAC2B;AAC3B,MAAI,WAAW,UAAa,WAAW,GAAG;AACxC,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO,CAAC,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,IAAI;AAC5C;AAkBO,IAAM,OAAN,MAAM,cAAkD,KAAQ;AAAA,EACrE,YAAY,iBAA6B,CAAC,GAAG;AAC3C,UAAM,cAAc;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKS,OAAO,iBAA6B,CAAC,GAAY;AACxD,WAAO,IAAI,MAAQ,cAAc;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKS,aAA4C;AACnD,UAAM,SAAS;AAAA,MACb,WAAW,eAAe;AAAA,MAC1B,QAAQ;AAAA,MACR,UAAU,aAAkB;AAAA,MAC5B,OAAO,KAAK,IAAI;AAAA,MAChB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQH;AAAA,MACR,QAAQE;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AACA,WAAO,OAAO,OAAO,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS,QAA2B;AAClC,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AAEjD,WAAO,iBAAiB;AAAA,MACtB,QAAQ;AAAA,MACR,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,OAAO;AAAA,MACP,IAAI;AAAA,MACJ,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,IACnB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAe,QAA4B;AAC/C,UAAM,QAAQ,KAAK,WAAW,OAAO,MAAM;AAC3C,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,OAAe,QAAkC;AAC1D,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAc,cAAc,QAAQ,KAAK,QAAQ;AAEvD,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AACjD,UAAM,OAAO,KAAK;AAClB,UAAM,SAAS,KAAK;AAEpB,UAAM,iBAAiB,YAAY,QAAQ,IAAI;AAE/C,QAAI;AACF,YAAM,SAAS,eAAe;AAAA,QAC5B,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,IAAI;AAAA,QACJ;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,YAAY,KAAK;AAAA,MACnB,CAAC;AAED,UAAI,CAAC,OAAO,OAAO;AACjB,eAAO;AAAA,MACT;AAGA,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,MAAqD;AAC1D,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,WAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,aAAqB,QAAgB,QAA2B;AACrE,UAAM,OAAO,KAAK,WAAW;AAE7B,WAAO,gBAAgB;AAAA,MACrB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAmB;AACjB,UAAM,OAAO,KAAK,WAAW;AAE7B,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AACjD,WAAO,eAAe,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAwB;AACtB,UAAM,OAAO,KAAK,WAAW;AAE7B,UAAM,eAAe,KAAK,MAAM,KAAK,QAAQ,GAAI;AACjD,WAAO,iBAAiB,cAAc,KAAK,MAAM,CAAC;AAAA,EACpD;AACF;;;ACjOA,SAAS,kBAAkB,0BAA0B;AACrD,SAAS,qBAAAE,0BAAyB;AAClC,SAAS,qBAAAC,0BAAyB;AAClC,SAAS,gBAAgBC,mBAAkB,cAAcC,uBAAsB;AAiB/E,IAAMC,iBAAgB,IAAIC,mBAAkB;AAK5C,IAAMC,iBAAgB,IAAIC,mBAAkB;AAK5C,SAAS,kBAAkB,QAAmB,WAA0C;AACtF,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,MAAM;AAC7C,SAAOD,eAAc,OAAO,KAAK;AACnC;AAKA,SAAS,kBAAkB,eAAgC,WAAoC;AAC7F,QAAM,QAAQA,eAAc,OAAO,aAAa;AAChD,SAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AACvC;AAmBO,IAAM,gBAAN,MAAM,uBAA6E,KAAQ;AAAA,EAChG,YAAY,iBAA6B,CAAC,GAAG;AAC3C,UAAM,cAAc;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKS,OAAO,iBAA6B,CAAC,GAAqB;AACjE,WAAO,IAAI,eAAiB,cAAc;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKS,aAAqD;AAC5D,UAAM,SAAS;AAAA,MACb,WAAW,eAAe;AAAA,MAC1B,QAAQ;AAAA,MACR,UAAU,aAAkB;AAAA,MAC5B,OAAO,KAAK,IAAI;AAAA,MAChB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQF;AAAA,MACR,QAAQE;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AACA,WAAO,OAAO,OAAO,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQS,SAAS,QAAiC;AACjD,UAAM,OAAO,KAAK,WAAW;AAG7B,UAAM,cAAcA,eAAc,OAAO,MAAM;AAC/C,UAAM,QAAQ,KAAK;AACnB,UAAM,eAAe,SAAS,OAAO,KAAK,MAAM,QAAQ,GAAI,IAAI;AAEhE,WAAOE,kBAAiB;AAAA,MACtB,QAAQ;AAAA,MACR,WAAW,KAAK;AAAA,MAChB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,OAAO;AAAA,MACP,IAAI;AAAA,MACJ,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,IACnB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,MAAM,OAAe,QAAkC;AAC9D,UAAM,QAAQ,KAAK,WAAW,OAAO,MAAM;AAC3C,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,WAAW,OAAe,QAAwC;AACzE,UAAM,OAAO,KAAK,WAAW;AAC7B,UAAM,cAAcF,eAAc,OAAO,MAAM;AAC/C,UAAM,QAAQ,KAAK;AACnB,UAAM,eAAe,SAAS,OAAO,KAAK,MAAM,QAAQ,GAAI,IAAI;AAChE,UAAM,OAAO,KAAK;AAClB,UAAM,SAAS,KAAK;AAGpB,QAAI,iBAA4C;AAChD,QAAI,OAAO,WAAW,UAAU;AAC9B,uBAAiB,SAAS;AAAA,IAC5B,WAAW,MAAM,QAAQ,MAAM,GAAG;AAChC,uBAAiB,CAAC,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,IAAI;AAAA,IACtD;AAEA,QAAI;AACF,YAAM,SAASG,gBAAe;AAAA,QAC5B,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,IAAI;AAAA,QACJ;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,YAAY,KAAK;AAAA,MACnB,CAAC;AAED,UAAI,CAAC,OAAO,OAAO;AACjB,eAAO;AAAA,MACT;AAEA,aAAO,OAAO;AAAA,IAChB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQS,OAAO,MAA2D;AACzE,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AACA,WAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAAoC;AACzC,UAAM,OAAO,KAAK,WAAW;AAC7B,QAAI,KAAK,YAAY;AACnB,aAAO,KAAK,WAAW,QAAQ,KAAK,QAAQ;AAAA,IAC9C;AACA,WAAO,kBAAkB,QAAQ,KAAK,QAAQ;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAAoC;AACzC,UAAM,OAAO,KAAK,WAAW;AAC7B,QAAI,KAAK,YAAY;AACnB,aAAO,KAAK,WAAW,QAAQ,KAAK,QAAQ;AAAA,IAC9C;AACA,WAAO,kBAAkB,QAAQ,KAAK,QAAQ;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAe,gBAAwB,IAAqB;AAC1D,UAAM,OAAO,KAAK,WAAW;AAC7B,WAAO,mBAAmB;AAAA,MACxB,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;;;AC7IA,SAAS,qBAAAC,0BAAyB;AAClC,SAAS,qBAAAC,0BAAyB;AA/B3B,IAAM,OAAO,IAAI,KAAK;AAatB,IAAM,OAAO,IAAI,KAAK;AActB,IAAM,gBAAgB,IAAI,cAAc;","names":["ScureBase32Plugin","NobleCryptoPlugin","defaultCrypto","NobleCryptoPlugin","defaultBase32","ScureBase32Plugin","ScureBase32Plugin","NobleCryptoPlugin","totpGenerateSync","totpVerifySync","defaultCrypto","NobleCryptoPlugin","defaultBase32","ScureBase32Plugin","totpGenerateSync","totpVerifySync","NobleCryptoPlugin","ScureBase32Plugin"]}
@@ -1 +1 @@
1
- {"inputs":{"src/types.ts":{"bytes":3630,"imports":[],"format":"esm"},"src/hotp.ts":{"bytes":5108,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/hotp","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/totp.ts":{"bytes":6254,"imports":[{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/authenticator.ts":{"bytes":6823,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/index.ts":{"bytes":2636,"imports":[{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":33986},"dist/index.cjs":{"imports":[{"path":"@otplib/core","kind":"require-call","external":true},{"path":"@otplib/hotp","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/uri","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/totp","kind":"require-call","external":true},{"path":"@otplib/uri","kind":"require-call","external":true},{"path":"@otplib/core","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/totp","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":760},"src/hotp.ts":{"bytesInOutput":3612},"src/types.ts":{"bytesInOutput":212},"src/totp.ts":{"bytesInOutput":4433},"src/authenticator.ts":{"bytesInOutput":4882}},"bytes":15075}}}
1
+ {"inputs":{"src/types.ts":{"bytes":3735,"imports":[],"format":"esm"},"src/hotp.ts":{"bytes":5309,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/hotp","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"@scure/base","kind":"import-statement","external":true},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/totp.ts":{"bytes":6326,"imports":[{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/authenticator.ts":{"bytes":6895,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/index.ts":{"bytes":2636,"imports":[{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":34642},"dist/index.cjs":{"imports":[{"path":"@otplib/core","kind":"require-call","external":true},{"path":"@otplib/hotp","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/uri","kind":"require-call","external":true},{"path":"@scure/base","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/totp","kind":"require-call","external":true},{"path":"@otplib/uri","kind":"require-call","external":true},{"path":"@otplib/core","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/totp","kind":"require-call","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"require-call","external":true},{"path":"@otplib/plugin-base32-scure","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":760},"src/hotp.ts":{"bytesInOutput":3806},"src/types.ts":{"bytesInOutput":212},"src/totp.ts":{"bytesInOutput":4505},"src/authenticator.ts":{"bytesInOutput":4954}},"bytes":15413}}}
@@ -1 +1 @@
1
- {"inputs":{"src/types.ts":{"bytes":3630,"imports":[],"format":"esm"},"src/hotp.ts":{"bytes":5108,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/hotp","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/totp.ts":{"bytes":6254,"imports":[{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/authenticator.ts":{"bytes":6823,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/index.ts":{"bytes":2636,"imports":[{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":33916},"dist/index.js":{"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/hotp","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true}],"exports":["Authenticator","HOTP","HashAlgorithms","KeyEncodings","NobleCryptoPlugin","ScureBase32Plugin","TOTP","authenticator","hotp","hotpDigestToToken","totp"],"entryPoint":"src/index.ts","inputs":{"src/hotp.ts":{"bytesInOutput":3540},"src/types.ts":{"bytesInOutput":212},"src/index.ts":{"bytesInOutput":261},"src/totp.ts":{"bytesInOutput":4445},"src/authenticator.ts":{"bytesInOutput":4892}},"bytes":13674}}}
1
+ {"inputs":{"src/types.ts":{"bytes":3735,"imports":[],"format":"esm"},"src/hotp.ts":{"bytes":5309,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/hotp","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"@scure/base","kind":"import-statement","external":true},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/totp.ts":{"bytes":6326,"imports":[{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/authenticator.ts":{"bytes":6895,"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/index.ts":{"bytes":2636,"imports":[{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/authenticator.ts","kind":"import-statement","original":"./authenticator.js"},{"path":"src/hotp.ts","kind":"import-statement","original":"./hotp.js"},{"path":"src/totp.ts","kind":"import-statement","original":"./totp.js"},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":34577},"dist/index.js":{"imports":[{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/hotp","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"@scure/base","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/uri","kind":"import-statement","external":true},{"path":"@otplib/core","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/totp","kind":"import-statement","external":true},{"path":"@otplib/plugin-crypto-noble","kind":"import-statement","external":true},{"path":"@otplib/plugin-base32-scure","kind":"import-statement","external":true}],"exports":["Authenticator","HOTP","HashAlgorithms","KeyEncodings","NobleCryptoPlugin","ScureBase32Plugin","TOTP","authenticator","hotp","hotpDigestToToken","totp"],"entryPoint":"src/index.ts","inputs":{"src/hotp.ts":{"bytesInOutput":3726},"src/types.ts":{"bytesInOutput":212},"src/index.ts":{"bytesInOutput":261},"src/totp.ts":{"bytesInOutput":4517},"src/authenticator.ts":{"bytesInOutput":4964}},"bytes":14004}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otplib/v12-adapter",
3
- "version": "13.1.1",
3
+ "version": "13.2.0",
4
4
  "description": "Drop-in replacement adapter for migrating from otplib v12 to v13",
5
5
  "license": "MIT",
6
6
  "author": "Gerald Yeo <support@yeojz.dev>",
@@ -47,17 +47,18 @@
47
47
  "LICENSE"
48
48
  ],
49
49
  "dependencies": {
50
- "@otplib/core": "13.1.1",
51
- "@otplib/totp": "13.1.1",
52
- "@otplib/uri": "13.1.1",
53
- "@otplib/plugin-base32-scure": "13.1.1",
54
- "@otplib/plugin-crypto-noble": "13.1.1",
55
- "@otplib/hotp": "13.1.1"
50
+ "@scure/base": "^2.0.0",
51
+ "@otplib/hotp": "13.2.0",
52
+ "@otplib/core": "13.2.0",
53
+ "@otplib/totp": "13.2.0",
54
+ "@otplib/plugin-crypto-noble": "13.2.0",
55
+ "@otplib/uri": "13.2.0",
56
+ "@otplib/plugin-base32-scure": "13.2.0"
56
57
  },
57
58
  "devDependencies": {
58
59
  "tsup": "^8.0.1",
59
60
  "typescript": "^5.3.3",
60
- "vitest": "^4.0.16",
61
+ "vitest": "^4.0.18",
61
62
  "@repo/testing": "13.0.1"
62
63
  },
63
64
  "publishConfig": {