UNPKG

xotp

Version:

One-Time Password (HOTP/TOTP) library for Node.js, Deno and Bun, with support for Google Authenticator.

108 lines (107 loc) 5.33 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _TOTP_instances, _TOTP_hotp, _TOTP_calcHotpCounter; Object.defineProperty(exports, "__esModule", { value: true }); exports.TOTP = void 0; const hotp_1 = require("./hotp"); class TOTP { constructor({ algorithm = this.defaults.algorithm, window = this.defaults.window, duration = this.defaults.duration, digits = this.defaults.digits, issuer = this.defaults.issuer, account = this.defaults.account, } = {}) { _TOTP_instances.add(this); this.algorithm = this.defaults.algorithm; this.digits = this.defaults.digits; this.window = this.defaults.window; this.duration = this.defaults.duration; this.issuer = this.defaults.issuer; this.account = this.defaults.account; _TOTP_hotp.set(this, void 0); this.algorithm = algorithm; this.digits = digits; this.window = window; this.duration = duration; this.issuer = issuer; this.account = account; __classPrivateFieldSet(this, _TOTP_hotp, new hotp_1.HOTP({ algorithm, window, digits }), "f"); } get defaults() { return Object.freeze({ algorithm: "sha1", duration: 30, digits: 6, window: 1, issuer: "xotp", account: "", }); } generate({ secret, timestamp = Date.now(), algorithm = this.algorithm, digits = this.digits, duration = this.duration, }) { return __classPrivateFieldGet(this, _TOTP_hotp, "f").generate({ secret, counter: __classPrivateFieldGet(this, _TOTP_instances, "m", _TOTP_calcHotpCounter).call(this, { timestamp, duration }), algorithm, digits, }); } validate({ token, secret, timestamp = Date.now(), algorithm = this.algorithm, digits = this.digits, duration = this.duration, window = this.window, }) { return __classPrivateFieldGet(this, _TOTP_hotp, "f").validate({ token, secret, counter: __classPrivateFieldGet(this, _TOTP_instances, "m", _TOTP_calcHotpCounter).call(this, { timestamp, duration }), algorithm, digits, window: window, }); } compare({ token, secret, timestamp = Date.now(), algorithm = this.algorithm, digits = this.digits, duration = this.duration, window = this.window, }) { return __classPrivateFieldGet(this, _TOTP_hotp, "f").compare({ token, secret, window, algorithm, digits, counter: __classPrivateFieldGet(this, _TOTP_instances, "m", _TOTP_calcHotpCounter).call(this, { timestamp, duration }), }); } equals({ token, secret, timestamp = Date.now(), algorithm = this.algorithm, digits = this.digits, duration = this.duration, }) { return __classPrivateFieldGet(this, _TOTP_hotp, "f").equals({ token, secret, algorithm, digits, counter: __classPrivateFieldGet(this, _TOTP_instances, "m", _TOTP_calcHotpCounter).call(this, { timestamp, duration }), }); } timeUsed({ timestamp = Date.now(), duration = this.duration, } = {}) { return ((timestamp / 1000) | 0) % duration; } timeRemaining({ timestamp = Date.now(), duration = this.duration, } = {}) { return duration - this.timeUsed({ timestamp, duration }); } keyUri({ secret, account, issuer = this.issuer, algorithm = this.algorithm, duration = this.duration, digits = this.digits, }) { const e = encodeURIComponent; const params = [ `secret=${e(secret.toString("base32").replace(/=+$/, ""))}`, `algorithm=${e(algorithm.toUpperCase())}`, `digits=${e(digits)}`, `period=${e(duration)}`, ]; let label = account; if (issuer) { label = `${e(issuer)}:${e(label)}`; params.push(`issuer=${e(issuer)}`); } return `otpauth://totp/${label}?${params.join("&")}`; } } exports.TOTP = TOTP; _TOTP_hotp = new WeakMap(), _TOTP_instances = new WeakSet(), _TOTP_calcHotpCounter = function _TOTP_calcHotpCounter({ timestamp, duration, }) { return (timestamp / 1000 / duration) | 0; };