@levminer/speakeasy
Advanced tools
Comparing version 1.0.4 to 1.0.5
147
main.js
@@ -21,3 +21,3 @@ const base32 = require("base32.js") | ||
exports.digest = digest = (options) => { | ||
exports.digest = function digest(options) { | ||
let i | ||
@@ -33,3 +33,3 @@ | ||
if (options.key != null) { | ||
console.error("@levminer/speakeasy - Deprecation Notice - Specifying the secret using `key` is no longer supported. Use `secret` instead.") | ||
console.warn("@levminer/speakeasy - Deprecation Notice - Specifying the secret using `key` is no longer supported. Use `secret` instead.") | ||
secret = options.key | ||
@@ -43,24 +43,2 @@ } | ||
let secret_buffer_size | ||
if (algorithm === "sha1") { | ||
secret_buffer_size = 20 // 20 bytes | ||
} else if (algorithm === "sha256") { | ||
secret_buffer_size = 32 // 32 bytes | ||
} else if (algorithm === "sha512") { | ||
secret_buffer_size = 64 // 64 bytes | ||
} else { | ||
console.error( | ||
`@levminer/speakeasy - The algorithm provided (\`${algorithm}\`) is not officially supported, results may be different than expected.` | ||
) | ||
} | ||
// The secret for sha1, sha256 and sha512 needs to be a fixed number of bytes for the one-time-password to be calculated correctly | ||
// Pad the buffer to the correct size be repeating the secret to the desired length | ||
if (secret_buffer_size && secret.length !== secret_buffer_size) { | ||
secret = Buffer.from(Array(Math.ceil(secret_buffer_size / secret.length) + 1).join(secret.toString("hex")), "hex").slice( | ||
0, | ||
secret_buffer_size | ||
) | ||
} | ||
// create an buffer from the counter | ||
@@ -97,3 +75,4 @@ const buf = Buffer.alloc(8) | ||
* @param {Buffer} [options.digest] Digest, automatically generated by default | ||
* @param {Integer} [options.digits=6] The number of digits for the one-time passcode. | ||
* @param {Integer} [options.digits=6] The number of digits for the one-time | ||
* passcode. | ||
* @param {String} [options.encoding="ascii"] Key encoding (ascii, hex, | ||
@@ -110,18 +89,3 @@ * base32, base64). | ||
exports.hotp = hotpGenerate = (options) => { | ||
// verify secret and counter exists | ||
const secret = options.secret | ||
const key = options.key | ||
const counter = options.counter | ||
if (key === null || typeof key === "undefined") { | ||
if (secret === null || typeof secret === "undefined") { | ||
throw new Error("@levminer/speakeasy - hotp - Missing secret") | ||
} | ||
} | ||
if (counter === null || typeof counter === "undefined") { | ||
throw new Error("@levminer/speakeasy - hotp - Missing counter") | ||
} | ||
exports.hotp = function hotpGenerate(options) { | ||
// unpack digits | ||
@@ -131,3 +95,3 @@ // backward compatibility: `length` is also accepted here, but deprecated | ||
if (options.length != null) | ||
console.error( | ||
console.warn( | ||
"@levminer/speakeasy - Deprecation Notice - Specifying token digits using `length` is no longer supported. Use `digits` instead." | ||
@@ -193,3 +157,3 @@ ) | ||
exports.hotp.verifyDelta = hotpVerifyDelta = (options) => { | ||
exports.hotp.verifyDelta = function hotpVerifyDelta(options) { | ||
let i | ||
@@ -200,9 +164,4 @@ | ||
// verify secret and token exist | ||
const secret = options.secret | ||
let token = options.token | ||
if (secret === null || typeof secret === "undefined") throw new Error("@levminer/@levminer/speakeasy - hotp.verifyDelta - Missing secret") | ||
if (token === null || typeof token === "undefined") throw new Error("@levminer/@levminer/speakeasy - hotp.verifyDelta - Missing token") | ||
token = String(options.token) | ||
// unpack options | ||
let token = String(options.token) | ||
const digits = parseInt(options.digits, 10) || 6 | ||
@@ -264,3 +223,3 @@ const window = parseInt(options.window, 10) || 0 | ||
*/ | ||
exports.hotp.verify = hotpVerify = (options) => { | ||
exports.hotp.verify = function hotpVerify(options) { | ||
return exports.hotp.verifyDelta(options) != null | ||
@@ -287,3 +246,3 @@ } | ||
exports._counter = _counter = (options) => { | ||
exports._counter = function _counter(options) { | ||
const step = options.step || 30 | ||
@@ -295,4 +254,4 @@ const time = options.time != null ? options.time * 1000 : Date.now() | ||
if (options.initial_time != null) | ||
console.error( | ||
"@levminer/@levminer/speakeasy - Deprecation Notice - Specifying the epoch using `initial_time` is no longer supported. Use `epoch` instead." | ||
console.warn( | ||
"@levminer/speakeasy - Deprecation Notice - Specifying the epoch using `initial_time` is no longer supported. Use `epoch` instead." | ||
) | ||
@@ -338,15 +297,6 @@ | ||
exports.totp = totpGenerate = (options) => { | ||
exports.totp = function totpGenerate(options) { | ||
// shadow options | ||
options = Object.create(options) | ||
// verify secret exists if key is not specified | ||
const key = options.key | ||
const secret = options.secret | ||
if (key === null || typeof key === "undefined") { | ||
if (secret === null || typeof secret === "undefined") { | ||
throw new Error("@levminer/@levminer/speakeasy - totp - Missing secret") | ||
} | ||
} | ||
// calculate default counter value | ||
@@ -408,10 +358,5 @@ if (options.counter == null) options.counter = exports._counter(options) | ||
exports.totp.verifyDelta = totpVerifyDelta = (options) => { | ||
exports.totp.verifyDelta = function totpVerifyDelta(options) { | ||
// shadow options | ||
options = Object.create(options) | ||
// verify secret and token exist | ||
const secret = options.secret | ||
const token = options.token | ||
if (secret === null || typeof secret === "undefined") throw new Error("@levminer/@levminer/speakeasy - totp.verifyDelta - Missing secret") | ||
if (token === null || typeof token === "undefined") throw new Error("@levminer/@levminer/speakeasy - totp.verifyDelta - Missing token") | ||
@@ -470,3 +415,3 @@ // unpack options | ||
*/ | ||
exports.totp.verify = totpVerify = (options) => { | ||
exports.totp.verify = function totpVerify(options) { | ||
return exports.totp.verifyDelta(options) != null | ||
@@ -484,3 +429,4 @@ } | ||
* @property {String} qr_code_base32 URL for the QR code for the base32 secret. | ||
* @property {String} google_auth_qr URL for the Google Authenticator otpauth URL's QR code. | ||
* @property {String} google_auth_qr URL for the Google Authenticator otpauth | ||
* URL's QR code. | ||
* @property {String} otpauth_url Google Authenticator-compatible otpauth URL. | ||
@@ -509,12 +455,10 @@ */ | ||
* implementation.) Output a Google Authenticator otpauth:// QR code URL. | ||
* @param {String} [options.issuer=''] The provider or service with which the | ||
* secret key is associated. | ||
* @return {Object} | ||
* @return {GeneratedSecret} The generated secret key. | ||
*/ | ||
exports.generateSecret = generateSecret = (options) => { | ||
exports.generateSecret = function generateSecret(options) { | ||
// options | ||
if (!options) options = {} | ||
const length = options.length || 32 | ||
const name = options.name || "SecretKey" | ||
const name = encodeURIComponent(options.name || "SecretKey") | ||
const qr_codes = options.qr_codes || false | ||
@@ -524,3 +468,2 @@ const google_auth_qr = options.google_auth_qr || false | ||
let symbols = true | ||
const issuer = options.issuer | ||
@@ -538,9 +481,9 @@ // turn off symbols only when explicity told to | ||
SecretKey.ascii = key | ||
SecretKey.hex = Buffer.from(key, "ascii").toString("hex") | ||
SecretKey.base32 = base32.encode(Buffer.from(key)).toString().replace(/=/g, "") | ||
SecretKey.hex = Buffer.alloc(key, "ascii").toString("hex") | ||
SecretKey.base32 = base32.encode(Buffer.alloc(key)).toString().replace(/=/g, "") | ||
// generate some qr codes if requested | ||
if (qr_codes) { | ||
console.error( | ||
"@levminer/@levminer/speakeasy - Deprecation Notice - generateSecret() QR codes are deprecated and no longer supported. Please use your own QR code implementation." | ||
console.warn( | ||
"@levminer/speakeasy - Deprecation Notice - generateSecret() QR codes are deprecated and no longer supported. Please use your own QR code implementation." | ||
) | ||
@@ -557,3 +500,2 @@ SecretKey.qr_code_ascii = `https://chart.googleapis.com/chart?chs=166x166&chld=L|0&cht=qr&chl=${encodeURIComponent(SecretKey.ascii)}` | ||
label: name, | ||
issuer: issuer, | ||
}) | ||
@@ -564,4 +506,4 @@ } | ||
if (google_auth_qr) { | ||
console.error( | ||
"@levminer/@levminer/speakeasy - Deprecation Notice - generateSecret() Google Auth QR code is deprecated and no longer supported. Please use your own QR code implementation." | ||
console.warn( | ||
"@levminer/speakeasy - Deprecation Notice - generateSecret() Google Auth QR code is deprecated and no longer supported. Please use your own QR code implementation." | ||
) | ||
@@ -579,3 +521,3 @@ SecretKey.google_auth_qr = `https://chart.googleapis.com/chart?chs=166x166&chld=L|0&cht=qr&chl=${encodeURIComponent( | ||
return exports.generateSecret(options) | ||
}, "@levminer/@levminer/speakeasy - Deprecation Notice - `generate_key()` is depreciated, please use `generateSecret()` instead.") | ||
}, "@levminer/speakeasy - Deprecation Notice - `generate_key()` is depreciated, please use `generateSecret()` instead.") | ||
@@ -590,3 +532,3 @@ /** | ||
*/ | ||
exports.generateSecretASCII = generateSecretASCII = (length, symbols) => { | ||
exports.generateSecretASCII = function generateSecretASCII(length, symbols) { | ||
const bytes = crypto.randomBytes(length || 32) | ||
@@ -608,3 +550,3 @@ let set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz" | ||
return exports.generateSecretASCII(length, symbols) | ||
}, "@levminer/@levminer/speakeasy - Deprecation Notice - `generate_key_ascii()` is depreciated, please use `generateSecretASCII()` instead.") | ||
}, "@levminer/speakeasy - Deprecation Notice - `generate_key_ascii()` is depreciated, please use `generateSecretASCII()` instead.") | ||
@@ -651,3 +593,3 @@ /** | ||
exports.otpauthURL = otpauthURL = (options) => { | ||
exports.otpauthURL = function otpauthURL(options) { | ||
// unpack options | ||
@@ -659,5 +601,5 @@ let secret = options.secret | ||
const counter = options.counter | ||
const algorithm = (options.algorithm || "sha1").toLowerCase() | ||
const digits = options.digits || 6 | ||
let period = options.period || 30 | ||
const algorithm = options.algorithm | ||
const digits = options.digits | ||
let period = options.period | ||
const encoding = options.encoding || "ascii" | ||
@@ -671,16 +613,16 @@ | ||
default: | ||
throw new Error(`@levminer/@levminer/speakeasy - otpauthURL - Invalid type \`${type}\`; must be \`hotp\` or \`totp\``) | ||
throw new Error(`@levminer/speakeasy - otpauthURL - Invalid type \`${type}\`; must be \`hotp\` or \`totp\``) | ||
} | ||
// validate required options | ||
if (!secret) throw new Error("@levminer/@levminer/speakeasy - otpauthURL - Missing secret") | ||
if (!label) throw new Error("@levminer/@levminer/speakeasy - otpauthURL - Missing label") | ||
if (!secret) throw new Error("@levminer/speakeasy - otpauthURL - Missing secret") | ||
if (!label) throw new Error("@levminer/speakeasy - otpauthURL - Missing label") | ||
// require counter for HOTP | ||
if (type === "hotp" && (counter === null || typeof counter === "undefined")) { | ||
throw new Error("@levminer/@levminer/speakeasy - otpauthURL - Missing counter value for HOTP") | ||
throw new Error("@levminer/speakeasy - otpauthURL - Missing counter value for HOTP") | ||
} | ||
// convert secret to base32 | ||
if (encoding !== "base32") secret = Buffer.from(secret, encoding) | ||
if (encoding !== "base32") secret = Buffer.alloc(secret, encoding) | ||
if (Buffer.isBuffer(secret)) secret = base32.encode(secret) | ||
@@ -691,5 +633,2 @@ | ||
if (issuer) query.issuer = issuer | ||
if (type === "hotp") { | ||
query.counter = counter | ||
} | ||
@@ -704,3 +643,3 @@ // validate algorithm | ||
default: | ||
console.error("@levminer/@levminer/speakeasy - otpauthURL - Warning - Algorithm generally should be SHA1, SHA256, or SHA512") | ||
console.warn("@levminer/speakeasy - otpauthURL - Warning - Algorithm generally should be SHA1, SHA256, or SHA512") | ||
} | ||
@@ -713,3 +652,3 @@ query.algorithm = algorithm.toUpperCase() | ||
if (isNaN(digits)) { | ||
throw new Error(`@levminer/@levminer/speakeasy - otpauthURL - Invalid digits \`${digits}\``) | ||
throw new Error(`@levminer/speakeasy - otpauthURL - Invalid digits \`${digits}\``) | ||
} else { | ||
@@ -721,3 +660,3 @@ switch (parseInt(digits, 10)) { | ||
default: | ||
console.error("@levminer/@levminer/speakeasy - otpauthURL - Warning - Digits generally should be either 6 or 8") | ||
console.warn("@levminer/speakeasy - otpauthURL - Warning - Digits generally should be either 6 or 8") | ||
} | ||
@@ -732,3 +671,3 @@ } | ||
if (~~period !== period) { | ||
throw new Error(`@levminer/@levminer/speakeasy - otpauthURL - Invalid period \`${period}\``) | ||
throw new Error(`@levminer/speakeasy - otpauthURL - Invalid period \`${period}\``) | ||
} | ||
@@ -743,5 +682,5 @@ query.period = period | ||
hostname: type, | ||
pathname: encodeURIComponent(label), | ||
pathname: label, | ||
query: query, | ||
}) | ||
} |
{ | ||
"name": "@levminer/speakeasy", | ||
"description": "Two-factor authentication for Node.js. Generate One-time passcode generator (HOTP/TOTP) with support for Google Authenticator.", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"homepage": "http://github.com/Levminer/speakeasy", | ||
@@ -24,3 +24,3 @@ "bugs": "https://github.com/Levminer/speakeasy/issues", | ||
"dependencies": { | ||
"base32.js": "0.0.1" | ||
"base32.js": "0.1.0" | ||
}, | ||
@@ -27,0 +27,0 @@ "devDependencies": { |
84565
621
+ Addedbase32.js@0.1.0(transitive)
- Removedbase32.js@0.0.1(transitive)
Updatedbase32.js@0.1.0