Encrypted LND Sockets
This commit is contained in:
parent
643443434d
commit
9dc028d8fb
1 changed files with 145 additions and 43 deletions
188
src/sockets.js
188
src/sockets.js
|
|
@ -1,67 +1,169 @@
|
||||||
|
/** @prettier */
|
||||||
// app/sockets.js
|
// app/sockets.js
|
||||||
|
|
||||||
const logger = require("winston");
|
const logger = require('winston')
|
||||||
const LightningServices = require("../utils/lightningServices");
|
const Encryption = require('../utils/encryptionStore')
|
||||||
|
const LightningServices = require('../utils/lightningServices')
|
||||||
|
|
||||||
module.exports = (
|
module.exports = (
|
||||||
/** @type {import('socket.io').Server} */
|
/** @type {import('socket.io').Server} */
|
||||||
io
|
io
|
||||||
) => {
|
) => {
|
||||||
const Mediator = require("../services/gunDB/Mediator/index.js");
|
const Mediator = require('../services/gunDB/Mediator/index.js')
|
||||||
|
|
||||||
|
// This should be used for encrypting and emitting your data
|
||||||
|
const emitEncryptedEvent = ({ eventName, data, socket }) => {
|
||||||
|
try {
|
||||||
|
if (Encryption.isNonEncrypted(eventName)) {
|
||||||
|
return socket.emit(eventName, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deviceId = socket.handshake.query['x-shockwallet-device-id']
|
||||||
|
const authorized = Encryption.isAuthorizedDevice({ deviceId })
|
||||||
|
|
||||||
|
if (!deviceId) {
|
||||||
|
throw {
|
||||||
|
field: 'deviceId',
|
||||||
|
message: 'Please specify a device ID'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
throw {
|
||||||
|
field: 'deviceId',
|
||||||
|
message: 'Please exchange keys with the API before using the socket'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const encryptedMessage = Encryption.encryptMessage({
|
||||||
|
message: data,
|
||||||
|
deviceId
|
||||||
|
})
|
||||||
|
|
||||||
|
return socket.emit(eventName, encryptedMessage)
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(
|
||||||
|
`[SOCKET] An error has occurred while encrypting an event (${eventName}):`,
|
||||||
|
err
|
||||||
|
)
|
||||||
|
|
||||||
|
return socket.emit('encryption:error', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseJSON = data => {
|
||||||
|
try {
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
return JSON.parse(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
} catch (err) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const decryptEvent = ({ eventName, data, socket }) => {
|
||||||
|
try {
|
||||||
|
const deviceId = socket.handshake.query['x-shockwallet-device-id']
|
||||||
|
if (Encryption.isNonEncrypted(eventName)) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedData = parseJSON(data)
|
||||||
|
|
||||||
|
if (!deviceId) {
|
||||||
|
throw {
|
||||||
|
field: 'deviceId',
|
||||||
|
message: 'Please specify a device ID'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Encryption.isAuthorizedDevice({ deviceId })) {
|
||||||
|
throw {
|
||||||
|
field: 'deviceId',
|
||||||
|
message: 'Please exchange keys with the API before using the socket'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const decryptedKey = Encryption.decryptKey({
|
||||||
|
deviceId,
|
||||||
|
message: parsedData.encryptedKey
|
||||||
|
})
|
||||||
|
const decryptedMessage = Encryption.decryptMessage({
|
||||||
|
message: parsedData.encryptedData,
|
||||||
|
key: decryptedKey,
|
||||||
|
iv: parsedData.iv
|
||||||
|
})
|
||||||
|
const decryptedData = JSON.parse(decryptedMessage)
|
||||||
|
return decryptedData
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(
|
||||||
|
`[SOCKET] An error has occurred while decrypting an event (${eventName}):`,
|
||||||
|
err
|
||||||
|
)
|
||||||
|
|
||||||
|
return socket.emit('encryption:error', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const onNewInvoice = socket => {
|
const onNewInvoice = socket => {
|
||||||
const { lightning } = LightningServices.services;
|
const { lightning } = LightningServices.services
|
||||||
logger.warn("Subscribing to invoices socket...")
|
logger.warn('Subscribing to invoices socket...')
|
||||||
const stream = lightning.subscribeInvoices({});
|
const stream = lightning.subscribeInvoices({})
|
||||||
stream.on("data", data => {
|
stream.on('data', data => {
|
||||||
logger.info("[SOCKET] New invoice data:", data);
|
logger.info('[SOCKET] New invoice data:', data)
|
||||||
socket.emit("invoice:new", data)
|
emitEncryptedEvent({ eventName: 'invoice:new', data, socket })
|
||||||
})
|
})
|
||||||
stream.on("end", () => {
|
stream.on('end', () => {
|
||||||
logger.info("New invoice stream ended, starting a new one...")
|
logger.info('New invoice stream ended, starting a new one...')
|
||||||
onNewInvoice(socket);
|
onNewInvoice(socket)
|
||||||
})
|
})
|
||||||
stream.on("error", err => {
|
stream.on('error', err => {
|
||||||
logger.error("New invoice stream error:", err);
|
logger.error('New invoice stream error:', err)
|
||||||
})
|
})
|
||||||
stream.on("status", status => {
|
stream.on('status', status => {
|
||||||
logger.error("New invoice stream status:", status);
|
logger.warn('New invoice stream status:', status)
|
||||||
if (status.code === 14) {
|
if (status.code === 14) {
|
||||||
onNewInvoice(socket);
|
onNewInvoice(socket)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const onNewTransaction = socket => {
|
const onNewTransaction = socket => {
|
||||||
const { lightning } = LightningServices.services;
|
const { lightning } = LightningServices.services
|
||||||
const stream = lightning.subscribeTransactions({});
|
const stream = lightning.subscribeTransactions({})
|
||||||
logger.warn("Subscribing to transactions socket...")
|
logger.warn('Subscribing to transactions socket...')
|
||||||
stream.on("data", data => {
|
stream.on('data', data => {
|
||||||
logger.info("[SOCKET] New transaction data:", data);
|
logger.info('[SOCKET] New transaction data:', data)
|
||||||
socket.emit("transaction:new", data)
|
emitEncryptedEvent({ eventName: 'transaction:new', data, socket })
|
||||||
})
|
})
|
||||||
stream.on("end", () => {
|
stream.on('end', () => {
|
||||||
logger.info("New invoice stream ended, starting a new one...")
|
logger.info('New invoice stream ended, starting a new one...')
|
||||||
onNewTransaction(socket);
|
onNewTransaction(socket)
|
||||||
})
|
})
|
||||||
stream.on("error", err => {
|
stream.on('error', err => {
|
||||||
logger.error("New invoice stream error:", err);
|
logger.error('New invoice stream error:', err)
|
||||||
})
|
})
|
||||||
stream.on("status", status => {
|
stream.on('status', status => {
|
||||||
logger.error("New invoice stream status:", status);
|
logger.error('New invoice stream status:', status)
|
||||||
if (status.code === 14) {
|
if (status.code === 14) {
|
||||||
onNewTransaction(socket);
|
onNewTransaction(socket)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
io.on("connection", socket => {
|
io.on('connection', socket => {
|
||||||
logger.info(`io.onconnection`)
|
logger.info(`io.onconnection`)
|
||||||
|
|
||||||
logger.info("socket.handshake", socket.handshake);
|
logger.info('socket.handshake', socket.handshake)
|
||||||
|
|
||||||
/** printing out the client who joined */
|
/** printing out the client who joined */
|
||||||
logger.info("New socket client connected (id=" + socket.id + ").");
|
logger.info('New socket client connected (id=' + socket.id + ').')
|
||||||
|
|
||||||
const isOneTimeUseSocket = !!socket.handshake.query.IS_GUN_AUTH
|
const isOneTimeUseSocket = !!socket.handshake.query.IS_GUN_AUTH
|
||||||
const isLNDSocket = !!socket.handshake.query.IS_LND_SOCKET
|
const isLNDSocket = !!socket.handshake.query.IS_LND_SOCKET
|
||||||
|
|
@ -92,18 +194,18 @@ module.exports = (
|
||||||
logger.info('New socket is NOT one time use')
|
logger.info('New socket is NOT one time use')
|
||||||
// this is where we create the websocket connection
|
// this is where we create the websocket connection
|
||||||
// with the GunDB service.
|
// with the GunDB service.
|
||||||
Mediator.createMediator(socket);
|
Mediator.createMediator(socket)
|
||||||
if (isLNDSocket) {
|
if (isLNDSocket) {
|
||||||
onNewInvoice(socket);
|
onNewInvoice(socket)
|
||||||
onNewTransaction(socket);
|
onNewTransaction(socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** listening if client has disconnected */
|
/** listening if client has disconnected */
|
||||||
socket.on("disconnect", () => {
|
socket.on('disconnect', () => {
|
||||||
logger.info("client disconnected (id=" + socket.id + ").");
|
logger.info('client disconnected (id=' + socket.id + ').')
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return io;
|
return io
|
||||||
};
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue