diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3c18776f..0714b004 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -52,5 +52,5 @@ Before submitting a pull request, please make sure the following is done:
Thank you for contributing!
-[pr-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
+[pr-welcome-badge]: https://img.shields.io/badge/welcome-PRs-brightgreen.svg?style=flat-square&longCache=true
[pr-welcome-link]: https://github.com/yeojz/otplib/blob/master/CONTRIBUTING.md
diff --git a/README.md b/README.md
index d7c2a868..c25a14e5 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+
# otplib
> Time-based (TOTP) and HMAC-based (HOTP) One-Time Password library
@@ -6,9 +7,8 @@
[![Build Status][circle-badge]][circle-link]
[![Coverage Status][coveralls-badge]][coveralls-link]
[![npm downloads][npm-downloads-badge]][npm-link]
-[![PRs Welcome][pr-welcome-badge]][pr-welcome-link]
+[![TypeScript Support][type-ts-badge]][type-ts-link]
-
- [About](#about)
- [Demo and Documentation](#demo-and-documentation)
@@ -335,11 +335,14 @@ qrcode.toDataURL(otpauth, (err, imageUrl) => {
Check out: [CONTRIBUTING.md][pr-welcome-link]
[![Support Project][coffee-badge]][coffee-link]
+[![PRs Welcome][pr-welcome-badge]][pr-welcome-link]
## License
`otplib` is [MIT licensed](./LICENSE)
+
+
[npm-badge]: https://img.shields.io/npm/v/otplib.svg?style=flat-square
[npm-link]: https://www.npmjs.com/package/otplib
@@ -349,7 +352,7 @@ Check out: [CONTRIBUTING.md][pr-welcome-link]
[circle-link]: https://circleci.com/gh/yeojz/otplib
[coveralls-badge]: https://img.shields.io/coveralls/yeojz/otplib/master.svg?style=flat-square
[coveralls-link]: https://coveralls.io/github/yeojz/otplib
-[pr-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
+[pr-welcome-badge]: https://img.shields.io/badge/welcome-PRs-brightgreen.svg?style=flat-square&longCache=true
[pr-welcome-link]: https://github.com/yeojz/otplib/blob/master/CONTRIBUTING.md
[mdn-uint8array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
[mdn-crypto]: https://developer.mozilla.org/en-US/docs/Web/API/Window/crypto
@@ -363,5 +366,7 @@ Check out: [CONTRIBUTING.md][pr-welcome-link]
[rfc-6238-wiki]: http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
[donate-badge]: https://img.shields.io/badge/donate-%3C3-red.svg?longCache=true&style=flat-square
[donate-link]: https://www.paypal.me/yeojz
-[coffee-badge]: https://img.shields.io/badge/%E2%98%95%EF%B8%8F%20%20-buy%20me%20a%20coffee-orange.svg?longCache=true&style=flat-square
+[coffee-badge]: https://img.shields.io/badge/%E2%98%95%EF%B8%8F%20-buy%20me%20a%20coffee-orange.svg?longCache=true&style=flat-square
[coffee-link]: https://ko-fi.com/geraldyeo
+[type-ts-badge]: https://img.shields.io/badge/included-.d.ts-blue.svg?style=flat-square&longCache=true
+[type-ts-link]: https://github.com/yeojz/otplib/tree/master/packages/types-ts
diff --git a/package.json b/package.json
index f3b0221a..547fae96 100644
--- a/package.json
+++ b/package.json
@@ -78,20 +78,17 @@
},
"jest": {
"coverageDirectory": "./coverage/",
- "coveragePathIgnorePatterns": [
- "/scripts/*",
- "/dist/*"
- ],
+ "coveragePathIgnorePatterns": [],
"modulePaths": [
"/packages/"
],
+ "roots": [
+ "/packages/"
+ ],
"resetMocks": true,
"setupFiles": [],
"testPathIgnorePatterns": [
- "/node_modules/",
- "/dist/*",
- "/scripts/*",
- "/tests/"
+ "/node_modules/"
]
},
"repl": [
diff --git a/packages/otplib-core/hotpDigest.js b/packages/otplib-core/hotpDigest.js
index 65bc31d6..8f4dba36 100644
--- a/packages/otplib-core/hotpDigest.js
+++ b/packages/otplib-core/hotpDigest.js
@@ -25,7 +25,10 @@ function hotpDigest(secret, counter, options) {
}
// Convert secret to encoding for hmacSecret
- const hmacSecret = options.createHmacSecret(secret, options);
+ const hmacSecret = options.createHmacSecret(secret, {
+ algorithm: options.algorithm,
+ encoding: options.encoding
+ });
// Ensure counter is a buffer or string (for HMAC creation)
const hexCounter = hotpCounter(counter);
diff --git a/packages/otplib-core/totpCounter.js b/packages/otplib-core/totpCounter.js
index 94a25211..f29e5af9 100644
--- a/packages/otplib-core/totpCounter.js
+++ b/packages/otplib-core/totpCounter.js
@@ -2,7 +2,7 @@
* Generates a counter for TOTP
*
* @module otplib-core/totpCounter
- * @param {string} epoch - starting time since the UNIX epoch (seconds)
+ * @param {number} epoch - starting time since the UNIX epoch (seconds)
* @param {number} step - time step (seconds)
* @return {float}
*/
diff --git a/packages/types-ts/index.d.ts b/packages/types-ts/index.d.ts
index 430b765e..c1308412 100644
--- a/packages/types-ts/index.d.ts
+++ b/packages/types-ts/index.d.ts
@@ -1,52 +1,103 @@
-type CreateHmacSecretFunction = (secret: string, options: any) => Buffer;
-
-interface HOTPOptions {
+interface hmacOptions {
algorithm?: string;
- createHmacSecret?: CreateHmacSecretFunction;
+ encoding?: string;
+}
+
+type createHmacSecret = (
+ secret: string,
+ options: hmacOptions
+) => Buffer;
+
+interface hotpOptionsInterface extends hmacOptions {
+ createHmacSecret?: createHmacSecret;
crypto?: any;
digits?: number;
- encoding?: string;
}
-interface HOTPVerifyOptions {
+interface hotpVerifyOptionsInterface {
token?: string;
secret?: string;
counter?: number;
}
-interface TOTPOptions extends HOTPOptions {
+type hotpCheck = (
+ token: string,
+ secret: string,
+ counter: number,
+ options: hotpOptionsInterface
+) => boolean;
+
+type hotpCounter = (counter: number) => string;
+
+type hotpDigest = (
+ secret: string,
+ counter: number,
+ options: hotpOptionsInterface
+) => string;
+
+type hotpOptions = (options: any) => hotpOptionsInterface;
+
+type hotpSecret = createHmacSecret;
+
+type hotpToken = (
+ secret: string,
+ counter: number,
+ options: hotpOptionsInterface
+) => string;
+
+interface totpOptionsInterface extends hotpOptionsInterface {
epoch?: any;
step?: number;
window?: number | number[];
}
-interface TOTPVerifyOptions {
+interface totpVerifyOptionsInterface {
token?: string;
secret?: string;
}
+type totpCheck = (
+ token: string,
+ secret: string,
+ options: totpOptionsInterface
+) => boolean;
+
+type totpCheckWithWindow = (
+ token: string,
+ secret: string,
+ options: totpOptionsInterface
+) => number | null;
+
+type totpCounter = (epoch: number, step: number) => number;
+
+type totpOptions = (options: any) => totpOptionsInterface;
+
+type totpSecret = createHmacSecret;
+
+type totpToken = (secret: string, options: totpOptionsInterface) => string;
+
declare class HOTP {
HOTP: typeof HOTP;
getClass(): typeof HOTP;
- options: HOTPOptions;
- optionsAll: HOTPOptions;
+ options: totpOptionsInterface;
+ optionsAll: totpOptionsInterface;
resetOptions(): this;
generate(secret: string, counter: number): string;
check(token: string, secret: string, counter: number): boolean;
- verify(opts: HOTPVerifyOptions): boolean;
+ verify(opts: hotpVerifyOptionsInterface): boolean;
}
declare class TOTP extends HOTP {
TOTP: typeof TOTP;
getClass(): typeof TOTP;
- options: TOTPOptions;
- optionsAll: TOTPOptions;
+ options: totpOptionsInterface;
+ optionsAll: totpOptionsInterface;
generate(secret: string): string;
check(token: string, secret: string): boolean;
checkDelta(token: string, secret: string): number | null;
- verify(opts: TOTPVerifyOptions): boolean;
+ verify(opts: totpVerifyOptionsInterface): boolean;
}
declare class Authenticator extends TOTP {
@@ -82,3 +133,22 @@ declare module 'otplib/hotp' {
const hotp: HOTP;
export = hotp;
}
+
+declare module 'otplib/core' {
+ interface core {
+ hotpCheck: hotpCheck;
+ hotpCounter: hotpCounter;
+ hotpDigest: hotpDigest;
+ hotpOptions: hotpOptions;
+ hotpSecret: hotpSecret;
+ hotpToken: hotpToken;
+ totpCheck: totpCheck;
+ totpCheckWithWindow: totpCheckWithWindow;
+ totpCounter: totpCounter;
+ totpOptions: totpOptions;
+ totpSecret: totpSecret;
+ totpToken: totpToken;
+ }
+ const lib: core;
+ export = lib;
+}
diff --git a/packages/types-ts/index.spec.ts b/packages/types-ts/index.spec.ts
index 1ed2b7c4..3b7f755a 100644
--- a/packages/types-ts/index.spec.ts
+++ b/packages/types-ts/index.spec.ts
@@ -1,5 +1,6 @@
import * as otplib from 'otplib';
import authenticator = require('otplib/authenticator');
+import core = require('otplib/core');
import hotp = require('otplib/hotp');
import totp = require('otplib/totp');
@@ -7,8 +8,8 @@ const SECRET = '1234567890';
let secret = '';
let token = '';
-secret = otplib.authenticator.generateSecret(20);
-token = otplib.authenticator.generate(secret);
+secret = otplib.authenticator.generateSecret(20); // $ExpectType string
+token = otplib.authenticator.generate(secret); // $ExpectType string
otplib.authenticator.check(token, secret); // $ExpectType boolean
otplib.authenticator.checkDelta(token, secret); // $ExpectType number | null
@@ -27,7 +28,7 @@ authenticator.keyuri('me', 'otplib-test', secret); // $ExpectType string
authenticator.Authenticator;
authenticator.getClass();
-token = otplib.totp.generate(SECRET);
+token = otplib.totp.generate(SECRET); // $ExpectType string
otplib.totp.check(token, SECRET); // $ExpectType boolean
otplib.totp.checkDelta(token, SECRET); // $ExpectType number | null
otplib.totp.verify({ secret: SECRET, token }); // $ExpectType boolean
@@ -39,7 +40,7 @@ totp.verify({ secret: SECRET, token }); // $ExpectType boolean
totp.TOTP;
totp.getClass();
-token = otplib.hotp.generate(SECRET, 1);
+token = otplib.hotp.generate(SECRET, 1); // $ExpectType string
otplib.hotp.check(token, SECRET, 1); // $ExpectType boolean
otplib.hotp.verify({ secret: SECRET, token, counter: 1 }); // $ExpectType boolean
otplib.hotp.HOTP;
@@ -48,3 +49,17 @@ hotp.check(token, SECRET, 1); // $ExpectType boolean
hotp.verify({ secret: SECRET, token, counter: 1 }); // $ExpectType boolean
hotp.HOTP;
hotp.getClass();
+
+const hotpOpt = core.hotpOptions({});
+core.hotpCheck('123', SECRET, 0, hotpOpt); // $ExpectType boolean
+core.hotpCounter(0); // $ExpectType string
+core.hotpDigest(SECRET, 0, hotpOpt); // $ExpectType string
+core.hotpSecret(SECRET, { algorithm: hotpOpt.algorithm, encoding: hotpOpt.encoding }); // $ExpectType Buffer
+core.hotpToken(SECRET, 0, hotpOpt); // $ExpectType string
+
+const totpOpt = core.totpOptions({});
+core.totpCheck('123', SECRET, totpOpt); // $ExpectType boolean
+core.totpCheckWithWindow('123', SECRET, totpOpt); // $ExpectType number | null
+core.totpCounter(new Date().valueOf(), 0); // $ExpectType number
+core.totpSecret(SECRET, { algorithm: totpOpt.algorithm, encoding: totpOpt.encoding }); // $ExpectType Buffer
+core.totpToken(SECRET, totpOpt); // $ExpectType string
diff --git a/packages/types-ts/tsconfig.json b/packages/types-ts/tsconfig.json
index fa1ff72e..60bf52fb 100644
--- a/packages/types-ts/tsconfig.json
+++ b/packages/types-ts/tsconfig.json
@@ -15,6 +15,9 @@
"otplib": [
"index"
],
+ "otplib/core": [
+ "core"
+ ],
"otplib/hotp": [
"hotp"
],