From 74b7d2a0d614f170ba5aea3a1a172a7a68356d80 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 13 Jun 2020 21:39:22 -0700 Subject: push notifications --- routes/balances.js | 61 -------------------------------------- routes/bitcoin/receive.js | 10 +++++-- routes/info.js | 72 +++++++++++++++++++++++++++++++++++++++++++++ routes/lightning/receive.js | 6 ++-- routes/liquid/receive.js | 8 +++-- routes/send.js | 3 +- routes/users.js | 41 ++++++++++++++++++++++++-- 7 files changed, 130 insertions(+), 71 deletions(-) delete mode 100644 routes/balances.js create mode 100644 routes/info.js (limited to 'routes') diff --git a/routes/balances.js b/routes/balances.js deleted file mode 100644 index ba834306..00000000 --- a/routes/balances.js +++ /dev/null @@ -1,61 +0,0 @@ -const sequelize = require("sequelize"); -const { Op } = sequelize; - -app.get("/info", async (req, res) => { - const accounts = await db.Account.findAll({ - attributes: [ - "asset", - [sequelize.fn("sum", sequelize.col("balance")), "total"] - ], - group: ["asset"], - }); - - let lnchannel; - let lnwallet; - let lninfo; - - if (config.lna) { - if (config.lna.clightning) { - const funds = await lna.listfunds(); - lninfo = await lna.getinfo(); - lnchannel = parseInt(funds.channels.reduce((a, b) => a + b.channel_sat, 0)); - lnwallet = parseInt(funds.outputs.reduce((a, b) => a + b.value, 0)); - } else { - lninfo = await lna.getInfo({}); - lnchannel = parseInt((await lna.channelBalance({})).balance); - lnwallet = parseInt((await lna.walletBalance({})).total_balance); - } - } - - let bitcoin, bitcoind; - if (config.bitcoin) { - bitcoin = parseInt((await bc.getBalance()) * SATS); - bitcoind = await bc.getNetworkInfo(); - } - - let assets, liquid, elementsd; - if (config.liquid) { - assets = await lq.getBalance(); - liquid = parseInt(assets.bitcoin * SATS); - elementsd = await lq.getNetworkInfo(); - } - - const info = { - bitcoind, - elementsd, - accounts, - assets, - bitcoin, - liquid, - lnchannel, - lnwallet, - }; - - info.total = - parseInt(bitcoin) + - parseInt(liquid) + - parseInt(lnchannel) + - parseInt(lnwallet); - - res.send(info); -}); diff --git a/routes/bitcoin/receive.js b/routes/bitcoin/receive.js index 6928dd5c..0593584e 100644 --- a/routes/bitcoin/receive.js +++ b/routes/bitcoin/receive.js @@ -106,7 +106,8 @@ zmqRawTx.on("message", async (topic, message, sequence) => { emit(user.username, "account", account); emit(user.username, "payment", payment); - l.info("bitcoin detected", user.username, o.value); + l.info("bitcoin detected", user.username, value); + notify(user, `${value} SAT payment detected`); } }) ); @@ -149,9 +150,11 @@ setInterval(async () => { const { user } = p; if (p) { + let total = p.amount + p.tip; + p.confirmed = 1; - p.account.balance += p.amount + p.tip; - p.account.pending -= Math.min(p.account.pending, p.amount + p.tip); + p.account.balance += total; + p.account.pending -= Math.min(p.account.pending, total); await p.account.save(); await p.save(); @@ -159,6 +162,7 @@ setInterval(async () => { emit(user.username, "account", p.account); emit(user.username, "payment", p); l.info("bitcoin confirmed", user.username, p.amount, p.tip); + notify(user, `${total} SAT payment confirmed`); } else { l.warn("couldn't find payment", hash); } diff --git a/routes/info.js b/routes/info.js new file mode 100644 index 00000000..81cb2095 --- /dev/null +++ b/routes/info.js @@ -0,0 +1,72 @@ +const sequelize = require("sequelize"); +const { Op } = sequelize; + +const fs = require("fs"); +try { + clientVersion = fs.readFileSync('config/clientversion').toString(); + l.info("client version", clientVersion); +} catch(e) { + l.warn("no client version found"); +} + +app.get("/info", async (req, res) => { + const accounts = await db.Account.findAll({ + attributes: [ + "asset", + [sequelize.fn("sum", sequelize.col("balance")), "total"] + ], + group: ["asset"], + }); + + let lnchannel; + let lnwallet; + let lninfo; + + if (config.lna) { + if (config.lna.clightning) { + const funds = await lna.listfunds(); + lninfo = await lna.getinfo(); + lnchannel = parseInt(funds.channels.reduce((a, b) => a + b.channel_sat, 0)); + lnwallet = parseInt(funds.outputs.reduce((a, b) => a + b.value, 0)); + } else { + lninfo = await lna.getInfo({}); + lnchannel = parseInt((await lna.channelBalance({})).balance); + lnwallet = parseInt((await lna.walletBalance({})).total_balance); + } + } + + let bitcoin, bitcoind; + if (config.bitcoin) { + bitcoin = parseInt((await bc.getBalance()) * SATS); + bitcoind = await bc.getNetworkInfo(); + } + + let assets, liquid, elementsd; + if (config.liquid) { + assets = await lq.getBalance(); + liquid = parseInt(assets.bitcoin * SATS); + elementsd = await lq.getNetworkInfo(); + } + + const info = { + bitcoind, + elementsd, + accounts, + assets, + bitcoin, + liquid, + lnchannel, + lnwallet, + rates: app.get("rates"), + nodes: networks, + clientVersion, + }; + + info.total = + parseInt(bitcoin) + + parseInt(liquid) + + parseInt(lnchannel) + + parseInt(lnwallet); + + res.send(info); +}); diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js index 6a9c95c8..292f19e2 100644 --- a/routes/lightning/receive.js +++ b/routes/lightning/receive.js @@ -48,8 +48,9 @@ const handlePayment = async msg => { }, { transaction }); - invoice.received += amount + tip; - account.balance += amount + tip; + let total = amount + tip; + invoice.received += total; + account.balance += total; await account.save({ transaction }); await invoice.save({ transaction }); @@ -60,6 +61,7 @@ const handlePayment = async msg => { payment.account = account.get({ plain: true }); emit(user.username, "payment", payment); emit(user.username, "account", payment.account); + notify(user, `Received ${total} SAT`); l.info( "lightning payment received", diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js index b3f82a2d..9a97aa47 100644 --- a/routes/liquid/receive.js +++ b/routes/liquid/receive.js @@ -121,6 +121,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => { emit(user.username, "payment", payment); l.info("liquid detected", user.username, asset, value); + notify(user, `${value} SAT payment detected`); } }) ); @@ -231,9 +232,10 @@ setInterval(async () => { const { user } = p; if (p) { + let total = p.amount + p.tip; p.confirmed = 1; - p.account.balance += p.amount + p.tip; - p.account.pending -= Math.min(p.account.pending, p.amount + p.tip); + p.account.balance += total; + p.account.pending -= Math.min(p.account.pending, total); await p.account.save(); await p.save(); @@ -247,6 +249,8 @@ setInterval(async () => { p.amount, p.tip ); + + notify(user, `${total} SAT payment confirmed`); } else { l.warn("couldn't find payment", hash); } diff --git a/routes/send.js b/routes/send.js index 837a9e45..8b4137d8 100644 --- a/routes/send.js +++ b/routes/send.js @@ -122,7 +122,8 @@ module.exports = async (req, res) => { emit(user.username, "account", account); emit(user.username, "payment", payment); - l.info("received internal", user.username, payment.amount); + l.info("received internal", user.username, amount); + notify(user, `Received ${amount} SAT`); }); } catch (e) { l.error( diff --git a/routes/users.js b/routes/users.js index fc2f2975..9de84b83 100644 --- a/routes/users.js +++ b/routes/users.js @@ -101,7 +101,10 @@ app.post("/register", async (req, res) => { let ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress; - if (!challenge[ip] || user.response.toLowerCase() !== challenge[ip].toLowerCase()) { + if ( + !challenge[ip] || + user.response.toLowerCase() !== challenge[ip].toLowerCase() + ) { l.info("failed challenge", ip, user.response, challenge[ip]); return res.status(500).send("Failed challenge"); } @@ -203,7 +206,8 @@ app.post("/user", auth, async (req, res) => { twofa, pin, password, - passconfirm + passconfirm, + tokens } = req.body; let exists = await db.User.findOne({ @@ -231,6 +235,7 @@ app.post("/user", auth, async (req, res) => { user.currency = currency; user.currencies = currencies; + user.tokens = tokens; user.twofa = twofa; user.pin = pin; @@ -290,6 +295,19 @@ app.post("/login", async (req, res) => { } }); + +app.post("/logout", auth, async (req, res) => { + let { subscription } = req.body; + l.info("logging out", req.user.username); + if (!subscription) return res.end(); + let i = req.user.subscriptions.findIndex(s => JSON.stringify(s) === subscription); + if (i > -1) { + req.user.subscriptions.splice(i, 1); + } + await req.user.save(); + res.end(); +}); + app.post("/address", auth, async (req, res) => { if (!config.bitcoin) return res.status(500).send("Bitcoin not configured"); @@ -363,3 +381,22 @@ app.post("/shiftAccount", auth, async (req, res) => { }); setInterval(() => (faucet = 2000), DAY); + +app.get("/vapidPublicKey", function(req, res) { + res.send(config.vapid.publicKey); +}); + +app.post("/subscribe", auth, async function(req, res) { + let { subscriptions } = req.user; + let { subscription } = req.body; + if (!subscriptions) subscriptions = []; + if ( + !subscriptions.find(s => JSON.stringify(s) === JSON.stringify(subscription)) + ) + subscriptions.push(subscription); + req.user.subscriptions = subscriptions; + l.info("subscribing", req.user.username); + await req.user.save(); + res.sendStatus(201); +}); + -- cgit v1.2.3