otplib 12.0.0 → 13.0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
- The MIT License (MIT)
1
+ MIT License
2
2
 
3
- Copyright (c) 2014 Gerald Yeo <contact@fusedthought.com>
3
+ Copyright (c) 2026 Gerald Yeo
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,534 +1,98 @@
1
1
  # otplib
2
2
 
3
- > Time-based (TOTP) and HMAC-based (HOTP) One-Time Password library
4
-
5
- [![npm][badge-npm]][project-npm]
6
- [![Build Status][badge-circle]][project-circle]
7
- [![Coverage Status][badge-coveralls]][project-coveralls]
8
- [![npm downloads][badge-npm-downloads]][project-npm]
9
- [![TypeScript Support][badge-type-ts]][project-v-api]
10
-
11
- ---
12
-
13
- <!-- TOC depthFrom:2 -->
14
-
15
- - [About](#about)
16
- - [Features](#features)
17
- - [Quick Start](#quick-start)
18
- - [In Node.js](#in-nodejs)
19
- - [In Browser](#in-browser)
20
- - [References](#references)
21
- - [API / Demo Website](#api--demo-website)
22
- - [Versioning](#versioning)
23
- - [Migrating from v11.x](#migrating-from-v11x)
24
- - [Available Options](#available-options)
25
- - [HOTP Options](#hotp-options)
26
- - [TOTP Options](#totp-options)
27
- - [Authenticator Options](#authenticator-options)
28
- - [Appendix](#appendix)
29
- - [Type Definitions](#type-definitions)
30
- - [Async Support](#async-support)
31
- - [Browser Compatiblity](#browser-compatiblity)
32
- - [Length of Secrets](#length-of-secrets)
33
- - [Google Authenticator](#google-authenticator)
34
- - [Difference between Authenticator and TOTP](#difference-between-authenticator-and-totp)
35
- - [RFC3548 Base32](#rfc3548-base32)
36
- - [Displaying a QR code](#displaying-a-qr-code)
37
- - [Getting Time Remaining / Time Used](#getting-time-remaining--time-used)
38
- - [Using with Expo](#using-with-expo)
39
- - [Exploring with local-repl](#exploring-with-local-repl)
40
- - [OTP Backup Codes](#otp-backup-codes)
41
- - [Contributors](#contributors)
42
- - [License](#license)
43
-
44
- <!-- /TOC -->
45
-
46
- ## About
47
-
48
- `otplib` is a JavaScript One Time Password (OTP) library for OTP generation and verification.
49
-
50
- It implements both [HOTP][rfc-4226-wiki] - [RFC 4226][rfc-4226]
51
- and [TOTP][rfc-6238-wiki] - [RFC 6238][rfc-6238],
52
- and are tested against the test vectors provided in their respective RFC specifications.
53
- These datasets can be found in the `packages/tests-data` folder.
54
-
55
- - [RFC 4226 Dataset][rfc-4226-dataset]
56
- - [RFC 6238 Dataset][rfc-6238-dataset]
57
-
58
- This library is also compatible with [Google Authenticator](https://github.com/google/google-authenticator),
59
- and includes additional methods to allow you to work with Google Authenticator.
3
+ > The One-Time Password (OTP) library
4
+
5
+ TypeScript-first implementation of HOTP/TOTP with automatic crypto backend detection for optimal performance across Node.js, browsers, and edge environments.
6
+
7
+ ## Breaking Changes (v13)
8
+
9
+ > [!IMPORTANT]
10
+ > v13 is a complete rewrite with breaking changes:
11
+ >
12
+ > - **New**
13
+ > - **Security-audited plugins** — Default crypto uses `@noble/hashes` and `@scure/base`, both independently audited
14
+ > - **Cross-platform defaults** — Works out-of-the-box in Node.js, Bun, Deno, and browsers
15
+ > - **Full type safety** — Comprehensive TypeScript types with strict mode from the ground up
16
+ > - **Async-first API** — All operations are async by default; sync variants available for compatible plugins
17
+ > - **Removed**
18
+ > - **Separate authenticator package** — TOTP now covers all authenticator functionality
19
+ > - **Outdated plugins** — Legacy crypto adapters removed in favor of modern, audited alternatives
20
+ >
21
+ > See [Migration Guide](https://otplib.yeojz.dev/guide/migrating-v12-to-v13) for details.
60
22
 
61
23
  ## Features
62
24
 
63
- - Typescript support
64
- - [Class][link-mdn-classes] interfaces
65
- - [Function][link-mdn-functions] interfaces
66
- - [Async][link-mdn-async] interfaces
67
- - Pluggable modules (crypto / base32)
68
- - `crypto (node)`
69
- - `crypto-js`
70
- - `@ronomon/crypto-async`
71
- - `thirty-two`
72
- - `base32-encode` + `base32-decode`
73
- - Presets provided
74
- - `browser`
75
- - `default (node)`
76
- - `default-async (same as default, but with async methods)`
77
- - `v11 (adapter for previous version)`
78
-
79
- ## Quick Start
80
-
81
- > If you need to customise your base32 or crypto libraries,
82
- > check out the [In-Depth Guide][docs-in-depth] and [Available Packages][docs-available-packages]
25
+ - **Zero Configuration** - Works out of the box with sensible defaults
26
+ - **RFC Compliant** - RFC 6238 (TOTP) and RFC 4226 (HOTP)
27
+ - **TypeScript-First** - Full type definitions
28
+ - **Google Authenticator Compatible** - Full otpauth:// URI support
83
29
 
84
- ### In Node.js
30
+ ## Installation
85
31
 
86
32
  ```bash
87
- npm install otplib --save
88
- ```
89
-
90
- ```js
91
- import { authenticator } from 'otplib';
92
-
93
- const secret = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD';
94
- // Alternative:
95
- // const secret = authenticator.generateSecret();
96
- // Note: .generateSecret() is only available for authenticator and not totp/hotp
97
-
98
- const token = authenticator.generate(secret);
99
-
100
- try {
101
- const isValid = authenticator.check(token, secret);
102
- // or
103
- const isValid = authenticator.verify({ token, secret });
104
- } catch (err) {
105
- // Possible errors
106
- // - options validation
107
- // - "Invalid input - it is not base32 encoded string" (if thiry-two is used)
108
- console.error(err);
109
- }
110
- ```
111
-
112
- Please replace "authenticator" with "totp" or "hotp" depending on your requirements.
113
-
114
- ```js
115
- // For TOTP
116
- import { totp } from 'otplib';
117
- const token = totp.generate(secret);
118
- const isValid = totp.check(token, secret);
119
- const isValid = totp.verify({ token, secret });
120
-
121
- // For HOTP
122
- import { hotp } from 'otplib';
123
- const token = hotp.generate(secret, counter);
124
- const isValid = hotp.check(token, secret, counter);
125
- const isValid = hotp.verify({ token, secret, counter });
126
- ```
127
-
128
- For all available APIs, please refer to [API Documentation][project-v-api].
129
-
130
- ### In Browser
131
-
132
- The browser preset is a self-contained `umd` module, and it is provided in a separate bundle.
133
-
134
- ```bash
135
- npm install @otplib/preset-browser --save
136
- ```
137
-
138
- The following is an example, where we are using the scripts hosted by `unpkg.com`.
139
-
140
- ```html
141
- <script src="https://unpkg.com/@otplib/preset-browser@^12.0.0/buffer.js"></script>
142
- <script src="https://unpkg.com/@otplib/preset-browser@^12.0.0/index.js"></script>
143
-
144
- <script type="text/javascript">
145
- // window.otplib.authenticator
146
- // window.otplib.hotp
147
- // window.otplib.totp
148
- </script>
149
- ```
150
-
151
- For more details, please refer to the [@otplib/preset-browser documentation][docs-preset-browser].
152
-
153
- ## References
154
-
155
- ### API / Demo Website
156
-
157
- | Version | Links |
158
- | --------------- | ----------------------------------------------------------------------------------- |
159
- | v12.x | [Website][project-v-site] / [API][project-v-api] / [Readme][project-v-readme] |
160
- | v11.x | [API][project-v11-api] / [Readme][project-v11-readme] |
161
- | v10.x and below | Available via git history |
162
-
163
- ### Versioning
164
-
165
- This library follows `semver`. As such, major version bumps usually mean API changes or behavior changes.
166
- Please check [upgrade notes](https://github.com/yeojz/otplib/wiki/upgrade-notes) for more information,
167
- especially before making any major upgrades.
168
-
169
- To simplify releases, all packages within this repository have their versions synced.
170
- Therefore, if there are any releases or updates to a package, we will bump all packages.
171
-
172
- Check out the release notes associated with each tagged versions
173
- in the [releases](https://github.com/yeojz/otplib/releases) page.
174
-
175
- | Release Type | Version Pattern | Command | |
176
- | :---------------- | --------------- | ------------------------- | :------------------------------------ |
177
- | Current / Stable | 0.0.0 | `npm install otplib` | [![npm][badge-npm]][project-npm] |
178
- | Release Candidate | 0.0.0-0 | `npm install otplib@next` | [![npm][badge-npm-next]][project-npm] |
179
-
180
- ### Migrating from v11.x
181
-
182
- > v12.x is a huge architectural and language rewrite. Please check out the docs if you are migrating.
183
- > A preset adapter is available to provide methods that behave like `v11.x` of `otplib`.
184
-
185
- ```js
186
- // Update
187
- import { authenticator } from 'otplib'; // v11.x
188
- // to
189
- import { authenticator } from '@otplib/preset-v11';
190
-
191
- // There should be no changes to your current code.
192
- // However, deprecated or modified class methods will have console.warn.
33
+ npm install otplib
34
+ pnpm add otplib
35
+ yarn add otplib
193
36
  ```
194
37
 
195
- ### Available Options
196
-
197
- All instantiated classes will have their options inherited from their respective options
198
- generator. i.e. HOTP from `hotpOptions`, TOTP from `totpOptions`
199
- and Authenticator from `authenticatorOptions`.
200
-
201
- All OTP classes have an object setter and getter method to override these default options.
202
-
203
- For example,
204
-
205
- ```js
206
- import { authenticator, totp, hotp } from 'otplib';
207
-
208
- // setting
209
- authenticator.options = { digits: 6 };
210
- totp.options = { digits: 6 };
211
- hotp.options = { digits: 6 };
212
-
213
- // getting
214
- const opts = authenticator.options;
215
- const opts = totp.options;
216
- const opts = hotp.options;
217
-
218
- // reset to default
219
- authenticator.resetOptions();
220
- totp.resetOptions();
221
- hotp.resetOptions();
222
-
223
- // getting all options, with validation
224
- // and backfilled with library defaults
225
- const opts = authenticator.allOptions();
226
- const opts = totp.allOptions();
227
- const opts = hotp.allOptions();
228
- ```
229
-
230
- #### HOTP Options
231
-
232
- | Option | Type | Description |
233
- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
234
- | algorithm | string | The algorithm used for calculating the HMAC. |
235
- | createDigest | function | Creates the digest which token is derived from. |
236
- | createHmacKey | function | Formats the secret into a HMAC key, applying transformations (like padding) where needed. |
237
- | digest | string | **USE WITH CAUTION**. Same digest = same token. <br />Used in cases where digest is generated externally. (eg: async use cases) |
238
- | digits | integer | The length of the token. |
239
- | encoding | string | The encoding that was used on the secret. |
240
-
241
- ```js
242
- // HOTP defaults
243
- {
244
- algorithm: 'sha1'
245
- createDigest: undefined, // to be provided via a @otplib/plugin-*
246
- createHmacKey: hotpCreateHmacKey,
247
- digits: 6,
248
- encoding: 'ascii',
249
- }
250
- ```
251
-
252
- #### TOTP Options
253
-
254
- > Note: Includes all HOTP Options
255
-
256
- | Option | Type | Description |
257
- | ------ | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
258
- | epoch | integer | **USE WITH CAUTION**. Same epoch = same token. <br />Starting time since the UNIX epoch (seconds). <br /> Epoch is JavaScript formatted. i.e. `Date.now()` or `UNIX time * 1000` |
259
- | step | integer | Time step (seconds) |
260
- | window | integer, <br /> [number, number] | Tokens in the previous and future x-windows that should be considered valid. <br /> If integer, same value will be used for both. <br /> Alternatively, define array: `[past, future]` |
261
-
262
- ```js
263
- // TOTP defaults
264
- {
265
- // ...includes all HOTP defaults
266
- createHmacKey: totpCreateHmacKey,
267
- epoch: Date.now(),
268
- step: 30,
269
- window: 0,
270
- }
271
- ```
272
-
273
- #### Authenticator Options
274
-
275
- > Note: Includes all HOTP + TOTP Options
276
-
277
- | Option | Type | Description |
278
- | ----------------- | -------- | ----------------------------------------------------------------------------------------------------- |
279
- | createRandomBytes | function | Creates a random string containing the defined number of bytes to be used in generating a secret key. |
280
- | keyEncoder | function | Encodes a secret key into a Base32 string before it is sent to the user (in QR Code etc). |
281
- | keyDecoder | function | Decodes the Base32 string given by the user into a secret. |
282
-
283
- ```js
284
- // Authenticator defaults
285
- {
286
- // ...includes all HOTP + TOTP defaults
287
- encoding: 'hex',
288
- createRandomBytes: undefined, // to be provided via a @otplib/plugin-*
289
- keyEncoder: undefined, // to be provided via a @otplib/plugin-*
290
- keyDecoder: undefined, // to be provided via a @otplib/plugin-*
291
- }
292
- ```
293
-
294
- ## Appendix
295
-
296
- ### Type Definitions
297
-
298
- `TypeScript` support was introduced in `v10.0.0`, which added type definitions over `.js` files.
299
-
300
- As of `v12.0.0`, the library has been re-written in Typescript from the ground up.
301
-
302
- ### Async Support
303
-
304
- `async` support was introduced in `v12.0.0` as an additional core library.
305
-
306
- This was added as some libraries like [expo.io][link-expo-crypto] or even
307
- the browser API ([window.Crypto.subtle][link-mdn-subtlecrypto]) started providing
308
- only async methods.
309
-
310
- You to find more details in the [core-async][docs-core-async] folder.
311
-
312
- ### Browser Compatiblity
313
-
314
- `@otplib/preset-browser` is a `umd` bundle with some node modules replaced to reduce the browser size.
315
-
316
- The approximate size for the **optimised, minified + gzipped** bundle is **9.53KB**.
317
- Paired with the gzipped browser `buffer.js` module, it would be about `7.65KB + 9.53KB = 17.18KB`.
318
-
319
- For more details, please refer to the [@otplib/preset-browser documentation][docs-preset-browser].
320
-
321
- ### Length of Secrets
322
-
323
- In [RFC 6238][rfc-6238], the secret / seed length for different algorithms are predefined:
324
-
325
- ```txt
326
- HMAC-SHA1 - 20 bytes
327
- HMAC-SHA256 - 32 bytes
328
- HMAC-SHA512 - 64 bytes
329
- ```
330
-
331
- As such, the length of the secret provided (after any decoding) will be padded and sliced
332
- according to the expected length for respective algorithms.
333
-
334
- ### Google Authenticator
335
-
336
- #### Difference between Authenticator and TOTP
337
-
338
- The default encoding option has been set to `hex` (Authenticator) instead of `ascii` (TOTP).
339
-
340
- #### RFC3548 Base32
341
-
342
- > Note: [RFC4648][rfc-4648] obseletes [RFC 3548][rfc-3548].
343
- > Any encoders following the newer specifications will work.
344
-
345
- Google Authenticator requires keys to be base32 encoded.
346
- It also requires the base32 encoder to be [RFC 3548][rfc-3548] compliant.
347
-
348
- OTP calculation will still work should you want to use
349
- other base32 encoding methods (like Crockford's Base32)
350
- but it will NOT be compatible with Google Authenticator.
351
-
352
- ```js
353
- const secret = authenticator.generateSecret(); // base32 encoded hex secret key
354
- const token = authenticator.generate(secret);
355
- ```
356
-
357
- #### Displaying a QR code
358
-
359
- You may want to generate and display a QR Code so that users can scan
360
- instead of manually entering the secret. Google Authenticator and similar apps
361
- take in a QR code that holds a URL with the protocol `otpauth://`,
362
- which you get from `authenticator.keyuri`.
363
-
364
- Google Authenticator will ignore the `algorithm`, `digits`, and `step` options.
365
- See the [keyuri documentation](https://github.com/google/google-authenticator/wiki/Key-Uri-Format)
366
- for more information.
367
-
368
- If you are using a different authenticator app, check the documentation
369
- for that app to see if any options are ignored, which will result in invalid tokens.
370
-
371
- While this library provides the "otpauth" uri, you'll need a library to
372
- generate the QR Code image.
38
+ ## Quick Start
373
39
 
374
- An example is shown below:
40
+ ### Functional API (Recommended)
375
41
 
376
- ```js
377
- // npm install qrcode
378
- import qrcode from 'qrcode';
379
- import { authenticator } from '@otplib/preset-default';
42
+ ```typescript
43
+ import { generateSecret, generate, verify, generateURI } from "otplib";
380
44
 
381
- const user = 'A user name, possibly an email';
382
- const service = 'A service name';
45
+ // Generate a secret
46
+ const secret = generateSecret();
383
47
 
384
- // v11.x and above
385
- const otpauth = authenticator.keyuri(user, service, secret);
48
+ // Generate a TOTP token
49
+ const token = await generate({ secret });
386
50
 
387
- // v10.x and below
388
- const otpauth = authenticator.keyuri(
389
- encodeURIComponent(user),
390
- encodeURIComponent(service),
391
- secret
392
- );
51
+ // Verify a token
52
+ const isValid = await verify({ secret, token });
393
53
 
394
- qrcode.toDataURL(otpauth, (err, imageUrl) => {
395
- if (err) {
396
- console.log('Error with QR');
397
- return;
398
- }
399
- console.log(imageUrl);
54
+ // Generate QR code URI for authenticator apps
55
+ const uri = generateURI({
56
+ issuer: "MyService",
57
+ label: "user@example.com",
58
+ secret,
400
59
  });
401
60
  ```
402
61
 
403
- > **Note**: For versions `v10.x` and below, `keyuri` does not URI encode
404
- > `user` and `service`. You'll need to do so before passing in the parameteres.
405
-
406
- ### Getting Time Remaining / Time Used
407
-
408
- Helper methods for getting the remaining time and used time within a validity period
409
- of a `totp` or `authenticator` token were introduced in `v10.0.0`.
410
-
411
- ```js
412
- authenticator.timeUsed(); // or totp.timeUsed();
413
- authenticator.timeRemaining(); // or totp.timeRemaining();
414
-
415
- // The start of a new token would be when:
416
- // - timeUsed() === 0
417
- // - timeRemaining() === step
418
- ```
419
-
420
- ### Using with Expo
421
-
422
- [Expo][link-expo-io] contains modified crypto implmentations targeted at the platform.
423
- While `otplib` does not provide an `expo` specified package, with the re-architecture
424
- of `otplib`, you can now provide an expo native `createDigest` to the library.
62
+ ### Class API
425
63
 
426
- Alternatively, you can make use of crypto provided by `@otplib/plugin-crypto-js` or
427
- the bundled browser umd module `@otplib/preset-browser`.
64
+ ```typescript
65
+ import { OTP } from "otplib";
428
66
 
429
- Pull Requests are much welcomed for a native expo implementation as well.
67
+ // Create OTP instance (defaults to TOTP)
68
+ const otp = new OTP();
430
69
 
431
- ### Exploring with local-repl
70
+ // Generate a secret
71
+ const secret = otp.generateSecret();
432
72
 
433
- If you'll like to explore the library with `local-repl` you can do so as well.
73
+ // Generate a TOTP token
74
+ const token = await otp.generate({ secret });
434
75
 
435
- ```bash
436
- # after cloning the repo:
437
- npm run setup
438
- npm run build
439
- npx local-repl
440
- # You should see something like:
441
- # Node v8.9.4, local-repl 4.0.0
442
- # otplib 10.0.0
443
- # Context: otplib
444
- # [otplib] >
76
+ // Verify a token
77
+ const isValid = await otp.verify({ secret, token });
445
78
 
446
- [otplib] > secret = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD'
447
- [otplib] > otplib.authenticator.generate(secret)
79
+ // Generate QR code URI for authenticator apps
80
+ const uri = otp.generateURI({
81
+ issuer: "MyService",
82
+ label: "user@example.com",
83
+ secret,
84
+ });
448
85
  ```
449
86
 
450
- ### OTP Backup Codes
451
-
452
- It is common for services to also provide a set of backup codes to authenticate
453
- and bypass the OTP step in the event that you are not able to access your 2FA
454
- device or have misplaced the device.
455
-
456
- As this process is separate from the specifications for OTP, this library does not
457
- provide any backup code related verification logic, and thus would have to be
458
- implemented separately.
459
-
460
- ## Contributors
461
-
462
- Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
463
-
464
- <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
465
- <!-- prettier-ignore-start -->
466
- <!-- markdownlint-disable -->
467
- <table>
468
- <tr>
469
- <td align="center"><a href="https://github.com/yeojz"><img src="https://avatars2.githubusercontent.com/u/429598?v=4" width="80px;" alt="Gerald Yeo"/><br /><sub><b>Gerald Yeo</b></sub></a><br /><a href="https://github.com/yeojz/otplib/commits?author=yeojz" title="Code">💻</a> <a href="https://github.com/yeojz/otplib/commits?author=yeojz" title="Documentation">📖</a> <a href="#maintenance-yeojz" title="Maintenance">🚧</a> <a href="https://github.com/yeojz/otplib/commits?author=yeojz" title="Tests">⚠️</a></td>
470
- <td align="center"><a href="https://ols.io"><img src="https://avatars3.githubusercontent.com/u/6209178?v=4" width="80px;" alt="Oliver Schneider"/><br /><sub><b>Oliver Schneider</b></sub></a><br /><a href="https://github.com/yeojz/otplib/commits?author=olsio" title="Documentation">📖</a></td>
471
- <td align="center"><a href="https://developer.mozilla.org/profiles/madarche/"><img src="https://avatars0.githubusercontent.com/u/152407?v=4" width="80px;" alt="Marc-Aurèle DARCHE"/><br /><sub><b>Marc-Aurèle DARCHE</b></sub></a><br /><a href="https://github.com/yeojz/otplib/commits?author=madarche" title="Documentation">📖</a></td>
472
- <td align="center"><a href="http://shakram02.github.io/"><img src="https://avatars3.githubusercontent.com/u/10996982?v=4" width="80px;" alt="Ahmed Hamdy (@shakram02)"/><br /><sub><b>Ahmed Hamdy (@shakram02)</b></sub></a><br /><a href="https://github.com/yeojz/otplib/commits?author=shakram02" title="Documentation">📖</a></td>
473
- <td align="center"><a href="https://tony.brix.ninja"><img src="https://avatars3.githubusercontent.com/u/97994?v=4" width="80px;" alt="Tony Brix"/><br /><sub><b>Tony Brix</b></sub></a><br /><a href="https://github.com/yeojz/otplib/commits?author=UziTech" title="Code">💻</a> <a href="https://github.com/yeojz/otplib/commits?author=UziTech" title="Documentation">📖</a></td>
474
- </tr>
475
- </table>
476
-
477
- <!-- markdownlint-enable -->
478
- <!-- prettier-ignore-end -->
87
+ ## Documentation
479
88
 
480
- <!-- ALL-CONTRIBUTORS-LIST:END -->
89
+ Full documentation available at [here](https://otplib.yeojz.dev):
481
90
 
482
- This project follows the [all-contributors](https://github.com/all-contributors/all-contributors)
483
- specification. Contributions of any kind welcome!
91
+ - [Getting Started Guide](https://otplib.yeojz.dev/guide/getting-started)
92
+ - [Runtime Compatibility](https://otplib.yeojz.dev/guide/runtime-compatibility)
93
+ - [Security Considerations](https://otplib.yeojz.dev/guide/security)
94
+ - [API Reference](https://otplib.yeojz.dev/api/)
484
95
 
485
96
  ## License
486
97
 
487
- `otplib` is [MIT licensed][project-license]
488
-
489
- <img width="150" src="https://otplib.yeojz.dev/otplib.png" />
490
-
491
- <!-- Badges -->
492
-
493
- [badge-circle]: https://img.shields.io/circleci/project/github/yeojz/otplib/master.svg?style=flat-square
494
- [badge-coveralls]: https://img.shields.io/coveralls/yeojz/otplib/master.svg?style=flat-square
495
- [badge-npm-downloads]: https://img.shields.io/npm/dt/otplib.svg?style=flat-square
496
- [badge-npm-next]: https://img.shields.io/npm/v/otplib/next.svg?style=flat-square
497
- [badge-npm]: https://img.shields.io/npm/v/otplib.svg?style=flat-square
498
- [badge-type-ts]: https://img.shields.io/badge/typedef-.d.ts-blue.svg?style=flat-square&longCache=true
499
-
500
- <!-- External Links -->
501
-
502
- [link-expo-crypto]: https://docs.expo.io/versions/v33.0.0/sdk/crypto/
503
- [link-expo-io]: https://expo.io
504
- [link-mdn-async]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
505
- [link-mdn-classes]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
506
- [link-mdn-functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
507
- [link-mdn-subtlecrypto]: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
508
- [link-npm-buffer]: https://www.npmjs.com/package/buffer
509
- [rfc-3548]: http://tools.ietf.org/html/rfc3548
510
- [rfc-4226-dataset]: https://github.com/yeojz/otplib/blob/master/tests/data/rfc-4226.ts
511
- [rfc-4226-wiki]: http://en.wikipedia.org/wiki/HMAC-based_One-time_Password_Algorithm
512
- [rfc-4226]: http://tools.ietf.org/html/rfc4226
513
- [rfc-4648]: https://tools.ietf.org/html/rfc4648
514
- [rfc-6238-dataset]: https://github.com/yeojz/otplib/blob/master/tests/data/rfc-6238.ts
515
- [rfc-6238-wiki]: http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
516
- [rfc-6238]: http://tools.ietf.org/html/rfc6238
517
-
518
- <!-- Project Links -->
519
-
520
- [docs-available-packages]: https://github.com/yeojz/otplib/blob/master/packages/README.md
521
- [docs-core-async]: https://github.com/yeojz/otplib/blob/master/packages/otplib-core-async/README.md
522
- [docs-in-depth]: https://github.com/yeojz/otplib/blob/master/packages/otplib-core/README.md#getting-started
523
- [docs-preset-browser-src]: https://github.com/yeojz/otplib/blob/master/packages/otplib-preset-browser/src/index.ts
524
- [docs-preset-browser]: https://github.com/yeojz/otplib/blob/master/packages/otplib-preset-browser/README.md
525
- [project-circle]: https://circleci.com/gh/yeojz/otplib
526
- [project-coveralls]: https://coveralls.io/github/yeojz/otplib
527
- [project-license]: https://github.com/yeojz/otplib/blob/master/LICENSE
528
- [project-npm]: https://www.npmjs.com/package/otplib
529
- [project-repo]: https://github.com/yeojz/otplib
530
- [project-v-api]: https://otplib.yeojz.dev/api
531
- [project-v-readme]: https://github.com/yeojz/otplib/blob/master/README.md
532
- [project-v-site]: https://otplib.yeojz.dev
533
- [project-v11-api]: https://5d4d0cc4c85e00000788a456--otplib.netlify.com/docs
534
- [project-v11-readme]: https://github.com/yeojz/otplib/blob/d0aedccbca8ae7ec1983f40da4d7a14c9e815e9c/README.md
98
+ [MIT](./LICENSE) © 2026 Gerald Yeo
package/dist/class.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var h=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var w=(t,e)=>{for(var r in e)h(t,r,{get:e[r],enumerable:!0})},B=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of C(e))!D.call(t,o)&&o!==r&&h(t,o,{get:()=>e[o],enumerable:!(n=G(e,o))||n.enumerable});return t};var U=t=>B(h({},"__esModule",{value:!0}),t);var k={};w(k,{OTP:()=>P});module.exports=U(k);var v=require("@otplib/core"),H=require("@otplib/uri");var b=require("@otplib/plugin-base32-scure"),d=require("@otplib/plugin-crypto-noble"),g=Object.freeze(new d.NobleCryptoPlugin),u=Object.freeze(new b.ScureBase32Plugin);function l(t){return{secret:t.secret,strategy:t.strategy??"totp",crypto:t.crypto??g,base32:t.base32??u,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}}function T(t){return{...l(t),token:t.token,epochTolerance:t.epochTolerance??0,counterTolerance:t.counterTolerance??0}}var f=require("@otplib/core"),c=require("@otplib/hotp"),y=require("@otplib/totp"),I=require("@otplib/uri");function m(t,e,r){if(t==="totp")return r.totp();if(t==="hotp"){if(e===void 0)throw new f.ConfigurationError("Counter is required for HOTP strategy. Example: { strategy: 'hotp', counter: 0 }");return r.hotp(e)}throw new f.ConfigurationError(`Unknown OTP strategy: ${t}. Valid strategies are 'totp' or 'hotp'.`)}async function S(t){let e=l(t),{secret:r,crypto:n,base32:o,algorithm:s,digits:a}=e,i={secret:r,crypto:n,base32:o,algorithm:s,digits:a};return m(e.strategy,e.counter,{totp:()=>(0,y.generate)({...i,period:e.period,epoch:e.epoch,t0:e.t0}),hotp:p=>(0,c.generate)({...i,counter:p})})}function V(t){let e=l(t),{secret:r,crypto:n,base32:o,algorithm:s,digits:a}=e,i={secret:r,crypto:n,base32:o,algorithm:s,digits:a};return m(e.strategy,e.counter,{totp:()=>(0,y.generateSync)({...i,period:e.period,epoch:e.epoch,t0:e.t0}),hotp:p=>(0,c.generateSync)({...i,counter:p})})}async function R(t){let e=T(t),{secret:r,token:n,crypto:o,base32:s,algorithm:a,digits:i}=e,p={secret:r,token:n,crypto:o,base32:s,algorithm:a,digits:i};return m(e.strategy,e.counter,{totp:()=>(0,y.verify)({...p,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance}),hotp:O=>(0,c.verify)({...p,counter:O,counterTolerance:e.counterTolerance})})}function x(t){let e=T(t),{secret:r,token:n,crypto:o,base32:s,algorithm:a,digits:i}=e,p={secret:r,token:n,crypto:o,base32:s,algorithm:a,digits:i};return m(e.strategy,e.counter,{totp:()=>(0,y.verifySync)({...p,period:e.period,epoch:e.epoch,t0:e.t0,epochTolerance:e.epochTolerance}),hotp:O=>(0,c.verifySync)({...p,counter:O,counterTolerance:e.counterTolerance})})}var P=class{strategy;crypto;base32;constructor(e={}){let{strategy:r="totp",crypto:n=g,base32:o=u}=e;this.strategy=r,this.crypto=n,this.base32=o}getStrategy(){return this.strategy}generateSecret(e=20){return(0,v.generateSecret)({crypto:this.crypto,base32:this.base32,length:e})}async generate(e){return S({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32})}generateSync(e){return V({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32})}async verify(e){return R({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32})}verifySync(e){return x({...e,strategy:this.strategy,crypto:this.crypto,base32:this.base32})}generateURI(e){if(this.strategy==="hotp")throw new Error("generateURI is not available for HOTP strategy");let{issuer:r,label:n,secret:o,algorithm:s="sha1",digits:a=6,period:i=30}=e;return(0,H.generateTOTP)({issuer:r,label:n,secret:o,algorithm:s,digits:a,period:i})}};0&&(module.exports={OTP});
2
+ //# sourceMappingURL=class.cjs.map