Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@epic-web/totp

Package Overview
Dependencies
Maintainers
0
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@epic-web/totp - npm Package Compare versions

Comparing version 1.1.3 to 2.0.0

14

index.d.ts

@@ -15,4 +15,4 @@ /**

* base32 encoded (you can use https://npm.im/thirty-two). Defaults to a random
* secret: base32Encode(crypto.randomBytes(10), 'RFC4648').
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}}
* secret: base32Encode(crypto.getRandomValues(new Uint8Array(10)), 'RFC4648').
* @returns {Promise<{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}>}
* The OTP, secret, and config options used to generate the OTP.

@@ -26,3 +26,3 @@ */

secret?: string;
}): {
}): Promise<{
otp: string;

@@ -34,3 +34,3 @@ secret: string;

charSet: string;
};
}>;
/**

@@ -74,3 +74,3 @@ * Generates a otpauth:// URI which you can use to generate a QR code or users

*
* @returns {{delta: number}|null} an object with "delta" which is the delta
* @returns {Promise<{delta: number}|null>} an object with "delta" which is the delta
* between the current OTP and the OTP that was verified, or null if the OTP is

@@ -87,4 +87,4 @@ * invalid.

window?: number;
}): {
}): Promise<{
delta: number;
} | null;
} | null>;
/**
* This was copy/paste/modified/tested from https://npm.im/notp (MIT)
*/
import * as crypto from 'node:crypto'
import base32Encode from 'base32-encode'

@@ -14,3 +12,3 @@ import base32Decode from 'base32-decode'

// Learn more: https://www.rfc-editor.org/rfc/rfc4226#page-25 (B.1. SHA-1 Status)
const DEFAULT_ALGORITHM = 'SHA1'
const DEFAULT_ALGORITHM = 'SHA-1'
const DEFAULT_CHAR_SET = '0123456789'

@@ -34,5 +32,5 @@ const DEFAULT_DIGITS = 6

* @param {string} [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
* @returns {string} The generated HOTP.
* @returns {Promise<string>} The generated HOTP.
*/
function generateHOTP(
async function generateHOTP(
secret,

@@ -46,7 +44,12 @@ {

) {
const byteCounter = Buffer.from(intToBytes(counter))
const secretBuffer = Buffer.from(secret)
const hmac = crypto.createHmac(algorithm, secretBuffer)
const digest = hmac.update(byteCounter).digest('hex')
const hashBytes = hexToBytes(digest)
const byteCounter = intToBytes(counter)
const key = await crypto.subtle.importKey(
'raw',
secret,
{ name: 'HMAC', hash: algorithm },
false,
['sign']
)
const signature = await crypto.subtle.sign('HMAC', key, byteCounter)
const hashBytes = new Uint8Array(signature)
const offset = hashBytes[19] & 0xf

@@ -73,3 +76,3 @@ let hotpVal =

* @param {string} otp - The OTP to verify.
* @param {Buffer} secret - The secret used to generate the HOTP.
* @param {ArrayBuffer} secret - The secret used to generate the HOTP.
* @param {Object} options - The configuration options for the HOTP.

@@ -85,7 +88,7 @@ * @param {number} [options.counter=0] - The counter value to use for the HOTP.

* before and after the current counter value. Defaults to 1.
* @returns {{delta: number}|null} An object with the `delta` property
* @returns {Promise<{delta: number}|null>} An object with the `delta` property
* indicating the number of counter values between the current counter value and
* the verified counter value, or `null` if the OTP could not be verified.
*/
function verifyHOTP(
async function verifyHOTP(
otp,

@@ -103,3 +106,3 @@ secret,

if (
generateHOTP(secret, { counter: i, digits, algorithm, charSet }) === otp
await generateHOTP(secret, { counter: i, digits, algorithm, charSet }) === otp
) {

@@ -126,14 +129,14 @@ return { delta: i - counter }

* base32 encoded (you can use https://npm.im/thirty-two). Defaults to a random
* secret: base32Encode(crypto.randomBytes(10), 'RFC4648').
* @returns {{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}}
* secret: base32Encode(crypto.getRandomValues(new Uint8Array(10)), 'RFC4648').
* @returns {Promise<{otp: string, secret: string, period: number, digits: number, algorithm: string, charSet: string}>}
* The OTP, secret, and config options used to generate the OTP.
*/
export function generateTOTP({
export async function generateTOTP({
period = DEFAULT_PERIOD,
digits = DEFAULT_DIGITS,
algorithm = DEFAULT_ALGORITHM,
secret = base32Encode(crypto.randomBytes(10), 'RFC4648'),
secret = base32Encode(crypto.getRandomValues(new Uint8Array(10)), 'RFC4648'),
charSet = DEFAULT_CHAR_SET,
} = {}) {
const otp = generateHOTP(base32Decode(secret, 'RFC4648'), {
const otp = await generateHOTP(base32Decode(secret, 'RFC4648'), {
counter: getCounter(period),

@@ -201,7 +204,7 @@ digits,

*
* @returns {{delta: number}|null} an object with "delta" which is the delta
* @returns {Promise<{delta: number}|null>} an object with "delta" which is the delta
* between the current OTP and the OTP that was verified, or null if the OTP is
* invalid.
*/
export function verifyTOTP({
export async function verifyTOTP({
otp,

@@ -223,3 +226,3 @@ secret,

return verifyHOTP(otp, Buffer.from(decodedSecret), {
return verifyHOTP(otp, new Uint8Array(decodedSecret), {
counter: getCounter(period),

@@ -237,22 +240,14 @@ digits,

* @param {number} num The number to convert to a byte array.
* @returns {number[]} The byte array representation of the number.
* @returns {Uint8Array} The byte array representation of the number.
*/
function intToBytes(num) {
const buffer = Buffer.alloc(8)
// eslint-disable-next-line no-undef
buffer.writeBigInt64BE(BigInt(num))
return [...buffer]
const arr = new Uint8Array(8)
for (let i = 7; i >= 0; i--) {
arr[i] = num & 0xff
num = num >> 8
}
return arr
}
/**
* Converts a hexadecimal string to a byte array.
*
* @param {string} hex The hexadecimal string to convert to a byte array.
* @returns {number[]} The byte array representation of the hexadecimal string.
*/
function hexToBytes(hex) {
return [...Buffer.from(hex, 'hex')]
}
/**
* Calculates the current counter value for the TOTP based on the current time

@@ -268,2 +263,2 @@ * and the specified period.

return counter
}
}

@@ -14,3 +14,3 @@ {

},
"version": "1.1.3",
"version": "2.0.0",
"description": "Create and verify cryptographically secure Time-based One-time Passwords (TOTP) using the HMAC-based One-time Password (HOTP) algorithm.",

@@ -42,3 +42,3 @@ "main": "index.js",

"engines": {
"node": ">=18"
"node": ">=20"
},

@@ -45,0 +45,0 @@ "prettier": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc