2fa-plus
Version:
Implementation of two-factor authentication in Node, made simple.
85 lines (84 loc) • 2.55 kB
JavaScript
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/index.ts
import notp from "notp";
import crypto from "crypto";
import b32 from "thirty-two";
function generateSecret(name, account) {
return __async(this, null, function* () {
const bin = crypto.randomBytes(20);
const base32 = b32.encode(bin).toString("utf8").replace(/=/g, "");
const secret = base32.toLowerCase().replace(/(\w{4})/g, "$1 ").trim().split(" ").join("").toUpperCase();
const uri = `otpauth://totp/${name}:${account}?secret=${secret}&issuer=${name}`;
const qrLib = __require("qrcode");
const qr = yield new Promise((resolve, reject) => {
qrLib.toDataURL(uri, function(err, url) {
if (err) {
reject(err);
} else {
resolve(url);
}
});
});
return { secret, uri, qr };
});
}
function generateToken(secret) {
return __async(this, null, function* () {
if (!secret)
return "";
const unformatted = secret.replace(/\W+/g, "").toUpperCase();
const bin = b32.decode(unformatted);
return notp.totp.gen(bin);
});
}
function verifyToken(secret, token) {
return __async(this, null, function* () {
if (!token || !secret)
return false;
const unformatted = secret.replace(/\W+/g, "").toUpperCase();
const bin = b32.decode(unformatted);
const verify = notp.totp.verify(token.replace(/\W+/g, ""), bin, {
window: 4,
time: 30
});
if (!verify)
return false;
if (verify.delta)
return true;
if (verify.delta === 0)
return true;
return false;
});
}
export {
generateSecret,
generateToken,
verifyToken
};
//# sourceMappingURL=index.mjs.map