aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/createLnrpc.js2
-rw-r--r--models/users.js9
-rw-r--r--package.json3
-rw-r--r--payUser.js11
-rw-r--r--payments.js7
-rw-r--r--queryRoutes.js11
-rw-r--r--schema.sql74
-rw-r--r--sendLiquid.js7
-rw-r--r--sendPayment.js92
-rw-r--r--users.js98
-rw-r--r--yarn.lock71
11 files changed, 244 insertions, 141 deletions
diff --git a/lib/createLnrpc.js b/lib/createLnrpc.js
index 661440bb..e32f6be3 100644
--- a/lib/createLnrpc.js
+++ b/lib/createLnrpc.js
@@ -23,7 +23,7 @@ module.exports = async ({ server, tls, macaroon, channelpeers }) => {
let fn;
if (streaming) {
- if (key === "sendPayment") {
+ if (key === "sendPayment" || key === "sendToRoute") {
fn = params => method.call(lnrpc, target.meta, params);
} else {
fn = params => method.call(lnrpc, params, target.meta);
diff --git a/models/users.js b/models/users.js
index 8edc94b0..467a0e3b 100644
--- a/models/users.js
+++ b/models/users.js
@@ -85,6 +85,15 @@ module.exports = sequelize => {
comment: null,
field: "symbol"
},
+ otpsecret: {
+ type: DataTypes.STRING(255),
+ allowNull: true,
+ defaultValue: "CAD",
+ primaryKey: false,
+ autoIncrement: false,
+ comment: null,
+ field: "otpsecret"
+ },
currency: {
type: DataTypes.STRING(255),
allowNull: true,
diff --git a/package.json b/package.json
index b63e65bf..d558f398 100644
--- a/package.json
+++ b/package.json
@@ -32,13 +32,14 @@
"grpc": "^1.23.3",
"http-proxy-middleware": "^0.20.0",
"jsonwebtoken": "^8.5.1",
- "lnrpc": "^0.6.1",
+ "lnrpc": "^0.6.2",
"lodash": "^4.17.13",
"mailgun-js": "^0.22.0",
"moment": "^2.24.0",
"morgan": "^1.9.1",
"mysql": "^2.17.1",
"mysql2": "^1.6.5",
+ "otplib": "^12.0.1",
"passport": "0.4.0",
"passport-jwt": "^4.0.0",
"passport-local": "1.0.0",
diff --git a/payUser.js b/payUser.js
index 3712c12d..676b0093 100644
--- a/payUser.js
+++ b/payUser.js
@@ -1,4 +1,6 @@
-module.exports = (app, db, lnb) => async (req, res) => {
+const bolt11 = require("bolt11");
+
+module.exports = (app, db, lna, lnb) => async (req, res) => {
let { payuser, amount } = req.body;
let user = await db.User.findOne({
@@ -34,6 +36,11 @@ module.exports = (app, db, lnb) => async (req, res) => {
});
req.url = "/sendPayment";
- req.body.payreq = invoice.payment_request;
+ let payreq = bolt11.decode(hash);
+ const { routes } = await lna.queryRoutes({ "pub_key": payreq.payeeNodeKey, "amt": payreq.satoshis });
+ if (routes.length) req.body.route = routes[0];
+ else return res.status(500).send("No route available");
+ req.body.payreq = hash;
+
return app._router.handle(req, res);
};
diff --git a/payments.js b/payments.js
index 9866d244..ed8bfccf 100644
--- a/payments.js
+++ b/payments.js
@@ -10,11 +10,16 @@ module.exports = async (app, auth, addresses, bc, db, emit, seen, payments) => {
require("./lightningPayments")(app, db, lna, lnb, emit, payments);
app.post(
+ "/queryRoutes",
+ auth,
+ require("./queryRoutes")(app, db, emit, seen, lna, lnb)
+ );
+ app.post(
"/sendPayment",
auth,
require("./sendPayment")(app, db, emit, seen, lna, lnb)
);
- app.post("/payUser", auth, require("./payUser")(app, db, lnb));
+ app.post("/payUser", auth, require("./payUser")(app, db, lna, lnb));
app.post("/sendCoins", auth, require("./sendCoins")(app, bc, db, emit));
app.post("/sendLiquid", auth, require("./sendLiquid")(app, db, emit));
app.post("/addInvoice", auth, require("./addInvoice")(app, db, lnb));
diff --git a/queryRoutes.js b/queryRoutes.js
new file mode 100644
index 00000000..068027e7
--- /dev/null
+++ b/queryRoutes.js
@@ -0,0 +1,11 @@
+const bolt11 = require("bolt11");
+const config = require("./config");
+
+const l = console.log;
+
+module.exports = (app, db, emit, seen, lna, lnb) => async (req, res) => {
+ let hash = req.body.payreq;
+ let payreq = bolt11.decode(hash);
+ const routes = await lna.queryRoutes({ "pub_key": payreq.payeeNodeKey, "amt": payreq.satoshis });
+ res.send(routes);
+};
diff --git a/schema.sql b/schema.sql
index 38c37ea3..7bdf7d3b 100644
--- a/schema.sql
+++ b/schema.sql
@@ -1,8 +1,8 @@
--- MySQL dump 10.17 Distrib 10.3.12-MariaDB, for debian-linux-gnu (x86_64)
+-- MySQL dump 10.17 Distrib 10.3.22-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: coinos
-- ------------------------------------------------------
--- Server version 10.3.12-MariaDB-1:10.3.12+maria~bionic
+-- Server version 10.3.22-MariaDB-1:10.3.22+maria~bionic
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@@ -31,24 +31,6 @@ CREATE TABLE `SequelizeMeta` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `orders`
---
-
-DROP TABLE IF EXISTS `orders`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `orders` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `amount` int(11) DEFAULT NULL,
- `price` int(11) DEFAULT NULL,
- `type` varchar(255) DEFAULT NULL,
- `pair` varchar(255) DEFAULT NULL,
- `createdAt` datetime DEFAULT current_timestamp(),
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
-- Table structure for table `payments`
--
@@ -58,18 +40,20 @@ DROP TABLE IF EXISTS `payments`;
CREATE TABLE `payments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
- `hash` varchar(255) DEFAULT NULL,
+ `hash` text DEFAULT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
`rate` double DEFAULT NULL,
- `currency` varchar(255) DEFAULT NULL,
- `address` int(11) DEFAULT NULL,
+ `currency` varchar(255) NOT NULL,
+ `address` varchar(255) DEFAULT NULL,
`received` tinyint(1) DEFAULT NULL,
`amount` double DEFAULT NULL,
`tip` double DEFAULT NULL,
- `confirmed` tinyint(1) DEFAULT NOT NULL,
+ `confirmed` tinyint(1) NOT NULL,
+ `fee` double DEFAULT NULL,
+ `asset` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=1611 DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB AUTO_INCREMENT=2782 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -87,7 +71,7 @@ CREATE TABLE `users` (
`address` varchar(255) DEFAULT NULL,
`unit` varchar(255) DEFAULT NULL,
`symbol` varchar(255) DEFAULT NULL,
- `currency` varchar(255) NOT NULL DEFAULT 'CAD',
+ `currency` varchar(255) DEFAULT NULL,
`commission` varchar(255) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`pubkey` varchar(255) DEFAULT NULL,
@@ -106,42 +90,18 @@ CREATE TABLE `users` (
`pic` varchar(255) DEFAULT NULL,
`emailToken` varchar(255) DEFAULT NULL,
`phone` varchar(255) DEFAULT NULL,
- `phoneVerified` varchar(255) DEFAULT NULL,
+ `phoneVerified` tinyint(1) DEFAULT NULL,
`twofa` tinyint(1) DEFAULT NULL,
`authyId` varchar(255) DEFAULT NULL,
`pin` varchar(255) DEFAULT NULL,
`emailVerified` tinyint(1) DEFAULT NULL,
`phoneToken` varchar(255) DEFAULT NULL,
+ `confidential` varchar(255) DEFAULT NULL,
+ `liquid` varchar(255) DEFAULT NULL,
+ `currencies` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
+ `otp` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=305 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `users_balances`
---
-
-DROP TABLE IF EXISTS `users_balances`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `users_balances` (
- `user_id` int(11) DEFAULT NULL,
- `symbol` varchar(255) DEFAULT NULL,
- `balance` int(11) DEFAULT NULL,
- `pending` int(11) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `users_channels`
---
-
-DROP TABLE IF EXISTS `users_channels`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `users_channels` (
- `user_id` int(11) DEFAULT NULL,
- `channel_id` int(11) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+) ENGINE=InnoDB AUTO_INCREMENT=420 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -153,4 +113,4 @@ CREATE TABLE `users_channels` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2019-02-09 15:40:59
+-- Dump completed on 2020-02-09 15:22:43
diff --git a/sendLiquid.js b/sendLiquid.js
index 1a218afe..1008f014 100644
--- a/sendLiquid.js
+++ b/sendLiquid.js
@@ -30,6 +30,7 @@ module.exports = (app, db, emit) => async (req, res) => {
fee = parseInt(fee * SATS);
total = amount + fee;
} catch (e) {
+ l("funding failed", e);
return res.status(500).send(e.message);
}
@@ -52,13 +53,13 @@ module.exports = (app, db, emit) => async (req, res) => {
await user.save({ transaction });
});
} catch (e) {
- l(e);
+ l("balance check failed", e);
return res.status(500).send("Not enough satoshis");
}
try {
if (config.liquid.walletpass)
- await bc.walletPassphrase(config.bitcoin.walletpass, 300);
+ await bc.walletPassphrase(config.liquid.walletpass, 300);
rawtx = (await bc.signRawTransactionWithWallet(hex)).hex;
let txid = await bc.sendRawTransaction(rawtx);
@@ -87,7 +88,7 @@ module.exports = (app, db, emit) => async (req, res) => {
res.send(payment);
});
} catch (e) {
- l(e);
+ l("send failed", e);
return res.status(500).send(e.message);
}
};
diff --git a/sendPayment.js b/sendPayment.js
index ff5b9609..1bc8b99a 100644
--- a/sendPayment.js
+++ b/sendPayment.js
@@ -6,6 +6,7 @@ const l = console.log;
module.exports = (app, db, emit, seen, lna, lnb) => async (req, res) => {
let hash = req.body.payreq;
let payreq = bolt11.decode(hash);
+ let { route } = req.body;
let { user } = req;
l("sending lightning", user.username, payreq.satoshis);
@@ -36,60 +37,57 @@ module.exports = (app, db, emit, seen, lna, lnb) => async (req, res) => {
return res.status(500).send("Not enough satoshis");
}
- const stream = lna.sendPayment(lna.meta, {});
- stream.write({ payment_request: req.body.payreq });
-
- stream.on("data", async m => {
- if (m.payment_error) {
- res.status(500).send(m.payment_error);
- } else {
- if (seen.includes(m.payment_preimage)) return;
- seen.push(m.payment_preimage);
-
- let total = parseInt(m.payment_route.total_amt);
- let fee = m.payment_route.total_fees;
+ let m;
+ try {
+ let paymentHash = payreq.tags.find(t => t.tagName === 'payment_hash').data;
+ m = await lna.sendToRouteSync({
+ "payment_hash": Buffer.from(paymentHash, 'hex'),
+ route
+ });
- user.balance -= total - payreq.satoshis;
+ if (seen.includes(m.payment_preimage)) return;
+ seen.push(m.payment_preimage);
- await db.transaction(async transaction => {
- await user.save({ transaction });
+ let total = parseInt(m.payment_route.total_amt);
+ let fee = m.payment_route.total_fees;
- const payment = await db.Payment.create(
- {
- amount: -total,
- fee,
- user_id: user.id,
- hash,
- rate: app.get("rates")[user.currency],
- currency: user.currency,
- confirmed: true,
- asset: 'LNBTC',
- },
- { transaction }
- );
+ user.balance -= total - payreq.satoshis;
- emit(user.username, "payment", payment);
- emit(user.username, "user", user);
+ await db.transaction(async transaction => {
+ await user.save({ transaction });
- if (payreq.payeeNodeKey === config.lnb.id) {
- let invoice = await lna.addInvoice({ value: payreq.satoshis });
- let payback = lnb.sendPayment(lnb.meta, {});
+ const payment = await db.Payment.create(
+ {
+ amount: -total,
+ fee,
+ user_id: user.id,
+ hash,
+ rate: app.get("rates")[user.currency],
+ currency: user.currency,
+ confirmed: true,
+ asset: 'LNBTC',
+ },
+ { transaction }
+ );
- /* eslint-disable-next-line */
- let { payment_request } = invoice;
- /* eslint-disable-next-line */
- payback.write({ payment_request });
- }
+ emit(user.username, "payment", payment);
+ emit(user.username, "user", user);
- seen.push(hash);
- res.send(payment);
- });
- }
- });
+ if (payreq.payeeNodeKey === config.lnb.id) {
+ let invoice = await lna.addInvoice({ value: payreq.satoshis });
+ let payback = lnb.sendPayment(lnb.meta, {});
- stream.on("error", e => {
- let msg = e.message;
+ /* eslint-disable-next-line */
+ let { payment_request } = invoice;
+ /* eslint-disable-next-line */
+ payback.write({ payment_request });
+ }
- res.status(500).send(msg);
- });
+ seen.push(hash);
+ res.send(payment);
+ });
+ } catch (e) {
+ l(e);
+ return res.status(500).send(e);
+ }
};
diff --git a/users.js b/users.js
index 05d6ae97..8575bf25 100644
--- a/users.js
+++ b/users.js
@@ -1,23 +1,30 @@
-const { Client } = require("authy-client");
const axios = require("axios");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const mailgun = require("mailgun-js");
const uuidv4 = require("uuid/v4");
const BitcoinCore = require("bitcoin-core");
-const authyVerify = require("./authy");
const config = require("./config");
-const authy = new Client({ key: config.authy.key });
const whitelist = require("./whitelist");
const fb = "https://graph.facebook.com/";
const liquid = new BitcoinCore(config.liquid);
const Sequelize = require("sequelize");
+const authenticator = require("otplib").authenticator;
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
const l = console.log;
let faucet = 1000;
const DAY = 24 * 60 * 60 * 1000;
+const twofa = (req, res, next) => {
+ let {
+ user,
+ body: { token }
+ } = req;
+ if (!user.twofa || authenticator.check(token, user.otpsecret)) next();
+ else res.status(401).send("2fa required");
+};
+
module.exports = (addresses, auth, app, bc, db, emit) => {
app.get("/liquidate", async (req, res) => {
let users = await db.User.findAll();
@@ -30,6 +37,11 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
)).unconfidential;
await user.save();
}
+
+ if (!user.otpsecret) {
+ user.otpsecret = authenticator.generateSecret();
+ await user.save();
+ }
}
res.end();
});
@@ -40,17 +52,17 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
faucet -= 100;
const payment = await db.Payment.create({
user_id: user.id,
- hash: 'Welcome Gift',
+ hash: "Welcome Gift",
amount: 100,
currency: user.currency,
rate: app.get("rates")[user.currency],
received: true,
confirmed: 1,
- asset: 'GIFT',
+ asset: "GIFT"
});
await user.save();
}
- }
+ };
app.post("/register", async (req, res) => {
let err = m => res.status(500).send(m);
@@ -66,24 +78,24 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
user.confidential
)).unconfidential;
user.name = user.username;
- let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
+ let ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
let countries = {
CA: "CAD",
US: "USD",
JP: "JPY",
CN: "CNY",
AU: "AUD",
- GB: "GBP",
+ GB: "GBP"
};
- if (ip === "127.0.0.1")
- user.currency = "CAD";
+ if (ip === "127.0.0.1") user.currency = "CAD";
else {
let info = await axios.get(`http://api.ipstack.com/${ip}?access_key=${config.ipstack}`);
user.currency = countries[info.data.country_code] || "USD";
}
user.currencies = [user.currency];
+ user.otpsecret = authenticator.generateSecret();
addresses[user.address] = user.username;
addresses[user.liquid] = user.username;
@@ -143,6 +155,38 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
res.end();
});
+ app.post("/disable2fa", auth, twofa, async (req, res) => {
+ let { user } = req;
+ user.twofa = false;
+ await user.save();
+ emit(user.username, "user", user);
+ emit(user.username, "otpsecret", user.otpsecret);
+ res.end();
+ });
+
+ app.get("/otpsecret", auth, twofa, async (req, res) => {
+ let { user } = req;
+ emit(user.username, "otpsecret", user.otpsecret);
+ res.end();
+ });
+
+ app.post("/2fa", auth, async (req, res) => {
+ let { user } = req;
+ try {
+ const isValid = authenticator.check(req.body.token, req.user.otpsecret);
+ if (isValid) {
+ user.twofa = true;
+ user.save();
+ emit(user.username, "user", req.user);
+ } else {
+ return res.status(500).send("Invalid token");
+ }
+ } catch (e) {
+ l(e);
+ }
+ res.end();
+ });
+
app.post("/user", auth, async (req, res) => {
try {
let { user } = req;
@@ -170,7 +214,9 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
addresses[user.address] = username;
addresses[user.liquid] = user.username;
token = jwt.sign({ username }, config.jwt);
- res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
+ res.cookie("token", token, {
+ expires: new Date(Date.now() + 432000000)
+ });
}
if (email && user.email !== email) {
@@ -206,15 +252,6 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
user.password = await bcrypt.hash(password, 1);
}
- if (twofa && !user.authyId && user.phoneVerified) {
- try {
- let r = await authy.registerUser({ countryCode: "CA", email, phone });
- user.authyId = r.user.id;
- } catch (e) {
- l(e);
- }
- }
-
await user.save();
emit(user.username, "user", req.user);
res.send({ user, token });
@@ -297,6 +334,8 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
});
app.post("/login", async (req, res) => {
+ let twofa = req.body.token;
+
try {
let user = await db.User.findOne({
where: {
@@ -306,12 +345,15 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
if (
!user ||
- (user.password && !(await bcrypt.compare(req.body.password, user.password))) ||
- (user.twofa && !(await authyVerify(user)))
+ (user.password &&
+ !(await bcrypt.compare(req.body.password, user.password)))
) {
return res.status(401).end();
}
+ if (user.twofa && (typeof twofa === "undefined" || !authenticator.check(twofa, user.otpsecret)))
+ return res.status(401).send("2fa required");
+
let payload = { username: user.username };
let token = jwt.sign(payload, config.jwt);
res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
@@ -319,13 +361,14 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
user = pick(user, ...whitelist);
res.send({ user, token });
} catch (err) {
- console.log(err);
+ l(err);
res.status(401).end();
}
});
app.post("/facebookLogin", async (req, res) => {
let { accessToken, userID } = req.body;
+ let twofa = req.body.token;
let url = `https://graph.facebook.com/debug_token?input_token=${accessToken}&access_token=${
config.facebook.appToken
@@ -367,17 +410,18 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
await gift(user);
}
+ if (user.twofa && (typeof twofa === "undefined" || !authenticator.check(twofa, user.otpsecret)))
+ return res.status(401).send("2fa required");
+
user.pic = (await axios.get(
`${fb}/me/picture?access_token=${accessToken}&redirect=false`
)).data.data.url;
user.fbtoken = accessToken;
await user.save();
- if (user.twofa && !(await authyVerify(user))) res.status(401).end();
-
let payload = { username: user.username };
let token = jwt.sign(payload, config.jwt);
- res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
+ res.cookie("token", token , { expires: new Date(Date.now() + 432000000) });
res.send({ user, token });
} catch (err) {
l(err);
@@ -423,5 +467,5 @@ module.exports = (addresses, auth, app, bc, db, emit) => {
}
});
- setInterval(() => faucet = 2000, DAY)
+ setInterval(() => (faucet = 2000), DAY);
};
diff --git a/yarn.lock b/yarn.lock
index 3f09bd9a..d2c1ce3a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -161,6 +161,54 @@ __metadata:
languageName: node
linkType: hard
+"@otplib/core@npm:^12.0.1":
+ version: 12.0.1
+ resolution: "@otplib/core@npm:12.0.1"
+ checksum: 3a73c409dc4e9a3dbb8d1e4bd3cb438883c0c7f287c8a7485ef558b47e8e72af18e23e4817d085b9f5e40ce970d7b0ce11ae5524692927c964c80ce399840480
+ languageName: node
+ linkType: hard
+
+"@otplib/plugin-crypto@npm:^12.0.1":
+ version: 12.0.1
+ resolution: "@otplib/plugin-crypto@npm:12.0.1"
+ dependencies:
+ "@otplib/core": ^12.0.1
+ checksum: f83458ed5a4ac91118d7bc113385d0ab296c7b97e243903a887f2097c1b03421e5f670be60f808d96a9934f3a0049aceb2af02f71e54d5f22f065000b841a0c6
+ languageName: node
+ linkType: hard
+
+"@otplib/plugin-thirty-two@npm:^12.0.1":
+ version: 12.0.1
+ resolution: "@otplib/plugin-thirty-two@npm:12.0.1"
+ dependencies:
+ "@otplib/core": ^12.0.1
+ thirty-two: ^1.0.2
+ checksum: 4deec8586480f880239a087f6f6599eb4425abdda184e383112f97993bb5961943fdb435fbea086b1f9d1116768ec0c2fb6df9e8a0dbb854b7c0765dbbdcd9fe
+ languageName: node
+ linkType: hard
+
+"@otplib/preset-default@npm:^12.0.1":
+ version: 12.0.1
+ resolution: "@otplib/preset-default@npm:12.0.1"
+ dependencies:
+ "@otplib/core": ^12.0.1
+ "@otplib/plugin-crypto": ^12.0.1
+ "@otplib/plugin-thirty-two": ^12.0.1
+ checksum: 32b214c0f750c793147f1e988093959aef8eded36c9d7df2c2c7ff4e4fb54de85b76b5ff28ee8ee39b1572c933d205c081a3c8f2df192199813b3572e61a7305
+ languageName: node
+ linkType: hard
+
+"@otplib/preset-v11@npm:^12.0.1":
+ version: 12.0.1
+ resolution: "@otplib/preset-v11@npm:12.0.1"
+ dependencies:
+ "@otplib/core": ^12.0.1
+ "@otplib/plugin-crypto": ^12.0.1
+ "@otplib/plugin-thirty-two": ^12.0.1
+ checksum: 89366b1c52a8de2a1cd434c9fd534d97fcde0b103f92d15ff3cf37ed1d3579746b7b4b70efe398aa532ab44e15daa008d471f90f8b4de04f8cba81c05dfda7de
+ languageName: node
+ linkType: hard
+
"@pm2/agent-node@npm:^1.1.10":
version: 1.1.10
resolution: "@pm2/agent-node@npm:1.1.10"
@@ -1877,7 +1925,7 @@ __metadata:
grpc: ^1.23.3
http-proxy-middleware: ^0.20.0
jsonwebtoken: ^8.5.1
- lnrpc: ^0.6.1
+ lnrpc: ^0.6.2
lodash: ^4.17.13
mailgun-js: ^0.22.0
moment: ^2.24.0
@@ -1885,6 +1933,7 @@ __metadata:
mysql: ^2.17.1
mysql2: ^1.6.5
nodemon: ^2.0.2
+ otplib: ^12.0.1
passport: 0.4.0
passport-jwt: ^4.0.0
passport-local: 1.0.0
@@ -4970,7 +5019,7 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
-"lnrpc@npm:^0.6.1":
+"lnrpc@npm:^0.6.2":
version: 0.6.2
resolution: "lnrpc@npm:0.6.2"
dependencies:
@@ -6070,6 +6119,17 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"otplib@npm:^12.0.1":
+ version: 12.0.1
+ resolution: "otplib@npm:12.0.1"
+ dependencies:
+ "@otplib/core": ^12.0.1
+ "@otplib/preset-default": ^12.0.1
+ "@otplib/preset-v11": ^12.0.1
+ checksum: 93b006b69d7c51fa1e8d6e7a661c1208aa9410be10274a8eb81dcd1d2b1b08c3b9f1e2ef4e10d2a4ad4ef3a8f3e43da4830d21d674161a4fa43ac9e23594c437
+ languageName: node
+ linkType: hard
+
"p-cancelable@npm:^0.3.0":
version: 0.3.0
resolution: "p-cancelable@npm:0.3.0"
@@ -8350,6 +8410,13 @@ fsevents@~2.1.2:
languageName: node
linkType: hard
+"thirty-two@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "thirty-two@npm:1.0.2"
+ checksum: 573755c8a09da50666b4354fe6b6f8624cf2bfcf2c71ffbed531b6d73b988e1907be792ef23664749144978620ddb7026a158fc1c72d3eee4545b422dfc4e814
+ languageName: node
+ linkType: hard
+
"through@npm:^2.3.8":
version: 2.3.8
resolution: "through@npm:2.3.8"