UNPKG

otp-code-generator-and-validator

Version:

Generate and validate time-based OTP (one time password) for multifactor authentication.

68 lines 1.94 kB
import lodash from "lodash"; import { toDataURL } from "qrcode"; import { generateHOTP, getCounterFromTime } from "./utils.js"; export { generateSecret, generateTOTP, verifyTOTP, generateKeyUri, generateQRCode }; function generateSecret() { let length = 16; let delimiter = ""; let array = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".repeat(length).split(delimiter); for (let i = (array.length - 1); i > 0; i--) { let j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array.join(delimiter).substring(0, length); } function generateTOTP({ secret, now = Date.now(), timeStep = 30 }) { let counter = getCounterFromTime({ now, timeStep }); return generateHOTP({ key: secret, counter }); } function verifyTOTP({ secret, token, now = Date.now(), timeStep = 30 }) { let counter = getCounterFromTime({ now, timeStep }); return generateHOTP({ key: secret, counter }) === token; } function generateKeyUri({ secret, account, app = "", timeStep = 30 }) { let params = {}; if (app) { params = { ...params, issuer: app }; } params = { ...params, secret, algorithm: "SHA1", digits: 6, period: timeStep }; let paramsString = lodash(params).map((value, key) => { return (encodeURIComponent(key) + "=" + encodeURIComponent(value)); }).join("&"); return ("otpauth://totp/" + (app ?? (encodeURIComponent(app) + ":")) + encodeURIComponent(account) + "?" + paramsString); } async function generateQRCode({ text, options = { errorCorrectionLevel: "medium", type: "image/png", width: 500, color: { dark: "#000000", light: "#ffffff" } } }) { return toDataURL(text.trim(), { ...options }); } //# sourceMappingURL=index.js.map