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
JavaScript
"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;
};