otplib 13.2.1 → 13.4.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/README.md CHANGED
@@ -2,32 +2,30 @@
2
2
 
3
3
  TypeScript-first library for HOTP and TOTP / Authenticator with multi-runtime (Node, Bun, Deno, Browser) support via plugins.
4
4
 
5
- A web based demo is available at [https://otplib.yeojz.dev](https://otplib.yeojz.dev).
5
+ > [!TIP]
6
+ >
7
+ > A web based demo is available at [https://otplib.yeojz.dev](https://otplib.yeojz.dev).
8
+ >
9
+ > You can scan the TOTP / HOTP QR Code samples with your chosen authenticator app to test.
6
10
 
7
11
  ## Features
8
12
 
9
13
  - **Zero Configuration** - Works out of the box with sensible defaults
10
- - **RFC Compliant** - RFC 6238 (TOTP) and RFC 4226 (HOTP)
14
+ - **RFC Compliant** - RFC 6238 (TOTP) and RFC 4226 (HOTP) + Google Authenticator Compatible
11
15
  - **TypeScript-First** - Full type definitions
12
- - **Google Authenticator Compatible** - Full otpauth:// URI support
13
16
  - **Plugin Interface** - Flexible plugin system for customising your cryptographic and base32 requirements (if you want to deviate from the defaults)
14
17
  - **Cross-platform** - Tested against Node.js, Bun, Deno, and browsers
18
+ - **Security-audited plugins** — Default crypto uses `@noble/hashes` and `@scure/base`, both independently audited
19
+ - **Async-first API** — All operations are async by default; sync variants available for compatible plugins
15
20
 
16
- ## Breaking Changes (v13)
17
-
18
- > [!IMPORTANT]
19
- > v13 is a complete rewrite with breaking changes:
21
+ > [!IMPORTANT]
22
+ >
23
+ > v13 is a complete rewrite with breaking changes. For example:
20
24
  >
21
- > - **New**
22
- > - **Security-audited plugins** — Default crypto uses `@noble/hashes` and `@scure/base`, both independently audited
23
- > - **Cross-platform defaults** — Works out-of-the-box in Node.js, Bun, Deno, and browsers
24
- > - **Full type safety** — Comprehensive TypeScript types with strict mode from the ground up
25
- > - **Async-first API** — All operations are async by default; sync variants available for compatible plugins
26
- > - **Removed**
27
- > - **Separate authenticator package** — TOTP now covers all authenticator functionality
28
- > - **Outdated plugins** — Legacy crypto adapters removed in favor of modern, audited alternatives
25
+ > - **(Removed) Separate authenticator package** — TOTP now covers all authenticator functionality with default plugins
26
+ > - **(Removed) Outdated plugins** — Legacy crypto adapters removed in favor of modern, audited alternatives
29
27
  >
30
- > See [Migration Guide](https://otplib.yeojz.dev/guide/v12-adapter) for details.
28
+ > See [Migration Guide](https://otplib.yeojz.dev/guide/v12-adapter.html) for details.
31
29
 
32
30
  ## Installation
33
31
 
@@ -44,6 +42,27 @@ bun add otplib
44
42
  deno install npm:otplib
45
43
  ```
46
44
 
45
+ ### CDN / Script Tag
46
+
47
+ A self-contained IIFE build is available for use directly in browsers via a `<script>` tag:
48
+
49
+ ```html
50
+ <!-- unpkg -->
51
+ <script src="https://unpkg.com/otplib/dist/index.global.js"></script>
52
+
53
+ <!-- or jsdelivr -->
54
+ <script src="https://cdn.jsdelivr.net/npm/otplib/dist/index.global.js"></script>
55
+
56
+ <script>
57
+ const { generateSecret, generate, verify } = otplib;
58
+
59
+ const secret = generateSecret();
60
+ generate({ secret }).then((token) => console.log("Token:", token));
61
+ </script>
62
+ ```
63
+
64
+ The IIFE build bundles all dependencies (including crypto and base32 plugins) into a single file and exposes everything under the `otplib` global.
65
+
47
66
  ## Quick Start
48
67
 
49
68
  ### Functional API (Recommended)
@@ -57,8 +76,9 @@ const secret = generateSecret();
57
76
  // Generate a TOTP token
58
77
  const token = await generate({ secret });
59
78
 
60
- // Verify a token
61
- const isValid = await verify({ secret, token });
79
+ // Verify a token — returns VerifyResult, not a boolean
80
+ const result = await verify({ secret, token });
81
+ console.log(result.valid); // true or false
62
82
 
63
83
  // Generate QR code URI for authenticator apps
64
84
  const uri = generateURI({
@@ -68,12 +88,14 @@ const uri = generateURI({
68
88
  });
69
89
  ```
70
90
 
91
+ Sync variants (`generateSync`, `verifySync`) are available when using a sync-compatible crypto plugin such as `@otplib/plugin-crypto-node` or `@otplib/plugin-crypto-noble`.
92
+
71
93
  ### Class API
72
94
 
73
95
  ```typescript
74
96
  import { OTP } from "otplib";
75
97
 
76
- // Create OTP instance (defaults to TOTP)
98
+ // Create OTP instance (defaults to TOTP strategy)
77
99
  const otp = new OTP();
78
100
 
79
101
  // Generate a secret
@@ -82,8 +104,9 @@ const secret = otp.generateSecret();
82
104
  // Generate a TOTP token
83
105
  const token = await otp.generate({ secret });
84
106
 
85
- // Verify a token
86
- const isValid = await otp.verify({ secret, token });
107
+ // Verify a token — returns VerifyResult, not a boolean
108
+ const result = await otp.verify({ secret, token });
109
+ console.log(result.valid); // true or false
87
110
 
88
111
  // Generate QR code URI for authenticator apps
89
112
  const uri = otp.generateURI({
@@ -93,11 +116,30 @@ const uri = otp.generateURI({
93
116
  });
94
117
  ```
95
118
 
96
- ## Notes
119
+ The class also exposes `generateSync` and `verifySync` for use with sync-compatible crypto plugins.
120
+
121
+ #### HOTP (counter-based) with the Class API
122
+
123
+ Pass `strategy: 'hotp'` to switch to counter-based OTP. A `counter` value is required for generation and verification.
124
+
125
+ ```typescript
126
+ import { OTP } from "otplib";
127
+
128
+ const otp = new OTP({ strategy: "hotp" });
129
+ const secret = otp.generateSecret();
130
+
131
+ const token = await otp.generate({ secret, counter: 0 });
132
+ const result = await otp.verify({ secret, token, counter: 0 });
133
+ console.log(result.valid); // true or false
134
+ ```
135
+
136
+ ## Compatibility with Authenticator Apps
97
137
 
98
138
  ### Secret Format
99
139
 
100
- By default, otplib expects secrets to be in **Base32** format. While the core HOTP (RFC 4226) and TOTP (RFC 6238) specifications work with raw binary data and don't mandate Base32 encoding, Base32 is the standard format used by authenticator applications and QR code URIs for compatibility.
140
+ By default, otplib expects secrets to be in **Base32** format. This is the ensure broader compatiblity as it the standard format used by authenticator applications and QR code URIs.
141
+
142
+ While the core HOTP (RFC 4226) and TOTP (RFC 6238) specifications work with raw binary data and don't mandate Base32 encoding, Base32
101
143
 
102
144
  ```typescript
103
145
  // Base32 secret (standard format for authenticator compatibility)
@@ -106,7 +148,22 @@ const secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY";
106
148
 
107
149
  However, if you need to use secrets in other formats, you can either use the `plugin-base32-alt` plugin for raw strings or pass a byte array (using `stringToBytes` helper) for binary data.
108
150
 
109
- For more details and examples, see the [Secret Handling Guide](https://otplib.yeojz.dev/guide/secret-handling.md) and related plugin documentation in the guides directory.
151
+ For more details and examples, see the [Secret Handling Guide](https://otplib.yeojz.dev/guide/secret-handling) and related plugin documentation in the guides directory.
152
+
153
+ ### Configuration Defaults
154
+
155
+ RFC 4226 (HOTP) and RFC 6238 (TOTP) define flexible algorithms that allow different hash functions, digit lengths, and time steps. However, most authenticator apps (Google Authenticator, Authy, Microsoft Authenticator, 1Password, etc.) and services offering 2 factor authentication use the following defaults:
156
+
157
+ | Parameter | Value |
158
+ | ----------- | ------------- |
159
+ | `algorithm` | `sha1` |
160
+ | `digits` | `6` |
161
+ | `period` | `30` |
162
+ | `secret` | Base32 string |
163
+
164
+ If you are deviating from these values, do validate that it is supported by the target application.
165
+
166
+ If you need to provision an authenticator app via QR code, use [`@otplib/uri`](https://www.npmjs.com/package/@otplib/uri) to generate an `otpauth://totp/` URI.
110
167
 
111
168
  ## Documentation
112
169
 
@@ -119,4 +176,4 @@ Refer to the [Getting Started Guide](https://otplib.yeojz.dev/guide/getting-star
119
176
 
120
177
  ## License
121
178
 
122
- [MIT](./LICENSE) © 2026 Gerald Yeo
179
+ [MIT](./LICENSE)
package/dist/class.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var T=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var U=(r,e)=>{for(var t in e)T(r,t,{get:e[t],enumerable:!0})},B=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of C(e))!D.call(r,a)&&a!==t&&T(r,a,{get:()=>e[a],enumerable:!(i=v(e,a))||i.enumerable});return r};var A=r=>B(T({},"__esModule",{value:!0}),r);var I={};U(I,{OTP:()=>b});module.exports=A(I);var d=require("@otplib/core");var S=require("@otplib/core"),c=require("@otplib/plugin-base32-scure"),l=require("@otplib/plugin-crypto-noble");function m(r){return{secret:r.secret,strategy:r.strategy??"totp",crypto:r.crypto??l.crypto,base32:r.base32??c.base32,algorithm:r.algorithm??"sha1",digits:r.digits??6,period:r.period??30,epoch:r.epoch??Math.floor(Date.now()/1e3),t0:r.t0??0,counter:r.counter,guardrails:r.guardrails??(0,S.createGuardrails)()}}function P(r){return{...m(r),token:r.token,epochTolerance:r.epochTolerance??0,counterTolerance:r.counterTolerance??0}}var O=require("@otplib/core"),g=require("@otplib/hotp"),u=require("@otplib/totp"),h=require("@otplib/uri");function f(r,e,t){if(r==="totp")return t.totp();if(r==="hotp"){if(e===void 0)throw new O.ConfigurationError("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return t.hotp(e)}throw new O.ConfigurationError(`Unknown OTP strategy: ${r}. Valid strategies are 'totp' or 'hotp'.`)}function V(r){let{strategy:e="totp",issuer:t,label:i,secret:a,algorithm:s="sha1",digits:p=6,period:o=30,counter:n}=r;return f(e,n,{totp:()=>(0,h.generateTOTP)({issuer:t,label:i,secret:a,algorithm:s,digits:p,period:o}),hotp:y=>(0,h.generateHOTP)({issuer:t,label:i,secret:a,algorithm:s,digits:p,counter:y})})}async function R(r){let e=m(r),{secret:t,crypto:i,base32:a,algorithm:s,digits:p}=e,o={secret:t,crypto:i,base32:a,algorithm:s,digits:p};return f(e.strategy,e.counter,{totp:()=>(0,u.generate)({...o,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:n=>(0,g.generate)({...o,counter:n,guardrails:e.guardrails})})}function G(r){let e=m(r),{secret:t,crypto:i,base32:a,algorithm:s,digits:p}=e,o={secret:t,crypto:i,base32:a,algorithm:s,digits:p};return f(e.strategy,e.counter,{totp:()=>(0,u.generateSync)({...o,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:n=>(0,g.generateSync)({...o,counter:n,guardrails:e.guardrails})})}async function x(r){let e=P(r),{secret:t,token:i,crypto:a,base32:s,algorithm:p,digits:o}=e,n={secret:t,token:i,crypto:a,base32:s,algorithm:p,digits:o};return f(e.strategy,e.counter,{totp:()=>(0,u.verify)({...n,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,guardrails:e.guardrails}),hotp:y=>(0,g.verify)({...n,counter:y,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}function H(r){let e=P(r),{secret:t,token:i,crypto:a,base32:s,algorithm:p,digits:o}=e,n={secret:t,token:i,crypto:a,base32:s,algorithm:p,digits:o};return f(e.strategy,e.counter,{totp:()=>(0,u.verifySync)({...n,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,guardrails:e.guardrails}),hotp:y=>(0,g.verifySync)({...n,counter:y,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}var b=class{strategy;crypto;base32;guardrails;constructor(e={}){let{strategy:t="totp",crypto:i=l.crypto,base32:a=c.base32,guardrails:s}=e;this.strategy=t,this.crypto=i,this.base32=a,this.guardrails=(0,d.createGuardrails)(s)}getStrategy(){return this.strategy}generateSecret(e=20){return(0,d.generateSecret)({crypto:this.crypto,base32:this.base32,length:e})}async generate(e){return R({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateSync(e){return G({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}async verify(e){return x({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}verifySync(e){return H({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateURI(e){return V({...e,strategy:this.strategy})}};0&&(module.exports={OTP});
1
+ "use strict";var P=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var U=(r,e)=>{for(var t in e)P(r,t,{get:e[t],enumerable:!0})},B=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of C(e))!D.call(r,a)&&a!==t&&P(r,a,{get:()=>e[a],enumerable:!(i=k(e,a))||i.enumerable});return r};var A=r=>B(P({},"__esModule",{value:!0}),r);var I={};U(I,{OTP:()=>S});module.exports=A(I);var O=require("@otplib/core");var V=require("@otplib/core"),c=require("@otplib/plugin-base32-scure"),l=require("@otplib/plugin-crypto-noble");function m(r){return{secret:r.secret,strategy:r.strategy??"totp",crypto:r.crypto??l.crypto,base32:r.base32??c.base32,algorithm:r.algorithm??"sha1",digits:r.digits??6,period:r.period??30,epoch:r.epoch??Math.floor(Date.now()/1e3),t0:r.t0??0,counter:r.counter,guardrails:r.guardrails??(0,V.createGuardrails)(),hooks:r.hooks}}function b(r){return{...m(r),token:r.token,epochTolerance:r.epochTolerance??0,counterTolerance:r.counterTolerance??0,afterTimeStep:r.afterTimeStep}}var T=require("@otplib/core"),u=require("@otplib/hotp"),y=require("@otplib/totp"),h=require("@otplib/uri");function f(r,e,t){if(r==="totp")return t.totp();if(r==="hotp"){if(e===void 0)throw new T.ConfigurationError("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return t.hotp(e)}throw new T.ConfigurationError(`Unknown OTP strategy: ${r}. Valid strategies are 'totp' or 'hotp'.`)}function R(r){let{strategy:e="totp",issuer:t,label:i,secret:a,algorithm:o="sha1",digits:s=6,period:n=30,counter:p}=r;return f(e,p,{totp:()=>(0,h.generateTOTP)({issuer:t,label:i,secret:a,algorithm:o,digits:s,period:n}),hotp:g=>(0,h.generateHOTP)({issuer:t,label:i,secret:a,algorithm:o,digits:s,counter:g})})}async function G(r){let e=m(r),{secret:t,crypto:i,base32:a,algorithm:o,digits:s,hooks:n}=e,p={secret:t,crypto:i,base32:a,algorithm:o,digits:s,hooks:n};return f(e.strategy,e.counter,{totp:()=>(0,y.generate)({...p,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:g=>(0,u.generate)({...p,counter:g,guardrails:e.guardrails})})}function H(r){let e=m(r),{secret:t,crypto:i,base32:a,algorithm:o,digits:s}=e,n={secret:t,crypto:i,base32:a,algorithm:o,digits:s};return f(e.strategy,e.counter,{totp:()=>(0,y.generateSync)({...n,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:p=>(0,u.generateSync)({...n,counter:p,guardrails:e.guardrails})})}async function x(r){let e=b(r),{secret:t,token:i,crypto:a,base32:o,algorithm:s,digits:n,hooks:p}=e,g={secret:t,token:i,crypto:a,base32:o,algorithm:s,digits:n,hooks:p};return f(e.strategy,e.counter,{totp:()=>(0,y.verify)({...g,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:d=>(0,u.verify)({...g,counter:d,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}function v(r){let e=b(r),{secret:t,token:i,crypto:a,base32:o,algorithm:s,digits:n,hooks:p}=e,g={secret:t,token:i,crypto:a,base32:o,algorithm:s,digits:n,hooks:p};return f(e.strategy,e.counter,{totp:()=>(0,y.verifySync)({...g,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:d=>(0,u.verifySync)({...g,counter:d,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}var S=class{strategy;crypto;base32;guardrails;constructor(e={}){let{strategy:t="totp",crypto:i=l.crypto,base32:a=c.base32,guardrails:o}=e;this.strategy=t,this.crypto=i,this.base32=a,this.guardrails=(0,O.createGuardrails)(o)}getStrategy(){return this.strategy}generateSecret(e=20){return(0,O.generateSecret)({crypto:this.crypto,base32:this.base32,length:e})}async generate(e){return G({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateSync(e){return H({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}async verify(e){return x({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}verifySync(e){return v({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateURI(e){return R({...e,strategy:this.strategy})}};0&&(module.exports={OTP});
2
2
  //# sourceMappingURL=class.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/class.ts","../src/defaults.ts","../src/functional.ts"],"sourcesContent":["/**\n * OTP Wrapper Class\n *\n * A unified class that dynamically handles TOTP and HOTP strategies.\n */\n\nimport { createGuardrails, generateSecret as generateSecretCore } from \"@otplib/core\";\n\nimport { defaultCrypto, defaultBase32 } from \"./defaults.js\";\nimport {\n generate as functionalGenerate,\n generateSync as functionalGenerateSync,\n verify as functionalVerify,\n verifySync as functionalVerifySync,\n generateURI as functionalGenerateURI,\n} from \"./functional.js\";\n\nimport type { OTPStrategy } from \"./functional.js\";\nimport type {\n CryptoPlugin,\n Digits,\n HashAlgorithm,\n Base32Plugin,\n OTPGuardrails,\n} from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\n/**\n * Combined verify result that works for both TOTP and HOTP\n */\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\n/**\n * Options for the OTP class\n */\nexport type OTPClassOptions = {\n /**\n * OTP strategy to use\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n */\n strategy?: OTPStrategy;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for generating a token with the OTP class\n */\nexport type OTPGenerateOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for verifying a token with the OTP class\n */\nexport type OTPVerifyOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * OTP code to verify\n */\n token: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Time tolerance in seconds for TOTP verification (default: 0)\n * - Number: symmetric tolerance (same for past and future)\n * - Tuple [past, future]: asymmetric tolerance\n * Use [5, 0] for RFC-compliant past-only verification.\n */\n epochTolerance?: number | [number, number];\n\n /**\n * Counter tolerance for HOTP verification (default: 0)\n * - Number: creates look-ahead only tolerance [0, n]\n * - Tuple [past, future]: explicit window control\n */\n counterTolerance?: number | [number, number];\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for generating URI with the OTP class\n */\nexport type OTPURIGenerateOptions = {\n /**\n * Issuer name (e.g., 'ACME Co')\n */\n issuer: string;\n\n /**\n * Label/Account name (e.g., 'john@example.com')\n */\n label: string;\n\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value (default: 0)\n * Used by HOTP strategy\n */\n counter?: number;\n};\n\n/**\n * OTP Class\n *\n * A wrapper class that dynamically handles TOTP and HOTP strategies.\n *\n * @example\n * ```ts\n * import { OTP } from 'otplib';\n *\n * // Create OTP instance with TOTP strategy (default)\n * const otp = new OTP({ strategy: 'totp' });\n *\n * // Generate and verify\n * const secret = otp.generateSecret();\n * const token = await otp.generate({ secret });\n * const result = await otp.verify({ secret, token });\n * ```\n *\n * @example With HOTP strategy\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'hotp' });\n * const token = await otp.generate({ secret: 'ABC123', counter: 0 });\n * ```\n *\n * @example Generating otpauth:// URI for authenticator apps\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'totp' });\n * const uri = otp.generateURI({\n * issuer: 'MyApp',\n * label: 'user@example.com',\n * secret: 'ABC123',\n * });\n * ```\n */\nexport class OTP {\n private readonly strategy: OTPStrategy;\n private readonly crypto: CryptoPlugin;\n private readonly base32: Base32Plugin;\n private readonly guardrails: OTPGuardrails;\n\n constructor(options: OTPClassOptions = {}) {\n const {\n strategy = \"totp\",\n crypto = defaultCrypto,\n base32 = defaultBase32,\n guardrails,\n } = options;\n\n this.strategy = strategy;\n this.crypto = crypto;\n this.base32 = base32;\n this.guardrails = createGuardrails(guardrails);\n }\n\n /**\n * Get the current strategy\n */\n getStrategy(): OTPStrategy {\n return this.strategy;\n }\n\n /**\n * Generate a random secret key\n *\n * @param length - Number of random bytes (default: 20)\n * @returns Base32-encoded secret key\n */\n generateSecret(length: number = 20): string {\n return generateSecretCore({ crypto: this.crypto, base32: this.base32, length });\n }\n\n /**\n * Generate an OTP token based on the configured strategy\n *\n * @param options - Generation options\n * @returns OTP code\n */\n async generate(options: OTPGenerateOptions): Promise<string> {\n return functionalGenerate({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an OTP token based on the configured strategy synchronously\n *\n * @param options - Generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n generateSync(options: OTPGenerateOptions): string {\n return functionalGenerateSync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n */\n async verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n return functionalVerify({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy synchronously\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n verifySync(options: OTPVerifyOptions): VerifyResult {\n return functionalVerifySync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an otpauth:// URI for QR code generation\n *\n * Supports both TOTP and HOTP strategies.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n */\n generateURI(options: OTPURIGenerateOptions): string {\n return functionalGenerateURI({\n ...options,\n strategy: this.strategy,\n });\n }\n}\n","/**\n * Default plugin instances\n *\n * Shared across functional and class APIs to ensure singleton behavior\n * and reduce memory overhead. Uses pre-instantiated frozen singletons\n * from the plugin packages.\n */\nimport { createGuardrails } from \"@otplib/core\";\nimport { base32 as defaultBase32 } from \"@otplib/plugin-base32-scure\";\nimport { crypto as defaultCrypto } from \"@otplib/plugin-crypto-noble\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPGenerateOptionsWithDefaults,\n OTPVerifyOptionsWithDefaults,\n} from \"./types.js\";\n\nexport { defaultCrypto, defaultBase32 };\n\nexport function normalizeGenerateOptions(\n options: OTPGenerateOptions,\n): OTPGenerateOptionsWithDefaults {\n return {\n secret: options.secret,\n strategy: options.strategy ?? \"totp\",\n crypto: options.crypto ?? defaultCrypto,\n base32: options.base32 ?? defaultBase32,\n algorithm: options.algorithm ?? \"sha1\",\n digits: options.digits ?? 6,\n period: options.period ?? 30,\n epoch: options.epoch ?? Math.floor(Date.now() / 1000),\n t0: options.t0 ?? 0,\n counter: options.counter,\n guardrails: options.guardrails ?? createGuardrails(),\n };\n}\n\nexport function normalizeVerifyOptions(options: OTPVerifyOptions): OTPVerifyOptionsWithDefaults {\n return {\n ...normalizeGenerateOptions(options),\n token: options.token,\n epochTolerance: options.epochTolerance ?? 0,\n counterTolerance: options.counterTolerance ?? 0,\n };\n}\n","import { generateSecret as generateSecretCore, ConfigurationError } from \"@otplib/core\";\nimport {\n generate as generateHOTP,\n generateSync as generateHOTPSync,\n verify as verifyHOTP,\n verifySync as verifyHOTPSync,\n} from \"@otplib/hotp\";\nimport {\n generate as generateTOTP,\n generateSync as generateTOTPSync,\n verify as verifyTOTP,\n verifySync as verifyTOTPSync,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI, generateHOTP as generateHOTURI } from \"@otplib/uri\";\n\nimport {\n defaultCrypto,\n defaultBase32,\n normalizeGenerateOptions,\n normalizeVerifyOptions,\n} from \"./defaults.js\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPStrategy,\n StrategyHandlers,\n} from \"./types.js\";\nimport type { CryptoPlugin, Base32Plugin, Digits, HashAlgorithm } from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\nexport type { OTPStrategy };\n\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\nfunction executeByStrategy<T>(\n strategy: OTPStrategy,\n counter: number | undefined,\n handlers: StrategyHandlers<T>,\n): T {\n if (strategy === \"totp\") {\n return handlers.totp();\n }\n if (strategy === \"hotp\") {\n if (counter === undefined) {\n throw new ConfigurationError(\n \"Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }\",\n );\n }\n return handlers.hotp(counter);\n }\n throw new ConfigurationError(\n `Unknown OTP strategy: ${strategy}. Valid strategies are 'totp' or 'hotp'.`,\n );\n}\n\n/**\n * Generate a random secret key for use with OTP\n *\n * The secret is encoded in Base32 format for compatibility with\n * Google Authenticator and other authenticator apps.\n *\n * @param options - Secret generation options\n * @returns Base32-encoded secret key\n *\n * @example\n * ```ts\n * import { generateSecret } from 'otplib';\n *\n * const secret = generateSecret();\n * // Returns: 'JBSWY3DPEHPK3PXP'\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generateSecret, NodeCryptoPlugin } from 'otplib';\n *\n * const secret = generateSecret({\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport function generateSecret(options?: {\n /**\n * Number of random bytes to generate (default: 20)\n * 20 bytes = 160 bits, which provides a good security margin\n */\n length?: number;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n}): string {\n const { crypto = defaultCrypto, base32 = defaultBase32, length = 20 } = options || {};\n\n return generateSecretCore({ crypto, base32, length });\n}\n\n/**\n * Generate an otpauth:// URI for QR code generation\n *\n * This URI can be used to generate a QR code that can be scanned\n * by Google Authenticator and other authenticator apps.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n *\n * @example TOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: 'otpauth://totp/ACME%20Co:john%40example.com?secret=...'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * strategy: 'hotp',\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * counter: 5,\n * });\n * // Returns: 'otpauth://hotp/ACME%20Co:john%40example.com?secret=...&counter=5'\n * ```\n */\nexport function generateURI(options: {\n /**\n * OTP strategy to use (default: 'totp')\n */\n strategy?: OTPStrategy;\n issuer: string;\n label: string;\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n algorithm?: HashAlgorithm;\n digits?: Digits;\n period?: number;\n counter?: number;\n}): string {\n const {\n strategy = \"totp\",\n issuer,\n label,\n secret,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n counter,\n } = options;\n\n return executeByStrategy(strategy, counter, {\n totp: () => generateTOTPURI({ issuer, label, secret, algorithm, digits, period }),\n hotp: (counter) => generateHOTURI({ issuer, label, secret, algorithm, digits, counter }),\n });\n}\n\n/**\n * Generate an OTP code\n *\n * Generates a one-time password based on the specified strategy.\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n *\n * @param options - OTP generation options\n * @returns OTP code\n *\n * @example TOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: '123456'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generate, NodeCryptoPlugin } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function generate(options: OTPGenerateOptions): Promise<string> {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTP({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Generate an OTP code synchronously\n *\n * This is the synchronous version of {@link generate}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { generateSync } from 'otplib';\n *\n * const token = generateSync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * ```\n */\nexport function generateSync(options: OTPGenerateOptions): string {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTPSync({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code\n *\n * Verifies a provided OTP code against the expected value based on the strategy.\n * - 'totp': Time-based OTP (default, Google Authenticator compatible)\n * - 'hotp': HMAC-based OTP\n *\n * Uses constant-time comparison to prevent timing attacks.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n *\n * @example TOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * // Returns: { valid: true, delta: 0 }\n * ```\n *\n * @example HOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With epochTolerance for TOTP\n * ```ts\n * import { verify, NodeCryptoPlugin } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * epochTolerance: 30,\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTP({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code synchronously\n *\n * This is the synchronous version of {@link verify}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { verifySync } from 'otplib';\n *\n * const result = verifySync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * ```\n */\nexport function verifySync(options: OTPVerifyOptions): VerifyResult {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTPSync({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,SAAAE,IAAA,eAAAC,EAAAH,GAMA,IAAAI,EAAuE,wBCCvE,IAAAC,EAAiC,wBACjCC,EAAwC,uCACxCC,EAAwC,uCAWjC,SAASC,EACdC,EACgC,CAChC,MAAO,CACL,OAAQA,EAAQ,OAChB,SAAUA,EAAQ,UAAY,OAC9B,OAAQA,EAAQ,QAAU,EAAAC,OAC1B,OAAQD,EAAQ,QAAU,EAAAE,OAC1B,UAAWF,EAAQ,WAAa,OAChC,OAAQA,EAAQ,QAAU,EAC1B,OAAQA,EAAQ,QAAU,GAC1B,MAAOA,EAAQ,OAAS,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EACpD,GAAIA,EAAQ,IAAM,EAClB,QAASA,EAAQ,QACjB,WAAYA,EAAQ,eAAc,oBAAiB,CACrD,CACF,CAEO,SAASG,EAAuBH,EAAyD,CAC9F,MAAO,CACL,GAAGD,EAAyBC,CAAO,EACnC,MAAOA,EAAQ,MACf,eAAgBA,EAAQ,gBAAkB,EAC1C,iBAAkBA,EAAQ,kBAAoB,CAChD,CACF,CC7CA,IAAAI,EAAyE,wBACzEC,EAKO,wBACPC,EAKO,wBACPC,EAAgF,uBAuBhF,SAASC,EACPC,EACAC,EACAC,EACG,CACH,GAAIF,IAAa,OACf,OAAOE,EAAS,KAAK,EAEvB,GAAIF,IAAa,OAAQ,CACvB,GAAIC,IAAY,OACd,MAAM,IAAI,qBACR,kFACF,EAEF,OAAOC,EAAS,KAAKD,CAAO,CAC9B,CACA,MAAM,IAAI,qBACR,yBAAyBD,CAAQ,0CACnC,CACF,CAqFO,SAASG,EAAYC,EAkBjB,CACT,GAAM,CACJ,SAAAC,EAAW,OACX,OAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EAAS,GACT,QAAAC,CACF,EAAIR,EAEJ,OAAOS,EAAkBR,EAAUO,EAAS,CAC1C,KAAM,OAAM,EAAAE,cAAgB,CAAE,OAAAR,EAAQ,MAAAC,EAAO,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,OAAAC,CAAO,CAAC,EAChF,KAAOC,MAAY,EAAAG,cAAe,CAAE,OAAAT,EAAQ,MAAAC,EAAO,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,QAAAE,CAAQ,CAAC,CACzF,CAAC,CACH,CA2CA,eAAsBI,EAASZ,EAA8C,CAC3E,IAAMa,EAAOC,EAAyBd,CAAO,EACvC,CAAE,OAAAI,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EAChDI,EAAgB,CAAE,OAAAb,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAElE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,OACJ,EAAAK,UAAa,CACX,GAAGD,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,MACL,EAAAW,UAAa,CACX,GAAGF,EACH,QAAAT,EACA,WAAYK,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAqBO,SAASO,EAAapB,EAAqC,CAChE,IAAMa,EAAOC,EAAyBd,CAAO,EACvC,CAAE,OAAAI,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EAChDI,EAAgB,CAAE,OAAAb,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAElE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,OACJ,EAAAQ,cAAiB,CACf,GAAGJ,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,MACL,EAAAc,cAAiB,CACf,GAAGL,EACH,QAAAT,EACA,WAAYK,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAiDA,eAAsBU,EAAOvB,EAAkD,CAC7E,IAAMa,EAAOW,EAAuBxB,CAAO,EACrC,CAAE,OAAAI,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EACvDI,EAAgB,CAAE,OAAAb,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAEzE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,OACJ,EAAAa,QAAW,CACT,GAAGT,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,eAAgBA,EAAK,eACrB,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,MACL,EAAAmB,QAAW,CACT,GAAGV,EACH,QAAAT,EACA,iBAAkBK,EAAK,iBACvB,WAAYA,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAsBO,SAASe,EAAW5B,EAAyC,CAClE,IAAMa,EAAOW,EAAuBxB,CAAO,EACrC,CAAE,OAAAI,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EACvDI,EAAgB,CAAE,OAAAb,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAEzE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,OACJ,EAAAgB,YAAe,CACb,GAAGZ,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,eAAgBA,EAAK,eACrB,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,MACL,EAAAsB,YAAe,CACb,GAAGb,EACH,QAAAT,EACA,iBAAkBK,EAAK,iBACvB,WAAYA,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CFlIO,IAAMkB,EAAN,KAAU,CACE,SACA,OACA,OACA,WAEjB,YAAYC,EAA2B,CAAC,EAAG,CACzC,GAAM,CACJ,SAAAC,EAAW,OACX,OAAAC,EAAS,EAAAC,OACT,OAAAC,EAAS,EAAAC,OACT,WAAAC,CACF,EAAIN,EAEJ,KAAK,SAAWC,EAChB,KAAK,OAASC,EACd,KAAK,OAASE,EACd,KAAK,cAAa,oBAAiBE,CAAU,CAC/C,CAKA,aAA2B,CACzB,OAAO,KAAK,QACd,CAQA,eAAeC,EAAiB,GAAY,CAC1C,SAAO,EAAAC,gBAAmB,CAAE,OAAQ,KAAK,OAAQ,OAAQ,KAAK,OAAQ,OAAAD,CAAO,CAAC,CAChF,CAQA,MAAM,SAASP,EAA8C,CAC3D,OAAOS,EAAmB,CACxB,GAAGT,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CASA,aAAaA,EAAqC,CAChD,OAAOU,EAAuB,CAC5B,GAAGV,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CAQA,MAAM,OAAOA,EAAkD,CAC7D,OAAOW,EAAiB,CACtB,GAAGX,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CASA,WAAWA,EAAyC,CAClD,OAAOY,EAAqB,CAC1B,GAAGZ,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CAUA,YAAYA,EAAwC,CAClD,OAAOa,EAAsB,CAC3B,GAAGb,EACH,SAAU,KAAK,QACjB,CAAC,CACH,CACF","names":["class_exports","__export","OTP","__toCommonJS","import_core","import_core","import_plugin_base32_scure","import_plugin_crypto_noble","normalizeGenerateOptions","options","defaultCrypto","defaultBase32","normalizeVerifyOptions","import_core","import_hotp","import_totp","import_uri","executeByStrategy","strategy","counter","handlers","generateURI","options","strategy","issuer","label","secret","algorithm","digits","period","counter","executeByStrategy","generateTOTPURI","generateHOTURI","generate","opts","normalizeGenerateOptions","crypto","base32","commonOptions","generateTOTP","generateHOTP","generateSync","generateTOTPSync","generateHOTPSync","verify","normalizeVerifyOptions","token","verifyTOTP","verifyHOTP","verifySync","verifyTOTPSync","verifyHOTPSync","OTP","options","strategy","crypto","defaultCrypto","base32","defaultBase32","guardrails","length","generateSecretCore","generate","generateSync","verify","verifySync","generateURI"]}
1
+ {"version":3,"sources":["../src/class.ts","../src/defaults.ts","../src/functional.ts"],"sourcesContent":["/**\n * OTP Wrapper Class\n *\n * A unified class that dynamically handles TOTP and HOTP strategies.\n */\n\nimport { createGuardrails, generateSecret as generateSecretCore } from \"@otplib/core\";\n\nimport { defaultCrypto, defaultBase32 } from \"./defaults.js\";\nimport {\n generate as functionalGenerate,\n generateSync as functionalGenerateSync,\n verify as functionalVerify,\n verifySync as functionalVerifySync,\n generateURI as functionalGenerateURI,\n} from \"./functional.js\";\n\nimport type { OTPStrategy } from \"./functional.js\";\nimport type {\n CryptoPlugin,\n Digits,\n HashAlgorithm,\n Base32Plugin,\n OTPGuardrails,\n OTPHooks,\n} from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\n/**\n * Combined verify result that works for both TOTP and HOTP\n */\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\n/**\n * Options for the OTP class\n */\nexport type OTPClassOptions = {\n /**\n * OTP strategy to use\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n */\n strategy?: OTPStrategy;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for generating a token with the OTP class\n */\nexport type OTPGenerateOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n\n /**\n * Hooks for customizing token encoding and validation\n */\n hooks?: OTPHooks;\n};\n\n/**\n * Options for verifying a token with the OTP class\n */\nexport type OTPVerifyOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * OTP code to verify\n */\n token: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Time tolerance in seconds for TOTP verification (default: 0)\n * - Number: symmetric tolerance (same for past and future)\n * - Tuple [past, future]: asymmetric tolerance\n * Use [5, 0] for RFC-compliant past-only verification.\n */\n epochTolerance?: number | [number, number];\n\n /**\n * Counter tolerance for HOTP verification (default: 0)\n * - Number: creates look-ahead only tolerance [0, n]\n * - Tuple [past, future]: explicit window control\n */\n counterTolerance?: number | [number, number];\n\n /**\n * Minimum allowed TOTP time step for replay protection (optional)\n *\n * Rejects tokens with timeStep <= afterTimeStep.\n * Only used by TOTP strategy.\n */\n afterTimeStep?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n\n /**\n * Hooks for customizing token encoding and validation\n */\n hooks?: OTPHooks;\n};\n\n/**\n * Options for generating URI with the OTP class\n */\nexport type OTPURIGenerateOptions = {\n /**\n * Issuer name (e.g., 'ACME Co')\n */\n issuer: string;\n\n /**\n * Label/Account name (e.g., 'john@example.com')\n */\n label: string;\n\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value (default: 0)\n * Used by HOTP strategy\n */\n counter?: number;\n};\n\n/**\n * OTP Class\n *\n * A wrapper class that dynamically handles TOTP and HOTP strategies.\n *\n * @example\n * ```ts\n * import { OTP } from 'otplib';\n *\n * // Create OTP instance with TOTP strategy (default)\n * const otp = new OTP({ strategy: 'totp' });\n *\n * // Generate and verify\n * const secret = otp.generateSecret();\n * const token = await otp.generate({ secret });\n * const result = await otp.verify({ secret, token });\n * ```\n *\n * @example With HOTP strategy\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'hotp' });\n * const token = await otp.generate({ secret: 'ABC123', counter: 0 });\n * ```\n *\n * @example Generating otpauth:// URI for authenticator apps\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'totp' });\n * const uri = otp.generateURI({\n * issuer: 'MyApp',\n * label: 'user@example.com',\n * secret: 'ABC123',\n * });\n * ```\n */\nexport class OTP {\n private readonly strategy: OTPStrategy;\n private readonly crypto: CryptoPlugin;\n private readonly base32: Base32Plugin;\n private readonly guardrails: OTPGuardrails;\n\n constructor(options: OTPClassOptions = {}) {\n const {\n strategy = \"totp\",\n crypto = defaultCrypto,\n base32 = defaultBase32,\n guardrails,\n } = options;\n\n this.strategy = strategy;\n this.crypto = crypto;\n this.base32 = base32;\n this.guardrails = createGuardrails(guardrails);\n }\n\n /**\n * Get the current strategy\n */\n getStrategy(): OTPStrategy {\n return this.strategy;\n }\n\n /**\n * Generate a random secret key\n *\n * @param length - Number of random bytes (default: 20)\n * @returns Base32-encoded secret key\n */\n generateSecret(length: number = 20): string {\n return generateSecretCore({ crypto: this.crypto, base32: this.base32, length });\n }\n\n /**\n * Generate an OTP token based on the configured strategy\n *\n * @param options - Generation options\n * @returns OTP code\n */\n async generate(options: OTPGenerateOptions): Promise<string> {\n return functionalGenerate({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an OTP token based on the configured strategy synchronously\n *\n * @param options - Generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n generateSync(options: OTPGenerateOptions): string {\n return functionalGenerateSync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n */\n async verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n return functionalVerify({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy synchronously\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n verifySync(options: OTPVerifyOptions): VerifyResult {\n return functionalVerifySync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an otpauth:// URI for QR code generation\n *\n * Supports both TOTP and HOTP strategies.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n */\n generateURI(options: OTPURIGenerateOptions): string {\n return functionalGenerateURI({\n ...options,\n strategy: this.strategy,\n });\n }\n}\n","/**\n * Default plugin instances\n *\n * Shared across functional and class APIs to ensure singleton behavior\n * and reduce memory overhead. Uses pre-instantiated frozen singletons\n * from the plugin packages.\n */\nimport { createGuardrails } from \"@otplib/core\";\nimport { base32 as defaultBase32 } from \"@otplib/plugin-base32-scure\";\nimport { crypto as defaultCrypto } from \"@otplib/plugin-crypto-noble\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPGenerateOptionsWithDefaults,\n OTPVerifyOptionsWithDefaults,\n} from \"./types.js\";\n\nexport { defaultCrypto, defaultBase32 };\n\nexport function normalizeGenerateOptions(\n options: OTPGenerateOptions,\n): OTPGenerateOptionsWithDefaults {\n return {\n secret: options.secret,\n strategy: options.strategy ?? \"totp\",\n crypto: options.crypto ?? defaultCrypto,\n base32: options.base32 ?? defaultBase32,\n algorithm: options.algorithm ?? \"sha1\",\n digits: options.digits ?? 6,\n period: options.period ?? 30,\n epoch: options.epoch ?? Math.floor(Date.now() / 1000),\n t0: options.t0 ?? 0,\n counter: options.counter,\n guardrails: options.guardrails ?? createGuardrails(),\n hooks: options.hooks,\n };\n}\n\nexport function normalizeVerifyOptions(options: OTPVerifyOptions): OTPVerifyOptionsWithDefaults {\n return {\n ...normalizeGenerateOptions(options),\n token: options.token,\n epochTolerance: options.epochTolerance ?? 0,\n counterTolerance: options.counterTolerance ?? 0,\n afterTimeStep: options.afterTimeStep,\n };\n}\n","import { generateSecret as generateSecretCore, ConfigurationError } from \"@otplib/core\";\nimport {\n generate as generateHOTP,\n generateSync as generateHOTPSync,\n verify as verifyHOTP,\n verifySync as verifyHOTPSync,\n} from \"@otplib/hotp\";\nimport {\n generate as generateTOTP,\n generateSync as generateTOTPSync,\n verify as verifyTOTP,\n verifySync as verifyTOTPSync,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI, generateHOTP as generateHOTURI } from \"@otplib/uri\";\n\nimport {\n defaultCrypto,\n defaultBase32,\n normalizeGenerateOptions,\n normalizeVerifyOptions,\n} from \"./defaults.js\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPStrategy,\n StrategyHandlers,\n} from \"./types.js\";\nimport type { CryptoPlugin, Base32Plugin, Digits, HashAlgorithm } from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\nexport type { OTPStrategy };\n\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\nfunction executeByStrategy<T>(\n strategy: OTPStrategy,\n counter: number | undefined,\n handlers: StrategyHandlers<T>,\n): T {\n if (strategy === \"totp\") {\n return handlers.totp();\n }\n if (strategy === \"hotp\") {\n if (counter === undefined) {\n throw new ConfigurationError(\n \"Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }\",\n );\n }\n return handlers.hotp(counter);\n }\n throw new ConfigurationError(\n `Unknown OTP strategy: ${strategy}. Valid strategies are 'totp' or 'hotp'.`,\n );\n}\n\n/**\n * Generate a random secret key for use with OTP\n *\n * The secret is encoded in Base32 format for compatibility with\n * Google Authenticator and other authenticator apps.\n *\n * @param options - Secret generation options\n * @returns Base32-encoded secret key\n *\n * @example\n * ```ts\n * import { generateSecret } from 'otplib';\n *\n * const secret = generateSecret();\n * // Returns: 'JBSWY3DPEHPK3PXP'\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generateSecret, NodeCryptoPlugin } from 'otplib';\n *\n * const secret = generateSecret({\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport function generateSecret(options?: {\n /**\n * Number of random bytes to generate (default: 20)\n * 20 bytes = 160 bits, which provides a good security margin\n */\n length?: number;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n}): string {\n const { crypto = defaultCrypto, base32 = defaultBase32, length = 20 } = options || {};\n\n return generateSecretCore({ crypto, base32, length });\n}\n\n/**\n * Generate an otpauth:// URI for QR code generation\n *\n * This URI can be used to generate a QR code that can be scanned\n * by Google Authenticator and other authenticator apps.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n *\n * @example TOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: 'otpauth://totp/ACME%20Co:john%40example.com?secret=...'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * strategy: 'hotp',\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * counter: 5,\n * });\n * // Returns: 'otpauth://hotp/ACME%20Co:john%40example.com?secret=...&counter=5'\n * ```\n */\nexport function generateURI(options: {\n /**\n * OTP strategy to use (default: 'totp')\n */\n strategy?: OTPStrategy;\n issuer: string;\n label: string;\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n algorithm?: HashAlgorithm;\n digits?: Digits;\n period?: number;\n counter?: number;\n}): string {\n const {\n strategy = \"totp\",\n issuer,\n label,\n secret,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n counter,\n } = options;\n\n return executeByStrategy(strategy, counter, {\n totp: () => generateTOTPURI({ issuer, label, secret, algorithm, digits, period }),\n hotp: (counter) => generateHOTURI({ issuer, label, secret, algorithm, digits, counter }),\n });\n}\n\n/**\n * Generate an OTP code\n *\n * Generates a one-time password based on the specified strategy.\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n *\n * @param options - OTP generation options\n * @returns OTP code\n *\n * @example TOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: '123456'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generate, NodeCryptoPlugin } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function generate(options: OTPGenerateOptions): Promise<string> {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTP({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Generate an OTP code synchronously\n *\n * This is the synchronous version of {@link generate}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { generateSync } from 'otplib';\n *\n * const token = generateSync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * ```\n */\nexport function generateSync(options: OTPGenerateOptions): string {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTPSync({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code\n *\n * Verifies a provided OTP code against the expected value based on the strategy.\n * - 'totp': Time-based OTP (default, Google Authenticator compatible)\n * - 'hotp': HMAC-based OTP\n *\n * Uses constant-time comparison to prevent timing attacks.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n *\n * @example TOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * // Returns: { valid: true, delta: 0 }\n * ```\n *\n * @example HOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With epochTolerance for TOTP\n * ```ts\n * import { verify, NodeCryptoPlugin } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * epochTolerance: 30,\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n afterTimeStep: opts.afterTimeStep,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTP({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code synchronously\n *\n * This is the synchronous version of {@link verify}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { verifySync } from 'otplib';\n *\n * const result = verifySync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * ```\n */\nexport function verifySync(options: OTPVerifyOptions): VerifyResult {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n afterTimeStep: opts.afterTimeStep,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTPSync({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n"],"mappings":"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","names":["class_exports","__export","OTP","__toCommonJS","import_core","import_core","import_plugin_base32_scure","import_plugin_crypto_noble","normalizeGenerateOptions","options","defaultCrypto","defaultBase32","normalizeVerifyOptions","import_core","import_hotp","import_totp","import_uri","executeByStrategy","strategy","counter","handlers","generateURI","options","strategy","issuer","label","secret","algorithm","digits","period","counter","executeByStrategy","generateTOTPURI","generateHOTURI","generate","opts","normalizeGenerateOptions","crypto","base32","hooks","commonOptions","generateTOTP","generateHOTP","generateSync","generateTOTPSync","generateHOTPSync","verify","normalizeVerifyOptions","token","verifyTOTP","verifyHOTP","verifySync","verifyTOTPSync","verifyHOTPSync","OTP","options","strategy","crypto","defaultCrypto","base32","defaultBase32","guardrails","length","generateSecretCore","generate","generateSync","verify","verifySync","generateURI"]}
package/dist/class.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as OTPStrategy } from './types-Bap9LCID.cjs';
2
- import { CryptoPlugin, Base32Plugin, OTPGuardrails, HashAlgorithm, Digits } from '@otplib/core';
1
+ import { b as OTPStrategy } from './types-BBT_82HF.cjs';
2
+ import { CryptoPlugin, Base32Plugin, OTPGuardrails, HashAlgorithm, Digits, OTPHooks } from '@otplib/core';
3
3
  import { VerifyResult as VerifyResult$2 } from '@otplib/hotp';
4
4
  import { VerifyResult as VerifyResult$1 } from '@otplib/totp';
5
5
 
@@ -79,6 +79,10 @@ type OTPGenerateOptions = {
79
79
  * Validation guardrails
80
80
  */
81
81
  guardrails?: OTPGuardrails;
82
+ /**
83
+ * Hooks for customizing token encoding and validation
84
+ */
85
+ hooks?: OTPHooks;
82
86
  };
83
87
  /**
84
88
  * Options for verifying a token with the OTP class
@@ -136,10 +140,21 @@ type OTPVerifyOptions = {
136
140
  * - Tuple [past, future]: explicit window control
137
141
  */
138
142
  counterTolerance?: number | [number, number];
143
+ /**
144
+ * Minimum allowed TOTP time step for replay protection (optional)
145
+ *
146
+ * Rejects tokens with timeStep <= afterTimeStep.
147
+ * Only used by TOTP strategy.
148
+ */
149
+ afterTimeStep?: number;
139
150
  /**
140
151
  * Validation guardrails
141
152
  */
142
153
  guardrails?: OTPGuardrails;
154
+ /**
155
+ * Hooks for customizing token encoding and validation
156
+ */
157
+ hooks?: OTPHooks;
143
158
  };
144
159
  /**
145
160
  * Options for generating URI with the OTP class
package/dist/class.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { c as OTPStrategy } from './types-Bap9LCID.js';
2
- import { CryptoPlugin, Base32Plugin, OTPGuardrails, HashAlgorithm, Digits } from '@otplib/core';
1
+ import { b as OTPStrategy } from './types-BBT_82HF.js';
2
+ import { CryptoPlugin, Base32Plugin, OTPGuardrails, HashAlgorithm, Digits, OTPHooks } from '@otplib/core';
3
3
  import { VerifyResult as VerifyResult$2 } from '@otplib/hotp';
4
4
  import { VerifyResult as VerifyResult$1 } from '@otplib/totp';
5
5
 
@@ -79,6 +79,10 @@ type OTPGenerateOptions = {
79
79
  * Validation guardrails
80
80
  */
81
81
  guardrails?: OTPGuardrails;
82
+ /**
83
+ * Hooks for customizing token encoding and validation
84
+ */
85
+ hooks?: OTPHooks;
82
86
  };
83
87
  /**
84
88
  * Options for verifying a token with the OTP class
@@ -136,10 +140,21 @@ type OTPVerifyOptions = {
136
140
  * - Tuple [past, future]: explicit window control
137
141
  */
138
142
  counterTolerance?: number | [number, number];
143
+ /**
144
+ * Minimum allowed TOTP time step for replay protection (optional)
145
+ *
146
+ * Rejects tokens with timeStep <= afterTimeStep.
147
+ * Only used by TOTP strategy.
148
+ */
149
+ afterTimeStep?: number;
139
150
  /**
140
151
  * Validation guardrails
141
152
  */
142
153
  guardrails?: OTPGuardrails;
154
+ /**
155
+ * Hooks for customizing token encoding and validation
156
+ */
157
+ hooks?: OTPHooks;
143
158
  };
144
159
  /**
145
160
  * Options for generating URI with the OTP class
package/dist/class.js CHANGED
@@ -1,2 +1,2 @@
1
- import{createGuardrails as A,generateSecret as I}from"@otplib/core";import{createGuardrails as S}from"@otplib/core";import{base32 as y}from"@otplib/plugin-base32-scure";import{crypto as c}from"@otplib/plugin-crypto-noble";function l(r){return{secret:r.secret,strategy:r.strategy??"totp",crypto:r.crypto??c,base32:r.base32??y,algorithm:r.algorithm??"sha1",digits:r.digits??6,period:r.period??30,epoch:r.epoch??Math.floor(Date.now()/1e3),t0:r.t0??0,counter:r.counter,guardrails:r.guardrails??S()}}function f(r){return{...l(r),token:r.token,epochTolerance:r.epochTolerance??0,counterTolerance:r.counterTolerance??0}}import{generateSecret as E,ConfigurationError as m}from"@otplib/core";import{generate as V,generateSync as R,verify as G,verifySync as x}from"@otplib/hotp";import{generate as H,generateSync as v,verify as C,verifySync as D}from"@otplib/totp";import{generateTOTP as U,generateHOTP as B}from"@otplib/uri";function u(r,e,t){if(r==="totp")return t.totp();if(r==="hotp"){if(e===void 0)throw new m("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return t.hotp(e)}throw new m(`Unknown OTP strategy: ${r}. Valid strategies are 'totp' or 'hotp'.`)}function O(r){let{strategy:e="totp",issuer:t,label:a,secret:i,algorithm:s="sha1",digits:p=6,period:o=30,counter:n}=r;return u(e,n,{totp:()=>U({issuer:t,label:a,secret:i,algorithm:s,digits:p,period:o}),hotp:g=>B({issuer:t,label:a,secret:i,algorithm:s,digits:p,counter:g})})}async function h(r){let e=l(r),{secret:t,crypto:a,base32:i,algorithm:s,digits:p}=e,o={secret:t,crypto:a,base32:i,algorithm:s,digits:p};return u(e.strategy,e.counter,{totp:()=>H({...o,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:n=>V({...o,counter:n,guardrails:e.guardrails})})}function d(r){let e=l(r),{secret:t,crypto:a,base32:i,algorithm:s,digits:p}=e,o={secret:t,crypto:a,base32:i,algorithm:s,digits:p};return u(e.strategy,e.counter,{totp:()=>v({...o,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:n=>R({...o,counter:n,guardrails:e.guardrails})})}async function T(r){let e=f(r),{secret:t,token:a,crypto:i,base32:s,algorithm:p,digits:o}=e,n={secret:t,token:a,crypto:i,base32:s,algorithm:p,digits:o};return u(e.strategy,e.counter,{totp:()=>C({...n,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,guardrails:e.guardrails}),hotp:g=>G({...n,counter:g,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}function P(r){let e=f(r),{secret:t,token:a,crypto:i,base32:s,algorithm:p,digits:o}=e,n={secret:t,token:a,crypto:i,base32:s,algorithm:p,digits:o};return u(e.strategy,e.counter,{totp:()=>D({...n,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,guardrails:e.guardrails}),hotp:g=>x({...n,counter:g,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}var b=class{strategy;crypto;base32;guardrails;constructor(e={}){let{strategy:t="totp",crypto:a=c,base32:i=y,guardrails:s}=e;this.strategy=t,this.crypto=a,this.base32=i,this.guardrails=A(s)}getStrategy(){return this.strategy}generateSecret(e=20){return I({crypto:this.crypto,base32:this.base32,length:e})}async generate(e){return h({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateSync(e){return d({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}async verify(e){return T({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}verifySync(e){return P({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateURI(e){return O({...e,strategy:this.strategy})}};export{b as OTP};
1
+ import{createGuardrails as A,generateSecret as I}from"@otplib/core";import{createGuardrails as V}from"@otplib/core";import{base32 as y}from"@otplib/plugin-base32-scure";import{crypto as c}from"@otplib/plugin-crypto-noble";function l(r){return{secret:r.secret,strategy:r.strategy??"totp",crypto:r.crypto??c,base32:r.base32??y,algorithm:r.algorithm??"sha1",digits:r.digits??6,period:r.period??30,epoch:r.epoch??Math.floor(Date.now()/1e3),t0:r.t0??0,counter:r.counter,guardrails:r.guardrails??V(),hooks:r.hooks}}function m(r){return{...l(r),token:r.token,epochTolerance:r.epochTolerance??0,counterTolerance:r.counterTolerance??0,afterTimeStep:r.afterTimeStep}}import{generateSecret as q,ConfigurationError as T}from"@otplib/core";import{generate as R,generateSync as G,verify as H,verifySync as x}from"@otplib/hotp";import{generate as v,generateSync as k,verify as C,verifySync as D}from"@otplib/totp";import{generateTOTP as U,generateHOTP as B}from"@otplib/uri";function u(r,e,t){if(r==="totp")return t.totp();if(r==="hotp"){if(e===void 0)throw new T("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return t.hotp(e)}throw new T(`Unknown OTP strategy: ${r}. Valid strategies are 'totp' or 'hotp'.`)}function h(r){let{strategy:e="totp",issuer:t,label:a,secret:i,algorithm:o="sha1",digits:s=6,period:n=30,counter:p}=r;return u(e,p,{totp:()=>U({issuer:t,label:a,secret:i,algorithm:o,digits:s,period:n}),hotp:g=>B({issuer:t,label:a,secret:i,algorithm:o,digits:s,counter:g})})}async function O(r){let e=l(r),{secret:t,crypto:a,base32:i,algorithm:o,digits:s,hooks:n}=e,p={secret:t,crypto:a,base32:i,algorithm:o,digits:s,hooks:n};return u(e.strategy,e.counter,{totp:()=>v({...p,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:g=>R({...p,counter:g,guardrails:e.guardrails})})}function d(r){let e=l(r),{secret:t,crypto:a,base32:i,algorithm:o,digits:s}=e,n={secret:t,crypto:a,base32:i,algorithm:o,digits:s};return u(e.strategy,e.counter,{totp:()=>k({...n,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:p=>G({...n,counter:p,guardrails:e.guardrails})})}async function P(r){let e=m(r),{secret:t,token:a,crypto:i,base32:o,algorithm:s,digits:n,hooks:p}=e,g={secret:t,token:a,crypto:i,base32:o,algorithm:s,digits:n,hooks:p};return u(e.strategy,e.counter,{totp:()=>C({...g,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:f=>H({...g,counter:f,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}function b(r){let e=m(r),{secret:t,token:a,crypto:i,base32:o,algorithm:s,digits:n,hooks:p}=e,g={secret:t,token:a,crypto:i,base32:o,algorithm:s,digits:n,hooks:p};return u(e.strategy,e.counter,{totp:()=>D({...g,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:f=>x({...g,counter:f,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}var S=class{strategy;crypto;base32;guardrails;constructor(e={}){let{strategy:t="totp",crypto:a=c,base32:i=y,guardrails:o}=e;this.strategy=t,this.crypto=a,this.base32=i,this.guardrails=A(o)}getStrategy(){return this.strategy}generateSecret(e=20){return I({crypto:this.crypto,base32:this.base32,length:e})}async generate(e){return O({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateSync(e){return d({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}async verify(e){return P({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}verifySync(e){return b({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32,guardrails:e.guardrails??this.guardrails})}generateURI(e){return h({...e,strategy:this.strategy})}};export{S as OTP};
2
2
  //# sourceMappingURL=class.js.map
package/dist/class.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/class.ts","../src/defaults.ts","../src/functional.ts"],"sourcesContent":["/**\n * OTP Wrapper Class\n *\n * A unified class that dynamically handles TOTP and HOTP strategies.\n */\n\nimport { createGuardrails, generateSecret as generateSecretCore } from \"@otplib/core\";\n\nimport { defaultCrypto, defaultBase32 } from \"./defaults.js\";\nimport {\n generate as functionalGenerate,\n generateSync as functionalGenerateSync,\n verify as functionalVerify,\n verifySync as functionalVerifySync,\n generateURI as functionalGenerateURI,\n} from \"./functional.js\";\n\nimport type { OTPStrategy } from \"./functional.js\";\nimport type {\n CryptoPlugin,\n Digits,\n HashAlgorithm,\n Base32Plugin,\n OTPGuardrails,\n} from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\n/**\n * Combined verify result that works for both TOTP and HOTP\n */\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\n/**\n * Options for the OTP class\n */\nexport type OTPClassOptions = {\n /**\n * OTP strategy to use\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n */\n strategy?: OTPStrategy;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for generating a token with the OTP class\n */\nexport type OTPGenerateOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for verifying a token with the OTP class\n */\nexport type OTPVerifyOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * OTP code to verify\n */\n token: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Time tolerance in seconds for TOTP verification (default: 0)\n * - Number: symmetric tolerance (same for past and future)\n * - Tuple [past, future]: asymmetric tolerance\n * Use [5, 0] for RFC-compliant past-only verification.\n */\n epochTolerance?: number | [number, number];\n\n /**\n * Counter tolerance for HOTP verification (default: 0)\n * - Number: creates look-ahead only tolerance [0, n]\n * - Tuple [past, future]: explicit window control\n */\n counterTolerance?: number | [number, number];\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for generating URI with the OTP class\n */\nexport type OTPURIGenerateOptions = {\n /**\n * Issuer name (e.g., 'ACME Co')\n */\n issuer: string;\n\n /**\n * Label/Account name (e.g., 'john@example.com')\n */\n label: string;\n\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value (default: 0)\n * Used by HOTP strategy\n */\n counter?: number;\n};\n\n/**\n * OTP Class\n *\n * A wrapper class that dynamically handles TOTP and HOTP strategies.\n *\n * @example\n * ```ts\n * import { OTP } from 'otplib';\n *\n * // Create OTP instance with TOTP strategy (default)\n * const otp = new OTP({ strategy: 'totp' });\n *\n * // Generate and verify\n * const secret = otp.generateSecret();\n * const token = await otp.generate({ secret });\n * const result = await otp.verify({ secret, token });\n * ```\n *\n * @example With HOTP strategy\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'hotp' });\n * const token = await otp.generate({ secret: 'ABC123', counter: 0 });\n * ```\n *\n * @example Generating otpauth:// URI for authenticator apps\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'totp' });\n * const uri = otp.generateURI({\n * issuer: 'MyApp',\n * label: 'user@example.com',\n * secret: 'ABC123',\n * });\n * ```\n */\nexport class OTP {\n private readonly strategy: OTPStrategy;\n private readonly crypto: CryptoPlugin;\n private readonly base32: Base32Plugin;\n private readonly guardrails: OTPGuardrails;\n\n constructor(options: OTPClassOptions = {}) {\n const {\n strategy = \"totp\",\n crypto = defaultCrypto,\n base32 = defaultBase32,\n guardrails,\n } = options;\n\n this.strategy = strategy;\n this.crypto = crypto;\n this.base32 = base32;\n this.guardrails = createGuardrails(guardrails);\n }\n\n /**\n * Get the current strategy\n */\n getStrategy(): OTPStrategy {\n return this.strategy;\n }\n\n /**\n * Generate a random secret key\n *\n * @param length - Number of random bytes (default: 20)\n * @returns Base32-encoded secret key\n */\n generateSecret(length: number = 20): string {\n return generateSecretCore({ crypto: this.crypto, base32: this.base32, length });\n }\n\n /**\n * Generate an OTP token based on the configured strategy\n *\n * @param options - Generation options\n * @returns OTP code\n */\n async generate(options: OTPGenerateOptions): Promise<string> {\n return functionalGenerate({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an OTP token based on the configured strategy synchronously\n *\n * @param options - Generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n generateSync(options: OTPGenerateOptions): string {\n return functionalGenerateSync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n */\n async verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n return functionalVerify({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy synchronously\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n verifySync(options: OTPVerifyOptions): VerifyResult {\n return functionalVerifySync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an otpauth:// URI for QR code generation\n *\n * Supports both TOTP and HOTP strategies.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n */\n generateURI(options: OTPURIGenerateOptions): string {\n return functionalGenerateURI({\n ...options,\n strategy: this.strategy,\n });\n }\n}\n","/**\n * Default plugin instances\n *\n * Shared across functional and class APIs to ensure singleton behavior\n * and reduce memory overhead. Uses pre-instantiated frozen singletons\n * from the plugin packages.\n */\nimport { createGuardrails } from \"@otplib/core\";\nimport { base32 as defaultBase32 } from \"@otplib/plugin-base32-scure\";\nimport { crypto as defaultCrypto } from \"@otplib/plugin-crypto-noble\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPGenerateOptionsWithDefaults,\n OTPVerifyOptionsWithDefaults,\n} from \"./types.js\";\n\nexport { defaultCrypto, defaultBase32 };\n\nexport function normalizeGenerateOptions(\n options: OTPGenerateOptions,\n): OTPGenerateOptionsWithDefaults {\n return {\n secret: options.secret,\n strategy: options.strategy ?? \"totp\",\n crypto: options.crypto ?? defaultCrypto,\n base32: options.base32 ?? defaultBase32,\n algorithm: options.algorithm ?? \"sha1\",\n digits: options.digits ?? 6,\n period: options.period ?? 30,\n epoch: options.epoch ?? Math.floor(Date.now() / 1000),\n t0: options.t0 ?? 0,\n counter: options.counter,\n guardrails: options.guardrails ?? createGuardrails(),\n };\n}\n\nexport function normalizeVerifyOptions(options: OTPVerifyOptions): OTPVerifyOptionsWithDefaults {\n return {\n ...normalizeGenerateOptions(options),\n token: options.token,\n epochTolerance: options.epochTolerance ?? 0,\n counterTolerance: options.counterTolerance ?? 0,\n };\n}\n","import { generateSecret as generateSecretCore, ConfigurationError } from \"@otplib/core\";\nimport {\n generate as generateHOTP,\n generateSync as generateHOTPSync,\n verify as verifyHOTP,\n verifySync as verifyHOTPSync,\n} from \"@otplib/hotp\";\nimport {\n generate as generateTOTP,\n generateSync as generateTOTPSync,\n verify as verifyTOTP,\n verifySync as verifyTOTPSync,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI, generateHOTP as generateHOTURI } from \"@otplib/uri\";\n\nimport {\n defaultCrypto,\n defaultBase32,\n normalizeGenerateOptions,\n normalizeVerifyOptions,\n} from \"./defaults.js\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPStrategy,\n StrategyHandlers,\n} from \"./types.js\";\nimport type { CryptoPlugin, Base32Plugin, Digits, HashAlgorithm } from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\nexport type { OTPStrategy };\n\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\nfunction executeByStrategy<T>(\n strategy: OTPStrategy,\n counter: number | undefined,\n handlers: StrategyHandlers<T>,\n): T {\n if (strategy === \"totp\") {\n return handlers.totp();\n }\n if (strategy === \"hotp\") {\n if (counter === undefined) {\n throw new ConfigurationError(\n \"Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }\",\n );\n }\n return handlers.hotp(counter);\n }\n throw new ConfigurationError(\n `Unknown OTP strategy: ${strategy}. Valid strategies are 'totp' or 'hotp'.`,\n );\n}\n\n/**\n * Generate a random secret key for use with OTP\n *\n * The secret is encoded in Base32 format for compatibility with\n * Google Authenticator and other authenticator apps.\n *\n * @param options - Secret generation options\n * @returns Base32-encoded secret key\n *\n * @example\n * ```ts\n * import { generateSecret } from 'otplib';\n *\n * const secret = generateSecret();\n * // Returns: 'JBSWY3DPEHPK3PXP'\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generateSecret, NodeCryptoPlugin } from 'otplib';\n *\n * const secret = generateSecret({\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport function generateSecret(options?: {\n /**\n * Number of random bytes to generate (default: 20)\n * 20 bytes = 160 bits, which provides a good security margin\n */\n length?: number;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n}): string {\n const { crypto = defaultCrypto, base32 = defaultBase32, length = 20 } = options || {};\n\n return generateSecretCore({ crypto, base32, length });\n}\n\n/**\n * Generate an otpauth:// URI for QR code generation\n *\n * This URI can be used to generate a QR code that can be scanned\n * by Google Authenticator and other authenticator apps.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n *\n * @example TOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: 'otpauth://totp/ACME%20Co:john%40example.com?secret=...'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * strategy: 'hotp',\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * counter: 5,\n * });\n * // Returns: 'otpauth://hotp/ACME%20Co:john%40example.com?secret=...&counter=5'\n * ```\n */\nexport function generateURI(options: {\n /**\n * OTP strategy to use (default: 'totp')\n */\n strategy?: OTPStrategy;\n issuer: string;\n label: string;\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n algorithm?: HashAlgorithm;\n digits?: Digits;\n period?: number;\n counter?: number;\n}): string {\n const {\n strategy = \"totp\",\n issuer,\n label,\n secret,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n counter,\n } = options;\n\n return executeByStrategy(strategy, counter, {\n totp: () => generateTOTPURI({ issuer, label, secret, algorithm, digits, period }),\n hotp: (counter) => generateHOTURI({ issuer, label, secret, algorithm, digits, counter }),\n });\n}\n\n/**\n * Generate an OTP code\n *\n * Generates a one-time password based on the specified strategy.\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n *\n * @param options - OTP generation options\n * @returns OTP code\n *\n * @example TOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: '123456'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generate, NodeCryptoPlugin } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function generate(options: OTPGenerateOptions): Promise<string> {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTP({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Generate an OTP code synchronously\n *\n * This is the synchronous version of {@link generate}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { generateSync } from 'otplib';\n *\n * const token = generateSync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * ```\n */\nexport function generateSync(options: OTPGenerateOptions): string {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTPSync({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code\n *\n * Verifies a provided OTP code against the expected value based on the strategy.\n * - 'totp': Time-based OTP (default, Google Authenticator compatible)\n * - 'hotp': HMAC-based OTP\n *\n * Uses constant-time comparison to prevent timing attacks.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n *\n * @example TOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * // Returns: { valid: true, delta: 0 }\n * ```\n *\n * @example HOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With epochTolerance for TOTP\n * ```ts\n * import { verify, NodeCryptoPlugin } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * epochTolerance: 30,\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTP({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code synchronously\n *\n * This is the synchronous version of {@link verify}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { verifySync } from 'otplib';\n *\n * const result = verifySync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * ```\n */\nexport function verifySync(options: OTPVerifyOptions): VerifyResult {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTPSync({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n"],"mappings":"AAMA,OAAS,oBAAAA,EAAkB,kBAAkBC,MAA0B,eCCvE,OAAS,oBAAAC,MAAwB,eACjC,OAAS,UAAUC,MAAqB,8BACxC,OAAS,UAAUC,MAAqB,8BAWjC,SAASC,EACdC,EACgC,CAChC,MAAO,CACL,OAAQA,EAAQ,OAChB,SAAUA,EAAQ,UAAY,OAC9B,OAAQA,EAAQ,QAAUC,EAC1B,OAAQD,EAAQ,QAAUE,EAC1B,UAAWF,EAAQ,WAAa,OAChC,OAAQA,EAAQ,QAAU,EAC1B,OAAQA,EAAQ,QAAU,GAC1B,MAAOA,EAAQ,OAAS,KAAK,MAAM,KAAK,IAAI,EAAI,GAAI,EACpD,GAAIA,EAAQ,IAAM,EAClB,QAASA,EAAQ,QACjB,WAAYA,EAAQ,YAAcG,EAAiB,CACrD,CACF,CAEO,SAASC,EAAuBJ,EAAyD,CAC9F,MAAO,CACL,GAAGD,EAAyBC,CAAO,EACnC,MAAOA,EAAQ,MACf,eAAgBA,EAAQ,gBAAkB,EAC1C,iBAAkBA,EAAQ,kBAAoB,CAChD,CACF,CC7CA,OAAS,kBAAkBK,EAAoB,sBAAAC,MAA0B,eACzE,OACE,YAAYC,EACZ,gBAAgBC,EAChB,UAAUC,EACV,cAAcC,MACT,eACP,OACE,YAAYC,EACZ,gBAAgBC,EAChB,UAAUC,EACV,cAAcC,MACT,eACP,OAAS,gBAAgBC,EAAiB,gBAAgBC,MAAsB,cAuBhF,SAASC,EACPC,EACAC,EACAC,EACG,CACH,GAAIF,IAAa,OACf,OAAOE,EAAS,KAAK,EAEvB,GAAIF,IAAa,OAAQ,CACvB,GAAIC,IAAY,OACd,MAAM,IAAIE,EACR,kFACF,EAEF,OAAOD,EAAS,KAAKD,CAAO,CAC9B,CACA,MAAM,IAAIE,EACR,yBAAyBH,CAAQ,0CACnC,CACF,CAqFO,SAASI,EAAYC,EAkBjB,CACT,GAAM,CACJ,SAAAC,EAAW,OACX,OAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EAAY,OACZ,OAAAC,EAAS,EACT,OAAAC,EAAS,GACT,QAAAC,CACF,EAAIR,EAEJ,OAAOS,EAAkBR,EAAUO,EAAS,CAC1C,KAAM,IAAME,EAAgB,CAAE,OAAAR,EAAQ,MAAAC,EAAO,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,OAAAC,CAAO,CAAC,EAChF,KAAOC,GAAYG,EAAe,CAAE,OAAAT,EAAQ,MAAAC,EAAO,OAAAC,EAAQ,UAAAC,EAAW,OAAAC,EAAQ,QAAAE,CAAQ,CAAC,CACzF,CAAC,CACH,CA2CA,eAAsBI,EAASZ,EAA8C,CAC3E,IAAMa,EAAOC,EAAyBd,CAAO,EACvC,CAAE,OAAAI,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EAChDI,EAAgB,CAAE,OAAAb,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAElE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJK,EAAa,CACX,GAAGD,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,GACLW,EAAa,CACX,GAAGF,EACH,QAAAT,EACA,WAAYK,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAqBO,SAASO,EAAapB,EAAqC,CAChE,IAAMa,EAAOC,EAAyBd,CAAO,EACvC,CAAE,OAAAI,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EAChDI,EAAgB,CAAE,OAAAb,EAAQ,OAAAW,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAElE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJQ,EAAiB,CACf,GAAGJ,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,GACLc,EAAiB,CACf,GAAGL,EACH,QAAAT,EACA,WAAYK,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAiDA,eAAsBU,EAAOvB,EAAkD,CAC7E,IAAMa,EAAOW,EAAuBxB,CAAO,EACrC,CAAE,OAAAI,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EACvDI,EAAgB,CAAE,OAAAb,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAEzE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJa,EAAW,CACT,GAAGT,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,eAAgBA,EAAK,eACrB,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,GACLmB,EAAW,CACT,GAAGV,EACH,QAAAT,EACA,iBAAkBK,EAAK,iBACvB,WAAYA,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CAsBO,SAASe,EAAW5B,EAAyC,CAClE,IAAMa,EAAOW,EAAuBxB,CAAO,EACrC,CAAE,OAAAI,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAAIO,EACvDI,EAAgB,CAAE,OAAAb,EAAQ,MAAAqB,EAAO,OAAAV,EAAQ,OAAAC,EAAQ,UAAAX,EAAW,OAAAC,CAAO,EAEzE,OAAOG,EAAkBI,EAAK,SAAUA,EAAK,QAAS,CACpD,KAAM,IACJgB,EAAe,CACb,GAAGZ,EACH,OAAQJ,EAAK,OACb,MAAOA,EAAK,MACZ,GAAIA,EAAK,GACT,eAAgBA,EAAK,eACrB,WAAYA,EAAK,UACnB,CAAC,EACH,KAAOL,GACLsB,EAAe,CACb,GAAGb,EACH,QAAAT,EACA,iBAAkBK,EAAK,iBACvB,WAAYA,EAAK,UACnB,CAAC,CACL,CAAC,CACH,CFlIO,IAAMkB,EAAN,KAAU,CACE,SACA,OACA,OACA,WAEjB,YAAYC,EAA2B,CAAC,EAAG,CACzC,GAAM,CACJ,SAAAC,EAAW,OACX,OAAAC,EAASC,EACT,OAAAC,EAASC,EACT,WAAAC,CACF,EAAIN,EAEJ,KAAK,SAAWC,EAChB,KAAK,OAASC,EACd,KAAK,OAASE,EACd,KAAK,WAAaG,EAAiBD,CAAU,CAC/C,CAKA,aAA2B,CACzB,OAAO,KAAK,QACd,CAQA,eAAeE,EAAiB,GAAY,CAC1C,OAAOC,EAAmB,CAAE,OAAQ,KAAK,OAAQ,OAAQ,KAAK,OAAQ,OAAAD,CAAO,CAAC,CAChF,CAQA,MAAM,SAASR,EAA8C,CAC3D,OAAOU,EAAmB,CACxB,GAAGV,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CASA,aAAaA,EAAqC,CAChD,OAAOW,EAAuB,CAC5B,GAAGX,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CAQA,MAAM,OAAOA,EAAkD,CAC7D,OAAOY,EAAiB,CACtB,GAAGZ,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CASA,WAAWA,EAAyC,CAClD,OAAOa,EAAqB,CAC1B,GAAGb,EACH,SAAU,KAAK,SACf,OAAQ,KAAK,OACb,OAAQ,KAAK,OACb,WAAYA,EAAQ,YAAc,KAAK,UACzC,CAAC,CACH,CAUA,YAAYA,EAAwC,CAClD,OAAOc,EAAsB,CAC3B,GAAGd,EACH,SAAU,KAAK,QACjB,CAAC,CACH,CACF","names":["createGuardrails","generateSecretCore","createGuardrails","defaultBase32","defaultCrypto","normalizeGenerateOptions","options","defaultCrypto","defaultBase32","createGuardrails","normalizeVerifyOptions","generateSecretCore","ConfigurationError","generateHOTP","generateHOTPSync","verifyHOTP","verifyHOTPSync","generateTOTP","generateTOTPSync","verifyTOTP","verifyTOTPSync","generateTOTPURI","generateHOTURI","executeByStrategy","strategy","counter","handlers","ConfigurationError","generateURI","options","strategy","issuer","label","secret","algorithm","digits","period","counter","executeByStrategy","generateTOTPURI","generateHOTURI","generate","opts","normalizeGenerateOptions","crypto","base32","commonOptions","generateTOTP","generateHOTP","generateSync","generateTOTPSync","generateHOTPSync","verify","normalizeVerifyOptions","token","verifyTOTP","verifyHOTP","verifySync","verifyTOTPSync","verifyHOTPSync","OTP","options","strategy","crypto","defaultCrypto","base32","defaultBase32","guardrails","createGuardrails","length","generateSecretCore","generate","generateSync","verify","verifySync","generateURI"]}
1
+ {"version":3,"sources":["../src/class.ts","../src/defaults.ts","../src/functional.ts"],"sourcesContent":["/**\n * OTP Wrapper Class\n *\n * A unified class that dynamically handles TOTP and HOTP strategies.\n */\n\nimport { createGuardrails, generateSecret as generateSecretCore } from \"@otplib/core\";\n\nimport { defaultCrypto, defaultBase32 } from \"./defaults.js\";\nimport {\n generate as functionalGenerate,\n generateSync as functionalGenerateSync,\n verify as functionalVerify,\n verifySync as functionalVerifySync,\n generateURI as functionalGenerateURI,\n} from \"./functional.js\";\n\nimport type { OTPStrategy } from \"./functional.js\";\nimport type {\n CryptoPlugin,\n Digits,\n HashAlgorithm,\n Base32Plugin,\n OTPGuardrails,\n OTPHooks,\n} from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\n/**\n * Combined verify result that works for both TOTP and HOTP\n */\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\n/**\n * Options for the OTP class\n */\nexport type OTPClassOptions = {\n /**\n * OTP strategy to use\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n */\n strategy?: OTPStrategy;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n};\n\n/**\n * Options for generating a token with the OTP class\n */\nexport type OTPGenerateOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n\n /**\n * Hooks for customizing token encoding and validation\n */\n hooks?: OTPHooks;\n};\n\n/**\n * Options for verifying a token with the OTP class\n */\nexport type OTPVerifyOptions = {\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string | Uint8Array;\n\n /**\n * OTP code to verify\n */\n token: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Current Unix epoch timestamp in seconds (default: now)\n * Used by TOTP strategy\n */\n epoch?: number;\n\n /**\n * Initial Unix time to start counting time steps (default: 0)\n * Used by TOTP strategy\n */\n t0?: number;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value\n * Used by HOTP strategy (required)\n */\n counter?: number;\n\n /**\n * Time tolerance in seconds for TOTP verification (default: 0)\n * - Number: symmetric tolerance (same for past and future)\n * - Tuple [past, future]: asymmetric tolerance\n * Use [5, 0] for RFC-compliant past-only verification.\n */\n epochTolerance?: number | [number, number];\n\n /**\n * Counter tolerance for HOTP verification (default: 0)\n * - Number: creates look-ahead only tolerance [0, n]\n * - Tuple [past, future]: explicit window control\n */\n counterTolerance?: number | [number, number];\n\n /**\n * Minimum allowed TOTP time step for replay protection (optional)\n *\n * Rejects tokens with timeStep <= afterTimeStep.\n * Only used by TOTP strategy.\n */\n afterTimeStep?: number;\n\n /**\n * Validation guardrails\n */\n guardrails?: OTPGuardrails;\n\n /**\n * Hooks for customizing token encoding and validation\n */\n hooks?: OTPHooks;\n};\n\n/**\n * Options for generating URI with the OTP class\n */\nexport type OTPURIGenerateOptions = {\n /**\n * Issuer name (e.g., 'ACME Co')\n */\n issuer: string;\n\n /**\n * Label/Account name (e.g., 'john@example.com')\n */\n label: string;\n\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n\n /**\n * Hash algorithm (default: 'sha1')\n */\n algorithm?: HashAlgorithm;\n\n /**\n * Number of digits (default: 6)\n */\n digits?: Digits;\n\n /**\n * Time step in seconds (default: 30)\n * Used by TOTP strategy\n */\n period?: number;\n\n /**\n * Counter value (default: 0)\n * Used by HOTP strategy\n */\n counter?: number;\n};\n\n/**\n * OTP Class\n *\n * A wrapper class that dynamically handles TOTP and HOTP strategies.\n *\n * @example\n * ```ts\n * import { OTP } from 'otplib';\n *\n * // Create OTP instance with TOTP strategy (default)\n * const otp = new OTP({ strategy: 'totp' });\n *\n * // Generate and verify\n * const secret = otp.generateSecret();\n * const token = await otp.generate({ secret });\n * const result = await otp.verify({ secret, token });\n * ```\n *\n * @example With HOTP strategy\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'hotp' });\n * const token = await otp.generate({ secret: 'ABC123', counter: 0 });\n * ```\n *\n * @example Generating otpauth:// URI for authenticator apps\n * ```ts\n * import { OTP } from 'otplib';\n *\n * const otp = new OTP({ strategy: 'totp' });\n * const uri = otp.generateURI({\n * issuer: 'MyApp',\n * label: 'user@example.com',\n * secret: 'ABC123',\n * });\n * ```\n */\nexport class OTP {\n private readonly strategy: OTPStrategy;\n private readonly crypto: CryptoPlugin;\n private readonly base32: Base32Plugin;\n private readonly guardrails: OTPGuardrails;\n\n constructor(options: OTPClassOptions = {}) {\n const {\n strategy = \"totp\",\n crypto = defaultCrypto,\n base32 = defaultBase32,\n guardrails,\n } = options;\n\n this.strategy = strategy;\n this.crypto = crypto;\n this.base32 = base32;\n this.guardrails = createGuardrails(guardrails);\n }\n\n /**\n * Get the current strategy\n */\n getStrategy(): OTPStrategy {\n return this.strategy;\n }\n\n /**\n * Generate a random secret key\n *\n * @param length - Number of random bytes (default: 20)\n * @returns Base32-encoded secret key\n */\n generateSecret(length: number = 20): string {\n return generateSecretCore({ crypto: this.crypto, base32: this.base32, length });\n }\n\n /**\n * Generate an OTP token based on the configured strategy\n *\n * @param options - Generation options\n * @returns OTP code\n */\n async generate(options: OTPGenerateOptions): Promise<string> {\n return functionalGenerate({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an OTP token based on the configured strategy synchronously\n *\n * @param options - Generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n generateSync(options: OTPGenerateOptions): string {\n return functionalGenerateSync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n */\n async verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n return functionalVerify({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Verify an OTP token based on the configured strategy synchronously\n *\n * @param options - Verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n */\n verifySync(options: OTPVerifyOptions): VerifyResult {\n return functionalVerifySync({\n ...options,\n strategy: this.strategy,\n crypto: this.crypto,\n base32: this.base32,\n guardrails: options.guardrails ?? this.guardrails,\n });\n }\n\n /**\n * Generate an otpauth:// URI for QR code generation\n *\n * Supports both TOTP and HOTP strategies.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n */\n generateURI(options: OTPURIGenerateOptions): string {\n return functionalGenerateURI({\n ...options,\n strategy: this.strategy,\n });\n }\n}\n","/**\n * Default plugin instances\n *\n * Shared across functional and class APIs to ensure singleton behavior\n * and reduce memory overhead. Uses pre-instantiated frozen singletons\n * from the plugin packages.\n */\nimport { createGuardrails } from \"@otplib/core\";\nimport { base32 as defaultBase32 } from \"@otplib/plugin-base32-scure\";\nimport { crypto as defaultCrypto } from \"@otplib/plugin-crypto-noble\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPGenerateOptionsWithDefaults,\n OTPVerifyOptionsWithDefaults,\n} from \"./types.js\";\n\nexport { defaultCrypto, defaultBase32 };\n\nexport function normalizeGenerateOptions(\n options: OTPGenerateOptions,\n): OTPGenerateOptionsWithDefaults {\n return {\n secret: options.secret,\n strategy: options.strategy ?? \"totp\",\n crypto: options.crypto ?? defaultCrypto,\n base32: options.base32 ?? defaultBase32,\n algorithm: options.algorithm ?? \"sha1\",\n digits: options.digits ?? 6,\n period: options.period ?? 30,\n epoch: options.epoch ?? Math.floor(Date.now() / 1000),\n t0: options.t0 ?? 0,\n counter: options.counter,\n guardrails: options.guardrails ?? createGuardrails(),\n hooks: options.hooks,\n };\n}\n\nexport function normalizeVerifyOptions(options: OTPVerifyOptions): OTPVerifyOptionsWithDefaults {\n return {\n ...normalizeGenerateOptions(options),\n token: options.token,\n epochTolerance: options.epochTolerance ?? 0,\n counterTolerance: options.counterTolerance ?? 0,\n afterTimeStep: options.afterTimeStep,\n };\n}\n","import { generateSecret as generateSecretCore, ConfigurationError } from \"@otplib/core\";\nimport {\n generate as generateHOTP,\n generateSync as generateHOTPSync,\n verify as verifyHOTP,\n verifySync as verifyHOTPSync,\n} from \"@otplib/hotp\";\nimport {\n generate as generateTOTP,\n generateSync as generateTOTPSync,\n verify as verifyTOTP,\n verifySync as verifyTOTPSync,\n} from \"@otplib/totp\";\nimport { generateTOTP as generateTOTPURI, generateHOTP as generateHOTURI } from \"@otplib/uri\";\n\nimport {\n defaultCrypto,\n defaultBase32,\n normalizeGenerateOptions,\n normalizeVerifyOptions,\n} from \"./defaults.js\";\n\nimport type {\n OTPGenerateOptions,\n OTPVerifyOptions,\n OTPStrategy,\n StrategyHandlers,\n} from \"./types.js\";\nimport type { CryptoPlugin, Base32Plugin, Digits, HashAlgorithm } from \"@otplib/core\";\nimport type { VerifyResult as HOTPVerifyResult } from \"@otplib/hotp\";\nimport type { VerifyResult as TOTPVerifyResult } from \"@otplib/totp\";\n\nexport type { OTPStrategy };\n\nexport type VerifyResult = TOTPVerifyResult | HOTPVerifyResult;\n\nfunction executeByStrategy<T>(\n strategy: OTPStrategy,\n counter: number | undefined,\n handlers: StrategyHandlers<T>,\n): T {\n if (strategy === \"totp\") {\n return handlers.totp();\n }\n if (strategy === \"hotp\") {\n if (counter === undefined) {\n throw new ConfigurationError(\n \"Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }\",\n );\n }\n return handlers.hotp(counter);\n }\n throw new ConfigurationError(\n `Unknown OTP strategy: ${strategy}. Valid strategies are 'totp' or 'hotp'.`,\n );\n}\n\n/**\n * Generate a random secret key for use with OTP\n *\n * The secret is encoded in Base32 format for compatibility with\n * Google Authenticator and other authenticator apps.\n *\n * @param options - Secret generation options\n * @returns Base32-encoded secret key\n *\n * @example\n * ```ts\n * import { generateSecret } from 'otplib';\n *\n * const secret = generateSecret();\n * // Returns: 'JBSWY3DPEHPK3PXP'\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generateSecret, NodeCryptoPlugin } from 'otplib';\n *\n * const secret = generateSecret({\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport function generateSecret(options?: {\n /**\n * Number of random bytes to generate (default: 20)\n * 20 bytes = 160 bits, which provides a good security margin\n */\n length?: number;\n\n /**\n * Crypto plugin to use (default: NobleCryptoPlugin)\n */\n crypto?: CryptoPlugin;\n\n /**\n * Base32 plugin to use (default: ScureBase32Plugin)\n */\n base32?: Base32Plugin;\n}): string {\n const { crypto = defaultCrypto, base32 = defaultBase32, length = 20 } = options || {};\n\n return generateSecretCore({ crypto, base32, length });\n}\n\n/**\n * Generate an otpauth:// URI for QR code generation\n *\n * This URI can be used to generate a QR code that can be scanned\n * by Google Authenticator and other authenticator apps.\n *\n * @param options - URI generation options\n * @returns otpauth:// URI string\n *\n * @example TOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: 'otpauth://totp/ACME%20Co:john%40example.com?secret=...'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generateURI } from 'otplib';\n *\n * const uri = generateURI({\n * strategy: 'hotp',\n * issuer: 'ACME Co',\n * label: 'john@example.com',\n * secret: 'JBSWY3DPEHPK3PXP',\n * counter: 5,\n * });\n * // Returns: 'otpauth://hotp/ACME%20Co:john%40example.com?secret=...&counter=5'\n * ```\n */\nexport function generateURI(options: {\n /**\n * OTP strategy to use (default: 'totp')\n */\n strategy?: OTPStrategy;\n issuer: string;\n label: string;\n /**\n * Base32-encoded secret key\n *\n * **Note**: By default, strings are assumed to be Base32 encoded.\n * If you have a raw string/passphrase, you must convert it to Uint8Array first.\n */\n secret: string;\n algorithm?: HashAlgorithm;\n digits?: Digits;\n period?: number;\n counter?: number;\n}): string {\n const {\n strategy = \"totp\",\n issuer,\n label,\n secret,\n algorithm = \"sha1\",\n digits = 6,\n period = 30,\n counter,\n } = options;\n\n return executeByStrategy(strategy, counter, {\n totp: () => generateTOTPURI({ issuer, label, secret, algorithm, digits, period }),\n hotp: (counter) => generateHOTURI({ issuer, label, secret, algorithm, digits, counter }),\n });\n}\n\n/**\n * Generate an OTP code\n *\n * Generates a one-time password based on the specified strategy.\n * - 'totp': Time-based OTP (default)\n * - 'hotp': HMAC-based OTP\n *\n * @param options - OTP generation options\n * @returns OTP code\n *\n * @example TOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * // Returns: '123456'\n * ```\n *\n * @example HOTP\n * ```ts\n * import { generate } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With custom plugins\n * ```ts\n * import { generate, NodeCryptoPlugin } from 'otplib';\n *\n * const token = await generate({\n * secret: 'JBSWY3DPEHPK3PXP',\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function generate(options: OTPGenerateOptions): Promise<string> {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTP({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Generate an OTP code synchronously\n *\n * This is the synchronous version of {@link generate}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP generation options\n * @returns OTP code\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { generateSync } from 'otplib';\n *\n * const token = generateSync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * });\n * ```\n */\nexport function generateSync(options: OTPGenerateOptions): string {\n const opts = normalizeGenerateOptions(options);\n const { secret, crypto, base32, algorithm, digits } = opts;\n const commonOptions = { secret, crypto, base32, algorithm, digits };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n generateTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n generateHOTPSync({\n ...commonOptions,\n counter,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code\n *\n * Verifies a provided OTP code against the expected value based on the strategy.\n * - 'totp': Time-based OTP (default, Google Authenticator compatible)\n * - 'hotp': HMAC-based OTP\n *\n * Uses constant-time comparison to prevent timing attacks.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n *\n * @example TOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * // Returns: { valid: true, delta: 0 }\n * ```\n *\n * @example HOTP\n * ```ts\n * import { verify } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * strategy: 'hotp',\n * counter: 0,\n * });\n * ```\n *\n * @example With epochTolerance for TOTP\n * ```ts\n * import { verify, NodeCryptoPlugin } from 'otplib';\n *\n * const result = await verify({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * epochTolerance: 30,\n * crypto: new NodeCryptoPlugin(),\n * });\n * ```\n */\nexport async function verify(options: OTPVerifyOptions): Promise<VerifyResult> {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTP({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n afterTimeStep: opts.afterTimeStep,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTP({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n\n/**\n * Verify an OTP code synchronously\n *\n * This is the synchronous version of {@link verify}. It requires a crypto\n * plugin that supports synchronous HMAC operations.\n *\n * @param options - OTP verification options\n * @returns Verification result with validity and optional delta\n * @throws {HMACError} If the crypto plugin doesn't support sync operations\n *\n * @example\n * ```ts\n * import { verifySync } from 'otplib';\n *\n * const result = verifySync({\n * secret: 'JBSWY3DPEHPK3PXP',\n * token: '123456',\n * });\n * ```\n */\nexport function verifySync(options: OTPVerifyOptions): VerifyResult {\n const opts = normalizeVerifyOptions(options);\n const { secret, token, crypto, base32, algorithm, digits, hooks } = opts;\n const commonOptions = { secret, token, crypto, base32, algorithm, digits, hooks };\n\n return executeByStrategy(opts.strategy, opts.counter, {\n totp: () =>\n verifyTOTPSync({\n ...commonOptions,\n period: opts.period,\n epoch: opts.epoch,\n t0: opts.t0,\n epochTolerance: opts.epochTolerance,\n afterTimeStep: opts.afterTimeStep,\n guardrails: opts.guardrails,\n }),\n hotp: (counter) =>\n verifyHOTPSync({\n ...commonOptions,\n counter,\n counterTolerance: opts.counterTolerance,\n guardrails: opts.guardrails,\n }),\n });\n}\n"],"mappings":"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","names":["createGuardrails","generateSecretCore","createGuardrails","defaultBase32","defaultCrypto","normalizeGenerateOptions","options","defaultCrypto","defaultBase32","createGuardrails","normalizeVerifyOptions","generateSecretCore","ConfigurationError","generateHOTP","generateHOTPSync","verifyHOTP","verifyHOTPSync","generateTOTP","generateTOTPSync","verifyTOTP","verifyTOTPSync","generateTOTPURI","generateHOTURI","executeByStrategy","strategy","counter","handlers","ConfigurationError","generateURI","options","strategy","issuer","label","secret","algorithm","digits","period","counter","executeByStrategy","generateTOTPURI","generateHOTURI","generate","opts","normalizeGenerateOptions","crypto","base32","hooks","commonOptions","generateTOTP","generateHOTP","generateSync","generateTOTPSync","generateHOTPSync","verify","normalizeVerifyOptions","token","verifyTOTP","verifyHOTP","verifySync","verifyTOTPSync","verifyHOTPSync","OTP","options","strategy","crypto","defaultCrypto","base32","defaultBase32","guardrails","createGuardrails","length","generateSecretCore","generate","generateSync","verify","verifySync","generateURI"]}
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var x=(t,e)=>{for(var r in e)d(t,r,{get:e[r],enumerable:!0})},H=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of V(e))!b.call(t,o)&&o!==r&&d(t,o,{get:()=>e[o],enumerable:!(n=S(e,o))||n.enumerable});return t};var R=t=>H(d({},"__esModule",{value:!0}),t);var B={};x(B,{generate:()=>C,generateSecret:()=>v,generateSync:()=>D,generateURI:()=>G,verify:()=>w,verifySync:()=>k});module.exports=R(B);var l=require("@otplib/core"),c=require("@otplib/hotp"),g=require("@otplib/totp"),m=require("@otplib/uri");var P=require("@otplib/core"),f=require("@otplib/plugin-base32-scure"),T=require("@otplib/plugin-crypto-noble");function O(t){return{secret:t.secret,strategy:t.strategy??"totp",crypto:t.crypto??T.crypto,base32:t.base32??f.base32,algorithm:t.algorithm??"sha1",digits:t.digits??6,period:t.period??30,epoch:t.epoch??Math.floor(Date.now()/1e3),t0:t.t0??0,counter:t.counter,guardrails:t.guardrails??(0,P.createGuardrails)()}}function h(t){return{...O(t),token:t.token,epochTolerance:t.epochTolerance??0,counterTolerance:t.counterTolerance??0}}function y(t,e,r){if(t==="totp")return r.totp();if(t==="hotp"){if(e===void 0)throw new l.ConfigurationError("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return r.hotp(e)}throw new l.ConfigurationError(`Unknown OTP strategy: ${t}. Valid strategies are 'totp' or 'hotp'.`)}function v(t){let{crypto:e=T.crypto,base32:r=f.base32,length:n=20}=t||{};return(0,l.generateSecret)({crypto:e,base32:r,length:n})}function G(t){let{strategy:e="totp",issuer:r,label:n,secret:o,algorithm:s="sha1",digits:p=6,period:a=30,counter:i}=t;return y(e,i,{totp:()=>(0,m.generateTOTP)({issuer:r,label:n,secret:o,algorithm:s,digits:p,period:a}),hotp:u=>(0,m.generateHOTP)({issuer:r,label:n,secret:o,algorithm:s,digits:p,counter:u})})}async function C(t){let e=O(t),{secret:r,crypto:n,base32:o,algorithm:s,digits:p}=e,a={secret:r,crypto:n,base32:o,algorithm:s,digits:p};return y(e.strategy,e.counter,{totp:()=>(0,g.generate)({...a,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:i=>(0,c.generate)({...a,counter:i,guardrails:e.guardrails})})}function D(t){let e=O(t),{secret:r,crypto:n,base32:o,algorithm:s,digits:p}=e,a={secret:r,crypto:n,base32:o,algorithm:s,digits:p};return y(e.strategy,e.counter,{totp:()=>(0,g.generateSync)({...a,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:i=>(0,c.generateSync)({...a,counter:i,guardrails:e.guardrails})})}async function w(t){let e=h(t),{secret:r,token:n,crypto:o,base32:s,algorithm:p,digits:a}=e,i={secret:r,token:n,crypto:o,base32:s,algorithm:p,digits:a};return y(e.strategy,e.counter,{totp:()=>(0,g.verify)({...i,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,guardrails:e.guardrails}),hotp:u=>(0,c.verify)({...i,counter:u,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}function k(t){let e=h(t),{secret:r,token:n,crypto:o,base32:s,algorithm:p,digits:a}=e,i={secret:r,token:n,crypto:o,base32:s,algorithm:p,digits:a};return y(e.strategy,e.counter,{totp:()=>(0,g.verifySync)({...i,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,guardrails:e.guardrails}),hotp:u=>(0,c.verifySync)({...i,counter:u,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}0&&(module.exports={generate,generateSecret,generateSync,generateURI,verify,verifySync});
1
+ "use strict";var d=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var H=(t,e)=>{for(var r in e)d(t,r,{get:e[r],enumerable:!0})},R=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of b(e))!x.call(t,o)&&o!==r&&d(t,o,{get:()=>e[o],enumerable:!(a=V(e,o))||a.enumerable});return t};var k=t=>R(d({},"__esModule",{value:!0}),t);var z={};H(z,{generate:()=>C,generateSecret:()=>v,generateSync:()=>D,generateURI:()=>G,verify:()=>w,verifySync:()=>B});module.exports=k(z);var l=require("@otplib/core"),g=require("@otplib/hotp"),u=require("@otplib/totp"),O=require("@otplib/uri");var S=require("@otplib/core"),f=require("@otplib/plugin-base32-scure"),T=require("@otplib/plugin-crypto-noble");function m(t){return{secret:t.secret,strategy:t.strategy??"totp",crypto:t.crypto??T.crypto,base32:t.base32??f.base32,algorithm:t.algorithm??"sha1",digits:t.digits??6,period:t.period??30,epoch:t.epoch??Math.floor(Date.now()/1e3),t0:t.t0??0,counter:t.counter,guardrails:t.guardrails??(0,S.createGuardrails)(),hooks:t.hooks}}function P(t){return{...m(t),token:t.token,epochTolerance:t.epochTolerance??0,counterTolerance:t.counterTolerance??0,afterTimeStep:t.afterTimeStep}}function y(t,e,r){if(t==="totp")return r.totp();if(t==="hotp"){if(e===void 0)throw new l.ConfigurationError("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return r.hotp(e)}throw new l.ConfigurationError(`Unknown OTP strategy: ${t}. Valid strategies are 'totp' or 'hotp'.`)}function v(t){let{crypto:e=T.crypto,base32:r=f.base32,length:a=20}=t||{};return(0,l.generateSecret)({crypto:e,base32:r,length:a})}function G(t){let{strategy:e="totp",issuer:r,label:a,secret:o,algorithm:i="sha1",digits:n=6,period:s=30,counter:p}=t;return y(e,p,{totp:()=>(0,O.generateTOTP)({issuer:r,label:a,secret:o,algorithm:i,digits:n,period:s}),hotp:c=>(0,O.generateHOTP)({issuer:r,label:a,secret:o,algorithm:i,digits:n,counter:c})})}async function C(t){let e=m(t),{secret:r,crypto:a,base32:o,algorithm:i,digits:n,hooks:s}=e,p={secret:r,crypto:a,base32:o,algorithm:i,digits:n,hooks:s};return y(e.strategy,e.counter,{totp:()=>(0,u.generate)({...p,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:c=>(0,g.generate)({...p,counter:c,guardrails:e.guardrails})})}function D(t){let e=m(t),{secret:r,crypto:a,base32:o,algorithm:i,digits:n}=e,s={secret:r,crypto:a,base32:o,algorithm:i,digits:n};return y(e.strategy,e.counter,{totp:()=>(0,u.generateSync)({...s,period:e.period,epoch:e.epoch,t0:e.t0,guardrails:e.guardrails}),hotp:p=>(0,g.generateSync)({...s,counter:p,guardrails:e.guardrails})})}async function w(t){let e=P(t),{secret:r,token:a,crypto:o,base32:i,algorithm:n,digits:s,hooks:p}=e,c={secret:r,token:a,crypto:o,base32:i,algorithm:n,digits:s,hooks:p};return y(e.strategy,e.counter,{totp:()=>(0,u.verify)({...c,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:h=>(0,g.verify)({...c,counter:h,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}function B(t){let e=P(t),{secret:r,token:a,crypto:o,base32:i,algorithm:n,digits:s,hooks:p}=e,c={secret:r,token:a,crypto:o,base32:i,algorithm:n,digits:s,hooks:p};return y(e.strategy,e.counter,{totp:()=>(0,u.verifySync)({...c,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance,afterTimeStep:e.afterTimeStep,guardrails:e.guardrails}),hotp:h=>(0,g.verifySync)({...c,counter:h,counterTolerance:e.counterTolerance,guardrails:e.guardrails})})}0&&(module.exports={generate,generateSecret,generateSync,generateURI,verify,verifySync});
2
2
  //# sourceMappingURL=functional.cjs.map