From da49c83d765e88fb505bcfc76e6f41763f5ceedd Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 2 Mar 2018 16:46:49 -0800 Subject: authenticate sockets and only emit to specific subscribers --- db.js | 7 ++++++ index.js | 75 +++++++++++++++++++++++++++++++++++++++++++++--------------- package.json | 2 ++ passport.js | 9 ++++++-- yarn.lock | 17 ++++++++++++++ 5 files changed, 90 insertions(+), 20 deletions(-) diff --git a/db.js b/db.js index 445df70e..42ba47f9 100644 --- a/db.js +++ b/db.js @@ -70,6 +70,13 @@ const p = (lnrpc) => { db[k] = db.define(k, fields, { tableName: t }) + if (t === 'invoices') { + db['Invoice'].belongsTo(db['User'], { + as: 'user', + foreignKey: 'user_id' + }) + } + let typefields = {} let options = {} diff --git a/index.js b/index.js index 1584adc8..f36b5b92 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ import dotenv from 'dotenv' import express from 'express' import fs from 'fs' import grpc from 'grpc' +import io from 'socket.io' import jwt from 'jsonwebtoken' import reverse from 'buffer-reverse' import zmq from 'zmq' @@ -36,10 +37,6 @@ const l = console.log metab.add('macaroon', macb.toString('hex')) lnb.meta = metab - const db = await require('./db')(lna) - const passport = require('./passport')(db) - const auth = passport.authenticate('jwt', { session: false }) - const bc = new core({ username: 'adam', password: 'MPJzfq97', @@ -53,21 +50,56 @@ const l = console.log app.use(cookieParser()) app.use(cors({ credentials: true, origin: 'http://*:*' })) app.use(compression()) - app.use(passport.initialize()) const server = require('http').Server(app) - const io = require('socket.io')(server, { origins: '*:*' }) + const socket = io(server, { origins: '*:*' }) + const db = await require('./db')(lna) + const passport = require('./passport')(db) + const auth = passport.authenticate('jwt', { session: false }) + const sids = {} - const invoices = lna.subscribeInvoices({}) - invoices.on('data', msg => { - io.emit('invoices', msg) + socket.use((socket, next) => { + try { + let token = socket.request.headers.cookie.match(`;\\s*token=([^;]+)`)[1] + let user = jwt.decode(token).username + socket.request.user = user + sids[user] = socket.id + l(sids) + } catch (e) { l(e) } + next() }) - const invoicesb = lnb.subscribeInvoices({}) - invoicesb.on('data', msg => { - io.emit('invoices', msg) + socket.sockets.on('connect', socket => { + socket.emit('success', { + message: 'success logged in!', + user: socket.request.user + }) }) + app.use(passport.initialize()) + + const handlePayment = async msg => { + let invoice = await db['Invoice'].findOne({ + include: { model: db['User'], as: 'user' }, + where: { + payreq: msg.payment_request + } + }) + + if (!invoice) return + + invoice.user.channelbalance += parseInt(msg.value) + await invoice.user.save() + + socket.to(sids[invoice.user.username]).emit('invoice', msg) + } + + const invoices = lna.subscribeInvoices({}) + invoices.on('data', handlePayment) + + const invoicesb = lnb.subscribeInvoices({}) + invoicesb.on('data', handlePayment) + const zmqSock = zmq.socket('sub') zmqSock.connect('tcp://127.0.0.1:18503') zmqSock.subscribe('rawblock') @@ -75,7 +107,6 @@ const l = console.log const seen = [] const channelpeers = [ - '02fa77e0f4ca666f7d158c4bb6675d1436e339903a9feeeaacbd6e55021b98e7ee', '039cc950286a8fa99218283d1adc2456e0d5e81be558da77dd6e85ba9a1fff5ad3', '0231eee2441073c86d38f6085aedaf2bb7ad3d43af4c0e2669c1edd1a7d566ce31', '022ea315e5052b152579e70a90bacfd6aa7420f2ce94674d4ca8da29d709bc70fd', @@ -111,7 +142,7 @@ const l = console.log user.balance += o.value await user.save() l('HIT!') - io.emit('tx', message) + socket.emit('tx', message) seen.push(message) } } catch(e) { } @@ -170,15 +201,22 @@ const l = console.log app.post('/faucet', auth, async (req, res) => { await bc.walletPassphrase('kek', 30000) await bc.sendToAddress(req.user.address, 0.001) + res.send('success') }) app.post('/sendPayment', auth, (req, res) => { const payments = lna.sendPayment(meta, {}) payments.write({ payment_request: req.body.payreq }) payments.on('data', async m => { - req.user.channelbalance -= m.value - await req.user.save() - res.send(m) + if (m.payment_error) { + l(m) + res.status(500).send({ error: m.payment_error }) + } else { + l(m, req.user.channelbalance) + req.user.channelbalance -= parseInt(m.payment_route.total_amt) + await req.user.save() + res.send(m) + } }) }) @@ -198,7 +236,7 @@ const l = console.log restClient.tickerGlobalPerSymbol('BTCCAD', (data) => { app.set('rates', JSON.parse(data)) }) - setTimeout(fetchRates, 120000) + setTimeout(fetchRates, 150000) })() app.get('/rates', (req, res) => { @@ -223,6 +261,7 @@ const l = console.log res.status(401).end() } } catch(err) { + l(err) res.status(401).end() } }) diff --git a/package.json b/package.json index 4eddb255..ce8804d2 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "node-http-proxy": "^0.2.3", "passport": "0.3.2", "passport-jwt": "^2.2.1", + "passport-jwt.socketio": "https://github.com/erreina/passport-jwt.socketio", "passport-local": "1.0.0", "redis": "2.6.2", "request": "~2.75.0", @@ -58,6 +59,7 @@ "sequelize-cli": "^3.2.0", "socket.io": "^2.0.4", "socket.io-client": "^2.0.4", + "socketio-jwt-auth": "https://github.com/adcentury/socketio-jwt-auth", "sql-template-strings": "^2.2.2", "twilio": "^2.11.1", "zeromq": "^4.6.0", diff --git a/passport.js b/passport.js index ac34178f..7456532a 100644 --- a/passport.js +++ b/passport.js @@ -3,16 +3,19 @@ import jwt from 'passport-jwt' import dotenv from 'dotenv' dotenv.config() +const l = console.log + function cookieExtractor (req) { if (req && req.cookies) return req.cookies['token'] return null } module.exports = (db) => { - passport.use(new jwt.Strategy({ + passport.use( + new jwt.Strategy({ jwtFromRequest: jwt.ExtractJwt.fromExtractors([cookieExtractor]), secretOrKey: process.env.SECRET - }, async function (payload, next) { + }, async (payload, next) => { try { let user = await db.User.findOne({ where: { @@ -21,6 +24,7 @@ module.exports = (db) => { }) next(null, user) } catch(err) { + l(err) next(null, false) } }) @@ -29,3 +33,4 @@ module.exports = (db) => { return passport } + diff --git a/yarn.lock b/yarn.lock index 7c552c7e..71eb74fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3759,6 +3759,10 @@ jws@^3.0.0, jws@^3.1.4: jwa "^1.1.4" safe-buffer "^5.0.1" +jwt-simple@^0.5: + version "0.5.1" + resolved "https://registry.yarnpkg.com/jwt-simple/-/jwt-simple-0.5.1.tgz#79ea01891b61de6b68e13e67c0b4b5bda937b294" + kind-of@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" @@ -4651,6 +4655,12 @@ parseurl@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" +"passport-jwt.socketio@https://github.com/erreina/passport-jwt.socketio": + version "0.1.1" + resolved "https://github.com/erreina/passport-jwt.socketio#a2b50969a62166442aba8f15b88036b7b2d79ee3" + dependencies: + passport-jwt "^2.2.1" + passport-jwt@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-2.2.1.tgz#0e004c94071319d673d9d9bcfd1574a868011527" @@ -5751,6 +5761,13 @@ socket.io@^2.0.4: socket.io-client "2.0.4" socket.io-parser "~3.1.1" +"socketio-jwt-auth@https://github.com/adcentury/socketio-jwt-auth": + version "0.0.6" + resolved "https://github.com/adcentury/socketio-jwt-auth#2d267ac397a2dcfed32c8862e6f1669dc933b8b8" + dependencies: + jwt-simple "^0.5" + xtend "^4.0.0" + sort-keys-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" -- cgit v1.2.3