From 244bc706c4b0f16fd1f6b845119b7757a13db6af Mon Sep 17 00:00:00 2001 From: ShahanaFarooqui Date: Fri, 19 Apr 2024 13:36:42 -0700 Subject: [PATCH] Updating Common Application Configuration --- backend/controllers/cln/channels.js | 12 +- backend/controllers/cln/getInfo.js | 6 +- backend/controllers/cln/invoices.js | 6 +- backend/controllers/cln/network.js | 10 +- backend/controllers/cln/offers.js | 8 +- backend/controllers/cln/onchain.js | 6 +- backend/controllers/cln/payments.js | 8 +- backend/controllers/cln/peers.js | 8 +- backend/controllers/cln/utility.js | 8 +- backend/controllers/cln/webSocketClient.js | 14 +- backend/controllers/eclair/channels.js | 16 +- backend/controllers/eclair/fees.js | 8 +- backend/controllers/eclair/getInfo.js | 8 +- backend/controllers/eclair/invoices.js | 20 +- backend/controllers/eclair/network.js | 6 +- backend/controllers/eclair/onchain.js | 10 +- backend/controllers/eclair/payments.js | 14 +- backend/controllers/eclair/peers.js | 12 +- backend/controllers/eclair/webSocketClient.js | 12 +- backend/controllers/lnd/balance.js | 2 +- backend/controllers/lnd/channels.js | 16 +- backend/controllers/lnd/channelsBackup.js | 24 +- backend/controllers/lnd/fees.js | 2 +- backend/controllers/lnd/getInfo.js | 8 +- backend/controllers/lnd/graph.js | 14 +- backend/controllers/lnd/invoices.js | 6 +- backend/controllers/lnd/message.js | 4 +- backend/controllers/lnd/newAddress.js | 2 +- backend/controllers/lnd/payments.js | 12 +- backend/controllers/lnd/peers.js | 10 +- backend/controllers/lnd/switch.js | 2 +- backend/controllers/lnd/transactions.js | 4 +- backend/controllers/lnd/wallet.js | 20 +- backend/controllers/lnd/webSocketClient.js | 12 +- backend/controllers/shared/RTLConf.js | 384 +++++++----------- backend/controllers/shared/authenticate.js | 22 +- backend/models/config.model.js | 105 ++--- backend/routes/shared/RTLConf.js | 16 +- backend/utils/app.js | 16 +- backend/utils/authCheck.js | 4 +- backend/utils/common.js | 179 ++++---- backend/utils/config.js | 162 ++++---- backend/utils/cors.js | 4 +- backend/utils/csrf.js | 4 +- backend/utils/database.js | 22 +- backend/utils/logger.js | 28 +- backend/utils/webSocketServer.js | 26 +- server/controllers/cln/channels.ts | 12 +- server/controllers/cln/getInfo.ts | 6 +- server/controllers/cln/invoices.ts | 6 +- server/controllers/cln/network.ts | 14 +- server/controllers/cln/offers.ts | 8 +- server/controllers/cln/onchain.ts | 6 +- server/controllers/cln/payments.ts | 12 +- server/controllers/cln/peers.ts | 8 +- server/controllers/cln/utility.ts | 8 +- server/controllers/cln/webSocketClient.ts | 24 +- server/controllers/eclair/channels.ts | 20 +- server/controllers/eclair/fees.ts | 14 +- server/controllers/eclair/getInfo.ts | 8 +- server/controllers/eclair/invoices.ts | 26 +- server/controllers/eclair/network.ts | 10 +- server/controllers/eclair/onchain.ts | 10 +- server/controllers/eclair/payments.ts | 22 +- server/controllers/eclair/peers.ts | 16 +- server/controllers/eclair/webSocketClient.ts | 22 +- server/controllers/lnd/balance.ts | 2 +- server/controllers/lnd/channels.ts | 20 +- server/controllers/lnd/channelsBackup.ts | 24 +- server/controllers/lnd/fees.ts | 2 +- server/controllers/lnd/getInfo.ts | 8 +- server/controllers/lnd/graph.ts | 18 +- server/controllers/lnd/invoices.ts | 6 +- server/controllers/lnd/message.ts | 4 +- server/controllers/lnd/newAddress.ts | 2 +- server/controllers/lnd/payments.ts | 16 +- server/controllers/lnd/peers.ts | 14 +- server/controllers/lnd/switch.ts | 2 +- server/controllers/lnd/transactions.ts | 4 +- server/controllers/lnd/wallet.ts | 20 +- server/controllers/lnd/webSocketClient.ts | 30 +- server/controllers/shared/RTLConf.ts | 378 +++++++---------- server/controllers/shared/authenticate.ts | 22 +- server/models/config.model.ts | 107 ++--- server/routes/shared/RTLConf.ts | 16 +- server/utils/app.ts | 16 +- server/utils/authCheck.ts | 4 +- server/utils/common.ts | 191 +++++---- server/utils/config.ts | 160 ++++---- server/utils/cors.ts | 4 +- server/utils/csrf.ts | 4 +- server/utils/database.ts | 40 +- server/utils/logger.ts | 28 +- server/utils/webSocketServer.ts | 32 +- 94 files changed, 1290 insertions(+), 1438 deletions(-) diff --git a/backend/controllers/cln/channels.js b/backend/controllers/cln/channels.js index 4f8a239e..15d7ae70 100644 --- a/backend/controllers/cln/channels.js +++ b/backend/controllers/cln/channels.js @@ -11,7 +11,7 @@ export const listPeerChannels = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeerchannels'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels }); return Promise.all(body.channels?.map((channel) => { @@ -33,7 +33,7 @@ export const openChannel = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/fundchannel'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fundchannel'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body }); request.post(options).then((body) => { @@ -50,7 +50,7 @@ export const setChannelFee = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/setchannel'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/setchannel'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body }); request.post(options).then((body) => { @@ -68,7 +68,7 @@ export const closeChannel = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/close'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/close'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url }); request.post(options).then((body) => { @@ -86,7 +86,7 @@ export const listForwards = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listforwards'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listforwards'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body }); @@ -103,7 +103,7 @@ export const funderUpdatePolicy = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/funderupdate'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/funderupdate'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body }); request.post(options).then((body) => { diff --git a/backend/controllers/cln/getInfo.js b/backend/controllers/cln/getInfo.js index 486a403f..9b917173 100644 --- a/backend/controllers/cln/getInfo.js +++ b/backend/controllers/cln/getInfo.js @@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo'; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url }); if (!options.headers || !options.headers.rune) { const errMsg = 'Core lightning get info failed due to missing rune!'; @@ -48,7 +48,7 @@ export const getInfo = (req, res, next) => { body.uris.push(body.id + '@' + addr.address + ':' + addr.port); }); } - req.session.selectedNode.ln_version = body.version || ''; + req.session.selectedNode.lnVersion = body.version || ''; req.session.selectedNode.api_version = body.api_version || ''; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' }); clWsClient.updateSelectedNode(req.session.selectedNode); diff --git a/backend/controllers/cln/invoices.js b/backend/controllers/cln/invoices.js index d7fdf280..2f26a949 100644 --- a/backend/controllers/cln/invoices.js +++ b/backend/controllers/cln/invoices.js @@ -10,7 +10,7 @@ export const deleteExpiredInvoice = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/delexpiredinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/delexpiredinvoice'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body }); @@ -26,7 +26,7 @@ export const listInvoices = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listinvoices'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listinvoices'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url }); request.post(options).then((body) => { @@ -43,7 +43,7 @@ export const addInvoice = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/invoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoice'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body }); diff --git a/backend/controllers/cln/network.js b/backend/controllers/cln/network.js index de74ebdf..81c72d29 100644 --- a/backend/controllers/cln/network.js +++ b/backend/controllers/cln/network.js @@ -10,7 +10,7 @@ export const getRoute = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/getroute'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getroute'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body }); @@ -29,7 +29,7 @@ export const listChannels = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listchannels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listchannels'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body }); @@ -46,7 +46,7 @@ export const feeRates = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/feerates'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/feerates'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body }); @@ -64,7 +64,7 @@ export const listNodes = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listnodes'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listnodes'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url }); request.post(options).then((body) => { @@ -80,7 +80,7 @@ export const listNodes = (req, res, next) => { }); }; export const getAlias = (selNode, peer, id) => { - options.url = selNode.ln_server_url + '/v1/listnodes'; + options.url = selNode.settings.lnServerUrl + '/v1/listnodes'; if (!peer[id]) { logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' }); peer.alias = ''; diff --git a/backend/controllers/cln/offers.js b/backend/controllers/cln/offers.js index 7b6113b9..f427d538 100644 --- a/backend/controllers/cln/offers.js +++ b/backend/controllers/cln/offers.js @@ -34,7 +34,7 @@ export const listOffers = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listoffers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listoffers'; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url }); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body }); @@ -50,7 +50,7 @@ export const createOffer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/offer'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/offer'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body }); @@ -66,7 +66,7 @@ export const fetchOfferInvoice = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/fetchinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fetchinvoice'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body }); request.post(options).then((body) => { @@ -83,7 +83,7 @@ export const disableOffer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/disableOffer'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disableOffer'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body }); diff --git a/backend/controllers/cln/onchain.js b/backend/controllers/cln/onchain.js index 5b39c870..f4615442 100644 --- a/backend/controllers/cln/onchain.js +++ b/backend/controllers/cln/onchain.js @@ -10,7 +10,7 @@ export const getNewAddress = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/newaddr'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddr'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); @@ -26,7 +26,7 @@ export const onChainWithdraw = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/withdraw'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/withdraw'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body }); request.post(options).then((body) => { @@ -43,7 +43,7 @@ export const getUTXOs = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listfunds'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listfunds'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body }); // Local Remote Balance Calculation diff --git a/backend/controllers/cln/payments.js b/backend/controllers/cln/payments.js index 2cacaaf6..6a756a00 100644 --- a/backend/controllers/cln/payments.js +++ b/backend/controllers/cln/payments.js @@ -8,7 +8,7 @@ const logger = Logger; const common = Common; const databaseService = Database; export const getMemo = (selNode, payment) => { - options.url = selNode.ln_server_url + '/v1/decode'; + options.url = selNode.settings.lnServerUrl + '/v1/decode'; options.body = { string: payment.bolt11 }; return request.post(options).then((res) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res }); @@ -81,7 +81,7 @@ export const listPayments = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listsendpays'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listsendpays'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments }); body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : []; @@ -103,7 +103,7 @@ export const postPayment = (req, res, next) => { const options_body = JSON.parse(JSON.stringify(req.body)); if (paymentType === 'KEYSEND') { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' }); - options.url = req.session.selectedNode.ln_server_url + '/v1/keysend'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/keysend'; delete options_body.uiMessage; delete options_body.fromDialog; delete options_body.paymentType; @@ -144,7 +144,7 @@ export const postPayment = (req, res, next) => { delete options_body.pubkey; delete options_body.saveToDB; options.body = options_body; - options.url = req.session.selectedNode.ln_server_url + '/v1/pay'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/pay'; } request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body }); diff --git a/backend/controllers/cln/peers.js b/backend/controllers/cln/peers.js index 70a01a33..dba0c304 100644 --- a/backend/controllers/cln/peers.js +++ b/backend/controllers/cln/peers.js @@ -11,7 +11,7 @@ export const getPeers = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); const peers = !body.peers ? [] : body.peers; @@ -30,12 +30,12 @@ export const postPeer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/connect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/connect'; options.body = req.body; request.post(options).then((connectRes) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes }); const listOptions = common.getOptions(req); - listOptions.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; + listOptions.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers'; request.post(listOptions).then((listPeersRes) => { const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : []; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers }); @@ -55,7 +55,7 @@ export const deletePeer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/disconnect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disconnect'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body }); diff --git a/backend/controllers/cln/utility.js b/backend/controllers/cln/utility.js index 2cace758..5a10dcdc 100644 --- a/backend/controllers/cln/utility.js +++ b/backend/controllers/cln/utility.js @@ -10,7 +10,7 @@ export const decodePayment = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/decode'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/decode'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); @@ -26,7 +26,7 @@ export const signMessage = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body }); @@ -42,7 +42,7 @@ export const verifyMessage = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/checkmessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/checkmessage'; options.body = req.body; request.post(options, (error, response, body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body }); @@ -58,7 +58,7 @@ export const listConfigs = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listconfigs'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listconfigs'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body }); res.status(200).json(body); diff --git a/backend/controllers/cln/webSocketClient.js b/backend/controllers/cln/webSocketClient.js index 5fb91a0b..5749ff92 100644 --- a/backend/controllers/cln/webSocketClient.js +++ b/backend/controllers/cln/webSocketClient.js @@ -27,14 +27,14 @@ export class CLWebSocketClient { try { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); if (!clientExists) { - if (selectedNode.ln_server_url) { + if (selectedNode.settings.lnServerUrl) { const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; this.connectWithClient(newWebSocketClient); this.webSocketClients.push(newWebSocketClient); } } else { - if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.ln_server_url) { + if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.settings.lnServerUrl) { clientExists.reConnect = true; this.connectWithClient(clientExists); } @@ -47,11 +47,11 @@ export class CLWebSocketClient { this.connectWithClient = (clWsClt) => { this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' }); try { - if (!clWsClt.selectedNode.rune_value) { - clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path); + if (!clWsClt.selectedNode.authentication.runeValue) { + clWsClt.selectedNode.authentication.runeValue = this.common.getRuneValue(clWsClt.selectedNode.authentication.runePath); } - clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, { - extraHeaders: { rune: clWsClt.selectedNode.rune_value }, + clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.settings.lnServerUrl, { + extraHeaders: { rune: clWsClt.selectedNode.authentication.runeValue }, transports: ['websocket'], secure: true, rejectUnauthorized: false @@ -65,7 +65,7 @@ export class CLWebSocketClient { this.waitTime = 0.5; }); clWsClt.webSocketClient.on('disconnect', (reason) => { - if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.ln_implementation === 'CLN') { + if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.lnImplementation === 'CLN') { this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason }); clWsClt.webSocketClient.close(); if (clWsClt.reConnect) { diff --git a/backend/controllers/eclair/channels.js b/backend/controllers/eclair/channels.js index 4923724e..e4bbfca8 100644 --- a/backend/controllers/eclair/channels.js +++ b/backend/controllers/eclair/channels.js @@ -27,7 +27,7 @@ export const simplifyAllChannels = (selNode, channels) => { }); }); channelNodeIds = channelNodeIds.substring(1); - options.url = selNode.ln_server_url + '/nodes'; + options.url = selNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: channelNodeIds }; logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds }); return request.post(options).then((nodes) => { @@ -47,7 +47,7 @@ export const getChannels = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/channels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/channels'; options.form = {}; if (req.query && req.query.nodeId) { options.form = req.query; @@ -55,7 +55,7 @@ export const getChannels = (req, res, next) => { } logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options }); if (common.read_dummy_data) { - common.getDummyData('Channels', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); + common.getDummyData('Channels', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); }); } else { request.post(options).then((body) => { @@ -83,7 +83,7 @@ export const getChannelStats = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/channelstats'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/channelstats'; const today = new Date(Date.now()); const tillToday = (Math.round(today.getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); @@ -105,7 +105,7 @@ export const openChannel = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/open'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/open'; options.form = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form }); request.post(options).then((body) => { @@ -122,7 +122,7 @@ export const updateChannelRelayFee = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/updaterelayfee'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/updaterelayfee'; options.form = req.query; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form }); request.post(options).then((body) => { @@ -140,11 +140,11 @@ export const closeChannel = (req, res, next) => { } if (req.query.force !== 'true') { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' }); - options.url = req.session.selectedNode.ln_server_url + '/close'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/close'; } else { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' }); - options.url = req.session.selectedNode.ln_server_url + '/forceclose'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/forceclose'; } options.form = { channelId: req.query.channelId }; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url }); diff --git a/backend/controllers/eclair/fees.js b/backend/controllers/eclair/fees.js index c1364716..660ad5af 100644 --- a/backend/controllers/eclair/fees.js +++ b/backend/controllers/eclair/fees.js @@ -99,7 +99,7 @@ export const getFees = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/audit'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/audit'; const today = new Date(Date.now()); const tillToday = (Math.round(today.getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); @@ -109,7 +109,7 @@ export const getFees = (req, res, next) => { }; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form }); if (common.read_dummy_data) { - common.getDummyData('Fees', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); }); + common.getDummyData('Fees', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); }); } else { request.post(options).then((body) => { @@ -127,11 +127,11 @@ export const getPayments = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/audit'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/audit'; const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); options.form = { from: 0, to: tillToday }; if (common.read_dummy_data) { - common.getDummyData('Payments', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); }); + common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); }); } else { request.post(options).then((body) => { diff --git a/backend/controllers/eclair/getInfo.js b/backend/controllers/eclair/getInfo.js index cae4a8cb..eb2ccf8b 100644 --- a/backend/controllers/eclair/getInfo.js +++ b/backend/controllers/eclair/getInfo.js @@ -16,12 +16,12 @@ export const getInfo = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/getinfo'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/getinfo'; options.form = {}; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url }); if (common.read_dummy_data) { - common.getDummyData('GetInfo', req.session.selectedNode.ln_implementation).then((data) => { + common.getDummyData('GetInfo', req.session.selectedNode.lnImplementation).then((data) => { data.lnImplementation = 'Eclair'; return res.status(200).json(data); }); @@ -36,7 +36,7 @@ export const getInfo = (req, res, next) => { return request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' }); body.lnImplementation = 'Eclair'; - req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; + req.session.selectedNode.lnVersion = body.version.split('-')[0] || ''; eclWsClient.updateSelectedNode(req.session.selectedNode); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); return res.status(200).json(body); diff --git a/backend/controllers/eclair/invoices.js b/backend/controllers/eclair/invoices.js index 712f9e74..e60680f0 100644 --- a/backend/controllers/eclair/invoices.js +++ b/backend/controllers/eclair/invoices.js @@ -39,7 +39,7 @@ export const getInvoice = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/getinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/getinvoice'; options.form = { paymentHash: req.params.paymentHash }; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body }); @@ -55,8 +55,8 @@ export const getInvoice = (req, res, next) => { }; export const listPendingInvoicesRequestCall = (selectedNode) => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/listpendinginvoices'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices'; options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() }; return new Promise((resolve, reject) => { request.post(options).then((pendingInvoicesResponse) => { @@ -76,16 +76,16 @@ export const listInvoices = (req, res, next) => { const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); options.form = { from: 0, to: tillToday }; const options1 = JSON.parse(JSON.stringify(options)); - options1.url = req.session.selectedNode.ln_server_url + '/listinvoices'; + options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices'; options1.form = { from: 0, to: tillToday }; const options2 = JSON.parse(JSON.stringify(options)); - options2.url = req.session.selectedNode.ln_server_url + '/listpendinginvoices'; + options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices'; options2.form = { from: 0, to: tillToday }; if (common.read_dummy_data) { - return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => { + return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then((body) => { const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; - return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). + return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))). then((values) => res.status(200).json(invoices)); }); } @@ -96,7 +96,7 @@ export const listInvoices = (req, res, next) => { const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; if (invoices && invoices.length > 0) { - return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). + return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))). then((values) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices }); return res.status(200).json(invoices); @@ -119,8 +119,8 @@ export const listInvoices = (req, res, next) => { }; export const createInvoiceRequestCall = (selectedNode, description, amount) => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/createinvoice'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/createinvoice'; options.form = { description: description, amountMsat: amount }; return new Promise((resolve, reject) => { request.post(options).then((invResponse) => { diff --git a/backend/controllers/eclair/network.js b/backend/controllers/eclair/network.js index 276d5def..c9924fd4 100644 --- a/backend/controllers/eclair/network.js +++ b/backend/controllers/eclair/network.js @@ -10,7 +10,7 @@ export const getNodes = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/nodes'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: req.params.id }; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body }); @@ -22,8 +22,8 @@ export const getNodes = (req, res, next) => { }; export const findRouteBetweenNodesRequestCall = (selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds = [], format = 'shortChannelId') => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/findroutebetweennodes'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/findroutebetweennodes'; options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format }; return new Promise((resolve, reject) => { request.post(options).then((body) => { diff --git a/backend/controllers/eclair/onchain.js b/backend/controllers/eclair/onchain.js index 696d6b3b..858e3e0e 100644 --- a/backend/controllers/eclair/onchain.js +++ b/backend/controllers/eclair/onchain.js @@ -21,7 +21,7 @@ export const getNewAddress = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/getnewaddress'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/getnewaddress'; options.form = {}; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); @@ -37,10 +37,10 @@ export const getBalance = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/onchainbalance'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/onchainbalance'; options.form = {}; if (common.read_dummy_data) { - common.getDummyData('OnChainBalance', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeBalances(data)); }); + common.getDummyData('OnChainBalance', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeBalances(data)); }); } else { request.post(options).then((body) => { @@ -59,7 +59,7 @@ export const getTransactions = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/onchaintransactions'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/onchaintransactions'; options.form = { count: req.query.count, skip: req.query.skip @@ -80,7 +80,7 @@ export const sendFunds = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/sendonchain'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/sendonchain'; options.form = { address: address, amountSatoshis: amount, confirmationTarget: blocks }; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form }); request.post(options).then((body) => { diff --git a/backend/controllers/eclair/payments.js b/backend/controllers/eclair/payments.js index fc7e1980..25f6d974 100644 --- a/backend/controllers/eclair/payments.js +++ b/backend/controllers/eclair/payments.js @@ -5,7 +5,7 @@ let options = null; const logger = Logger; const common = Common; export const getSentInfoFromPaymentRequest = (selNode, payment) => { - options.url = selNode.ln_server_url + '/getsentinfo'; + options.url = selNode.settings.lnServerUrl + '/getsentinfo'; options.form = { paymentHash: payment }; return request.post(options).then((body) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body }); @@ -21,7 +21,7 @@ export const getSentInfoFromPaymentRequest = (selNode, payment) => { }).catch((err) => err); }; export const getQueryNodes = (selNode, nodeIds) => { - options.url = selNode.ln_server_url + '/nodes'; + options.url = selNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: nodeIds?.reduce((acc, curr) => acc + ',' + curr) }; return request.post(options).then((nodes) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes }); @@ -34,7 +34,7 @@ export const decodePayment = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/parseinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/parseinvoice'; options.form = { invoice: req.params.invoice }; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); @@ -53,7 +53,7 @@ export const postPayment = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/payinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/payinvoice'; options.form = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form }); request.post(options).then((body) => { @@ -70,7 +70,7 @@ export const queryPaymentRoute = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/findroutetonode'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/findroutetonode'; options.form = { nodeId: req.query.nodeId, amountMsat: req.query.amountMsat @@ -129,8 +129,8 @@ export const getSentPaymentsInformation = (req, res, next) => { }; export const sendPaymentToRouteRequestCall = (selectedNode, shortChannelIds, invoice, amountMsat) => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/sendtoroute'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/sendtoroute'; options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice }; return new Promise((resolve, reject) => { logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form }); diff --git a/backend/controllers/eclair/peers.js b/backend/controllers/eclair/peers.js index 0436f2ec..c29f4e22 100644 --- a/backend/controllers/eclair/peers.js +++ b/backend/controllers/eclair/peers.js @@ -5,7 +5,7 @@ let options = null; const logger = Logger; const common = Common; export const getFilteredNodes = (selNode, peersNodeIds) => { - options.url = selNode.ln_server_url + '/nodes'; + options.url = selNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: peersNodeIds }; return request.post(options).then((nodes) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes }); @@ -18,10 +18,10 @@ export const getPeers = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/peers'; options.form = {}; if (common.read_dummy_data) { - common.getDummyData('Peers', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); + common.getDummyData('Peers', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); }); } else { request.post(options).then((body) => { @@ -58,7 +58,7 @@ export const connectPeer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/connect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/connect'; options.form = {}; if (req.query) { options.form = req.query; @@ -74,7 +74,7 @@ export const connectPeer = (req, res, next) => { const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); } - options.url = req.session.selectedNode.ln_server_url + '/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/peers'; options.form = {}; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body }); @@ -112,7 +112,7 @@ export const deletePeer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/disconnect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/disconnect'; options.form = {}; if (req.params.nodeId) { options.form = { nodeId: req.params.nodeId }; diff --git a/backend/controllers/eclair/webSocketClient.js b/backend/controllers/eclair/webSocketClient.js index 20539a65..6c692c3a 100644 --- a/backend/controllers/eclair/webSocketClient.js +++ b/backend/controllers/eclair/webSocketClient.js @@ -28,14 +28,14 @@ export class ECLWebSocketClient { try { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); if (!clientExists) { - if (selectedNode.ln_server_url) { + if (selectedNode.settings.lnServerUrl) { const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; this.connectWithClient(newWebSocketClient); this.webSocketClients.push(newWebSocketClient); } } else { - if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.ln_server_url) { + if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.settings.lnServerUrl) { clientExists.reConnect = true; this.connectWithClient(clientExists); } @@ -47,9 +47,9 @@ export class ECLWebSocketClient { }; this.connectWithClient = (eclWsClt) => { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' }); - const UpdatedLNServerURL = (eclWsClt.selectedNode.ln_server_url)?.replace(/^http/, 'ws'); + const UpdatedLNServerURL = (eclWsClt.selectedNode.settings.lnServerUrl)?.replace(/^http/, 'ws'); const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2); - const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.ln_api_password + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws'; + const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.authentication.lnApiPassword + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws'; eclWsClt.webSocketClient = new WebSocket(WS_LINK); eclWsClt.webSocketClient.onopen = () => { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' }); @@ -57,7 +57,7 @@ export class ECLWebSocketClient { this.heartbeat(eclWsClt); }; eclWsClt.webSocketClient.onclose = (e) => { - if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.ln_implementation === 'ECL') { + if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.lnImplementation === 'ECL') { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' }); eclWsClt.webSocketClient.close(); if (eclWsClt.reConnect) { @@ -75,7 +75,7 @@ export class ECLWebSocketClient { } }; eclWsClt.webSocketClient.onerror = (err) => { - if (eclWsClt.selectedNode.ln_version === '' || !eclWsClt.selectedNode.ln_version || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) { + if (eclWsClt.selectedNode.lnVersion === '' || !eclWsClt.selectedNode.lnVersion || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err }); const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }')); this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode); diff --git a/backend/controllers/lnd/balance.js b/backend/controllers/lnd/balance.js index a73898d5..b49f7a02 100644 --- a/backend/controllers/lnd/balance.js +++ b/backend/controllers/lnd/balance.js @@ -10,7 +10,7 @@ export const getBlockchainBalance = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/balance/blockchain'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/balance/blockchain'; options.qs = req.query; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query }); diff --git a/backend/controllers/lnd/channels.js b/backend/controllers/lnd/channels.js index 20a7922e..66d091e0 100644 --- a/backend/controllers/lnd/channels.js +++ b/backend/controllers/lnd/channels.js @@ -6,7 +6,7 @@ const logger = Logger; const common = Common; export const getAliasForChannel = (selNode, channel) => { const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : ''; - options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; + options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey; return request(options).then((aliasBody) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias }); channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20); @@ -22,7 +22,7 @@ export const getAllChannels = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels'; options.qs = req.query; let local = 0; let remote = 0; @@ -60,7 +60,7 @@ export const getPendingChannels = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/pending'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/pending'; options.qs = req.query; request(options).then((body) => { if (!body.total_limbo_balance) { @@ -98,7 +98,7 @@ export const getClosedChannels = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/closed'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/closed'; options.qs = req.query; request(options).then((body) => { if (body.channels && body.channels.length > 0) { @@ -129,7 +129,7 @@ export const postChannel = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels'; options.form = { node_pubkey_string: node_pubkey, local_funding_amount: local_funding_amount, @@ -162,7 +162,7 @@ export const postTransactions = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/transaction-stream'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/transaction-stream'; options.form = { payment_request: paymentReq }; if (paymentAmount) { options.form.amt = paymentAmount; @@ -208,7 +208,7 @@ export const closeChannel = (req, res, next) => { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } const channelpoint = req.params.channelPoint?.replace(':', '/'); - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/' + channelpoint + '?force=' + req.query.force; if (req.query.target_conf) { options.url = options.url + '&target_conf=' + req.query.target_conf; } @@ -232,7 +232,7 @@ export const postChanPolicy = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/chanpolicy'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/chanpolicy'; if (chanPoint === 'all') { options.form = JSON.stringify({ global: true, diff --git a/backend/controllers/lnd/channelsBackup.js b/backend/controllers/lnd/channelsBackup.js index 489deb5f..a00a8074 100644 --- a/backend/controllers/lnd/channelsBackup.js +++ b/backend/controllers/lnd/channelsBackup.js @@ -39,15 +39,15 @@ export const getBackup = (req, res, next) => { let channel_backup_file = ''; let message = ''; if (req.params.channelPoint === 'ALL') { - channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; + channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak'; message = 'All Channels Backup Successful.'; - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup'; } else { - channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; + channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; message = 'Channel Backup Successful.'; const channelpoint = req.params.channelPoint?.replace(':', '/'); - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/' + channelpoint; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/' + channelpoint; const exists = fs.existsSync(channel_backup_file); if (exists) { fs.writeFile(channel_backup_file, '', () => { }); @@ -86,13 +86,13 @@ export const postBackupVerify = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/verify'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/verify'; let channel_verify_file = ''; let message = ''; let verify_backup = ''; if (req.params.channelPoint === 'ALL') { message = 'All Channels Verify Successful.'; - channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; + channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak'; const exists = fs.existsSync(channel_verify_file); if (exists) { verify_backup = fs.readFileSync(channel_verify_file, 'utf-8'); @@ -116,7 +116,7 @@ export const postBackupVerify = (req, res, next) => { } else { message = 'Channel Verify Successful.'; - channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; + channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; const exists = fs.existsSync(channel_verify_file); if (exists) { verify_backup = fs.readFileSync(channel_verify_file, 'utf-8'); @@ -146,13 +146,13 @@ export const postRestore = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/restore'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/restore'; let channel_restore_file = ''; let message = ''; let restore_backup = ''; if (req.params.channelPoint === 'ALL') { message = 'All Channels Restore Successful.'; - channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep; + channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep; const exists = fs.existsSync(channel_restore_file + 'channel-all.bak'); const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak'); if (exists) { @@ -188,7 +188,7 @@ export const postRestore = (req, res, next) => { } else { message = 'Channel Restore Successful.'; - channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; + channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; const exists = fs.existsSync(channel_restore_file); if (exists) { restore_backup = fs.readFileSync(channel_restore_file, 'utf-8'); @@ -208,7 +208,7 @@ export const postRestore = (req, res, next) => { channel_restore_file = channel_restore_file + 'channel-all.bak'; } fs.rename(channel_restore_file, channel_restore_file + '.restored', () => { - getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { + getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => { if (getFilesListRes.error) { const errMsg = getFilesListRes.error; const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode); @@ -228,7 +228,7 @@ export const postRestore = (req, res, next) => { } }; export const getRestoreList = (req, res, next) => { - getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { + getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => { if (getFilesListRes.error) { return res.status(getFilesListRes.statusCode).json(getFilesListRes); } diff --git a/backend/controllers/lnd/fees.js b/backend/controllers/lnd/fees.js index 68766789..643a5e91 100644 --- a/backend/controllers/lnd/fees.js +++ b/backend/controllers/lnd/fees.js @@ -11,7 +11,7 @@ export const getFees = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/fees'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fees'; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body }); const today = new Date(Date.now()); diff --git a/backend/controllers/lnd/getInfo.js b/backend/controllers/lnd/getInfo.js index 461f3d10..fbc72493 100644 --- a/backend/controllers/lnd/getInfo.js +++ b/backend/controllers/lnd/getInfo.js @@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo'; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url }); if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) { const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!'; @@ -26,7 +26,7 @@ export const getInfo = (req, res, next) => { } else { common.nodes?.map((node) => { - if (node.ln_implementation === 'LND') { + if (node.lnImplementation === 'LND') { common.getAllNodeAllChannelBackup(node); } return node; @@ -42,7 +42,7 @@ export const getInfo = (req, res, next) => { return res.status(err.statusCode).json({ message: err.message, error: err.error }); } else { - req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; + req.session.selectedNode.lnVersion = body.version.split('-')[0] || ''; lndWsClient.updateSelectedNode(req.session.selectedNode); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); return res.status(200).json(body); diff --git a/backend/controllers/lnd/graph.js b/backend/controllers/lnd/graph.js index 37f99221..7d008e40 100644 --- a/backend/controllers/lnd/graph.js +++ b/backend/controllers/lnd/graph.js @@ -5,7 +5,7 @@ let options = null; const logger = Logger; const common = Common; export const getAliasFromPubkey = (selNode, pubkey) => { - options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; + options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey; return request(options).then((res) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias }); return res.node.alias; @@ -18,7 +18,7 @@ export const getDescribeGraph = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph'; request.get(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body }); res.status(200).json(body); @@ -33,7 +33,7 @@ export const getGraphInfo = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/info'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/info'; request.get(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body }); res.status(200).json(body); @@ -48,7 +48,7 @@ export const getGraphNode = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/node/' + req.params.pubKey; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/node/' + req.params.pubKey; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body }); res.status(200).json(body); @@ -63,7 +63,7 @@ export const getGraphEdge = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body }); res.status(200).json(body); @@ -78,7 +78,7 @@ export const getQueryRoutes = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount; if (req.query.outgoing_chan_id) { options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id; } @@ -116,7 +116,7 @@ export const getRemoteFeePolicy = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body }); let remoteNodeFee = {}; diff --git a/backend/controllers/lnd/invoices.js b/backend/controllers/lnd/invoices.js index 433f398e..59601ab9 100644 --- a/backend/controllers/lnd/invoices.js +++ b/backend/controllers/lnd/invoices.js @@ -12,7 +12,7 @@ export const invoiceLookup = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/invoices/lookup'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/invoices/lookup'; if (req.query.payment_addr) { options.url = options.url + '?payment_addr=' + req.query.payment_addr; } @@ -36,7 +36,7 @@ export const listInvoices = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset + + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body }); @@ -60,7 +60,7 @@ export const addInvoice = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/invoices'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices'; options.form = JSON.stringify(req.body); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body }); diff --git a/backend/controllers/lnd/message.js b/backend/controllers/lnd/message.js index d4151417..65a1328f 100644 --- a/backend/controllers/lnd/message.js +++ b/backend/controllers/lnd/message.js @@ -11,7 +11,7 @@ export const signMessage = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage'; options.form = JSON.stringify({ msg: Buffer.from(message).toString('base64') }); @@ -30,7 +30,7 @@ export const verifyMessage = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/verifymessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/verifymessage'; options.form = JSON.stringify({ msg: Buffer.from(message).toString('base64'), signature: signature diff --git a/backend/controllers/lnd/newAddress.js b/backend/controllers/lnd/newAddress.js index ac2f9e15..b8857064 100644 --- a/backend/controllers/lnd/newAddress.js +++ b/backend/controllers/lnd/newAddress.js @@ -10,7 +10,7 @@ export const getNewAddress = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/newaddress?type=' + req.query.type; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddress?type=' + req.query.type; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body }); res.status(200).json(body); diff --git a/backend/controllers/lnd/payments.js b/backend/controllers/lnd/payments.js index eb813925..208a1883 100644 --- a/backend/controllers/lnd/payments.js +++ b/backend/controllers/lnd/payments.js @@ -5,7 +5,7 @@ let options = null; const logger = Logger; const common = Common; export const decodePaymentFromPaymentRequest = (selNode, payment) => { - options.url = selNode.ln_server_url + '/v1/payreq/' + payment; + options.url = selNode.settings.lnServerUrl + '/v1/payreq/' + payment; return request(options).then((res) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description }); return res; @@ -17,7 +17,7 @@ export const decodePayment = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/payreq/' + req.params.payRequest; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payreq/' + req.params.payRequest; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body }); res.status(200).json(body); @@ -56,7 +56,7 @@ export const getPayments = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body }); res.status(200).json(body); @@ -69,8 +69,8 @@ export const getAllLightningTransactions = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' }); const options1 = JSON.parse(JSON.stringify(common.getOptions(req))); const options2 = JSON.parse(JSON.stringify(common.getOptions(req))); - // options1.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=100000&index_offset=0&reversed=true'; - options2.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true'; + // options1.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=100000&index_offset=0&reversed=true'; + options2.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true'; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 }); // return Promise.all([request(options1), request(options2)]).then((values) => { @@ -88,7 +88,7 @@ export const paymentLookup = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/router/track/' + req.params.paymentHash; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/router/track/' + req.params.paymentHash; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body }); res.status(200).json(body.result || body); diff --git a/backend/controllers/lnd/peers.js b/backend/controllers/lnd/peers.js index fce9e0d9..104dc753 100644 --- a/backend/controllers/lnd/peers.js +++ b/backend/controllers/lnd/peers.js @@ -5,7 +5,7 @@ let options = null; const logger = Logger; const common = Common; export const getAliasForPeers = (selNode, peer) => { - options.url = selNode.ln_server_url + '/v1/graph/node/' + peer.pub_key; + options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + peer.pub_key; return request(options).then((aliasBody) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias }); peer.alias = aliasBody.node.alias; @@ -21,7 +21,7 @@ export const getPeers = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers'; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); const peers = !body.peers ? [] : body.peers; @@ -41,14 +41,14 @@ export const postPeer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers'; options.form = JSON.stringify({ addr: { host: host, pubkey: pubkey }, perm: perm }); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body }); - options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers'; request(options).then((body) => { const peers = (!body.peers) ? [] : body.peers; return Promise.all(peers?.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => { @@ -76,7 +76,7 @@ export const deletePeer = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/peers/' + req.params.peerPubKey; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers/' + req.params.peerPubKey; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey }); request.delete(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body }); diff --git a/backend/controllers/lnd/switch.js b/backend/controllers/lnd/switch.js index 9307a92d..a8571941 100644 --- a/backend/controllers/lnd/switch.js +++ b/backend/controllers/lnd/switch.js @@ -27,7 +27,7 @@ export const getAllForwardingEvents = (req, start, end, offset, caller, callback return callback({ message: err.message, error: err.error, statusCode: err.statusCode }); } options = common.getOptions(req); - options.url = req.session.selectedNode.ln_server_url + '/v1/switch'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/switch'; options.form = {}; if (start) { options.form.start_time = start; diff --git a/backend/controllers/lnd/transactions.js b/backend/controllers/lnd/transactions.js index 769751c4..cb715822 100644 --- a/backend/controllers/lnd/transactions.js +++ b/backend/controllers/lnd/transactions.js @@ -10,7 +10,7 @@ export const getTransactions = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions'; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body }); res.status(200).json(body.transactions); @@ -26,7 +26,7 @@ export const postTransactions = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions'; options.form = { amount: amount, addr: address, diff --git a/backend/controllers/lnd/wallet.js b/backend/controllers/lnd/wallet.js index 5bdd943c..25217244 100644 --- a/backend/controllers/lnd/wallet.js +++ b/backend/controllers/lnd/wallet.js @@ -12,10 +12,10 @@ export const genSeed = (req, res, next) => { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (req.params.passphrase) { - options.url = req.session.selectedNode.ln_server_url + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64'); + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64'); } else { - options.url = req.session.selectedNode.ln_server_url + '/v1/genseed'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed'; } request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body }); @@ -35,7 +35,7 @@ export const operateWallet = (req, res, next) => { options.method = 'POST'; if (!req.params.operation || req.params.operation === 'unlockwallet') { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' }); - options.url = req.session.selectedNode.ln_server_url + '/v1/unlockwallet'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/unlockwallet'; options.form = JSON.stringify({ wallet_password: Buffer.from(atob(wallet_password)).toString('base64') }); @@ -43,7 +43,7 @@ export const operateWallet = (req, res, next) => { } else { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' }); - options.url = req.session.selectedNode.ln_server_url + '/v1/initwallet'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/initwallet'; if (aezeed_passphrase && aezeed_passphrase !== '') { options.form = JSON.stringify({ wallet_password: Buffer.from(atob(wallet_password)).toString('base64'), @@ -104,8 +104,8 @@ export const getUTXOs = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos'; - if (common.isVersionCompatible(req.session.selectedNode.ln_version, '0.14.0')) { + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos'; + if (common.isVersionCompatible(req.session.selectedNode.lnVersion, '0.14.0')) { options.form = JSON.stringify({ max_confs: req.query.max_confs }); } else { @@ -126,7 +126,7 @@ export const bumpFee = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/bumpfee'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/bumpfee'; options.form = {}; options.form.outpoint = { txid_str: txid, @@ -153,7 +153,7 @@ export const labelTransaction = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/tx/label'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/tx/label'; options.form = JSON.parse(JSON.stringify(options.form)); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form }); request.post(options).then((body) => { @@ -171,7 +171,7 @@ export const leaseUTXO = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/lease'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/lease'; options.form = {}; options.form.id = txid; options.form.outpoint = { @@ -195,7 +195,7 @@ export const releaseUTXO = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/release'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/release'; options.form = {}; options.form.id = txid; options.form.outpoint = { diff --git a/backend/controllers/lnd/webSocketClient.js b/backend/controllers/lnd/webSocketClient.js index 450eb2b3..0519da4f 100644 --- a/backend/controllers/lnd/webSocketClient.js +++ b/backend/controllers/lnd/webSocketClient.js @@ -13,7 +13,7 @@ export class LNDWebSocketClient { this.connect = (selectedNode) => { try { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); - if (!clientExists && selectedNode.ln_server_url) { + if (!clientExists && selectedNode.settings.lnServerUrl) { const newWebSocketClient = { selectedNode: selectedNode }; this.webSocketClients.push(newWebSocketClient); } @@ -25,7 +25,7 @@ export class LNDWebSocketClient { this.fetchUnpaidInvoices = (selectedNode) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' }); const options = this.setOptionsForSelNode(selectedNode); - options.url = selectedNode.ln_server_url + '/v1/invoices?pending_only=true'; + options.url = selectedNode.settings.lnServerUrl + '/v1/invoices?pending_only=true'; return request(options).then((body) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body }); if (body.invoices && body.invoices.length > 0) { @@ -44,7 +44,7 @@ export class LNDWebSocketClient { this.subscribeToInvoice = (options, selectedNode, rHash) => { rHash = rHash?.replace(/\+/g, '-')?.replace(/[/]/g, '_'); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' }); - options.url = selectedNode.ln_server_url + '/v2/invoices/subscribe/' + rHash; + options.url = selectedNode.settings.lnServerUrl + '/v2/invoices/subscribe/' + rHash; request(options).then((msg) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash }); if (typeof msg === 'string') { @@ -67,7 +67,7 @@ export class LNDWebSocketClient { }; this.subscribeToPayment = (options, selectedNode, paymentHash) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' }); - options.url = selectedNode.ln_server_url + '/v2/router/track/' + paymentHash; + options.url = selectedNode.settings.lnServerUrl + '/v2/router/track/' + paymentHash; request(options).then((msg) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash }); msg['type'] = 'payment'; @@ -84,7 +84,7 @@ export class LNDWebSocketClient { this.setOptionsForSelNode = (selectedNode) => { const options = { url: '', rejectUnauthorized: false, json: true, form: null }; try { - options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; + options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') }; } catch (err) { this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) }); @@ -107,7 +107,7 @@ export class LNDWebSocketClient { } newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode)); this.webSocketClients[clientIdx] = newClient; - if (this.webSocketClients[clientIdx].selectedNode.ln_version === '' || !this.webSocketClients[clientIdx].selectedNode.ln_version || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.ln_version, '0.11.0')) { + if (this.webSocketClients[clientIdx].selectedNode.lnVersion === '' || !this.webSocketClients[clientIdx].selectedNode.lnVersion || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.lnVersion, '0.11.0')) { this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode); } }; diff --git a/backend/controllers/shared/RTLConf.js b/backend/controllers/shared/RTLConf.js index d0a5669f..52b27598 100644 --- a/backend/controllers/shared/RTLConf.js +++ b/backend/controllers/shared/RTLConf.js @@ -12,208 +12,102 @@ const logger = Logger; const common = Common; const wsServer = WSServer; const databaseService = Database; -export const updateSelectedNode = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' }); - const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.initSelectedNode ? +common.initSelectedNode.index : 1; - req.session.selectedNode = common.findNode(selNodeIndex); - if (req.headers && req.headers.authorization && req.headers.authorization !== '') { - wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex); - if (req.params.prevNodeIndex !== '-1') { - databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id); - } - if (req.params.currNodeIndex !== '-1') { - databaseService.loadDatabase(req.session); +export const maskPasswords = (obj) => { + const keys = Object.keys(obj); + const length = keys.length; + if (length !== 0) { + for (let i = 0; i < length; i++) { + if (typeof obj[keys[i]] === 'object') { + keys[keys[i]] = maskPasswords(obj[keys[i]]); + } + if (typeof keys[i] === 'string' && + (keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') || + keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') || + keys[i].toLowerCase().includes('rpcuser'))) { + obj[keys[i]] = '*'.repeat(20); + } } } - const responseVal = !req.session.selectedNode.ln_node ? '' : req.session.selectedNode.ln_node; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal }); - res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' }); + return obj; }; -export const getRTLConfigInitial = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Initial RTL Configuration..' }); - const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - fs.readFile(confFile, 'utf8', (errRes, data) => { +export const getCurrencyRates = (req, res, next) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' }); + options.url = 'https://blockchain.info/ticker'; + request(options).then((body) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body }); + res.status(200).json(JSON.parse(body)); + }).catch((errRes) => { + const errMsg = 'Get Rates Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); + }); +}; +export const getFile = (req, res, next) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); + const file = req.query.path ? req.query.path : (req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak'); + logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); + logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); + fs.readFile(file, 'utf8', (errRes, data) => { if (errRes) { - if (errRes.code === 'ENOENT') { - logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); - res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] }); - } - else { - const errMsg = 'Get Node Config Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); + if (errRes.code && errRes.code === 'ENOENT') { + errRes.code = 'File Not Found!'; } + const errMsg = 'Reading File Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); } else { - const nodeConfData = JSON.parse(data); - const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link }; - const enable2FA = !!common.rtl_secret2fa; - const allowPasswordUpdate = common.flg_allow_password_update; - const nodesArr = []; - if (common.nodes && common.nodes.length > 0) { - common.nodes.forEach((node, i) => { - const settings = { unannouncedChannels: false }; - settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT'; - settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY'; - settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE'; - settings.unannouncedChannels = !!node.unannounced_channels || false; - settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false; - settings.currencyUnit = node.currency_unit; - nodesArr.push({ - index: node.index, - lnNode: node.ln_node, - lnImplementation: node.ln_implementation, - settings: settings, - authentication: {} - }); - }); - } - const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr }; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Initial RTL Configuration Received', data: body }); - res.status(200).json(body); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data }); + res.status(200).json(data); } }); }; export const getRTLConfig = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' }); - const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; fs.readFile(confFile, 'utf8', (errRes, data) => { if (errRes) { - if (errRes.code === 'ENOENT') { - logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); - res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] }); - } - else { - const errMsg = 'Get Node Config Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); - } + const errMsg = 'Get Node Config Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); } else { const nodeConfData = JSON.parse(data); - const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link }; - const enable2FA = !!common.rtl_secret2fa; - const allowPasswordUpdate = common.flg_allow_password_update; const nodesArr = []; if (common.nodes && common.nodes.length > 0) { common.nodes.forEach((node, i) => { - const authentication = {}; - authentication.configPath = (node.config_path) ? node.config_path : ''; - authentication.swapMacaroonPath = (node.swap_macaroon_path) ? node.swap_macaroon_path : ''; - authentication.boltzMacaroonPath = (node.boltz_macaroon_path) ? node.boltz_macaroon_path : ''; - const settings = { unannouncedChannels: false }; - settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT'; - settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY'; - settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE'; - settings.unannouncedChannels = !!node.unannounced_channels || false; - settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false; - settings.bitcoindConfigPath = node.bitcoind_config_path; - settings.logLevel = node.log_level ? node.log_level : 'ERROR'; - settings.lnServerUrl = node.ln_server_url; - settings.swapServerUrl = node.swap_server_url; - settings.boltzServerUrl = node.boltz_server_url; - settings.enableOffers = node.enable_offers; - settings.enablePeerswap = node.enable_peerswap; - settings.channelBackupPath = node.channel_backup_path; - settings.currencyUnit = node.currency_unit; nodesArr.push({ index: node.index, - lnNode: node.ln_node, - lnImplementation: node.ln_implementation, - settings: settings, - authentication: authentication + lnNode: node.lnNode, + lnImplementation: node.lnImplementation, + settings: node.settings, + authentication: req.params.init ? {} : node.authentication }); }); } - const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr }; + const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index), + sso: common.appConfig.sso, enable2FA: !!common.appConfig.rtlSecret2fa, allowPasswordUpdate: common.appConfig.allowPasswordUpdate, nodes: nodesArr }; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: body }); res.status(200).json(body); } }); }; -export const updateUISettings = (req, res, next) => { - const { updatedSettings } = req.body; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); - const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index)); - if (node && node.Settings) { - node.Settings.userPersona = updatedSettings.userPersona; - node.Settings.themeMode = updatedSettings.themeMode; - node.Settings.themeColor = updatedSettings.themeColor; - node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels; - node.Settings.fiatConversion = updatedSettings.fiatConversion; - if (updatedSettings.fiatConversion) { - node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; - } - else { - delete node.Settings.currencyUnit; - } - const selectedNode = common.findNode(req.session.selectedNode.index); - selectedNode.user_persona = updatedSettings.userPersona; - selectedNode.theme_mode = updatedSettings.themeMode; - selectedNode.theme_color = updatedSettings.themeColor; - selectedNode.unannounced_channels = updatedSettings.unannouncedChannels; - selectedNode.fiat_conversion = updatedSettings.fiatConversion; - if (updatedSettings.fiatConversion) { - selectedNode.currency_unit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; +export const updateSelectedNode = (req, res, next) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' }); + const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.selectedNode ? +common.selectedNode.index : 1; + req.session.selectedNode = common.findNode(selNodeIndex); + if (req.headers && req.headers.authorization && req.headers.authorization !== '') { + wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex); + if (req.params.prevNodeIndex !== '-1') { + databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id); } - else { - delete selectedNode.currency_unit; + if (req.params.currNodeIndex !== '-1') { + databaseService.loadDatabase(req.session); } - common.replaceNode(req, selectedNode); - } - try { - fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) }); - res.status(201).json({ message: 'Node Settings Updated Successfully' }); - } - catch (errRes) { - const errMsg = 'Update Node Settings Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); - } -}; -export const update2FASettings = (req, res, next) => { - const { secret2fa } = req.body; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); - if (secret2fa && secret2fa.trim() !== '') { - config.secret2fa = secret2fa; - } - else { - delete config.secret2fa; - } - const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.'; - try { - fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - common.rtl_secret2fa = config.secret2fa; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message }); - res.status(201).json({ message: message }); - } - catch (errRes) { - const errMsg = 'Update 2FA Settings Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); - } -}; -export const updateDefaultNode = (req, res, next) => { - const { defaultNodeIndex } = req.body; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); - config.defaultNodeIndex = defaultNodeIndex; - try { - fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) }); - res.status(201).json({ message: 'Default Node Updated Successfully' }); - } - catch (errRes) { - const errMsg = 'Update Default Node Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); } + const responseVal = !req.session.selectedNode.lnNode ? '' : req.session.selectedNode.lnNode; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal }); + res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' }); }; export const getConfig = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Reading Configuration File..' }); @@ -221,14 +115,14 @@ export const getConfig = (req, res, next) => { let fileFormat = 'INI'; switch (req.params.nodeType) { case 'ln': - confFile = req.session.selectedNode.config_path; + confFile = req.session.selectedNode.authentication.configPath; break; case 'bitcoind': - confFile = req.session.selectedNode.bitcoind_config_path; + confFile = req.session.selectedNode.settings.bitcoindConfigPath; break; case 'rtl': fileFormat = 'JSON'; - confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; break; default: confFile = ''; @@ -254,7 +148,7 @@ export const getConfig = (req, res, next) => { if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) { jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color; } - if (req.params.nodeType === 'ln' && req.session.selectedNode.ln_implementation === 'ECL' && !jsonConfig['eclair.api.password']) { + if (req.params.nodeType === 'ln' && req.session.selectedNode.lnImplementation === 'ECL' && !jsonConfig['eclair.api.password']) { fileFormat = 'HOCON'; jsonConfig = parseHocon(data); } @@ -266,42 +160,94 @@ export const getConfig = (req, res, next) => { } }); }; -export const getFile = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); - const file = req.query.path ? req.query.path : (req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak'); - logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); - logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); - fs.readFile(file, 'utf8', (errRes, data) => { - if (errRes) { - if (errRes.code && errRes.code === 'ENOENT') { - errRes.code = 'File Not Found!'; - } - const errMsg = 'Reading File Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); +export const updateNodeSettings = (req, res, next) => { + const { updatedSettings } = req.body; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' }); + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; + const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); + const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index)); + if (node && node.Settings) { + node.Settings.userPersona = updatedSettings.userPersona; + node.Settings.themeMode = updatedSettings.themeMode; + node.Settings.themeColor = updatedSettings.themeColor; + node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels; + node.Settings.fiatConversion = updatedSettings.fiatConversion; + if (updatedSettings.fiatConversion) { + node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; } else { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data }); - res.status(200).json(data); + delete node.Settings.currencyUnit; } - }); + const selectedNode = common.findNode(req.session.selectedNode.index); + selectedNode.settings.userPersona = updatedSettings.userPersona; + selectedNode.settings.themeMode = updatedSettings.themeMode; + selectedNode.settings.themeColor = updatedSettings.themeColor; + selectedNode.settings.unannouncedChannels = updatedSettings.unannouncedChannels; + selectedNode.settings.fiatConversion = updatedSettings.fiatConversion; + if (updatedSettings.fiatConversion) { + selectedNode.settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; + } + else { + delete selectedNode.settings.currencyUnit; + } + common.replaceNode(req, selectedNode); + } + try { + fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) }); + res.status(201).json({ message: 'Node Settings Updated Successfully' }); + } + catch (errRes) { + const errMsg = 'Update Node Settings Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); + } }; -export const getCurrencyRates = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' }); - options.url = 'https://blockchain.info/ticker'; - request(options).then((body) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body }); - res.status(200).json(JSON.parse(body)); - }).catch((errRes) => { - const errMsg = 'Get Rates Error'; +export const updateApplicationSettings = (req, res, next) => { + const { defaultNodeIndex } = req.body; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' }); + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; + const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); + config.defaultNodeIndex = defaultNodeIndex; + try { + fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) }); + res.status(201).json({ message: 'Default Node Updated Successfully' }); + } + catch (errRes) { + const errMsg = 'Update Default Node Error'; const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); return res.status(err.statusCode).json({ message: err.error, error: err.error }); - }); + } +}; +export const update2FASettings = (req, res, next) => { + const { secret2fa } = req.body; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' }); + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; + const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); + if (secret2fa && secret2fa.trim() !== '') { + config.secret2fa = secret2fa; + } + else { + delete config.secret2fa; + } + const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.'; + try { + fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); + common.appConfig.rtlSecret2fa = config.secret2fa; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message }); + res.status(201).json({ message: message }); + } + catch (errRes) { + const errMsg = 'Update 2FA Settings Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); + } }; export const updateSSO = (req, res, next) => { const { SSO } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating SSO Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); delete config.SSO; config.SSO = SSO; @@ -319,7 +265,7 @@ export const updateSSO = (req, res, next) => { export const updateServiceSettings = (req, res, next) => { const { service, settings } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Service Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const selectedNode = common.findNode(req.session.selectedNode.index); config.nodes.forEach((node) => { @@ -329,37 +275,37 @@ export const updateServiceSettings = (req, res, next) => { if (settings.enable) { node.Settings.swapServerUrl = settings.serverUrl; node.Authentication.swapMacaroonPath = settings.macaroonPath; - selectedNode.swap_server_url = settings.serverUrl; - selectedNode.swap_macaroon_path = settings.macaroonPath; + selectedNode.settings.swapServerUrl = settings.serverUrl; + selectedNode.authentication.swapMacaroonPath = settings.macaroonPath; } else { delete node.Settings.swapServerUrl; delete node.Authentication.swapMacaroonPath; - delete selectedNode.swap_server_url; - delete selectedNode.swap_macaroon_path; + delete selectedNode.settings.swapServerUrl; + delete selectedNode.authentication.swapMacaroonPath; } break; case 'BOLTZ': if (settings.enable) { node.Settings.boltzServerUrl = settings.serverUrl; node.Authentication.boltzMacaroonPath = settings.macaroonPath; - selectedNode.boltz_server_url = settings.serverUrl; - selectedNode.boltz_macaroon_path = settings.macaroonPath; + selectedNode.settings.boltzServerUrl = settings.serverUrl; + selectedNode.authentication.boltzMacaroonPath = settings.macaroonPath; } else { delete node.Settings.boltzServerUrl; delete node.Authentication.boltzMacaroonPath; - delete selectedNode.boltz_server_url; - delete selectedNode.boltz_macaroon_path; + delete selectedNode.settings.boltzServerUrl; + delete selectedNode.authentication.boltzMacaroonPath; } break; case 'OFFERS': node.Settings.enableOffers = settings.enableOffers; - selectedNode.enable_offers = settings.enableOffers; + selectedNode.settings.enableOffers = settings.enableOffers; break; case 'PEERSWAP': node.Settings.enablePeerswap = settings.enablePeerswap; - selectedNode.enable_peerswap = settings.enablePeerswap; + selectedNode.settings.enablePeerswap = settings.enablePeerswap; break; default: break; @@ -379,21 +325,3 @@ export const updateServiceSettings = (req, res, next) => { return res.status(err.statusCode).json({ message: err.error, error: err.error }); } }; -export const maskPasswords = (obj) => { - const keys = Object.keys(obj); - const length = keys.length; - if (length !== 0) { - for (let i = 0; i < length; i++) { - if (typeof obj[keys[i]] === 'object') { - keys[keys[i]] = maskPasswords(obj[keys[i]]); - } - if (typeof keys[i] === 'string' && - (keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') || - keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') || - keys[i].toLowerCase().includes('rpcuser'))) { - obj[keys[i]] = '********************'; - } - } - } - return obj; -}; diff --git a/backend/controllers/shared/authenticate.js b/backend/controllers/shared/authenticate.js index 1d34f8e9..4e16ada3 100644 --- a/backend/controllers/shared/authenticate.js +++ b/backend/controllers/shared/authenticate.js @@ -44,20 +44,20 @@ const handleMultipleFailedAttemptsError = (failed, currentTime, errMsg) => { }; } }; -export const verifyToken = (twoFAToken) => !!(common.rtl_secret2fa && common.rtl_secret2fa !== '' && otplib.authenticator.check(twoFAToken, common.rtl_secret2fa)); +export const verifyToken = (twoFAToken) => !!(common.appConfig.rtlSecret2fa && common.appConfig.rtlSecret2fa !== '' && otplib.authenticator.check(twoFAToken, common.appConfig.rtlSecret2fa)); export const authenticateUser = (req, res, next) => { const { authenticateWith, authenticationValue, twoFAToken } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' }); - if (+common.rtl_sso) { + if (+common.appConfig.sso.rtlSso) { if (authenticateWith === 'JWT' && jwt.verify(authenticationValue, common.secret_key)) { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' }); } else if (authenticateWith === 'PASSWORD') { - if (common.cookie_value.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.cookie_value).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) { + if (common.appConfig.sso.cookieValue.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.appConfig.sso.cookieValue).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) { common.refreshCookie(); if (!req.session.selectedNode) { - req.session.selectedNode = common.initSelectedNode; + req.session.selectedNode = common.selectedNode; } const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); @@ -75,7 +75,7 @@ export const authenticateUser = (req, res, next) => { const reqIP = common.getRequestIP(req); const failed = getFailedInfo(reqIP, currentTime); const password = authenticationValue; - if (common.rtl_pass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) { + if (common.appConfig.rtlPass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) { if (twoFAToken && twoFAToken !== '') { if (!verifyToken(twoFAToken)) { logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } }); @@ -85,7 +85,7 @@ export const authenticateUser = (req, res, next) => { } } if (!req.session.selectedNode) { - req.session.selectedNode = common.initSelectedNode; + req.session.selectedNode = common.selectedNode; } delete failedLoginAttempts[reqIP]; const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); @@ -94,8 +94,8 @@ export const authenticateUser = (req, res, next) => { } else { logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } }); - failed.count = common.rtl_pass !== password ? (failed.count + 1) : failed.count; - failed.lastTried = common.rtl_pass !== password ? currentTime : failed.lastTried; + failed.count = common.appConfig.rtlPass !== password ? (failed.count + 1) : failed.count; + failed.lastTried = common.appConfig.rtlPass !== password ? currentTime : failed.lastTried; return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!')); } } @@ -103,14 +103,14 @@ export const authenticateUser = (req, res, next) => { export const resetPassword = (req, res, next) => { const { currPassword, newPassword } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' }); - if (+common.rtl_sso) { + if (+common.appConfig.sso.rtlSso) { const errMsg = 'Password cannot be reset for SSO authentication'; const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg, req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); } else { - if (common.rtl_pass === currPassword) { - common.rtl_pass = common.replacePasswordWithHash(newPassword); + if (common.appConfig.rtlPass === currPassword) { + common.appConfig.rtlPass = common.replacePasswordWithHash(newPassword); const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' }); res.status(200).json({ token: token }); diff --git a/backend/models/config.model.js b/backend/models/config.model.js index a4f23777..cfc1f52f 100644 --- a/backend/models/config.model.js +++ b/backend/models/config.model.js @@ -1,62 +1,69 @@ -export class CommonSelectedNode { - constructor(options, ln_server_url, macaroon_path, macaroon_value, rune_path, rune_value, ln_api_password, swap_server_url, boltz_server_url, config_path, rtl_conf_file_path, swap_macaroon_path, boltz_macaroon_path, bitcoind_config_path, channel_backup_path, log_level, log_file, index, ln_node, ln_implementation, user_persona, theme_mode, theme_color, unannounced_channels, fiat_conversion, currency_unit, ln_version, api_version, enable_offers, enable_peerswap) { - this.options = options; - this.ln_server_url = ln_server_url; - this.macaroon_path = macaroon_path; - this.macaroon_value = macaroon_value; - this.rune_path = rune_path; - this.rune_value = rune_value; - this.ln_api_password = ln_api_password; - this.swap_server_url = swap_server_url; - this.boltz_server_url = boltz_server_url; - this.config_path = config_path; - this.rtl_conf_file_path = rtl_conf_file_path; - this.swap_macaroon_path = swap_macaroon_path; - this.boltz_macaroon_path = boltz_macaroon_path; - this.bitcoind_config_path = bitcoind_config_path; - this.channel_backup_path = channel_backup_path; - this.log_level = log_level; - this.log_file = log_file; - this.index = index; - this.ln_node = ln_node; - this.ln_implementation = ln_implementation; - this.user_persona = user_persona; - this.theme_mode = theme_mode; - this.theme_color = theme_color; - this.unannounced_channels = unannounced_channels; - this.fiat_conversion = fiat_conversion; - this.currency_unit = currency_unit; - this.ln_version = ln_version; - this.api_version = api_version; - this.enable_offers = enable_offers; - this.enable_peerswap = enable_peerswap; - } -} -export class AuthenticationConfiguration { - constructor(configPath, swapMacaroonPath, boltzMacaroonPath) { - this.configPath = configPath; - this.swapMacaroonPath = swapMacaroonPath; - this.boltzMacaroonPath = boltzMacaroonPath; - } -} -export class NodeSettingsConfiguration { - constructor(userPersona, themeMode, themeColor, unannouncedChannels, fiatConversion, currencyUnit, bitcoindConfigPath, logLevel, lnServerUrl, swapServerUrl, boltzServerUrl, channelBackupPath, enableOffers, enablePeerswap) { +export class NodeSettings { + constructor(lnServerUrl, swapServerUrl, boltzServerUrl, bitcoindConfigPath, channelBackupPath, logLevel, logFile, userPersona, themeMode, themeColor, unannouncedChannels, fiatConversion, currencyUnit, enableOffers, enablePeerswap) { + this.lnServerUrl = lnServerUrl; + this.swapServerUrl = swapServerUrl; + this.boltzServerUrl = boltzServerUrl; + this.bitcoindConfigPath = bitcoindConfigPath; + this.channelBackupPath = channelBackupPath; + this.logLevel = logLevel; + this.logFile = logFile; this.userPersona = userPersona; this.themeMode = themeMode; this.themeColor = themeColor; this.unannouncedChannels = unannouncedChannels; this.fiatConversion = fiatConversion; this.currencyUnit = currencyUnit; - this.bitcoindConfigPath = bitcoindConfigPath; - this.logLevel = logLevel; - this.lnServerUrl = lnServerUrl; - this.swapServerUrl = swapServerUrl; - this.boltzServerUrl = boltzServerUrl; - this.channelBackupPath = channelBackupPath; this.enableOffers = enableOffers; this.enablePeerswap = enablePeerswap; } } +export class NodeAuthentication { + constructor(options, configPath, macaroonPath, macaroonValue, runePath, runeValue, lnApiPassword, swapMacaroonPath, boltzMacaroonPath) { + this.options = options; + this.configPath = configPath; + this.macaroonPath = macaroonPath; + this.macaroonValue = macaroonValue; + this.runePath = runePath; + this.runeValue = runeValue; + this.lnApiPassword = lnApiPassword; + this.swapMacaroonPath = swapMacaroonPath; + this.boltzMacaroonPath = boltzMacaroonPath; + } +} +export class SelectedNode { + constructor(logLevel, logFile, index, lnNode, lnImplementation, lnVersion, apiVersion, settings, authentication) { + this.logLevel = logLevel; + this.logFile = logFile; + this.index = index; + this.lnNode = lnNode; + this.lnImplementation = lnImplementation; + this.lnVersion = lnVersion; + this.apiVersion = apiVersion; + this.settings = settings; + this.authentication = authentication; + } +} +export class SSO { + constructor(rtlSso, rtlCookiePath, logoutRedirectLink, cookieValue) { + this.rtlSso = rtlSso; + this.rtlCookiePath = rtlCookiePath; + this.logoutRedirectLink = logoutRedirectLink; + this.cookieValue = cookieValue; + } +} +export class ApplicationConfig { + constructor(defaultNodeIndex, selectedNodeIndex, dbDirectoryPath, rtlConfFilePath, rtlPass, allowPasswordUpdate, rtlSecret2fa, sso, nodes) { + this.defaultNodeIndex = defaultNodeIndex; + this.selectedNodeIndex = selectedNodeIndex; + this.dbDirectoryPath = dbDirectoryPath; + this.rtlConfFilePath = rtlConfFilePath; + this.rtlPass = rtlPass; + this.allowPasswordUpdate = allowPasswordUpdate; + this.rtlSecret2fa = rtlSecret2fa; + this.sso = sso; + this.nodes = nodes; + } +} export class LogJSONObj { constructor(level, msg, data, error, fileName, selectedNode) { this.level = level; diff --git a/backend/routes/shared/RTLConf.js b/backend/routes/shared/RTLConf.js index d783092d..f06a3f0d 100644 --- a/backend/routes/shared/RTLConf.js +++ b/backend/routes/shared/RTLConf.js @@ -1,17 +1,13 @@ import exprs from 'express'; const { Router } = exprs; import { isAuthenticated } from '../../utils/authCheck.js'; -import { getRTLConfigInitial, getRTLConfig, updateUISettings, update2FASettings, getConfig, getFile, updateSelectedNode, updateDefaultNode, updateServiceSettings, updateSSO, getCurrencyRates } from '../../controllers/shared/RTLConf.js'; +import { getRTLConfig, updateNodeSettings, getConfig, getFile, updateSelectedNode, updateApplicationSettings, getCurrencyRates } from '../../controllers/shared/RTLConf.js'; const router = Router(); -router.get('/rtlconfinit', getRTLConfigInitial); -router.get('/rtlconf', isAuthenticated, getRTLConfig); -router.post('/', isAuthenticated, updateUISettings); -router.post('/update2FA', isAuthenticated, update2FASettings); -router.get('/config/:nodeType', isAuthenticated, getConfig); +router.get('/rates', getCurrencyRates); router.get('/file', isAuthenticated, getFile); +router.get('/rtlconf/:init', isAuthenticated, getRTLConfig); router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode); -router.post('/updateDefaultNode', updateDefaultNode); -router.post('/updateServiceSettings', updateServiceSettings); -router.post('/updateSSO', updateSSO); -router.get('/rates', getCurrencyRates); +router.get('/config/:nodeType', isAuthenticated, getConfig); +router.post('/node', isAuthenticated, updateNodeSettings); +router.post('/application', isAuthenticated, updateApplicationSettings); export default router; diff --git a/backend/utils/app.js b/backend/utils/app.js index 8df632ac..5471cf88 100644 --- a/backend/utils/app.js +++ b/backend/utils/app.js @@ -30,7 +30,7 @@ export class ExpressApplication { this.setCORS = () => { CORS.mount(this.app); }; this.setCSRF = () => { CSRF.mount(this.app); }; this.setApplicationRoutes = () => { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' }); this.app.use(this.common.baseHref + '/api', sharedRoutes); this.app.use(this.common.baseHref + '/api/lnd', lndRoutes); this.app.use(this.common.baseHref + '/api/cln', clnRoutes); @@ -45,33 +45,33 @@ export class ExpressApplication { this.handleApplicationErrors(err, res); next(); }); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' }); }; this.handleApplicationErrors = (err, res) => { switch (err.code) { case 'EACCES': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' }); res.status(406).send('Server requires elevated privileges.'); break; case 'EADDRINUSE': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' }); res.status(409).send('Server is already in use.'); break; case 'ECONNREFUSED': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' }); res.status(401).send('Server is down/locked.'); break; case 'EBADCSRFTOKEN': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' }); res.status(403).send('Invalid CSRF token, form tempered.'); break; default: - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err }); res.status(400).send(JSON.stringify(err)); break; } }; - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' }); this.app.set('trust proxy', true); this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false })); this.app.use(cookieParser(this.common.secret_key)); diff --git a/backend/utils/authCheck.js b/backend/utils/authCheck.js index aa3d4e04..e6ee9dd1 100644 --- a/backend/utils/authCheck.js +++ b/backend/utils/authCheck.js @@ -46,7 +46,7 @@ export const verifyWSUser = (info, next) => { catch (err) { cookies = {}; updatedReq['cookies'] = JSON.parse(cookies); - logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err }); + logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err }); } csurfProtection(updatedReq, null, (err) => { if (err) { @@ -58,7 +58,7 @@ export const verifyWSUser = (info, next) => { }); } catch (err) { - logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err }); + logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err }); next(true); } } diff --git a/backend/utils/common.js b/backend/utils/common.js index 66193343..d25b0950 100644 --- a/backend/utils/common.js +++ b/backend/utils/common.js @@ -8,20 +8,11 @@ export class CommonService { constructor() { this.logger = Logger; this.nodes = []; - this.initSelectedNode = null; - this.rtl_conf_file_path = ''; + this.selectedNode = null; + this.ssoInit = { rtlSso: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' }; + this.appConfig = { defaultNodeIndex: 0, selectedNodeIndex: 0, rtlConfFilePath: '', dbDirectoryPath: join(dirname(fileURLToPath(import.meta.url)), '..', '..'), rtlPass: '', allowPasswordUpdate: true, rtlSecret2fa: '', sso: this.ssoInit, nodes: [] }; this.port = 3000; this.host = ''; - this.db_directory_path = join(dirname(fileURLToPath(import.meta.url)), '..', '..'); - this.rtl_pass = ''; - this.flg_allow_password_update = true; - this.rtl_secret2fa = ''; - this.rtl_sso = 0; - this.rtl_cookie_path = ''; - this.logout_redirect_link = ''; - this.cookie_value = ''; - this.ln_version = ''; - this.api_version = ''; this.secret_key = crypto.randomBytes(64).toString('hex'); this.read_dummy_data = false; this.baseHref = '/rtl'; @@ -32,96 +23,96 @@ export class CommonService { ]; this.setSwapServerOptions = (req) => { const swapOptions = { - baseUrl: req.session.selectedNode.swap_server_url, + baseUrl: req.session.selectedNode.settings.swapServerUrl, uri: '', rejectUnauthorized: false, json: true, headers: { 'Grpc-Metadata-macaroon': '' } }; - if (req.session.selectedNode.swap_macaroon_path) { + if (req.session.selectedNode.authentication.swapMacaroonPath) { try { - swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.swap_macaroon_path, 'loop.macaroon')).toString('hex') }; + swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.swapMacaroonPath, 'loop.macaroon')).toString('hex') }; } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err }); } } - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions }); return swapOptions; }; this.getBoltzServerOptions = (req) => { const boltzOptions = { - url: req.session.selectedNode.boltz_server_url, + url: req.session.selectedNode.settings.boltzServerUrl, rejectUnauthorized: false, json: true, headers: { 'Grpc-Metadata-macaroon': '' } }; - if (req.session.selectedNode.boltz_macaroon_path) { + if (req.session.selectedNode.authentication.boltzMacaroonPath) { try { - boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.boltz_macaroon_path, 'admin.macaroon')).toString('hex') }; + boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.boltzMacaroonPath, 'admin.macaroon')).toString('hex') }; } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err }); } } - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions }); return boltzOptions; }; this.getOptions = (req) => { - if (req.session.selectedNode && req.session.selectedNode.options) { - req.session.selectedNode.options.method = (req.session.selectedNode.ln_implementation && req.session.selectedNode.ln_implementation.toUpperCase() === 'LND') ? 'GET' : 'POST'; - delete req.session.selectedNode.options.form; - delete req.session.selectedNode.options.body; - req.session.selectedNode.options.qs = {}; - return req.session.selectedNode.options; + if (req.session.selectedNode && req.session.selectedNode.authentication.options) { + req.session.selectedNode.authentication.options.method = (req.session.selectedNode.lnImplementation && req.session.selectedNode.lnImplementation.toUpperCase() === 'LND') ? 'GET' : 'POST'; + delete req.session.selectedNode.authentication.options.form; + delete req.session.selectedNode.authentication.options.body; + req.session.selectedNode.authentication.options.qs = {}; + return req.session.selectedNode.authentication.options; } - return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.initSelectedNode); + return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.selectedNode); }; this.updateSelectedNodeOptions = (req) => { if (!req.session.selectedNode) { req.session.selectedNode = {}; } - req.session.selectedNode.options = { + req.session.selectedNode.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: null }; try { - if (req.session.selectedNode && req.session.selectedNode.ln_implementation) { - switch (req.session.selectedNode.ln_implementation.toUpperCase()) { + if (req.session.selectedNode && req.session.selectedNode.lnImplementation) { + switch (req.session.selectedNode.lnImplementation.toUpperCase()) { case 'CLN': try { - if (!req.session.selectedNode.rune_value) { - req.session.selectedNode.rune_value = this.getRuneValue(req.session.selectedNode.rune_path); + if (!req.session.selectedNode.authentication.runeValue) { + req.session.selectedNode.authentication.runeValue = this.getRuneValue(req.session.selectedNode.authentication.runePath); } - req.session.selectedNode.options.headers = { rune: req.session.selectedNode.rune_value }; + req.session.selectedNode.authentication.options.headers = { rune: req.session.selectedNode.authentication.runeValue }; } catch (err) { throw new Error(err); } break; case 'ECL': - req.session.selectedNode.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.ln_api_password).toString('base64') }; + req.session.selectedNode.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.authentication.lnApiPassword).toString('base64') }; break; default: - req.session.selectedNode.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; + req.session.selectedNode.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') }; break; } } if (req.session.selectedNode) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.ln_node, data: req.session.selectedNode.options }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.lnNode, data: req.session.selectedNode.authentication.options }); } return { status: 200, message: 'Updated Successfully' }; } catch (err) { - req.session.selectedNode.options = { + req.session.selectedNode.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: null }; - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err }); return { status: 502, message: err }; } }; @@ -137,50 +128,50 @@ export class CommonService { } }; this.setOptions = (req) => { - if (this.nodes[0].options && this.nodes[0].options.headers) { + if (this.nodes[0].authentication.options && this.nodes[0].authentication.options.headers) { return; } if (this.nodes && this.nodes.length > 0) { this.nodes.forEach((node) => { - node.options = { + node.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: null }; try { - if (node.ln_implementation) { - switch (node.ln_implementation.toUpperCase()) { + if (node.lnImplementation) { + switch (node.lnImplementation.toUpperCase()) { case 'CLN': try { - if (!node.rune_value) { - node.rune_value = this.getRuneValue(node.rune_path); + if (!node.authentication.runeValue) { + node.authentication.runeValue = this.getRuneValue(node.authentication.runePath); } - node.options.headers = { rune: node.rune_value }; + node.authentication.options.headers = { rune: node.authentication.runeValue }; } catch (err) { throw new Error(err); } break; case 'ECL': - node.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.ln_api_password).toString('base64') }; + node.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.authentication.lnApiPassword).toString('base64') }; break; default: - node.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.macaroon_path, 'admin.macaroon')).toString('hex') }; + node.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.authentication.macaroonPath, 'admin.macaroon')).toString('hex') }; break; } } } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err }); - node.options = { + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err }); + node.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: '' }; } - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.ln_node, data: node.options }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.lnNode, data: node.authentication.options }); }); this.updateSelectedNodeOptions(req); } @@ -260,9 +251,9 @@ export class CommonService { err = JSON.parse(JSON.stringify(errRes)); } if (!selectedNode) { - selectedNode = this.initSelectedNode; + selectedNode = this.selectedNode; } - switch (selectedNode.ln_implementation) { + switch (selectedNode.lnImplementation) { case 'LND': if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { delete err.options.headers['Grpc-Metadata-macaroon']; @@ -314,7 +305,7 @@ export class CommonService { (err.message && typeof err.message === 'string') ? err.message : (typeof err === 'string') ? err : 'Unknown Error') }; } - if (selectedNode.ln_implementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') { + if (selectedNode.lnImplementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') { newErrorObj.statusCode = 500; } return newErrorObj; @@ -325,16 +316,16 @@ export class CommonService { req.socket.remoteAddress || (req.connection.socket ? req.connection.socket.remoteAddress : null)); this.getDummyData = (dataKey, lnImplementation) => { - const dummyDataFile = this.rtl_conf_file_path + sep + 'ECLDummyData.log'; + const dummyDataFile = this.appConfig.rtlConfFilePath + sep + 'ECLDummyData.log'; return new Promise((resolve, reject) => { if (this.dummy_data_array_from_file.length === 0) { fs.readFile(dummyDataFile, 'utf8', (err, data) => { if (err) { if (err.code === 'ENOENT') { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' }); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' }); } } else { @@ -349,36 +340,36 @@ export class CommonService { }); }; this.readCookie = () => { - const exists = fs.existsSync(this.rtl_cookie_path); + const exists = fs.existsSync(this.appConfig.sso.rtlCookiePath); if (exists) { try { - this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); + this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8'); } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err }); throw new Error(err); } } else { try { - const directoryName = dirname(this.rtl_cookie_path); + const directoryName = dirname(this.appConfig.sso.rtlCookiePath); this.createDirectory(directoryName); - fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); - this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); + fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex')); + this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8'); } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err }); throw new Error(err); } } }; this.refreshCookie = () => { try { - fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); - this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); + fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex')); + this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8'); } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err }); throw new Error(err); } }; @@ -405,50 +396,50 @@ export class CommonService { }, initDir); }; this.replacePasswordWithHash = (multiPassHashed) => { - this.rtl_conf_file_path = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..'); + this.appConfig.rtlConfFilePath = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..'); try { - const RTLConfFile = this.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = this.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); config.multiPassHashed = multiPassHashed; delete config.multiPass; fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' }); return config.multiPassHashed; } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err }); } }; this.getAllNodeAllChannelBackup = (node) => { - const channel_backup_file = node.channel_backup_path + sep + 'channel-all.bak'; + const channel_backup_file = node.settings.channelBackupPath + sep + 'channel-all.bak'; const options = { - url: node.ln_server_url + '/v1/channels/backup', + url: node.settings.lnServerUrl + '/v1/channels/backup', rejectUnauthorized: false, json: true, - headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex') } + headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.authentication.macaroonPath + '/admin.macaroon').toString('hex') } }; - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.ln_node + '..' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.lnNode + '..' }); request(options).then((body) => { fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => { if (err) { - if (node.ln_node) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); + if (node.lnNode) { + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err }); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err }); } } else { - if (node.ln_node) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.ln_node, data: body }); + if (node.lnNode) { + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.lnNode, data: body }); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body }); } } }); }, (err) => { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err }); fs.writeFile(channel_backup_file, '', () => { }); }); }; @@ -458,8 +449,8 @@ export class CommonService { const pattern = /v?(\d+(\.\d+)*)/; const match = currentVersion.match(pattern); if (match && match.length && match.length > 1) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] }); - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion }); const currentVersionArr = match[1].split('.') || []; currentVersionArr[1] = currentVersionArr[1].substring(0, 2); const checkVersionsArr = checkVersion.split('.'); @@ -469,7 +460,7 @@ export class CommonService { (+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion }); return false; } } @@ -481,16 +472,16 @@ export class CommonService { if (selNode && selNode.index) { this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'PORT: ' + this.port }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'HOST: ' + this.host }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.db_directory_path }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.rtl_sso }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.appConfig.dbDirectoryPath }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.appConfig.sso.rtlSso }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + selNode.index }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'INDEX: ' + selNode.index }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.ln_node }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.ln_implementation }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.fiat_conversion }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.currency_unit }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.ln_server_url }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.logout_redirect_link + '\r\n' }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.lnNode }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.lnImplementation }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.settings.fiatConversion }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.settings.currencyUnit }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.settings.lnServerUrl }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.appConfig.sso.logoutRedirectLink + '\r\n' }); } }; this.filterData = (dataKey, lnImplementation) => { diff --git a/backend/utils/config.js b/backend/utils/config.js index 9f657249..56ba554f 100644 --- a/backend/utils/config.js +++ b/backend/utils/config.js @@ -95,9 +95,9 @@ export class ConfigService { }; this.updateLogByLevel = () => { let updateLogFlag = false; - this.common.rtl_conf_file_path = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); + this.common.appConfig.rtlConfFilePath = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); try { - const RTLConfFile = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); config.nodes.forEach((node) => { if (node.Settings.hasOwnProperty('enableLogging')) { @@ -117,19 +117,19 @@ export class ConfigService { this.validateNodeConfig = (config) => { if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { - this.common.rtl_pass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); - this.common.flg_allow_password_update = false; + this.common.appConfig.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); + this.common.appConfig.allowPasswordUpdate = false; } else if (config.multiPassHashed && config.multiPassHashed !== '') { - this.common.rtl_pass = config.multiPassHashed; + this.common.appConfig.rtlPass = config.multiPassHashed; } else if (config.multiPass && config.multiPass !== '') { - this.common.rtl_pass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex')); + this.common.appConfig.rtlPass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex')); } else { this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json'; } - this.common.rtl_secret2fa = config.secret2fa; + this.common.appConfig.rtlSecret2fa = config.secret2fa; } else { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { @@ -138,23 +138,23 @@ export class ConfigService { } this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000; this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null; - this.common.db_directory_path = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..'); + this.common.appConfig.dbDirectoryPath = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..'); if (config.nodes && config.nodes.length > 0) { config.nodes.forEach((node, idx) => { this.common.nodes[idx] = {}; this.common.nodes[idx].index = node.index; - this.common.nodes[idx].ln_node = node.lnNode; - this.common.nodes[idx].ln_implementation = (process?.env?.LN_IMPLEMENTATION) ? process?.env?.LN_IMPLEMENTATION : node.lnImplementation ? node.lnImplementation : 'LND'; - if (this.common.nodes[idx].ln_implementation === 'CLT') { - this.common.nodes[idx].ln_implementation = 'CLN'; + this.common.nodes[idx].lnNode = node.lnNode; + this.common.nodes[idx].lnImplementation = (process?.env?.lnImplementation) ? process?.env?.lnImplementation : node.lnImplementation ? node.lnImplementation : 'LND'; + if (this.common.nodes[idx].lnImplementation === 'CLT') { + this.common.nodes[idx].lnImplementation = 'CLN'; } - switch (this.common.nodes[idx].ln_implementation) { + switch (this.common.nodes[idx].lnImplementation) { case 'CLN': if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') { - this.common.nodes[idx].rune_path = process?.env?.RUNE_PATH; + this.common.nodes[idx].authentication.runePath = process?.env?.RUNE_PATH; } else if (node.Authentication && node.Authentication.runePath && node.Authentication.runePath.trim() !== '') { - this.common.nodes[idx].rune_path = node.Authentication.runePath; + this.common.nodes[idx].authentication.runePath = node.Authentication.runePath; } else { this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!'; @@ -162,21 +162,21 @@ export class ConfigService { break; case 'ECL': if (process?.env?.LN_API_PASSWORD) { - this.common.nodes[idx].ln_api_password = process?.env?.LN_API_PASSWORD; + this.common.nodes[idx].authentication.lnApiPassword = process?.env?.LN_API_PASSWORD; } else if (node.Authentication && node.Authentication.lnApiPassword) { - this.common.nodes[idx].ln_api_password = node.Authentication.lnApiPassword; + this.common.nodes[idx].authentication.lnApiPassword = node.Authentication.lnApiPassword; } else { - this.common.nodes[idx].ln_api_password = ''; + this.common.nodes[idx].authentication.lnApiPassword = ''; } break; default: if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') { - this.common.nodes[idx].macaroon_path = process?.env?.MACAROON_PATH; + this.common.nodes[idx].authentication.macaroonPath = process?.env?.MACAROON_PATH; } else if (node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') { - this.common.nodes[idx].macaroon_path = node.Authentication.macaroonPath; + this.common.nodes[idx].authentication.macaroonPath = node.Authentication.macaroonPath; } else { this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!'; @@ -184,114 +184,114 @@ export class ConfigService { break; } if (process?.env?.CONFIG_PATH) { - this.common.nodes[idx].config_path = process?.env?.CONFIG_PATH; + this.common.nodes[idx].authentication.configPath = process?.env?.CONFIG_PATH; } else if (node.Authentication && node.Authentication.configPath) { - this.common.nodes[idx].config_path = node.Authentication.configPath; + this.common.nodes[idx].authentication.configPath = node.Authentication.configPath; } else { - this.common.nodes[idx].config_path = ''; + this.common.nodes[idx].authentication.configPath = ''; } - if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '' && this.common.nodes[idx].config_path !== '') { + if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '' && this.common.nodes[idx].authentication.configPath !== '') { try { - const exists = fs.existsSync(this.common.nodes[idx].config_path || ''); + const exists = fs.existsSync(this.common.nodes[idx].authentication.configPath || ''); if (exists) { try { - const configFile = fs.readFileSync((this.common.nodes[idx].config_path || ''), 'utf-8'); + const configFile = fs.readFileSync((this.common.nodes[idx].authentication.configPath || ''), 'utf-8'); const iniParsed = ini.parse(configFile); - this.common.nodes[idx].ln_api_password = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password; + this.common.nodes[idx].authentication.lnApiPassword = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password; } catch (err) { this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err; } } else { - this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].config_path; + this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].authentication.configPath; } } catch (err) { this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err; } } - if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '') { + if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '') { this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!'; } if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') { - this.common.nodes[idx].ln_server_url = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL; + this.common.nodes[idx].settings.lnServerUrl = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL; } else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') { - this.common.nodes[idx].ln_server_url = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL; + this.common.nodes[idx].settings.lnServerUrl = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL; } else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') { - this.common.nodes[idx].ln_server_url = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl; + this.common.nodes[idx].settings.lnServerUrl = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl; } else if (node.Settings.lndServerUrl && node.Settings.lndServerUrl.trim() !== '') { - this.common.nodes[idx].ln_server_url = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl; + this.common.nodes[idx].settings.lnServerUrl = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl; } else { this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!'; } - this.common.nodes[idx].user_persona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT'; - this.common.nodes[idx].theme_mode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY'; - this.common.nodes[idx].theme_color = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE'; - this.common.nodes[idx].unannounced_channels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false; - this.common.nodes[idx].log_level = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR'; - this.common.nodes[idx].fiat_conversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false; - if (this.common.nodes[idx].fiat_conversion) { - this.common.nodes[idx].currency_unit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD'; + this.common.nodes[idx].settings.userPersona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT'; + this.common.nodes[idx].settings.themeMode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY'; + this.common.nodes[idx].settings.themeColor = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE'; + this.common.nodes[idx].settings.unannouncedChannels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false; + this.common.nodes[idx].settings.logLevel = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR'; + this.common.nodes[idx].settings.fiatConversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false; + if (this.common.nodes[idx].settings.fiatConversion) { + this.common.nodes[idx].settings.currencyUnit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD'; } if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') { - this.common.nodes[idx].swap_server_url = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL; - this.common.nodes[idx].swap_macaroon_path = process?.env?.SWAP_MACAROON_PATH; + this.common.nodes[idx].settings.swapServerUrl = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL; + this.common.nodes[idx].authentication.swapMacaroonPath = process?.env?.SWAP_MACAROON_PATH; } else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') { - this.common.nodes[idx].swap_server_url = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl; - this.common.nodes[idx].swap_macaroon_path = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : ''; + this.common.nodes[idx].settings.swapServerUrl = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl; + this.common.nodes[idx].authentication.swapMacaroonPath = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : ''; } else { - this.common.nodes[idx].swap_server_url = ''; - this.common.nodes[idx].swap_macaroon_path = ''; + this.common.nodes[idx].settings.swapServerUrl = ''; + this.common.nodes[idx].authentication.swapMacaroonPath = ''; } if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') { - this.common.nodes[idx].boltz_server_url = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL; - this.common.nodes[idx].boltz_macaroon_path = process?.env?.BOLTZ_MACAROON_PATH; + this.common.nodes[idx].settings.boltzServerUrl = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL; + this.common.nodes[idx].authentication.boltzMacaroonPath = process?.env?.BOLTZ_MACAROON_PATH; } else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') { - this.common.nodes[idx].boltz_server_url = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl; - this.common.nodes[idx].boltz_macaroon_path = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : ''; + this.common.nodes[idx].settings.boltzServerUrl = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl; + this.common.nodes[idx].authentication.boltzMacaroonPath = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : ''; } else { - this.common.nodes[idx].boltz_server_url = ''; - this.common.nodes[idx].boltz_macaroon_path = ''; + this.common.nodes[idx].settings.boltzServerUrl = ''; + this.common.nodes[idx].authentication.boltzMacaroonPath = ''; } - this.common.nodes[idx].enable_offers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false; - this.common.nodes[idx].enable_peerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false; - this.common.nodes[idx].bitcoind_config_path = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : ''; - this.common.nodes[idx].channel_backup_path = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.rtl_conf_file_path + sep + 'channels-backup' + sep + 'node-' + node.index; + this.common.nodes[idx].settings.enableOffers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false; + this.common.nodes[idx].settings.enablePeerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false; + this.common.nodes[idx].settings.bitcoindConfigPath = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : ''; + this.common.nodes[idx].settings.channelBackupPath = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.appConfig.rtlConfFilePath + sep + 'channels-backup' + sep + 'node-' + node.index; try { - this.common.createDirectory(this.common.nodes[idx].channel_backup_path); - const exists = fs.existsSync(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); + this.common.createDirectory(this.common.nodes[idx].settings.channelBackupPath); + const exists = fs.existsSync(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak'); if (!exists) { try { - if (this.common.nodes[idx].ln_implementation === 'LND') { + if (this.common.nodes[idx].lnImplementation === 'LND') { this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]); } else { - const createStream = fs.createWriteStream(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); + const createStream = fs.createWriteStream(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak'); createStream.end(); } } catch (err) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err }); } } } catch (err) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err }); } - this.common.nodes[idx].log_file = this.common.rtl_conf_file_path + '/logs/RTL-Node-' + node.index + '.log'; - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) }); - const log_file = this.common.nodes[idx].log_file; + this.common.nodes[idx].settings.logFile = this.common.appConfig.rtlConfFilePath + '/logs/RTL-Node-' + node.index + '.log'; + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) }); + const log_file = this.common.nodes[idx].settings.logFile; if (fs.existsSync(log_file || '')) { fs.writeFile((log_file || ''), '', () => { }); } @@ -303,7 +303,7 @@ export class ConfigService { createStream.end(); } catch (err) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err }); } } }); @@ -315,28 +315,28 @@ export class ConfigService { }; this.setSSOParams = (config) => { if (process?.env?.RTL_SSO) { - this.common.rtl_sso = +process?.env?.RTL_SSO; + this.common.appConfig.sso.rtlSso = +process?.env?.RTL_SSO; } else if (config.SSO && config.SSO.rtlSSO) { - this.common.rtl_sso = config.SSO.rtlSSO; + this.common.appConfig.sso.rtlSso = config.SSO.rtlSSO; } if (process?.env?.RTL_COOKIE_PATH) { - this.common.rtl_cookie_path = process?.env?.RTL_COOKIE_PATH; + this.common.appConfig.sso.rtlCookiePath = process?.env?.RTL_COOKIE_PATH; } else if (config.SSO && config.SSO.rtlCookiePath) { - this.common.rtl_cookie_path = config.SSO.rtlCookiePath; + this.common.appConfig.sso.rtlCookiePath = config.SSO.rtlCookiePath; } else { - this.common.rtl_cookie_path = ''; + this.common.appConfig.sso.rtlCookiePath = ''; } if (process?.env?.LOGOUT_REDIRECT_LINK) { - this.common.logout_redirect_link = process?.env?.LOGOUT_REDIRECT_LINK; + this.common.appConfig.sso.logoutRedirectLink = process?.env?.LOGOUT_REDIRECT_LINK; } else if (config.SSO && config.SSO.logoutRedirectLink) { - this.common.logout_redirect_link = config.SSO.logoutRedirectLink; + this.common.appConfig.sso.logoutRedirectLink = config.SSO.logoutRedirectLink; } - if (+this.common.rtl_sso) { - if (!this.common.rtl_cookie_path || this.common.rtl_cookie_path.trim() === '') { + if (+this.common.appConfig.sso.rtlSso) { + if (!this.common.appConfig.sso.rtlCookiePath || this.common.appConfig.sso.rtlCookiePath.trim() === '') { this.errMsg = 'Please set rtlCookiePath value for single sign on option!'; } else { @@ -346,16 +346,16 @@ export class ConfigService { }; this.setSelectedNode = (config) => { if (config.defaultNodeIndex) { - this.common.initSelectedNode = this.common.findNode(config.defaultNodeIndex) || {}; + this.common.selectedNode = this.common.findNode(config.defaultNodeIndex) || {}; } else { - this.common.initSelectedNode = this.common.findNode(this.common.nodes[0].index) || {}; + this.common.selectedNode = this.common.findNode(this.common.nodes[0].index) || {}; } }; this.setServerConfiguration = () => { try { - this.common.rtl_conf_file_path = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); - const confFileFullPath = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; + this.common.appConfig.rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); + const confFileFullPath = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; if (!fs.existsSync(confFileFullPath)) { fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig())); } @@ -365,7 +365,7 @@ export class ConfigService { this.setSelectedNode(config); } catch (err) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err }); throw new Error(err); } }; diff --git a/backend/utils/cors.js b/backend/utils/cors.js index 4137b13d..b9f6f8a5 100644 --- a/backend/utils/cors.js +++ b/backend/utils/cors.js @@ -6,7 +6,7 @@ class CORS { this.common = Common; } mount(app) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' }); app.use((req, res, next) => { res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath'); @@ -17,7 +17,7 @@ class CORS { } next(); }); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' }); return app; } ; diff --git a/backend/utils/csrf.js b/backend/utils/csrf.js index bca5ab20..94c3b41d 100644 --- a/backend/utils/csrf.js +++ b/backend/utils/csrf.js @@ -8,11 +8,11 @@ class CSRF { this.common = Common; } mount(app) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' }); if (process.env.NODE_ENV !== 'development') { app.use((req, res, next) => this.csrfProtection(req, res, next)); } - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' }); return app; } ; diff --git a/backend/utils/database.js b/backend/utils/database.js index 84949bfc..8e5301e2 100644 --- a/backend/utils/database.js +++ b/backend/utils/database.js @@ -7,12 +7,12 @@ export class DatabaseService { constructor() { this.common = Common; this.logger = Logger; - this.dbDirectory = join(this.common.db_directory_path, 'database'); + this.dbDirectory = join(this.common.appConfig.dbDirectoryPath, 'database'); this.nodeDatabase = {}; } migrateDatabase() { this.common.nodes?.map((node) => { - if (node.ln_implementation === 'ECL') { + if (node.lnImplementation === 'ECL') { this.nodeDatabase[node.index] = { adapter: null, data: {} }; this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node); this.fetchNodeData(node); @@ -80,7 +80,7 @@ export class DatabaseService { } } fetchNodeData(selectedNode) { - switch (selectedNode.ln_implementation) { + switch (selectedNode.lnImplementation) { case 'CLN': for (const collectionName in CLNCollection) { if (CLNCollection.hasOwnProperty(collectionName)) { @@ -250,14 +250,14 @@ export class DatabaseAdapter { this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index; // For backward compatibility Start const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json'; - if (selNode.ln_implementation === 'CLN' && fs.existsSync(oldFilePath)) { + if (selNode.lnImplementation === 'CLN' && fs.existsSync(oldFilePath)) { this.renameOldDB(oldFilePath, selNode); } // For backward compatibility End this.insertSession(id); } renameOldDB(oldFilePath, selNode = null) { - const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.ln_implementation + '-Offers.json'; + const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.lnImplementation + '-Offers.json'; try { this.common.createDirectory(this.dbFilePath); const oldOffers = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8')); @@ -277,7 +277,7 @@ export class DatabaseAdapter { catch (err) { throw new Error(JSON.stringify(err)); } - const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; + const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json'; try { if (!fs.existsSync(collectionFilePath)) { fs.writeFileSync(collectionFilePath, '[]'); @@ -290,15 +290,15 @@ export class DatabaseAdapter { const otherFiles = fs.readdirSync(this.dbFilePath); otherFiles.forEach((oFileName) => { let collectionValid = false; - switch (this.selNode.ln_implementation) { + switch (this.selNode.lnImplementation) { case 'CLN': - collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); + collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false); break; case 'ECL': - collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); + collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false); break; default: - collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); + collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false); break; } if (oFileName.endsWith('.json') && !collectionValid) { @@ -324,7 +324,7 @@ export class DatabaseAdapter { saveData(collectionName, collectionData) { try { if (collectionData) { - const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; + const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json'; const tempFile = collectionFilePath + '.tmp'; fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2)); fs.renameSync(tempFile, collectionFilePath); diff --git a/backend/utils/logger.js b/backend/utils/logger.js index e2fc12c6..7ce9dbb1 100644 --- a/backend/utils/logger.js +++ b/backend/utils/logger.js @@ -16,15 +16,15 @@ export class LoggerService { msgStr = msgStr + '.\r\n'; } console.error(msgStr); - if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } break; case 'WARN': msgStr = prepMsgData(msgJSON, msgStr); - if (!msgJSON.selectedNode || msgJSON.selectedNode.log_level === 'WARN' || msgJSON.selectedNode.log_level === 'INFO' || msgJSON.selectedNode.log_level === 'DEBUG') { - if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (!msgJSON.selectedNode || msgJSON.selectedNode.settings.logLevel === 'WARN' || msgJSON.selectedNode.settings.logLevel === 'INFO' || msgJSON.selectedNode.settings.logLevel === 'DEBUG') { + if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } } break; @@ -32,18 +32,18 @@ export class LoggerService { if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') { console.log(msgStr + '.\r\n'); } - else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'INFO') { + else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'INFO') { msgStr = msgStr + '.\r\n'; console.log(msgStr); - if (msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } } - else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { + else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') { msgStr = prepMsgData(msgJSON, msgStr); console.log(msgStr); - if (msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } } break; @@ -51,11 +51,11 @@ export class LoggerService { if (!msgJSON.selectedNode) { console.log(msgStr + '.\r\n'); } - else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { + else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') { msgStr = prepMsgData(msgJSON, msgStr); console.log(msgStr); - if (msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } } break; diff --git a/backend/utils/webSocketServer.js b/backend/utils/webSocketServer.js index 590201f5..e30e7671 100644 --- a/backend/utils/webSocketServer.js +++ b/backend/utils/webSocketServer.js @@ -28,7 +28,7 @@ export class RTLWebSocketServer { } }, 1000 * 60 * 60); // Terminate broken connections every hour this.mount = (httpServer) => { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' }); this.webSocketServer = new WebSocketServer({ noServer: true, path: this.common.baseHref + '/api/ws', verifyClient: (process.env.NODE_ENV === 'development') ? null : verifyWSUser }); httpServer.on('upgrade', (request, socket, head) => { if (request.headers['upgrade'] !== 'websocket') { @@ -46,7 +46,7 @@ export class RTLWebSocketServer { }); this.webSocketServer.on('connection', this.mountEventsOnConnection); this.webSocketServer.on('close', () => clearInterval(this.pingInterval)); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' }); }; this.upgradeCallback = (websocket, request) => { this.webSocketServer.emit('connection', websocket, request); @@ -58,13 +58,13 @@ export class RTLWebSocketServer { websocket.isAlive = true; websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null; websocket.clientNodeIndex = +protocols[1]; - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); websocket.on('error', this.sendErrorToAllLNClients); websocket.on('message', this.sendEventsToAllLNClients); websocket.on('pong', () => { websocket.isAlive = true; }); websocket.on('close', (code, reason) => { this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); }); }; this.updateLNWSClientDetails = (sessionId, currNodeIndex, prevNodeIndex) => { @@ -85,7 +85,7 @@ export class RTLWebSocketServer { } else { const selectedNode = this.common.findNode(currNodeIndex); - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' }); } }; this.disconnectFromNodeClient = (sessionId, prevNodeIndex) => { @@ -99,8 +99,8 @@ export class RTLWebSocketServer { const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex); this.clientDetails.splice(foundClientIdx, 1); const prevSelectedNode = this.common.findNode(prevNodeIndex); - if (prevSelectedNode && prevSelectedNode.ln_implementation) { - switch (prevSelectedNode.ln_implementation) { + if (prevSelectedNode && prevSelectedNode.lnImplementation) { + switch (prevSelectedNode.lnImplementation) { case 'LND': this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex); break; @@ -129,8 +129,8 @@ export class RTLWebSocketServer { const currSelectedNode = this.common.findNode(currNodeIndex); foundClient = { index: currNodeIndex, sessionIds: [sessionId] }; this.clientDetails.push(foundClient); - if (currSelectedNode && currSelectedNode.ln_implementation) { - switch (currSelectedNode.ln_implementation) { + if (currSelectedNode && currSelectedNode.lnImplementation) { + switch (currSelectedNode.lnImplementation) { case 'LND': this.eventEmitterLND.emit('CONNECT', currNodeIndex); break; @@ -149,27 +149,27 @@ export class RTLWebSocketServer { this.sendErrorToAllLNClients = (serverError, selectedNode) => { try { this.webSocketServer.clients.forEach((client) => { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError }); if (+client.clientNodeIndex === +selectedNode.index) { client.send(serverError); } }); } catch (err) { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); } }; this.sendEventsToAllLNClients = (newMessage, selectedNode) => { try { this.webSocketServer.clients.forEach((client) => { if (+client.clientNodeIndex === +selectedNode.index) { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage }); client.send(newMessage); } }); } catch (err) { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); } }; this.generateAcceptValue = (acceptKey) => crypto.createHash('sha1').update(acceptKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary').digest('base64'); diff --git a/server/controllers/cln/channels.ts b/server/controllers/cln/channels.ts index 7529d37a..62f02914 100644 --- a/server/controllers/cln/channels.ts +++ b/server/controllers/cln/channels.ts @@ -11,7 +11,7 @@ export const listPeerChannels = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Peer Channels..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeerchannels'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels }); return Promise.all(body.channels?.map((channel) => { @@ -32,7 +32,7 @@ export const openChannel = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/fundchannel'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fundchannel'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body }); request.post(options).then((body) => { @@ -48,7 +48,7 @@ export const setChannelFee = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Setting Channel Fee..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/setchannel'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/setchannel'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body }); request.post(options).then((body) => { @@ -65,7 +65,7 @@ export const closeChannel = (req, res, next) => { req.setTimeout(60000 * 10); // timeout 10 mins options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/close'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/close'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url }); request.post(options).then((body) => { @@ -82,7 +82,7 @@ export const listForwards = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listforwards'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listforwards'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body }); @@ -98,7 +98,7 @@ export const funderUpdatePolicy = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting or Updating Funder Policy..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/funderupdate'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/funderupdate'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body }); request.post(options).then((body) => { diff --git a/server/controllers/cln/getInfo.ts b/server/controllers/cln/getInfo.ts index f1630c4b..bdb773d9 100644 --- a/server/controllers/cln/getInfo.ts +++ b/server/controllers/cln/getInfo.ts @@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => { common.setOptions(req); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo'; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url }); if (!options.headers || !options.headers.rune) { const errMsg = 'Core lightning get info failed due to missing rune!'; @@ -45,7 +45,7 @@ export const getInfo = (req, res, next) => { body.uris.push(body.id + '@' + addr.address + ':' + addr.port); }); } - req.session.selectedNode.ln_version = body.version || ''; + req.session.selectedNode.lnVersion = body.version || ''; req.session.selectedNode.api_version = body.api_version || ''; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' }); clWsClient.updateSelectedNode(req.session.selectedNode); diff --git a/server/controllers/cln/invoices.ts b/server/controllers/cln/invoices.ts index 3cac3ee8..7ff9eee5 100644 --- a/server/controllers/cln/invoices.ts +++ b/server/controllers/cln/invoices.ts @@ -9,7 +9,7 @@ export const deleteExpiredInvoice = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Deleting Expired Invoices..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/delexpiredinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/delexpiredinvoice'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body }); @@ -24,7 +24,7 @@ export const listInvoices = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Getting Invoices..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listinvoices'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listinvoices'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url }); request.post(options).then((body) => { @@ -40,7 +40,7 @@ export const addInvoice = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/invoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoice'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body }); diff --git a/server/controllers/cln/network.ts b/server/controllers/cln/network.ts index 31e14d41..37cf8ad1 100644 --- a/server/controllers/cln/network.ts +++ b/server/controllers/cln/network.ts @@ -1,7 +1,7 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; @@ -11,7 +11,7 @@ export const getRoute = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Routes..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/getroute'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getroute'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body }); @@ -29,7 +29,7 @@ export const listChannels = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listchannels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listchannels'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body }); @@ -45,7 +45,7 @@ export const feeRates = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Fee Rates..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/feerates'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/feerates'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body }); @@ -62,7 +62,7 @@ export const listNodes = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listnodes'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listnodes'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url }); request.post(options).then((body) => { @@ -78,8 +78,8 @@ export const listNodes = (req, res, next) => { }); }; -export const getAlias = (selNode: CommonSelectedNode, peer: any, id: string) => { - options.url = selNode.ln_server_url + '/v1/listnodes'; +export const getAlias = (selNode: SelectedNode, peer: any, id: string) => { + options.url = selNode.settings.lnServerUrl + '/v1/listnodes'; if (!peer[id]) { logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' }); peer.alias = ''; diff --git a/server/controllers/cln/offers.ts b/server/controllers/cln/offers.ts index 8fd2fe28..993b852c 100644 --- a/server/controllers/cln/offers.ts +++ b/server/controllers/cln/offers.ts @@ -36,7 +36,7 @@ export const listOffers = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offers..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listoffers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listoffers'; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url }); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body }); @@ -51,7 +51,7 @@ export const createOffer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Creating Offer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/offer'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/offer'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body }); @@ -66,7 +66,7 @@ export const fetchOfferInvoice = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Invoice..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/fetchinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fetchinvoice'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body }); request.post(options).then((body) => { @@ -82,7 +82,7 @@ export const disableOffer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Disabling Offer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/disableOffer'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disableOffer'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body }); diff --git a/server/controllers/cln/onchain.ts b/server/controllers/cln/onchain.ts index 3763135c..0495499b 100644 --- a/server/controllers/cln/onchain.ts +++ b/server/controllers/cln/onchain.ts @@ -9,7 +9,7 @@ export const getNewAddress = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/newaddr'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddr'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); @@ -24,7 +24,7 @@ export const onChainWithdraw = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Withdrawing from On Chain..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/withdraw'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/withdraw'; options.body = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body }); request.post(options).then((body) => { @@ -40,7 +40,7 @@ export const getUTXOs = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Listing Funds..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listfunds'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listfunds'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body }); // Local Remote Balance Calculation diff --git a/server/controllers/cln/payments.ts b/server/controllers/cln/payments.ts index 6a716c90..fbf424aa 100644 --- a/server/controllers/cln/payments.ts +++ b/server/controllers/cln/payments.ts @@ -3,15 +3,15 @@ import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; import { Database, DatabaseService } from '../../utils/database.js'; import { CollectionFieldsEnum, CollectionsEnum, Offer } from '../../models/database.model.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; const databaseService: DatabaseService = Database; -export const getMemo = (selNode: CommonSelectedNode, payment: any) => { - options.url = selNode.ln_server_url + '/v1/decode'; +export const getMemo = (selNode: SelectedNode, payment: any) => { + options.url = selNode.settings.lnServerUrl + '/v1/decode'; options.body = { string: payment.bolt11 }; return request.post(options).then((res) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res }); @@ -74,7 +74,7 @@ export const listPayments = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'List Payments..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listsendpays'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listsendpays'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments }); body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : []; @@ -95,7 +95,7 @@ export const postPayment = (req, res, next) => { const options_body = JSON.parse(JSON.stringify(req.body)); if (paymentType === 'KEYSEND') { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' }); - options.url = req.session.selectedNode.ln_server_url + '/v1/keysend'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/keysend'; delete options_body.uiMessage; delete options_body.fromDialog; delete options_body.paymentType; @@ -134,7 +134,7 @@ export const postPayment = (req, res, next) => { delete options_body.pubkey; delete options_body.saveToDB; options.body = options_body; - options.url = req.session.selectedNode.ln_server_url + '/v1/pay'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/pay'; } request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body }); diff --git a/server/controllers/cln/peers.ts b/server/controllers/cln/peers.ts index 24e19a02..2772cf40 100644 --- a/server/controllers/cln/peers.ts +++ b/server/controllers/cln/peers.ts @@ -11,7 +11,7 @@ export const getPeers = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'List Peers..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); const peers = !body.peers ? [] : body.peers; @@ -29,12 +29,12 @@ export const postPeer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/connect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/connect'; options.body = req.body; request.post(options).then((connectRes) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes }); const listOptions = common.getOptions(req); - listOptions.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; + listOptions.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers'; request.post(listOptions).then((listPeersRes) => { const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : []; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers }); @@ -53,7 +53,7 @@ export const deletePeer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/disconnect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disconnect'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body }); diff --git a/server/controllers/cln/utility.ts b/server/controllers/cln/utility.ts index 147a6656..2949d40d 100644 --- a/server/controllers/cln/utility.ts +++ b/server/controllers/cln/utility.ts @@ -10,7 +10,7 @@ export const decodePayment = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/decode'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/decode'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); @@ -25,7 +25,7 @@ export const signMessage = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage'; options.body = req.body; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body }); @@ -40,7 +40,7 @@ export const verifyMessage = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/checkmessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/checkmessage'; options.body = req.body; request.post(options, (error, response, body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body }); @@ -55,7 +55,7 @@ export const listConfigs = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/listconfigs'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listconfigs'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body }); res.status(200).json(body); diff --git a/server/controllers/cln/webSocketClient.ts b/server/controllers/cln/webSocketClient.ts index f9191d59..25100a20 100644 --- a/server/controllers/cln/webSocketClient.ts +++ b/server/controllers/cln/webSocketClient.ts @@ -2,14 +2,14 @@ import socketIOClient from 'socket.io-client'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; import { WSServer } from '../../utils/webSocketServer.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; export class CLWebSocketClient { public logger: LoggerService = Logger; public common: CommonService = Common; public wsServer = WSServer; - public webSocketClients: Array<{ selectedNode: CommonSelectedNode, reConnect: boolean, webSocketClient: any }> = []; + public webSocketClients: Array<{ selectedNode: SelectedNode, reConnect: boolean, webSocketClient: any }> = []; public reconnectTimeOut = null; public waitTime = 0.5; @@ -34,17 +34,17 @@ export class CLWebSocketClient { }, this.waitTime * 1000); }; - public connect = (selectedNode: CommonSelectedNode) => { + public connect = (selectedNode: SelectedNode) => { try { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); if (!clientExists) { - if (selectedNode.ln_server_url) { + if (selectedNode.settings.lnServerUrl) { const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; this.connectWithClient(newWebSocketClient); this.webSocketClients.push(newWebSocketClient); } } else { - if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.ln_server_url) { + if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.settings.lnServerUrl) { clientExists.reConnect = true; this.connectWithClient(clientExists); } @@ -57,11 +57,11 @@ export class CLWebSocketClient { public connectWithClient = (clWsClt) => { this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' }); try { - if (!clWsClt.selectedNode.rune_value) { - clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path); + if (!clWsClt.selectedNode.authentication.runeValue) { + clWsClt.selectedNode.authentication.runeValue = this.common.getRuneValue(clWsClt.selectedNode.authentication.runePath); } - clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, { - extraHeaders: { rune: clWsClt.selectedNode.rune_value }, + clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.settings.lnServerUrl, { + extraHeaders: { rune: clWsClt.selectedNode.authentication.runeValue }, transports: ['websocket'], secure: true, rejectUnauthorized: false @@ -76,7 +76,7 @@ export class CLWebSocketClient { }); clWsClt.webSocketClient.on('disconnect', (reason) => { - if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.ln_implementation === 'CLN') { + if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.lnImplementation === 'CLN') { this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason }); clWsClt.webSocketClient.close(); if (clWsClt.reConnect) { this.reconnect(clWsClt); } @@ -97,7 +97,7 @@ export class CLWebSocketClient { }); }; - public disconnect = (selectedNode: CommonSelectedNode) => { + public disconnect = (selectedNode: SelectedNode) => { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.connected) { this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the Core Lightning\'s Websocket Server..' }); @@ -108,7 +108,7 @@ export class CLWebSocketClient { } }; - public updateSelectedNode = (newSelectedNode: CommonSelectedNode) => { + public updateSelectedNode = (newSelectedNode: SelectedNode) => { const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index); let newClient = this.webSocketClients[clientIdx]; if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; } diff --git a/server/controllers/eclair/channels.ts b/server/controllers/eclair/channels.ts index d5b98053..2451d34c 100644 --- a/server/controllers/eclair/channels.ts +++ b/server/controllers/eclair/channels.ts @@ -1,7 +1,7 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; import { createInvoiceRequestCall, listPendingInvoicesRequestCall } from './invoices.js'; import { findRouteBetweenNodesRequestCall } from './network.js'; import { getSentInfoFromPaymentRequest, sendPaymentToRouteRequestCall } from './payments.js'; @@ -10,7 +10,7 @@ let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const simplifyAllChannels = (selNode: CommonSelectedNode, channels) => { +export const simplifyAllChannels = (selNode: SelectedNode, channels) => { let channelNodeIds = ''; const simplifiedChannels = []; channels.forEach((channel) => { @@ -30,7 +30,7 @@ export const simplifyAllChannels = (selNode: CommonSelectedNode, channels) => { }); }); channelNodeIds = channelNodeIds.substring(1); - options.url = selNode.ln_server_url + '/nodes'; + options.url = selNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: channelNodeIds }; logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds }); return request.post(options).then((nodes) => { @@ -49,7 +49,7 @@ export const getChannels = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'List Channels..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/channels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/channels'; options.form = {}; if (req.query && req.query.nodeId) { options.form = req.query; @@ -57,7 +57,7 @@ export const getChannels = (req, res, next) => { } logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options }); if (common.read_dummy_data) { - common.getDummyData('Channels', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); + common.getDummyData('Channels', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); }); } else { request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channels List Received', data: body }); @@ -82,7 +82,7 @@ export const getChannelStats = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel States..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/channelstats'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/channelstats'; const today = new Date(Date.now()); const tillToday = (Math.round(today.getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); @@ -103,7 +103,7 @@ export const openChannel = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/open'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/open'; options.form = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form }); request.post(options).then((body) => { @@ -119,7 +119,7 @@ export const updateChannelRelayFee = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Relay Fee..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/updaterelayfee'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/updaterelayfee'; options.form = req.query; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form }); request.post(options).then((body) => { @@ -136,10 +136,10 @@ export const closeChannel = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (req.query.force !== 'true') { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' }); - options.url = req.session.selectedNode.ln_server_url + '/close'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/close'; } else { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' }); - options.url = req.session.selectedNode.ln_server_url + '/forceclose'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/forceclose'; } options.form = { channelId: req.query.channelId }; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url }); diff --git a/server/controllers/eclair/fees.ts b/server/controllers/eclair/fees.ts index c6b196aa..e4c62b5e 100644 --- a/server/controllers/eclair/fees.ts +++ b/server/controllers/eclair/fees.ts @@ -1,12 +1,12 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const arrangeFees = (selNode: CommonSelectedNode, body, current_time) => { +export const arrangeFees = (selNode: SelectedNode, body, current_time) => { const fees = { daily_fee: 0, daily_txs: 0, weekly_fee: 0, weekly_txs: 0, monthly_fee: 0, monthly_txs: 0 }; const week_start_time = current_time - 604800000; const day_start_time = current_time - 86400000; @@ -42,7 +42,7 @@ export const arrangeFees = (selNode: CommonSelectedNode, body, current_time) => return fees; }; -export const arrangePayments = (selNode: CommonSelectedNode, body) => { +export const arrangePayments = (selNode: SelectedNode, body) => { const payments = { sent: body && body.sent ? body.sent : [], received: body && body.received ? body.received : [], @@ -84,7 +84,7 @@ export const getFees = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/audit'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/audit'; const today = new Date(Date.now()); const tillToday = (Math.round(today.getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); @@ -94,7 +94,7 @@ export const getFees = (req, res, next) => { }; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form }); if (common.read_dummy_data) { - common.getDummyData('Fees', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); }); + common.getDummyData('Fees', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); }); } else { request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body }); @@ -110,11 +110,11 @@ export const getPayments = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Payments..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/audit'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/audit'; const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); options.form = { from: 0, to: tillToday }; if (common.read_dummy_data) { - common.getDummyData('Payments', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); }); + common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); }); } else { request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Payments Received', data: body }); diff --git a/server/controllers/eclair/getInfo.ts b/server/controllers/eclair/getInfo.ts index 9c8bfbb3..ad7a0b3f 100644 --- a/server/controllers/eclair/getInfo.ts +++ b/server/controllers/eclair/getInfo.ts @@ -16,12 +16,12 @@ export const getInfo = (req, res, next) => { common.setOptions(req); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/getinfo'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/getinfo'; options.form = {}; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url }); if (common.read_dummy_data) { - common.getDummyData('GetInfo', req.session.selectedNode.ln_implementation).then((data: any) => { + common.getDummyData('GetInfo', req.session.selectedNode.lnImplementation).then((data: any) => { data.lnImplementation = 'Eclair'; return res.status(200).json(data); }); @@ -34,7 +34,7 @@ export const getInfo = (req, res, next) => { return request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' }); body.lnImplementation = 'Eclair'; - req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; + req.session.selectedNode.lnVersion = body.version.split('-')[0] || ''; eclWsClient.updateSelectedNode(req.session.selectedNode); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); return res.status(200).json(body); diff --git a/server/controllers/eclair/invoices.ts b/server/controllers/eclair/invoices.ts index 6738a3a0..eaa8e2b3 100644 --- a/server/controllers/eclair/invoices.ts +++ b/server/controllers/eclair/invoices.ts @@ -1,7 +1,7 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from 'server/models/config.model.js'; +import { SelectedNode } from 'server/models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; @@ -37,7 +37,7 @@ export const getInvoice = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Invoice..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/getinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/getinvoice'; options.form = { paymentHash: req.params.paymentHash }; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body }); @@ -52,10 +52,10 @@ export const getInvoice = (req, res, next) => { }); }; -export const listPendingInvoicesRequestCall = (selectedNode: CommonSelectedNode) => { +export const listPendingInvoicesRequestCall = (selectedNode: SelectedNode) => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/listpendinginvoices'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices'; options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() }; return new Promise((resolve, reject) => { request.post(options).then((pendingInvoicesResponse) => { @@ -74,16 +74,16 @@ export const listInvoices = (req, res, next) => { const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); options.form = { from: 0, to: tillToday }; const options1 = JSON.parse(JSON.stringify(options)); - options1.url = req.session.selectedNode.ln_server_url + '/listinvoices'; + options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices'; options1.form = { from: 0, to: tillToday }; const options2 = JSON.parse(JSON.stringify(options)); - options2.url = req.session.selectedNode.ln_server_url + '/listpendinginvoices'; + options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices'; options2.form = { from: 0, to: tillToday }; if (common.read_dummy_data) { - return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => { + return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then((body) => { const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; - return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). + return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))). then((values) => res.status(200).json(invoices)); }); } else { @@ -93,7 +93,7 @@ export const listInvoices = (req, res, next) => { const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; if (invoices && invoices.length > 0) { - return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). + return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))). then((values) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices }); return res.status(200).json(invoices); @@ -114,10 +114,10 @@ export const listInvoices = (req, res, next) => { } }; -export const createInvoiceRequestCall = (selectedNode: CommonSelectedNode, description: string, amount: number) => { +export const createInvoiceRequestCall = (selectedNode: SelectedNode, description: string, amount: number) => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/createinvoice'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/createinvoice'; options.form = { description: description, amountMsat: amount }; return new Promise((resolve, reject) => { request.post(options).then((invResponse) => { diff --git a/server/controllers/eclair/network.ts b/server/controllers/eclair/network.ts index 7dfe7bdb..934ec5f7 100644 --- a/server/controllers/eclair/network.ts +++ b/server/controllers/eclair/network.ts @@ -1,7 +1,7 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from 'server/models/config.model.js'; +import { SelectedNode } from 'server/models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; @@ -10,7 +10,7 @@ export const getNodes = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/nodes'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: req.params.id }; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body }); @@ -21,10 +21,10 @@ export const getNodes = (req, res, next) => { }); }; -export const findRouteBetweenNodesRequestCall = (selectedNode: CommonSelectedNode, amountMsat: number, sourceNodeId: string, targetNodeId: string, ignoreNodeIds: string[] = [], format: string = 'shortChannelId') => { +export const findRouteBetweenNodesRequestCall = (selectedNode: SelectedNode, amountMsat: number, sourceNodeId: string, targetNodeId: string, ignoreNodeIds: string[] = [], format: string = 'shortChannelId') => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/findroutebetweennodes'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/findroutebetweennodes'; options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format }; return new Promise((resolve, reject) => { request.post(options).then((body) => { diff --git a/server/controllers/eclair/onchain.ts b/server/controllers/eclair/onchain.ts index 34f3666b..4da0b24a 100644 --- a/server/controllers/eclair/onchain.ts +++ b/server/controllers/eclair/onchain.ts @@ -17,7 +17,7 @@ export const getNewAddress = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/getnewaddress'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/getnewaddress'; options.form = {}; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); @@ -32,10 +32,10 @@ export const getBalance = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Getting On Chain Balance..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/onchainbalance'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/onchainbalance'; options.form = {}; if (common.read_dummy_data) { - common.getDummyData('OnChainBalance', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeBalances(data)); }); + common.getDummyData('OnChainBalance', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeBalances(data)); }); } else { request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'On Chain Balance Received', data: body }); @@ -52,7 +52,7 @@ export const getTransactions = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Getting On Chain Transactions..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/onchaintransactions'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/onchaintransactions'; options.form = { count: req.query.count, skip: req.query.skip @@ -72,7 +72,7 @@ export const sendFunds = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Sending On Chain Funds..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/sendonchain'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/sendonchain'; options.form = { address: address, amountSatoshis: amount, confirmationTarget: blocks }; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form }); request.post(options).then((body) => { diff --git a/server/controllers/eclair/payments.ts b/server/controllers/eclair/payments.ts index 2a588a0f..80339325 100644 --- a/server/controllers/eclair/payments.ts +++ b/server/controllers/eclair/payments.ts @@ -1,13 +1,13 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const getSentInfoFromPaymentRequest = (selNode: CommonSelectedNode, payment) => { - options.url = selNode.ln_server_url + '/getsentinfo'; +export const getSentInfoFromPaymentRequest = (selNode: SelectedNode, payment) => { + options.url = selNode.settings.lnServerUrl + '/getsentinfo'; options.form = { paymentHash: payment }; return request.post(options).then((body) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body }); @@ -19,8 +19,8 @@ export const getSentInfoFromPaymentRequest = (selNode: CommonSelectedNode, payme }).catch((err) => err); }; -export const getQueryNodes = (selNode: CommonSelectedNode, nodeIds) => { - options.url = selNode.ln_server_url + '/nodes'; +export const getQueryNodes = (selNode: SelectedNode, nodeIds) => { + options.url = selNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: nodeIds?.reduce((acc, curr) => acc + ',' + curr) }; return request.post(options).then((nodes) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes }); @@ -32,7 +32,7 @@ export const decodePayment = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/parseinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/parseinvoice'; options.form = { invoice: req.params.invoice }; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); @@ -48,7 +48,7 @@ export const postPayment = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Paying Invoice..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/payinvoice'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/payinvoice'; options.form = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form }); request.post(options).then((body) => { @@ -64,7 +64,7 @@ export const queryPaymentRoute = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Querying Payment Route..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/findroutetonode'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/findroutetonode'; options.form = { nodeId: req.query.nodeId, amountMsat: req.query.amountMsat @@ -119,10 +119,10 @@ export const getSentPaymentsInformation = (req, res, next) => { } }; -export const sendPaymentToRouteRequestCall = (selectedNode: CommonSelectedNode, shortChannelIds: string, invoice: string, amountMsat: number) => { +export const sendPaymentToRouteRequestCall = (selectedNode: SelectedNode, shortChannelIds: string, invoice: string, amountMsat: number) => { logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); - options = selectedNode.options; - options.url = selectedNode.ln_server_url + '/sendtoroute'; + options = selectedNode.authentication.options; + options.url = selectedNode.settings.lnServerUrl + '/sendtoroute'; options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice }; return new Promise((resolve, reject) => { logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form }); diff --git a/server/controllers/eclair/peers.ts b/server/controllers/eclair/peers.ts index 78dcfc0b..2690774d 100644 --- a/server/controllers/eclair/peers.ts +++ b/server/controllers/eclair/peers.ts @@ -1,13 +1,13 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const getFilteredNodes = (selNode: CommonSelectedNode, peersNodeIds) => { - options.url = selNode.ln_server_url + '/nodes'; +export const getFilteredNodes = (selNode: SelectedNode, peersNodeIds) => { + options.url = selNode.settings.lnServerUrl + '/nodes'; options.form = { nodeIds: peersNodeIds }; return request.post(options).then((nodes) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes }); @@ -19,10 +19,10 @@ export const getPeers = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Getting Peers..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/peers'; options.form = {}; if (common.read_dummy_data) { - common.getDummyData('Peers', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); + common.getDummyData('Peers', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); }); } else { request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); @@ -56,7 +56,7 @@ export const connectPeer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Conneting Peer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/connect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/connect'; options.form = {}; if (req.query) { options.form = req.query; @@ -71,7 +71,7 @@ export const connectPeer = (req, res, next) => { const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); } - options.url = req.session.selectedNode.ln_server_url + '/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/peers'; options.form = {}; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body }); @@ -107,7 +107,7 @@ export const deletePeer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconneting Peer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/disconnect'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/disconnect'; options.form = {}; if (req.params.nodeId) { options.form = { nodeId: req.params.nodeId }; diff --git a/server/controllers/eclair/webSocketClient.ts b/server/controllers/eclair/webSocketClient.ts index e24bdbf0..218d284d 100644 --- a/server/controllers/eclair/webSocketClient.ts +++ b/server/controllers/eclair/webSocketClient.ts @@ -3,7 +3,7 @@ import WebSocket from 'ws'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; import { WSServer } from '../../utils/webSocketServer.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; import { ECLWSEventsEnum } from '../../models/ecl.model.js'; export class ECLWebSocketClient { @@ -11,7 +11,7 @@ export class ECLWebSocketClient { public logger: LoggerService = Logger; public common: CommonService = Common; public wsServer = WSServer; - public webSocketClients: Array<{ selectedNode: CommonSelectedNode, reConnect: boolean, webSocketClient: any }> = []; + public webSocketClients: Array<{ selectedNode: SelectedNode, reConnect: boolean, webSocketClient: any }> = []; public reconnectTimeOut = null; public waitTime = 0.5; @@ -36,17 +36,17 @@ export class ECLWebSocketClient { }, this.waitTime * 1000); }; - public connect = (selectedNode: CommonSelectedNode) => { + public connect = (selectedNode: SelectedNode) => { try { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); if (!clientExists) { - if (selectedNode.ln_server_url) { + if (selectedNode.settings.lnServerUrl) { const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; this.connectWithClient(newWebSocketClient); this.webSocketClients.push(newWebSocketClient); } } else { - if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.ln_server_url) { + if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.settings.lnServerUrl) { clientExists.reConnect = true; this.connectWithClient(clientExists); } @@ -58,9 +58,9 @@ export class ECLWebSocketClient { public connectWithClient = (eclWsClt) => { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' }); - const UpdatedLNServerURL = (eclWsClt.selectedNode.ln_server_url)?.replace(/^http/, 'ws'); + const UpdatedLNServerURL = (eclWsClt.selectedNode.settings.lnServerUrl)?.replace(/^http/, 'ws'); const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2); - const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.ln_api_password + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws'; + const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.authentication.lnApiPassword + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws'; eclWsClt.webSocketClient = new WebSocket(WS_LINK); eclWsClt.webSocketClient.onopen = () => { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' }); @@ -69,7 +69,7 @@ export class ECLWebSocketClient { }; eclWsClt.webSocketClient.onclose = (e) => { - if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.ln_implementation === 'ECL') { + if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.lnImplementation === 'ECL') { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' }); eclWsClt.webSocketClient.close(); if (eclWsClt.reConnect) { this.reconnet(eclWsClt); } @@ -87,7 +87,7 @@ export class ECLWebSocketClient { }; eclWsClt.webSocketClient.onerror = (err) => { - if (eclWsClt.selectedNode.ln_version === '' || !eclWsClt.selectedNode.ln_version || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) { + if (eclWsClt.selectedNode.lnVersion === '' || !eclWsClt.selectedNode.lnVersion || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) { this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err }); const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }')); this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode); @@ -99,7 +99,7 @@ export class ECLWebSocketClient { }; }; - public disconnect = (selectedNode: CommonSelectedNode) => { + public disconnect = (selectedNode: SelectedNode) => { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.readyState === WebSocket.OPEN) { this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Disconnecting from the Eclair\'s Websocket Server..' }); @@ -110,7 +110,7 @@ export class ECLWebSocketClient { } }; - public updateSelectedNode = (newSelectedNode: CommonSelectedNode) => { + public updateSelectedNode = (newSelectedNode: SelectedNode) => { const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index); let newClient = this.webSocketClients[clientIdx]; if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; } diff --git a/server/controllers/lnd/balance.ts b/server/controllers/lnd/balance.ts index 369fa4ad..fde5efa8 100644 --- a/server/controllers/lnd/balance.ts +++ b/server/controllers/lnd/balance.ts @@ -9,7 +9,7 @@ export const getBlockchainBalance = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Balance', msg: 'Getting Balance..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/balance/blockchain'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/balance/blockchain'; options.qs = req.query; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query }); diff --git a/server/controllers/lnd/channels.ts b/server/controllers/lnd/channels.ts index 3defaa49..76e196c4 100644 --- a/server/controllers/lnd/channels.ts +++ b/server/controllers/lnd/channels.ts @@ -1,14 +1,14 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const getAliasForChannel = (selNode: CommonSelectedNode, channel) => { +export const getAliasForChannel = (selNode: SelectedNode, channel) => { const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : ''; - options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; + options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey; return request(options).then((aliasBody) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias }); channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20); @@ -23,7 +23,7 @@ export const getAllChannels = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channels..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels'; options.qs = req.query; let local = 0; let remote = 0; @@ -61,7 +61,7 @@ export const getPendingChannels = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Pending Channels..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/pending'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/pending'; options.qs = req.query; request(options).then((body) => { if (!body.total_limbo_balance) { @@ -98,7 +98,7 @@ export const getClosedChannels = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Closed Channels..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/closed'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/closed'; options.qs = req.query; request(options).then((body) => { if (body.channels && body.channels.length > 0) { @@ -129,7 +129,7 @@ export const postChannel = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels'; options.form = { node_pubkey_string: node_pubkey, local_funding_amount: local_funding_amount, @@ -160,7 +160,7 @@ export const postTransactions = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Sending Payment..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/transaction-stream'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/transaction-stream'; options.form = { payment_request: paymentReq }; if (paymentAmount) { options.form.amt = paymentAmount; @@ -196,7 +196,7 @@ export const closeChannel = (req, res, next) => { options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } const channelpoint = req.params.channelPoint?.replace(':', '/'); - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/' + channelpoint + '?force=' + req.query.force; if (req.query.target_conf) { options.url = options.url + '&target_conf=' + req.query.target_conf; } if (req.query.sat_per_byte) { options.url = options.url + '&sat_per_byte=' + req.query.sat_per_byte; } logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel Options URL', data: options.url }); @@ -214,7 +214,7 @@ export const postChanPolicy = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Policy..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/chanpolicy'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/chanpolicy'; if (chanPoint === 'all') { options.form = JSON.stringify({ global: true, diff --git a/server/controllers/lnd/channelsBackup.ts b/server/controllers/lnd/channelsBackup.ts index 8cacb0c9..82eb0e95 100644 --- a/server/controllers/lnd/channelsBackup.ts +++ b/server/controllers/lnd/channelsBackup.ts @@ -39,14 +39,14 @@ export const getBackup = (req, res, next) => { let channel_backup_file = ''; let message = ''; if (req.params.channelPoint === 'ALL') { - channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; + channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak'; message = 'All Channels Backup Successful.'; - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup'; } else { - channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; + channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; message = 'Channel Backup Successful.'; const channelpoint = req.params.channelPoint?.replace(':', '/'); - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/' + channelpoint; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/' + channelpoint; const exists = fs.existsSync(channel_backup_file); if (exists) { fs.writeFile(channel_backup_file, '', () => { }); @@ -81,13 +81,13 @@ export const postBackupVerify = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Verifying Channel Backup..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/verify'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/verify'; let channel_verify_file = ''; let message = ''; let verify_backup = ''; if (req.params.channelPoint === 'ALL') { message = 'All Channels Verify Successful.'; - channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; + channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak'; const exists = fs.existsSync(channel_verify_file); if (exists) { verify_backup = fs.readFileSync(channel_verify_file, 'utf-8'); @@ -108,7 +108,7 @@ export const postBackupVerify = (req, res, next) => { } } else { message = 'Channel Verify Successful.'; - channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; + channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; const exists = fs.existsSync(channel_verify_file); if (exists) { verify_backup = fs.readFileSync(channel_verify_file, 'utf-8'); @@ -136,13 +136,13 @@ export const postRestore = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Restoring Channel Backup..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/restore'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/restore'; let channel_restore_file = ''; let message = ''; let restore_backup = ''; if (req.params.channelPoint === 'ALL') { message = 'All Channels Restore Successful.'; - channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep; + channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep; const exists = fs.existsSync(channel_restore_file + 'channel-all.bak'); const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak'); if (exists) { @@ -173,7 +173,7 @@ export const postRestore = (req, res, next) => { } } else { message = 'Channel Restore Successful.'; - channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; + channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak'; const exists = fs.existsSync(channel_restore_file); if (exists) { restore_backup = fs.readFileSync(channel_restore_file, 'utf-8'); @@ -190,7 +190,7 @@ export const postRestore = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'ChannelBackup', msg: 'Channel Restored', data: body }); if (req.params.channelPoint === 'ALL') { channel_restore_file = channel_restore_file + 'channel-all.bak'; } fs.rename(channel_restore_file, channel_restore_file + '.restored', () => { - getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { + getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => { if (getFilesListRes.error) { const errMsg = getFilesListRes.error; const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode); @@ -210,7 +210,7 @@ export const postRestore = (req, res, next) => { }; export const getRestoreList = (req, res, next) => { - getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { + getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => { if (getFilesListRes.error) { return res.status(getFilesListRes.statusCode).json(getFilesListRes); } else { diff --git a/server/controllers/lnd/fees.ts b/server/controllers/lnd/fees.ts index 7459ca12..428b1a41 100644 --- a/server/controllers/lnd/fees.ts +++ b/server/controllers/lnd/fees.ts @@ -10,7 +10,7 @@ export const getFees = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/fees'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fees'; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body }); const today = new Date(Date.now()); diff --git a/server/controllers/lnd/getInfo.ts b/server/controllers/lnd/getInfo.ts index 57010fa3..ad686995 100644 --- a/server/controllers/lnd/getInfo.ts +++ b/server/controllers/lnd/getInfo.ts @@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => { common.setOptions(req); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo'; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url }); if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) { const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!'; @@ -25,7 +25,7 @@ export const getInfo = (req, res, next) => { return res.status(err.statusCode).json({ message: err.message, error: err.error }); } else { common.nodes?.map((node: any) => { - if (node.ln_implementation === 'LND') { + if (node.lnImplementation === 'LND') { common.getAllNodeAllChannelBackup(node); } return node; @@ -38,7 +38,7 @@ export const getInfo = (req, res, next) => { const err = common.handleError(body, 'GetInfo', 'Get Info Error', req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); } else { - req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; + req.session.selectedNode.lnVersion = body.version.split('-')[0] || ''; lndWsClient.updateSelectedNode(req.session.selectedNode); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); return res.status(200).json(body); diff --git a/server/controllers/lnd/graph.ts b/server/controllers/lnd/graph.ts index cb98cbd3..6f5ff67b 100644 --- a/server/controllers/lnd/graph.ts +++ b/server/controllers/lnd/graph.ts @@ -1,13 +1,13 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const getAliasFromPubkey = (selNode: CommonSelectedNode, pubkey) => { - options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; +export const getAliasFromPubkey = (selNode: SelectedNode, pubkey) => { + options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey; return request(options).then((res) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias }); return res.node.alias; @@ -19,7 +19,7 @@ export const getDescribeGraph = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Network Graph..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph'; request.get(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body }); res.status(200).json(body); @@ -33,7 +33,7 @@ export const getGraphInfo = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Information..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/info'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/info'; request.get(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body }); res.status(200).json(body); @@ -47,7 +47,7 @@ export const getGraphNode = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Node Information..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/node/' + req.params.pubKey; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/node/' + req.params.pubKey; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body }); res.status(200).json(body); @@ -61,7 +61,7 @@ export const getGraphEdge = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Edge Information..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body }); res.status(200).json(body); @@ -75,7 +75,7 @@ export const getQueryRoutes = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Routes..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount; if (req.query.outgoing_chan_id) { options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id; } @@ -111,7 +111,7 @@ export const getRemoteFeePolicy = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Remote Fee Policy..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body }); let remoteNodeFee = {}; diff --git a/server/controllers/lnd/invoices.ts b/server/controllers/lnd/invoices.ts index 9db033ec..2897689f 100644 --- a/server/controllers/lnd/invoices.ts +++ b/server/controllers/lnd/invoices.ts @@ -12,7 +12,7 @@ export const invoiceLookup = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Getting Invoice Information..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/invoices/lookup'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/invoices/lookup'; if (req.query.payment_addr) { options.url = options.url + '?payment_addr=' + req.query.payment_addr; } else { @@ -34,7 +34,7 @@ export const listInvoices = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Getting List Invoices..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset + + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body }); @@ -57,7 +57,7 @@ export const addInvoice = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Adding Invoice..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/invoices'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices'; options.form = JSON.stringify(req.body); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body }); diff --git a/server/controllers/lnd/message.ts b/server/controllers/lnd/message.ts index 4ac609da..864dddd4 100644 --- a/server/controllers/lnd/message.ts +++ b/server/controllers/lnd/message.ts @@ -10,7 +10,7 @@ export const signMessage = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage'; options.form = JSON.stringify({ msg: Buffer.from(message).toString('base64') }); @@ -28,7 +28,7 @@ export const verifyMessage = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/verifymessage'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/verifymessage'; options.form = JSON.stringify({ msg: Buffer.from(message).toString('base64'), signature: signature diff --git a/server/controllers/lnd/newAddress.ts b/server/controllers/lnd/newAddress.ts index af53f9e2..cbeb6fc8 100644 --- a/server/controllers/lnd/newAddress.ts +++ b/server/controllers/lnd/newAddress.ts @@ -9,7 +9,7 @@ export const getNewAddress = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'Getting New Address..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/newaddress?type=' + req.query.type; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddress?type=' + req.query.type; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body }); res.status(200).json(body); diff --git a/server/controllers/lnd/payments.ts b/server/controllers/lnd/payments.ts index 83322075..dd927271 100644 --- a/server/controllers/lnd/payments.ts +++ b/server/controllers/lnd/payments.ts @@ -1,14 +1,14 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const decodePaymentFromPaymentRequest = (selNode: CommonSelectedNode, payment) => { - options.url = selNode.ln_server_url + '/v1/payreq/' + payment; +export const decodePaymentFromPaymentRequest = (selNode: SelectedNode, payment) => { + options.url = selNode.settings.lnServerUrl + '/v1/payreq/' + payment; return request(options).then((res) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description }); return res; @@ -19,7 +19,7 @@ export const decodePayment = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Decoding Payment..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/payreq/' + req.params.payRequest; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payreq/' + req.params.payRequest; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body }); res.status(200).json(body); @@ -55,7 +55,7 @@ export const getPayments = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting Payments List..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body }); res.status(200).json(body); @@ -69,8 +69,8 @@ export const getAllLightningTransactions = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' }); const options1 = JSON.parse(JSON.stringify(common.getOptions(req))); const options2 = JSON.parse(JSON.stringify(common.getOptions(req))); - // options1.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=100000&index_offset=0&reversed=true'; - options2.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true'; + // options1.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=100000&index_offset=0&reversed=true'; + options2.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true'; logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 }); // return Promise.all([request(options1), request(options2)]).then((values) => { @@ -87,7 +87,7 @@ export const paymentLookup = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Looking up Payment..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/router/track/' + req.params.paymentHash; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/router/track/' + req.params.paymentHash; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body }); res.status(200).json(body.result || body); diff --git a/server/controllers/lnd/peers.ts b/server/controllers/lnd/peers.ts index 5ef14d6b..0723ea03 100644 --- a/server/controllers/lnd/peers.ts +++ b/server/controllers/lnd/peers.ts @@ -1,13 +1,13 @@ import request from 'request-promise'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; let options = null; const logger: LoggerService = Logger; const common: CommonService = Common; -export const getAliasForPeers = (selNode: CommonSelectedNode, peer) => { - options.url = selNode.ln_server_url + '/v1/graph/node/' + peer.pub_key; +export const getAliasForPeers = (selNode: SelectedNode, peer) => { + options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + peer.pub_key; return request(options).then((aliasBody) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias }); peer.alias = aliasBody.node.alias; @@ -22,7 +22,7 @@ export const getPeers = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Getting Peers..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers'; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); const peers = !body.peers ? [] : body.peers; @@ -41,14 +41,14 @@ export const postPeer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers'; options.form = JSON.stringify({ addr: { host: host, pubkey: pubkey }, perm: perm }); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body }); - options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers'; request(options).then((body) => { const peers = (!body.peers) ? [] : body.peers; return Promise.all(peers?.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => { @@ -75,7 +75,7 @@ export const deletePeer = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/peers/' + req.params.peerPubKey; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers/' + req.params.peerPubKey; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey }); request.delete(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body }); diff --git a/server/controllers/lnd/switch.ts b/server/controllers/lnd/switch.ts index b12f78e9..be755263 100644 --- a/server/controllers/lnd/switch.ts +++ b/server/controllers/lnd/switch.ts @@ -25,7 +25,7 @@ export const getAllForwardingEvents = (req, start, end, offset, caller, callback const err = common.handleError({ message: 'Session Expired after a day\'s inactivity.', statusCode: 401 }, 'Balance', 'Get Balance Error', req.session.selectedNode); return callback({ message: err.message, error: err.error, statusCode: err.statusCode }); } options = common.getOptions(req); - options.url = req.session.selectedNode.ln_server_url + '/v1/switch'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/switch'; options.form = {}; if (start) { options.form.start_time = start; } if (end) { options.form.end_time = end; } diff --git a/server/controllers/lnd/transactions.ts b/server/controllers/lnd/transactions.ts index 0310238a..d92ea3ea 100644 --- a/server/controllers/lnd/transactions.ts +++ b/server/controllers/lnd/transactions.ts @@ -9,7 +9,7 @@ export const getTransactions = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Getting Transactions..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions'; request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body }); res.status(200).json(body.transactions); @@ -24,7 +24,7 @@ export const postTransactions = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Sending Transaction..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions'; options.form = { amount: amount, addr: address, diff --git a/server/controllers/lnd/wallet.ts b/server/controllers/lnd/wallet.ts index ee177c85..924fa297 100644 --- a/server/controllers/lnd/wallet.ts +++ b/server/controllers/lnd/wallet.ts @@ -11,9 +11,9 @@ export const genSeed = (req, res, next) => { options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (req.params.passphrase) { - options.url = req.session.selectedNode.ln_server_url + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64'); + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64'); } else { - options.url = req.session.selectedNode.ln_server_url + '/v1/genseed'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed'; } request(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body }); @@ -32,14 +32,14 @@ export const operateWallet = (req, res, next) => { options.method = 'POST'; if (!req.params.operation || req.params.operation === 'unlockwallet') { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' }); - options.url = req.session.selectedNode.ln_server_url + '/v1/unlockwallet'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/unlockwallet'; options.form = JSON.stringify({ wallet_password: Buffer.from(atob(wallet_password)).toString('base64') }); err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!'; } else { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' }); - options.url = req.session.selectedNode.ln_server_url + '/v1/initwallet'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/initwallet'; if (aezeed_passphrase && aezeed_passphrase !== '') { options.form = JSON.stringify({ wallet_password: Buffer.from(atob(wallet_password)).toString('base64'), @@ -94,8 +94,8 @@ export const getUTXOs = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Getting UTXOs..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos'; - if (common.isVersionCompatible(req.session.selectedNode.ln_version, '0.14.0')) { + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos'; + if (common.isVersionCompatible(req.session.selectedNode.lnVersion, '0.14.0')) { options.form = JSON.stringify({ max_confs: req.query.max_confs }); } else { options.url = options.url + '?max_confs=' + req.query.max_confs; @@ -114,7 +114,7 @@ export const bumpFee = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Bumping Fee..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/bumpfee'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/bumpfee'; options.form = {}; options.form.outpoint = { txid_str: txid, @@ -139,7 +139,7 @@ export const labelTransaction = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Labelling Transaction..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/tx/label'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/tx/label'; options.form = JSON.parse(JSON.stringify(options.form)); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form }); request.post(options).then((body) => { @@ -156,7 +156,7 @@ export const leaseUTXO = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Leasing UTXO..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/lease'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/lease'; options.form = {}; options.form.id = txid; options.form.outpoint = { @@ -179,7 +179,7 @@ export const releaseUTXO = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Releasing UTXO..' }); options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } - options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/release'; + options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/release'; options.form = {}; options.form.id = txid; options.form.outpoint = { diff --git a/server/controllers/lnd/webSocketClient.ts b/server/controllers/lnd/webSocketClient.ts index 359e06f3..09605704 100644 --- a/server/controllers/lnd/webSocketClient.ts +++ b/server/controllers/lnd/webSocketClient.ts @@ -5,14 +5,14 @@ import { join } from 'path'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; import { WSServer } from '../../utils/webSocketServer.js'; -import { CommonSelectedNode } from '../../models/config.model.js'; +import { SelectedNode } from '../../models/config.model.js'; export class LNDWebSocketClient { public logger: LoggerService = Logger; public common: CommonService = Common; public wsServer = WSServer; - public webSocketClients: Array<{ selectedNode: CommonSelectedNode }> = []; + public webSocketClients: Array<{ selectedNode: SelectedNode }> = []; constructor() { this.wsServer.eventEmitterLND.on('CONNECT', (nodeIndex) => { @@ -23,10 +23,10 @@ export class LNDWebSocketClient { }); } - public connect = (selectedNode: CommonSelectedNode) => { + public connect = (selectedNode: SelectedNode) => { try { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); - if (!clientExists && selectedNode.ln_server_url) { + if (!clientExists && selectedNode.settings.lnServerUrl) { const newWebSocketClient = { selectedNode: selectedNode }; this.webSocketClients.push(newWebSocketClient); } @@ -35,10 +35,10 @@ export class LNDWebSocketClient { } }; - public fetchUnpaidInvoices = (selectedNode: CommonSelectedNode) => { + public fetchUnpaidInvoices = (selectedNode: SelectedNode) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' }); const options = this.setOptionsForSelNode(selectedNode); - options.url = selectedNode.ln_server_url + '/v1/invoices?pending_only=true'; + options.url = selectedNode.settings.lnServerUrl + '/v1/invoices?pending_only=true'; return request(options).then((body) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body }); if (body.invoices && body.invoices.length > 0) { @@ -55,10 +55,10 @@ export class LNDWebSocketClient { }); }; - public subscribeToInvoice = (options: any, selectedNode: CommonSelectedNode, rHash: string) => { + public subscribeToInvoice = (options: any, selectedNode: SelectedNode, rHash: string) => { rHash = rHash?.replace(/\+/g, '-')?.replace(/[/]/g, '_'); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' }); - options.url = selectedNode.ln_server_url + '/v2/invoices/subscribe/' + rHash; + options.url = selectedNode.settings.lnServerUrl + '/v2/invoices/subscribe/' + rHash; request(options).then((msg) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash }); if (typeof msg === 'string') { @@ -80,9 +80,9 @@ export class LNDWebSocketClient { }); }; - public subscribeToPayment = (options: any, selectedNode: CommonSelectedNode, paymentHash: string) => { + public subscribeToPayment = (options: any, selectedNode: SelectedNode, paymentHash: string) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' }); - options.url = selectedNode.ln_server_url + '/v2/router/track/' + paymentHash; + options.url = selectedNode.settings.lnServerUrl + '/v2/router/track/' + paymentHash; request(options).then((msg) => { this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash }); msg['type'] = 'payment'; @@ -97,17 +97,17 @@ export class LNDWebSocketClient { }); }; - public setOptionsForSelNode = (selectedNode: CommonSelectedNode) => { + public setOptionsForSelNode = (selectedNode: SelectedNode) => { const options = { url: '', rejectUnauthorized: false, json: true, form: null }; try { - options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; + options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') }; } catch (err) { this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) }); } return options; }; - public disconnect = (selectedNode: CommonSelectedNode) => { + public disconnect = (selectedNode: SelectedNode) => { const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); if (clientExists) { this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the LND\'s Websocket Server..' }); @@ -116,13 +116,13 @@ export class LNDWebSocketClient { } }; - public updateSelectedNode = (newSelectedNode: CommonSelectedNode) => { + public updateSelectedNode = (newSelectedNode: SelectedNode) => { const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index); let newClient = this.webSocketClients[clientIdx]; if (!newClient) { newClient = { selectedNode: null }; } newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode)); this.webSocketClients[clientIdx] = newClient; - if (this.webSocketClients[clientIdx].selectedNode.ln_version === '' || !this.webSocketClients[clientIdx].selectedNode.ln_version || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.ln_version, '0.11.0')) { + if (this.webSocketClients[clientIdx].selectedNode.lnVersion === '' || !this.webSocketClients[clientIdx].selectedNode.lnVersion || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.lnVersion, '0.11.0')) { this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode); } }; diff --git a/server/controllers/shared/RTLConf.ts b/server/controllers/shared/RTLConf.ts index acae9dc3..60ce3e81 100644 --- a/server/controllers/shared/RTLConf.ts +++ b/server/controllers/shared/RTLConf.ts @@ -7,7 +7,7 @@ import { Database, DatabaseService } from '../../utils/database.js'; import { Logger, LoggerService } from '../../utils/logger.js'; import { Common, CommonService } from '../../utils/common.js'; import { WSServer } from '../../utils/webSocketServer.js'; -import { AuthenticationConfiguration, NodeSettingsConfiguration } from '../../models/config.model.js'; +import { NodeAuthentication, NodeSettings } from '../../models/config.model.js'; const options = { url: '' }; const logger: LoggerService = Logger; @@ -15,203 +15,103 @@ const common: CommonService = Common; const wsServer = WSServer; const databaseService: DatabaseService = Database; -export const updateSelectedNode = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' }); - const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.initSelectedNode ? +common.initSelectedNode.index : 1; - req.session.selectedNode = common.findNode(selNodeIndex); - if (req.headers && req.headers.authorization && req.headers.authorization !== '') { - wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex); - if (req.params.prevNodeIndex !== '-1') { - databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id); - } - if (req.params.currNodeIndex !== '-1') { - databaseService.loadDatabase(req.session); +export const maskPasswords = (obj) => { + const keys = Object.keys(obj); + const length = keys.length; + if (length !== 0) { + for (let i = 0; i < length; i++) { + if (typeof obj[keys[i]] === 'object') { + keys[keys[i]] = maskPasswords(obj[keys[i]]); + } + if (typeof keys[i] === 'string' && + (keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') || + keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') || + keys[i].toLowerCase().includes('rpcuser')) + ) { + obj[keys[i]] = '*'.repeat(20); + } } } - const responseVal = !req.session.selectedNode.ln_node ? '' : req.session.selectedNode.ln_node; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal }); - res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' }); + return obj; }; -export const getRTLConfigInitial = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Initial RTL Configuration..' }); - const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - fs.readFile(confFile, 'utf8', (errRes, data) => { +export const getCurrencyRates = (req, res, next) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' }); + options.url = 'https://blockchain.info/ticker'; + request(options).then((body) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body }); + res.status(200).json(JSON.parse(body)); + }).catch((errRes) => { + const errMsg = 'Get Rates Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); + }); +}; + +export const getFile = (req, res, next) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); + const file = req.query.path ? req.query.path : (req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak'); + logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); + logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); + fs.readFile(file, 'utf8', (errRes, data) => { if (errRes) { - if (errRes.code === 'ENOENT') { - logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); - res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] }); - } else { - const errMsg = 'Get Node Config Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); - } + if (errRes.code && errRes.code === 'ENOENT') { errRes.code = 'File Not Found!'; } + const errMsg = 'Reading File Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); } else { - const nodeConfData = JSON.parse(data); - const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link }; - const enable2FA = !!common.rtl_secret2fa; - const allowPasswordUpdate = common.flg_allow_password_update; - const nodesArr = []; - if (common.nodes && common.nodes.length > 0) { - common.nodes.forEach((node, i) => { - const settings: NodeSettingsConfiguration = { unannouncedChannels: false }; - settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT'; - settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY'; - settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE'; - settings.unannouncedChannels = !!node.unannounced_channels || false; - settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false; - settings.currencyUnit = node.currency_unit; - nodesArr.push({ - index: node.index, - lnNode: node.ln_node, - lnImplementation: node.ln_implementation, - settings: settings, - authentication: {} - }); - }); - } - const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr }; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Initial RTL Configuration Received', data: body }); - res.status(200).json(body); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data }); + res.status(200).json(data); } }); }; export const getRTLConfig = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' }); - const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; fs.readFile(confFile, 'utf8', (errRes, data) => { if (errRes) { - if (errRes.code === 'ENOENT') { - logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); - res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] }); - } else { - const errMsg = 'Get Node Config Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); - } + const errMsg = 'Get Node Config Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); } else { const nodeConfData = JSON.parse(data); - const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link }; - const enable2FA = !!common.rtl_secret2fa; - const allowPasswordUpdate = common.flg_allow_password_update; const nodesArr = []; if (common.nodes && common.nodes.length > 0) { common.nodes.forEach((node, i) => { - const authentication: AuthenticationConfiguration = {}; - authentication.configPath = (node.config_path) ? node.config_path : ''; - authentication.swapMacaroonPath = (node.swap_macaroon_path) ? node.swap_macaroon_path : ''; - authentication.boltzMacaroonPath = (node.boltz_macaroon_path) ? node.boltz_macaroon_path : ''; - const settings: NodeSettingsConfiguration = { unannouncedChannels: false }; - settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT'; - settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY'; - settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE'; - settings.unannouncedChannels = !!node.unannounced_channels || false; - settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false; - settings.bitcoindConfigPath = node.bitcoind_config_path; - settings.logLevel = node.log_level ? node.log_level : 'ERROR'; - settings.lnServerUrl = node.ln_server_url; - settings.swapServerUrl = node.swap_server_url; - settings.boltzServerUrl = node.boltz_server_url; - settings.enableOffers = node.enable_offers; - settings.enablePeerswap = node.enable_peerswap; - settings.channelBackupPath = node.channel_backup_path; - settings.currencyUnit = node.currency_unit; nodesArr.push({ index: node.index, - lnNode: node.ln_node, - lnImplementation: node.ln_implementation, - settings: settings, - authentication: authentication + lnNode: node.lnNode, + lnImplementation: node.lnImplementation, + settings: node.settings, + authentication: req.params.init ? {} : node.authentication }); }); } - const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr }; + const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index), + sso: common.appConfig.sso, enable2FA: !!common.appConfig.rtlSecret2fa, allowPasswordUpdate: common.appConfig.allowPasswordUpdate, nodes: nodesArr }; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: body }); res.status(200).json(body); } }); }; -export const updateUISettings = (req, res, next) => { - const { updatedSettings } = req.body; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); - const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index)); - if (node && node.Settings) { - node.Settings.userPersona = updatedSettings.userPersona; - node.Settings.themeMode = updatedSettings.themeMode; - node.Settings.themeColor = updatedSettings.themeColor; - node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels; - node.Settings.fiatConversion = updatedSettings.fiatConversion; - if (updatedSettings.fiatConversion) { - node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; - } else { - delete node.Settings.currencyUnit; +export const updateSelectedNode = (req, res, next) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' }); + const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.selectedNode ? +common.selectedNode.index : 1; + req.session.selectedNode = common.findNode(selNodeIndex); + if (req.headers && req.headers.authorization && req.headers.authorization !== '') { + wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex); + if (req.params.prevNodeIndex !== '-1') { + databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id); } - const selectedNode = common.findNode(req.session.selectedNode.index); - selectedNode.user_persona = updatedSettings.userPersona; - selectedNode.theme_mode = updatedSettings.themeMode; - selectedNode.theme_color = updatedSettings.themeColor; - selectedNode.unannounced_channels = updatedSettings.unannouncedChannels; - selectedNode.fiat_conversion = updatedSettings.fiatConversion; - if (updatedSettings.fiatConversion) { - selectedNode.currency_unit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; - } else { - delete selectedNode.currency_unit; + if (req.params.currNodeIndex !== '-1') { + databaseService.loadDatabase(req.session); } - common.replaceNode(req, selectedNode); - } - try { - fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) }); - res.status(201).json({ message: 'Node Settings Updated Successfully' }); - } catch (errRes) { - const errMsg = 'Update Node Settings Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); - } -}; - -export const update2FASettings = (req, res, next) => { - const { secret2fa } = req.body; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); - if (secret2fa && secret2fa.trim() !== '') { - config.secret2fa = secret2fa; - } else { - delete config.secret2fa; - } - const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.'; - try { - fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - common.rtl_secret2fa = config.secret2fa; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message }); - res.status(201).json({ message: message }); - } catch (errRes) { - const errMsg = 'Update 2FA Settings Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); - } -}; - -export const updateDefaultNode = (req, res, next) => { - const { defaultNodeIndex } = req.body; - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; - const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); - config.defaultNodeIndex = defaultNodeIndex; - try { - fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) }); - res.status(201).json({ message: 'Default Node Updated Successfully' }); - } catch (errRes) { - const errMsg = 'Update Default Node Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); } + const responseVal = !req.session.selectedNode.lnNode ? '' : req.session.selectedNode.lnNode; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal }); + res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' }); }; export const getConfig = (req, res, next) => { @@ -220,14 +120,14 @@ export const getConfig = (req, res, next) => { let fileFormat = 'INI'; switch (req.params.nodeType) { case 'ln': - confFile = req.session.selectedNode.config_path; + confFile = req.session.selectedNode.authentication.configPath; break; case 'bitcoind': - confFile = req.session.selectedNode.bitcoind_config_path; + confFile = req.session.selectedNode.settings.bitcoindConfigPath; break; case 'rtl': fileFormat = 'JSON'; - confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; break; default: confFile = ''; @@ -251,7 +151,7 @@ export const getConfig = (req, res, next) => { if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) { jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color; } - if (req.params.nodeType === 'ln' && req.session.selectedNode.ln_implementation === 'ECL' && !jsonConfig['eclair.api.password']) { + if (req.params.nodeType === 'ln' && req.session.selectedNode.lnImplementation === 'ECL' && !jsonConfig['eclair.api.password']) { fileFormat = 'HOCON'; jsonConfig = parseHocon(data); } @@ -264,41 +164,91 @@ export const getConfig = (req, res, next) => { }); }; -export const getFile = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); - const file = req.query.path ? req.query.path : (req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak'); - logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); - logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); - fs.readFile(file, 'utf8', (errRes, data) => { - if (errRes) { - if (errRes.code && errRes.code === 'ENOENT') { errRes.code = 'File Not Found!'; } - const errMsg = 'Reading File Error'; - const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.error, error: err.error }); +export const updateNodeSettings = (req, res, next) => { + const { updatedSettings } = req.body; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' }); + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; + const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); + const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index)); + if (node && node.Settings) { + node.Settings.userPersona = updatedSettings.userPersona; + node.Settings.themeMode = updatedSettings.themeMode; + node.Settings.themeColor = updatedSettings.themeColor; + node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels; + node.Settings.fiatConversion = updatedSettings.fiatConversion; + if (updatedSettings.fiatConversion) { + node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; } else { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data }); - res.status(200).json(data); + delete node.Settings.currencyUnit; } - }); + const selectedNode = common.findNode(req.session.selectedNode.index); + selectedNode.settings.userPersona = updatedSettings.userPersona; + selectedNode.settings.themeMode = updatedSettings.themeMode; + selectedNode.settings.themeColor = updatedSettings.themeColor; + selectedNode.settings.unannouncedChannels = updatedSettings.unannouncedChannels; + selectedNode.settings.fiatConversion = updatedSettings.fiatConversion; + if (updatedSettings.fiatConversion) { + selectedNode.settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD'; + } else { + delete selectedNode.settings.currencyUnit; + } + common.replaceNode(req, selectedNode); + } + try { + fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) }); + res.status(201).json({ message: 'Node Settings Updated Successfully' }); + } catch (errRes) { + const errMsg = 'Update Node Settings Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); + } }; -export const getCurrencyRates = (req, res, next) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' }); - options.url = 'https://blockchain.info/ticker'; - request(options).then((body) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body }); - res.status(200).json(JSON.parse(body)); - }).catch((errRes) => { - const errMsg = 'Get Rates Error'; +export const updateApplicationSettings = (req, res, next) => { + const { defaultNodeIndex } = req.body; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' }); + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; + const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); + config.defaultNodeIndex = defaultNodeIndex; + try { + fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) }); + res.status(201).json({ message: 'Default Node Updated Successfully' }); + } catch (errRes) { + const errMsg = 'Update Default Node Error'; const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); return res.status(err.statusCode).json({ message: err.error, error: err.error }); - }); + } +}; + +export const update2FASettings = (req, res, next) => { + const { secret2fa } = req.body; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' }); + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; + const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); + if (secret2fa && secret2fa.trim() !== '') { + config.secret2fa = secret2fa; + } else { + delete config.secret2fa; + } + const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.'; + try { + fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); + common.appConfig.rtlSecret2fa = config.secret2fa; + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message }); + res.status(201).json({ message: message }); + } catch (errRes) { + const errMsg = 'Update 2FA Settings Error'; + const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); + return res.status(err.statusCode).json({ message: err.error, error: err.error }); + } }; export const updateSSO = (req, res, next) => { const { SSO } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating SSO Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); delete config.SSO; config.SSO = SSO; @@ -316,7 +266,7 @@ export const updateSSO = (req, res, next) => { export const updateServiceSettings = (req, res, next) => { const { service, settings } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Service Settings..' }); - const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const selectedNode = common.findNode(req.session.selectedNode.index); config.nodes.forEach((node) => { @@ -326,13 +276,13 @@ export const updateServiceSettings = (req, res, next) => { if (settings.enable) { node.Settings.swapServerUrl = settings.serverUrl; node.Authentication.swapMacaroonPath = settings.macaroonPath; - selectedNode.swap_server_url = settings.serverUrl; - selectedNode.swap_macaroon_path = settings.macaroonPath; + selectedNode.settings.swapServerUrl = settings.serverUrl; + selectedNode.authentication.swapMacaroonPath = settings.macaroonPath; } else { delete node.Settings.swapServerUrl; delete node.Authentication.swapMacaroonPath; - delete selectedNode.swap_server_url; - delete selectedNode.swap_macaroon_path; + delete selectedNode.settings.swapServerUrl; + delete selectedNode.authentication.swapMacaroonPath; } break; @@ -340,24 +290,24 @@ export const updateServiceSettings = (req, res, next) => { if (settings.enable) { node.Settings.boltzServerUrl = settings.serverUrl; node.Authentication.boltzMacaroonPath = settings.macaroonPath; - selectedNode.boltz_server_url = settings.serverUrl; - selectedNode.boltz_macaroon_path = settings.macaroonPath; + selectedNode.settings.boltzServerUrl = settings.serverUrl; + selectedNode.authentication.boltzMacaroonPath = settings.macaroonPath; } else { delete node.Settings.boltzServerUrl; delete node.Authentication.boltzMacaroonPath; - delete selectedNode.boltz_server_url; - delete selectedNode.boltz_macaroon_path; + delete selectedNode.settings.boltzServerUrl; + delete selectedNode.authentication.boltzMacaroonPath; } break; case 'OFFERS': node.Settings.enableOffers = settings.enableOffers; - selectedNode.enable_offers = settings.enableOffers; + selectedNode.settings.enableOffers = settings.enableOffers; break; case 'PEERSWAP': node.Settings.enablePeerswap = settings.enablePeerswap; - selectedNode.enable_peerswap = settings.enablePeerswap; + selectedNode.settings.enablePeerswap = settings.enablePeerswap; break; default: @@ -377,23 +327,3 @@ export const updateServiceSettings = (req, res, next) => { return res.status(err.statusCode).json({ message: err.error, error: err.error }); } }; - -export const maskPasswords = (obj) => { - const keys = Object.keys(obj); - const length = keys.length; - if (length !== 0) { - for (let i = 0; i < length; i++) { - if (typeof obj[keys[i]] === 'object') { - keys[keys[i]] = maskPasswords(obj[keys[i]]); - } - if (typeof keys[i] === 'string' && - (keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') || - keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') || - keys[i].toLowerCase().includes('rpcuser')) - ) { - obj[keys[i]] = '********************'; - } - } - } - return obj; -}; diff --git a/server/controllers/shared/authenticate.ts b/server/controllers/shared/authenticate.ts index 2a68acec..08411d9f 100644 --- a/server/controllers/shared/authenticate.ts +++ b/server/controllers/shared/authenticate.ts @@ -47,19 +47,19 @@ const handleMultipleFailedAttemptsError = (failed, currentTime, errMsg) => { } }; -export const verifyToken = (twoFAToken) => !!(common.rtl_secret2fa && common.rtl_secret2fa !== '' && otplib.authenticator.check(twoFAToken, common.rtl_secret2fa)); +export const verifyToken = (twoFAToken) => !!(common.appConfig.rtlSecret2fa && common.appConfig.rtlSecret2fa !== '' && otplib.authenticator.check(twoFAToken, common.appConfig.rtlSecret2fa)); export const authenticateUser = (req, res, next) => { const { authenticateWith, authenticationValue, twoFAToken } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' }); - if (+common.rtl_sso) { + if (+common.appConfig.sso.rtlSso) { if (authenticateWith === 'JWT' && jwt.verify(authenticationValue, common.secret_key)) { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' }); } else if (authenticateWith === 'PASSWORD') { - if (common.cookie_value.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.cookie_value).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) { + if (common.appConfig.sso.cookieValue.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.appConfig.sso.cookieValue).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) { common.refreshCookie(); - if (!req.session.selectedNode) { req.session.selectedNode = common.initSelectedNode; } + if (!req.session.selectedNode) { req.session.selectedNode = common.selectedNode; } const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); res.status(200).json({ token: token }); @@ -74,7 +74,7 @@ export const authenticateUser = (req, res, next) => { const reqIP = common.getRequestIP(req); const failed = getFailedInfo(reqIP, currentTime); const password = authenticationValue; - if (common.rtl_pass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) { + if (common.appConfig.rtlPass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) { if (twoFAToken && twoFAToken !== '') { if (!verifyToken(twoFAToken)) { logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } }); @@ -83,15 +83,15 @@ export const authenticateUser = (req, res, next) => { return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid 2FA Token!')); } } - if (!req.session.selectedNode) { req.session.selectedNode = common.initSelectedNode; } + if (!req.session.selectedNode) { req.session.selectedNode = common.selectedNode; } delete failedLoginAttempts[reqIP]; const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); res.status(200).json({ token: token }); } else { logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } }); - failed.count = common.rtl_pass !== password ? (failed.count + 1) : failed.count; - failed.lastTried = common.rtl_pass !== password ? currentTime : failed.lastTried; + failed.count = common.appConfig.rtlPass !== password ? (failed.count + 1) : failed.count; + failed.lastTried = common.appConfig.rtlPass !== password ? currentTime : failed.lastTried; return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!')); } } @@ -100,13 +100,13 @@ export const authenticateUser = (req, res, next) => { export const resetPassword = (req, res, next) => { const { currPassword, newPassword } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' }); - if (+common.rtl_sso) { + if (+common.appConfig.sso.rtlSso) { const errMsg = 'Password cannot be reset for SSO authentication'; const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg, req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); } else { - if (common.rtl_pass === currPassword) { - common.rtl_pass = common.replacePasswordWithHash(newPassword); + if (common.appConfig.rtlPass === currPassword) { + common.appConfig.rtlPass = common.replacePasswordWithHash(newPassword); const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' }); res.status(200).json({ token: token }); diff --git a/server/models/config.model.ts b/server/models/config.model.ts index ea0d4545..be316093 100644 --- a/server/models/config.model.ts +++ b/server/models/config.model.ts @@ -1,71 +1,84 @@ -export class CommonSelectedNode { +export class NodeSettings { constructor( - public options?: any, - public ln_server_url?: string, - public macaroon_path?: string, - public macaroon_value?: string, - public rune_path?: string, - public rune_value?: string, - public ln_api_password?: string, - public swap_server_url?: string, - public boltz_server_url?: string, - public config_path?: string, - public rtl_conf_file_path?: string, - public swap_macaroon_path?: string, - public boltz_macaroon_path?: string, - public bitcoind_config_path?: string, - public channel_backup_path?: string, - public log_level?: string, - public log_file?: string, - public index?: string, - public ln_node?: string, - public ln_implementation?: string, - public user_persona?: string, - public theme_mode?: string, - public theme_color?: string, - public unannounced_channels?: boolean, - public fiat_conversion?: boolean, - public currency_unit?: string, - public ln_version?: string, - public api_version?: string, - public enable_offers?: boolean, - public enable_peerswap?: boolean + public lnServerUrl?: string, + public swapServerUrl?: string, + public boltzServerUrl?: string, + public bitcoindConfigPath?: string, + public channelBackupPath?: string, + public logLevel?: string, + public logFile?: string, + public userPersona?: string, + public themeMode?: string, + public themeColor?: string, + public unannouncedChannels?: boolean, + public fiatConversion?: boolean, + public currencyUnit?: string, + public enableOffers?: boolean, + public enablePeerswap?: boolean ) { } } -export class AuthenticationConfiguration { +export class NodeAuthentication { constructor( + public options?: any, public configPath?: string, + public macaroonPath?: string, + public macaroonValue?: string, + public runePath?: string, + public runeValue?: string, + public lnApiPassword?: string, public swapMacaroonPath?: string, public boltzMacaroonPath?: string ) { } } -export class NodeSettingsConfiguration { +export class SelectedNode { constructor( - public userPersona?: string, - public themeMode?: string, - public themeColor?: string, - public unannouncedChannels?: boolean, - public fiatConversion?: boolean, - public currencyUnit?: string, - public bitcoindConfigPath?: string, public logLevel?: string, - public lnServerUrl?: string, - public swapServerUrl?: string, - public boltzServerUrl?: string, - public channelBackupPath?: string, - public enableOffers?: boolean, - public enablePeerswap?: boolean + public logFile?: string, + public index?: string, + public lnNode?: string, + public lnImplementation?: string, + public lnVersion?: string, + public apiVersion?: string, + public settings?: NodeSettings, + public authentication?: NodeAuthentication ) { } } +export class SSO { + + constructor( + public rtlSso: number, + public rtlCookiePath: string, + public logoutRedirectLink: string, + public cookieValue: string + ) { } + +} + +export class ApplicationConfig { + + constructor( + public defaultNodeIndex: number, + public selectedNodeIndex: number, + public dbDirectoryPath?: string, + public rtlConfFilePath?: string, + public rtlPass?: string, + public allowPasswordUpdate?: boolean, + public rtlSecret2fa?: string, + public sso?: SSO, + public nodes?: SelectedNode[] + ) {} + +} + export class LogJSONObj { constructor( @@ -74,7 +87,7 @@ export class LogJSONObj { public data?: string | any | any[], public error?: string | any, public fileName?: string, - public selectedNode?: CommonSelectedNode + public selectedNode?: SelectedNode ) { } } diff --git a/server/routes/shared/RTLConf.ts b/server/routes/shared/RTLConf.ts index 032b87b8..83bc3f54 100644 --- a/server/routes/shared/RTLConf.ts +++ b/server/routes/shared/RTLConf.ts @@ -1,20 +1,16 @@ import exprs from 'express'; const { Router } = exprs; import { isAuthenticated } from '../../utils/authCheck.js'; -import { getRTLConfigInitial, getRTLConfig, updateUISettings, update2FASettings, getConfig, getFile, updateSelectedNode, updateDefaultNode, updateServiceSettings, updateSSO, getCurrencyRates } from '../../controllers/shared/RTLConf.js'; +import { getRTLConfig, updateNodeSettings, getConfig, getFile, updateSelectedNode, updateApplicationSettings, getCurrencyRates } from '../../controllers/shared/RTLConf.js'; const router = Router(); -router.get('/rtlconfinit', getRTLConfigInitial); -router.get('/rtlconf', isAuthenticated, getRTLConfig); -router.post('/', isAuthenticated, updateUISettings); -router.post('/update2FA', isAuthenticated, update2FASettings); -router.get('/config/:nodeType', isAuthenticated, getConfig); +router.get('/rates', getCurrencyRates); router.get('/file', isAuthenticated, getFile); +router.get('/rtlconf/:init', isAuthenticated, getRTLConfig); router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode); -router.post('/updateDefaultNode', updateDefaultNode); -router.post('/updateServiceSettings', updateServiceSettings); -router.post('/updateSSO', updateSSO); -router.get('/rates', getCurrencyRates); +router.get('/config/:nodeType', isAuthenticated, getConfig); +router.post('/node', isAuthenticated, updateNodeSettings); +router.post('/application', isAuthenticated, updateApplicationSettings); export default router; diff --git a/server/utils/app.ts b/server/utils/app.ts index 0a4a0e35..4c3c9e28 100644 --- a/server/utils/app.ts +++ b/server/utils/app.ts @@ -32,7 +32,7 @@ export class ExpressApplication { public directoryName = dirname(fileURLToPath(import.meta.url)); constructor() { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' }); this.app.set('trust proxy', true); this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false })); this.app.use(cookieParser(this.common.secret_key)); @@ -52,7 +52,7 @@ export class ExpressApplication { public setCSRF = () => { CSRF.mount(this.app); }; public setApplicationRoutes = () => { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' }); this.app.use(this.common.baseHref + '/api', sharedRoutes); this.app.use(this.common.baseHref + '/api/lnd', lndRoutes); this.app.use(this.common.baseHref + '/api/cln', clnRoutes); @@ -67,29 +67,29 @@ export class ExpressApplication { this.handleApplicationErrors(err, res); next(); }); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' }); }; public handleApplicationErrors = (err, res) => { switch (err.code) { case 'EACCES': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' }); res.status(406).send('Server requires elevated privileges.'); break; case 'EADDRINUSE': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' }); res.status(409).send('Server is already in use.'); break; case 'ECONNREFUSED': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' }); res.status(401).send('Server is down/locked.'); break; case 'EBADCSRFTOKEN': - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' }); res.status(403).send('Invalid CSRF token, form tempered.'); break; default: - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err }); res.status(400).send(JSON.stringify(err)); break; } diff --git a/server/utils/authCheck.ts b/server/utils/authCheck.ts index 5c46e8c2..16306ef7 100644 --- a/server/utils/authCheck.ts +++ b/server/utils/authCheck.ts @@ -44,7 +44,7 @@ export const verifyWSUser = (info, next) => { } catch (err) { cookies = {}; updatedReq['cookies'] = JSON.parse(cookies); - logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err }); + logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err }); } csurfProtection(updatedReq, null, (err) => { if (err) { @@ -54,7 +54,7 @@ export const verifyWSUser = (info, next) => { } }); } catch (err) { - logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err }); + logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err }); next(true); } } diff --git a/server/utils/common.ts b/server/utils/common.ts index 7d56d2d1..84725980 100644 --- a/server/utils/common.ts +++ b/server/utils/common.ts @@ -4,26 +4,17 @@ import { fileURLToPath } from 'url'; import * as crypto from 'crypto'; import request from 'request-promise'; import { Logger, LoggerService } from './logger.js'; -import { CommonSelectedNode } from '../models/config.model.js'; +import { ApplicationConfig, SelectedNode } from '../models/config.model.js'; export class CommonService { public logger: LoggerService = Logger; - public nodes: CommonSelectedNode[] = []; - public initSelectedNode: CommonSelectedNode = null; - public rtl_conf_file_path = ''; + public nodes: SelectedNode[] = []; + public selectedNode: SelectedNode = null; + public ssoInit = { rtlSso: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' }; + public appConfig: ApplicationConfig = { defaultNodeIndex: 0, selectedNodeIndex: 0, rtlConfFilePath: '', dbDirectoryPath: join(dirname(fileURLToPath(import.meta.url)), '..', '..'), rtlPass: '', allowPasswordUpdate: true, rtlSecret2fa: '', sso: this.ssoInit, nodes: [] }; public port = 3000; public host = ''; - public db_directory_path = join(dirname(fileURLToPath(import.meta.url)), '..', '..'); - public rtl_pass = ''; - public flg_allow_password_update = true; - public rtl_secret2fa = ''; - public rtl_sso = 0; - public rtl_cookie_path = ''; - public logout_redirect_link = ''; - public cookie_value = ''; - public ln_version = ''; - public api_version = ''; public secret_key = crypto.randomBytes(64).toString('hex'); public read_dummy_data = false; public baseHref = '/rtl'; @@ -33,101 +24,101 @@ export class CommonService { { name: 'JUL', days: 31 }, { name: 'AUG', days: 31 }, { name: 'SEP', days: 30 }, { name: 'OCT', days: 31 }, { name: 'NOV', days: 30 }, { name: 'DEC', days: 31 } ]; - constructor() { } + constructor() {} public setSwapServerOptions = (req) => { const swapOptions = { - baseUrl: req.session.selectedNode.swap_server_url, + baseUrl: req.session.selectedNode.settings.swapServerUrl, uri: '', rejectUnauthorized: false, json: true, headers: { 'Grpc-Metadata-macaroon': '' } }; - if (req.session.selectedNode.swap_macaroon_path) { + if (req.session.selectedNode.authentication.swapMacaroonPath) { try { - swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.swap_macaroon_path, 'loop.macaroon')).toString('hex') }; + swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.swapMacaroonPath, 'loop.macaroon')).toString('hex') }; } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err }); } } - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions }); return swapOptions; }; public getBoltzServerOptions = (req) => { const boltzOptions = { - url: req.session.selectedNode.boltz_server_url, + url: req.session.selectedNode.settings.boltzServerUrl, rejectUnauthorized: false, json: true, headers: { 'Grpc-Metadata-macaroon': '' } }; - if (req.session.selectedNode.boltz_macaroon_path) { + if (req.session.selectedNode.authentication.boltzMacaroonPath) { try { - boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.boltz_macaroon_path, 'admin.macaroon')).toString('hex') }; + boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.boltzMacaroonPath, 'admin.macaroon')).toString('hex') }; } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err }); } } - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions }); return boltzOptions; }; public getOptions = (req) => { - if (req.session.selectedNode && req.session.selectedNode.options) { - req.session.selectedNode.options.method = (req.session.selectedNode.ln_implementation && req.session.selectedNode.ln_implementation.toUpperCase() === 'LND') ? 'GET' : 'POST'; - delete req.session.selectedNode.options.form; - delete req.session.selectedNode.options.body; - req.session.selectedNode.options.qs = {}; - return req.session.selectedNode.options; + if (req.session.selectedNode && req.session.selectedNode.authentication.options) { + req.session.selectedNode.authentication.options.method = (req.session.selectedNode.lnImplementation && req.session.selectedNode.lnImplementation.toUpperCase() === 'LND') ? 'GET' : 'POST'; + delete req.session.selectedNode.authentication.options.form; + delete req.session.selectedNode.authentication.options.body; + req.session.selectedNode.authentication.options.qs = {}; + return req.session.selectedNode.authentication.options; } - return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.initSelectedNode); + return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.selectedNode); }; public updateSelectedNodeOptions = (req) => { if (!req.session.selectedNode) { req.session.selectedNode = {}; } - req.session.selectedNode.options = { + req.session.selectedNode.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: null }; try { - if (req.session.selectedNode && req.session.selectedNode.ln_implementation) { - switch (req.session.selectedNode.ln_implementation.toUpperCase()) { + if (req.session.selectedNode && req.session.selectedNode.lnImplementation) { + switch (req.session.selectedNode.lnImplementation.toUpperCase()) { case 'CLN': try { - if (!req.session.selectedNode.rune_value) { - req.session.selectedNode.rune_value = this.getRuneValue(req.session.selectedNode.rune_path); + if (!req.session.selectedNode.authentication.runeValue) { + req.session.selectedNode.authentication.runeValue = this.getRuneValue(req.session.selectedNode.authentication.runePath); } - req.session.selectedNode.options.headers = { rune: req.session.selectedNode.rune_value }; + req.session.selectedNode.authentication.options.headers = { rune: req.session.selectedNode.authentication.runeValue }; } catch (err) { throw new Error(err); } break; case 'ECL': - req.session.selectedNode.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.ln_api_password).toString('base64') }; + req.session.selectedNode.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.authentication.lnApiPassword).toString('base64') }; break; default: - req.session.selectedNode.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; + req.session.selectedNode.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') }; break; } } if (req.session.selectedNode) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.ln_node, data: req.session.selectedNode.options }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.lnNode, data: req.session.selectedNode.authentication.options }); } return { status: 200, message: 'Updated Successfully' }; } catch (err) { - req.session.selectedNode.options = { + req.session.selectedNode.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: null }; - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err }); return { status: 502, message: err }; } }; @@ -144,48 +135,48 @@ export class CommonService { }; public setOptions = (req) => { - if (this.nodes[0].options && this.nodes[0].options.headers) { return; } + if (this.nodes[0].authentication.options && this.nodes[0].authentication.options.headers) { return; } if (this.nodes && this.nodes.length > 0) { this.nodes.forEach((node) => { - node.options = { + node.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: null }; try { - if (node.ln_implementation) { - switch (node.ln_implementation.toUpperCase()) { + if (node.lnImplementation) { + switch (node.lnImplementation.toUpperCase()) { case 'CLN': try { - if (!node.rune_value) { - node.rune_value = this.getRuneValue(node.rune_path); + if (!node.authentication.runeValue) { + node.authentication.runeValue = this.getRuneValue(node.authentication.runePath); } - node.options.headers = { rune: node.rune_value }; + node.authentication.options.headers = { rune: node.authentication.runeValue }; } catch (err) { throw new Error(err); } break; case 'ECL': - node.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.ln_api_password).toString('base64') }; + node.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.authentication.lnApiPassword).toString('base64') }; break; default: - node.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.macaroon_path, 'admin.macaroon')).toString('hex') }; + node.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.authentication.macaroonPath, 'admin.macaroon')).toString('hex') }; break; } } } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err }); - node.options = { + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err }); + node.authentication.options = { url: '', rejectUnauthorized: false, json: true, form: '' }; } - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.ln_node, data: node.options }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.lnNode, data: node.authentication.options }); }); this.updateSelectedNodeOptions(req); } @@ -264,7 +255,7 @@ export class CommonService { } }; - public handleError = (errRes, fileName, errMsg, selectedNode: CommonSelectedNode) => { + public handleError = (errRes, fileName, errMsg, selectedNode: SelectedNode) => { let err = JSON.parse(JSON.stringify(errRes)); if (err && err.error && Object.keys(err.error).length === 0 && errRes.error && (errRes.error.stack || errRes.error.message)) { errRes.error = errRes.error.stack || errRes.error.message; @@ -273,8 +264,8 @@ export class CommonService { errRes.error = errRes.message || errRes.stack; err = JSON.parse(JSON.stringify(errRes)); } - if (!selectedNode) { selectedNode = this.initSelectedNode; } - switch (selectedNode.ln_implementation) { + if (!selectedNode) { selectedNode = this.selectedNode; } + switch (selectedNode.lnImplementation) { case 'LND': if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { delete err.options.headers['Grpc-Metadata-macaroon']; @@ -328,7 +319,7 @@ export class CommonService { ) }; } - if (selectedNode.ln_implementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') { newErrorObj.statusCode = 500; } + if (selectedNode.lnImplementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') { newErrorObj.statusCode = 500; } return newErrorObj; }; @@ -339,15 +330,15 @@ export class CommonService { (req.connection.socket ? req.connection.socket.remoteAddress : null)); public getDummyData = (dataKey, lnImplementation) => { - const dummyDataFile = this.rtl_conf_file_path + sep + 'ECLDummyData.log'; + const dummyDataFile = this.appConfig.rtlConfFilePath + sep + 'ECLDummyData.log'; return new Promise((resolve, reject) => { if (this.dummy_data_array_from_file.length === 0) { fs.readFile(dummyDataFile, 'utf8', (err, data) => { if (err) { if (err.code === 'ENOENT') { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' }); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' }); } } else { this.dummy_data_array_from_file = data.split('\n'); @@ -361,22 +352,22 @@ export class CommonService { }; public readCookie = () => { - const exists = fs.existsSync(this.rtl_cookie_path); + const exists = fs.existsSync(this.appConfig.sso.rtlCookiePath); if (exists) { try { - this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); + this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8'); } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err }); throw new Error(err); } } else { try { - const directoryName = dirname(this.rtl_cookie_path); + const directoryName = dirname(this.appConfig.sso.rtlCookiePath); this.createDirectory(directoryName); - fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); - this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); + fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex')); + this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8'); } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err }); throw new Error(err); } } @@ -384,10 +375,10 @@ export class CommonService { public refreshCookie = () => { try { - fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); - this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); + fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex')); + this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8'); } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err }); throw new Error(err); } }; @@ -414,47 +405,47 @@ export class CommonService { }; public replacePasswordWithHash = (multiPassHashed) => { - this.rtl_conf_file_path = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..'); + this.appConfig.rtlConfFilePath = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..'); try { - const RTLConfFile = this.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = this.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); config.multiPassHashed = multiPassHashed; delete config.multiPass; fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' }); return config.multiPassHashed; } catch (err) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err }); } }; - public getAllNodeAllChannelBackup = (node: CommonSelectedNode) => { - const channel_backup_file = node.channel_backup_path + sep + 'channel-all.bak'; + public getAllNodeAllChannelBackup = (node: SelectedNode) => { + const channel_backup_file = node.settings.channelBackupPath + sep + 'channel-all.bak'; const options = { - url: node.ln_server_url + '/v1/channels/backup', + url: node.settings.lnServerUrl + '/v1/channels/backup', rejectUnauthorized: false, json: true, - headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex') } + headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.authentication.macaroonPath + '/admin.macaroon').toString('hex') } }; - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.ln_node + '..' }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.lnNode + '..' }); request(options).then((body) => { fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => { if (err) { - if (node.ln_node) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); + if (node.lnNode) { + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err }); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err }); } } else { - if (node.ln_node) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.ln_node, data: body }); + if (node.lnNode) { + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.lnNode, data: body }); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body }); } } }); }, (err) => { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err }); fs.writeFile(channel_backup_file, '', () => { }); }); }; @@ -465,8 +456,8 @@ export class CommonService { const pattern = /v?(\d+(\.\d+)*)/; const match = currentVersion.match(pattern); if (match && match.length && match.length > 1) { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] }); - this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] }); + this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion }); const currentVersionArr = match[1].split('.') || []; currentVersionArr[1] = currentVersionArr[1].substring(0, 2); const checkVersionsArr = checkVersion.split('.'); @@ -475,7 +466,7 @@ export class CommonService { (+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] > +checkVersionsArr[1]) || (+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]); } else { - this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion }); + this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion }); return false; } } @@ -485,20 +476,20 @@ export class CommonService { public getMonthDays = (selMonth, selYear) => ((selMonth === 1 && selYear % 4 === 0) ? (this.MONTHS[selMonth].days + 1) : this.MONTHS[selMonth].days); public logEnvVariables = (req) => { - const selNode = req.session.selectedNode; + const selNode = req.session.selectedNode; if (selNode && selNode.index) { this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'PORT: ' + this.port }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'HOST: ' + this.host }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.db_directory_path }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.rtl_sso }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.appConfig.dbDirectoryPath }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.appConfig.sso.rtlSso }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + selNode.index }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'INDEX: ' + selNode.index }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.ln_node }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.ln_implementation }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.fiat_conversion }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.currency_unit }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.ln_server_url }); - this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.logout_redirect_link + '\r\n' }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.lnNode }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.lnImplementation }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.settings.fiatConversion }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.settings.currencyUnit }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.settings.lnServerUrl }); + this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.appConfig.sso.logoutRedirectLink + '\r\n' }); } }; diff --git a/server/utils/config.ts b/server/utils/config.ts index c6ed7dbb..c90ef9ba 100644 --- a/server/utils/config.ts +++ b/server/utils/config.ts @@ -103,9 +103,9 @@ export class ConfigService { private updateLogByLevel = () => { let updateLogFlag = false; - this.common.rtl_conf_file_path = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); + this.common.appConfig.rtlConfFilePath = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); try { - const RTLConfFile = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; + const RTLConfFile = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); config.nodes.forEach((node) => { if (node.Settings.hasOwnProperty('enableLogging')) { @@ -125,16 +125,16 @@ export class ConfigService { private validateNodeConfig = (config) => { if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { - this.common.rtl_pass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); - this.common.flg_allow_password_update = false; + this.common.appConfig.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); + this.common.appConfig.allowPasswordUpdate = false; } else if (config.multiPassHashed && config.multiPassHashed !== '') { - this.common.rtl_pass = config.multiPassHashed; + this.common.appConfig.rtlPass = config.multiPassHashed; } else if (config.multiPass && config.multiPass !== '') { - this.common.rtl_pass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex')); + this.common.appConfig.rtlPass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex')); } else { this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json'; } - this.common.rtl_secret2fa = config.secret2fa; + this.common.appConfig.rtlSecret2fa = config.secret2fa; } else { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { this.errMsg = this.errMsg + '\nRTL Password cannot be set with SSO. Please set SSO as 0 or remove password.'; @@ -142,20 +142,20 @@ export class ConfigService { } this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000; this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null; - this.common.db_directory_path = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..'); + this.common.appConfig.dbDirectoryPath = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..'); if (config.nodes && config.nodes.length > 0) { config.nodes.forEach((node, idx) => { this.common.nodes[idx] = {}; this.common.nodes[idx].index = node.index; - this.common.nodes[idx].ln_node = node.lnNode; - this.common.nodes[idx].ln_implementation = (process?.env?.LN_IMPLEMENTATION) ? process?.env?.LN_IMPLEMENTATION : node.lnImplementation ? node.lnImplementation : 'LND'; - if (this.common.nodes[idx].ln_implementation === 'CLT') { this.common.nodes[idx].ln_implementation = 'CLN'; } - switch (this.common.nodes[idx].ln_implementation) { + this.common.nodes[idx].lnNode = node.lnNode; + this.common.nodes[idx].lnImplementation = (process?.env?.lnImplementation) ? process?.env?.lnImplementation : node.lnImplementation ? node.lnImplementation : 'LND'; + if (this.common.nodes[idx].lnImplementation === 'CLT') { this.common.nodes[idx].lnImplementation = 'CLN'; } + switch (this.common.nodes[idx].lnImplementation) { case 'CLN': if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') { - this.common.nodes[idx].rune_path = process?.env?.RUNE_PATH; + this.common.nodes[idx].authentication.runePath = process?.env?.RUNE_PATH; } else if (node.Authentication && node.Authentication.runePath && node.Authentication.runePath.trim() !== '') { - this.common.nodes[idx].rune_path = node.Authentication.runePath; + this.common.nodes[idx].authentication.runePath = node.Authentication.runePath; } else { this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!'; } @@ -163,118 +163,118 @@ export class ConfigService { case 'ECL': if (process?.env?.LN_API_PASSWORD) { - this.common.nodes[idx].ln_api_password = process?.env?.LN_API_PASSWORD; + this.common.nodes[idx].authentication.lnApiPassword = process?.env?.LN_API_PASSWORD; } else if (node.Authentication && node.Authentication.lnApiPassword) { - this.common.nodes[idx].ln_api_password = node.Authentication.lnApiPassword; + this.common.nodes[idx].authentication.lnApiPassword = node.Authentication.lnApiPassword; } else { - this.common.nodes[idx].ln_api_password = ''; + this.common.nodes[idx].authentication.lnApiPassword = ''; } break; default: if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') { - this.common.nodes[idx].macaroon_path = process?.env?.MACAROON_PATH; + this.common.nodes[idx].authentication.macaroonPath = process?.env?.MACAROON_PATH; } else if (node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') { - this.common.nodes[idx].macaroon_path = node.Authentication.macaroonPath; + this.common.nodes[idx].authentication.macaroonPath = node.Authentication.macaroonPath; } else { this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!'; } break; } if (process?.env?.CONFIG_PATH) { - this.common.nodes[idx].config_path = process?.env?.CONFIG_PATH; + this.common.nodes[idx].authentication.configPath = process?.env?.CONFIG_PATH; } else if (node.Authentication && node.Authentication.configPath) { - this.common.nodes[idx].config_path = node.Authentication.configPath; + this.common.nodes[idx].authentication.configPath = node.Authentication.configPath; } else { - this.common.nodes[idx].config_path = ''; + this.common.nodes[idx].authentication.configPath = ''; } - if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '' && this.common.nodes[idx].config_path !== '') { + if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '' && this.common.nodes[idx].authentication.configPath !== '') { try { - const exists = fs.existsSync(this.common.nodes[idx].config_path || ''); + const exists = fs.existsSync(this.common.nodes[idx].authentication.configPath || ''); if (exists) { try { - const configFile = fs.readFileSync((this.common.nodes[idx].config_path || ''), 'utf-8'); + const configFile = fs.readFileSync((this.common.nodes[idx].authentication.configPath || ''), 'utf-8'); const iniParsed = ini.parse(configFile); - this.common.nodes[idx].ln_api_password = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password; + this.common.nodes[idx].authentication.lnApiPassword = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password; } catch (err) { this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err; } } else { - this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].config_path; + this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].authentication.configPath; } } catch (err) { this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err; } } - if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '') { + if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '') { this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!'; } if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') { - this.common.nodes[idx].ln_server_url = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL; + this.common.nodes[idx].settings.lnServerUrl = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL; } else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') { - this.common.nodes[idx].ln_server_url = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL; + this.common.nodes[idx].settings.lnServerUrl = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL; } else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') { - this.common.nodes[idx].ln_server_url = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl; + this.common.nodes[idx].settings.lnServerUrl = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl; } else if (node.Settings.lndServerUrl && node.Settings.lndServerUrl.trim() !== '') { - this.common.nodes[idx].ln_server_url = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl; + this.common.nodes[idx].settings.lnServerUrl = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl; } else { this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!'; } - this.common.nodes[idx].user_persona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT'; - this.common.nodes[idx].theme_mode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY'; - this.common.nodes[idx].theme_color = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE'; - this.common.nodes[idx].unannounced_channels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false; - this.common.nodes[idx].log_level = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR'; - this.common.nodes[idx].fiat_conversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false; - if (this.common.nodes[idx].fiat_conversion) { - this.common.nodes[idx].currency_unit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD'; + this.common.nodes[idx].settings.userPersona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT'; + this.common.nodes[idx].settings.themeMode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY'; + this.common.nodes[idx].settings.themeColor = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE'; + this.common.nodes[idx].settings.unannouncedChannels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false; + this.common.nodes[idx].settings.logLevel = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR'; + this.common.nodes[idx].settings.fiatConversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false; + if (this.common.nodes[idx].settings.fiatConversion) { + this.common.nodes[idx].settings.currencyUnit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD'; } if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') { - this.common.nodes[idx].swap_server_url = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL; - this.common.nodes[idx].swap_macaroon_path = process?.env?.SWAP_MACAROON_PATH; + this.common.nodes[idx].settings.swapServerUrl = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL; + this.common.nodes[idx].authentication.swapMacaroonPath = process?.env?.SWAP_MACAROON_PATH; } else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') { - this.common.nodes[idx].swap_server_url = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl; - this.common.nodes[idx].swap_macaroon_path = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : ''; + this.common.nodes[idx].settings.swapServerUrl = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl; + this.common.nodes[idx].authentication.swapMacaroonPath = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : ''; } else { - this.common.nodes[idx].swap_server_url = ''; - this.common.nodes[idx].swap_macaroon_path = ''; + this.common.nodes[idx].settings.swapServerUrl = ''; + this.common.nodes[idx].authentication.swapMacaroonPath = ''; } if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') { - this.common.nodes[idx].boltz_server_url = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL; - this.common.nodes[idx].boltz_macaroon_path = process?.env?.BOLTZ_MACAROON_PATH; + this.common.nodes[idx].settings.boltzServerUrl = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL; + this.common.nodes[idx].authentication.boltzMacaroonPath = process?.env?.BOLTZ_MACAROON_PATH; } else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') { - this.common.nodes[idx].boltz_server_url = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl; - this.common.nodes[idx].boltz_macaroon_path = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : ''; + this.common.nodes[idx].settings.boltzServerUrl = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl; + this.common.nodes[idx].authentication.boltzMacaroonPath = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : ''; } else { - this.common.nodes[idx].boltz_server_url = ''; - this.common.nodes[idx].boltz_macaroon_path = ''; + this.common.nodes[idx].settings.boltzServerUrl = ''; + this.common.nodes[idx].authentication.boltzMacaroonPath = ''; } - this.common.nodes[idx].enable_offers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false; - this.common.nodes[idx].enable_peerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false; - this.common.nodes[idx].bitcoind_config_path = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : ''; - this.common.nodes[idx].channel_backup_path = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.rtl_conf_file_path + sep + 'channels-backup' + sep + 'node-' + node.index; + this.common.nodes[idx].settings.enableOffers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false; + this.common.nodes[idx].settings.enablePeerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false; + this.common.nodes[idx].settings.bitcoindConfigPath = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : ''; + this.common.nodes[idx].settings.channelBackupPath = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.appConfig.rtlConfFilePath + sep + 'channels-backup' + sep + 'node-' + node.index; try { - this.common.createDirectory(this.common.nodes[idx].channel_backup_path); - const exists = fs.existsSync(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); + this.common.createDirectory(this.common.nodes[idx].settings.channelBackupPath); + const exists = fs.existsSync(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak'); if (!exists) { try { - if (this.common.nodes[idx].ln_implementation === 'LND') { + if (this.common.nodes[idx].lnImplementation === 'LND') { this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]); } else { - const createStream = fs.createWriteStream(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); + const createStream = fs.createWriteStream(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak'); createStream.end(); } } catch (err) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err }); } } } catch (err) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err }); } - this.common.nodes[idx].log_file = this.common.rtl_conf_file_path + '/logs/RTL-Node-' + node.index + '.log'; - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) }); - const log_file = this.common.nodes[idx].log_file; + this.common.nodes[idx].settings.logFile = this.common.appConfig.rtlConfFilePath + '/logs/RTL-Node-' + node.index + '.log'; + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) }); + const log_file = this.common.nodes[idx].settings.logFile; if (fs.existsSync(log_file || '')) { fs.writeFile((log_file || ''), '', () => { }); } else { @@ -284,7 +284,7 @@ export class ConfigService { const createStream = fs.createWriteStream(log_file || ''); createStream.end(); } catch (err) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err }); } } }); @@ -295,27 +295,27 @@ export class ConfigService { private setSSOParams = (config) => { if (process?.env?.RTL_SSO) { - this.common.rtl_sso = +process?.env?.RTL_SSO; + this.common.appConfig.sso.rtlSso = +process?.env?.RTL_SSO; } else if (config.SSO && config.SSO.rtlSSO) { - this.common.rtl_sso = config.SSO.rtlSSO; + this.common.appConfig.sso.rtlSso = config.SSO.rtlSSO; } if (process?.env?.RTL_COOKIE_PATH) { - this.common.rtl_cookie_path = process?.env?.RTL_COOKIE_PATH; + this.common.appConfig.sso.rtlCookiePath = process?.env?.RTL_COOKIE_PATH; } else if (config.SSO && config.SSO.rtlCookiePath) { - this.common.rtl_cookie_path = config.SSO.rtlCookiePath; + this.common.appConfig.sso.rtlCookiePath = config.SSO.rtlCookiePath; } else { - this.common.rtl_cookie_path = ''; + this.common.appConfig.sso.rtlCookiePath = ''; } if (process?.env?.LOGOUT_REDIRECT_LINK) { - this.common.logout_redirect_link = process?.env?.LOGOUT_REDIRECT_LINK; + this.common.appConfig.sso.logoutRedirectLink = process?.env?.LOGOUT_REDIRECT_LINK; } else if (config.SSO && config.SSO.logoutRedirectLink) { - this.common.logout_redirect_link = config.SSO.logoutRedirectLink; + this.common.appConfig.sso.logoutRedirectLink = config.SSO.logoutRedirectLink; } - if (+this.common.rtl_sso) { - if (!this.common.rtl_cookie_path || this.common.rtl_cookie_path.trim() === '') { + if (+this.common.appConfig.sso.rtlSso) { + if (!this.common.appConfig.sso.rtlCookiePath || this.common.appConfig.sso.rtlCookiePath.trim() === '') { this.errMsg = 'Please set rtlCookiePath value for single sign on option!'; } else { this.common.readCookie(); @@ -325,16 +325,16 @@ export class ConfigService { private setSelectedNode = (config) => { if (config.defaultNodeIndex) { - this.common.initSelectedNode = this.common.findNode(config.defaultNodeIndex) || {}; + this.common.selectedNode = this.common.findNode(config.defaultNodeIndex) || {}; } else { - this.common.initSelectedNode = this.common.findNode(this.common.nodes[0].index) || {}; + this.common.selectedNode = this.common.findNode(this.common.nodes[0].index) || {}; } }; public setServerConfiguration = () => { try { - this.common.rtl_conf_file_path = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); - const confFileFullPath = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; + this.common.appConfig.rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); + const confFileFullPath = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; if (!fs.existsSync(confFileFullPath)) { fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig())); } @@ -343,7 +343,7 @@ export class ConfigService { this.validateNodeConfig(config); this.setSelectedNode(config); } catch (err: any) { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err }); throw new Error(err); } }; diff --git a/server/utils/cors.ts b/server/utils/cors.ts index 57bec2d7..b3d31421 100644 --- a/server/utils/cors.ts +++ b/server/utils/cors.ts @@ -8,7 +8,7 @@ class CORS { public common: CommonService = Common; public mount(app: Application): Application { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' }); app.use((req, res, next) => { res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath'); @@ -19,7 +19,7 @@ class CORS { } next(); }); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' }); return app; }; diff --git a/server/utils/csrf.ts b/server/utils/csrf.ts index 7b12a82f..074a2dea 100644 --- a/server/utils/csrf.ts +++ b/server/utils/csrf.ts @@ -10,11 +10,11 @@ class CSRF { public common: CommonService = Common; public mount(app: Application): Application { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' }); if (process.env.NODE_ENV !== 'development') { app.use((req, res, next) => this.csrfProtection(req, res, next)); } - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' }); return app; }; diff --git a/server/utils/database.ts b/server/utils/database.ts index 4675e053..43e408a7 100644 --- a/server/utils/database.ts +++ b/server/utils/database.ts @@ -3,20 +3,20 @@ import { join, sep } from 'path'; import { Common, CommonService } from '../utils/common.js'; import { Logger, LoggerService } from '../utils/logger.js'; import { Collections, CollectionsEnum, validateDocument, LNDCollection, ECLCollection, CLNCollection, ECL_UPDATED_DB } from '../models/database.model.js'; -import { CommonSelectedNode } from '../models/config.model.js'; +import { SelectedNode } from '../models/config.model.js'; export class DatabaseService { public common: CommonService = Common; public logger: LoggerService = Logger; - public dbDirectory = join(this.common.db_directory_path, 'database'); + public dbDirectory = join(this.common.appConfig.dbDirectoryPath, 'database'); public nodeDatabase: { id?: { adapter: DatabaseAdapter, data: Collections } } = {}; constructor() { } migrateDatabase() { this.common.nodes?.map((node: any) => { - if (node.ln_implementation === 'ECL') { + if (node.lnImplementation === 'ECL') { this.nodeDatabase[node.index] = { adapter: null, data: {} }; this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node); this.fetchNodeData(node); @@ -82,8 +82,8 @@ export class DatabaseService { } } - fetchNodeData(selectedNode: CommonSelectedNode) { - switch (selectedNode.ln_implementation) { + fetchNodeData(selectedNode: SelectedNode) { + switch (selectedNode.lnImplementation) { case 'CLN': for (const collectionName in CLNCollection) { if (CLNCollection.hasOwnProperty(collectionName)) { @@ -121,7 +121,7 @@ export class DatabaseService { }); } - insert(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, newCollection: any) { + insert(selectedNode: SelectedNode, collectionName: CollectionsEnum, newCollection: any) { return new Promise((resolve, reject) => { try { if (!selectedNode || !selectedNode.index) { @@ -136,7 +136,7 @@ export class DatabaseService { }); } - update(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, updatedDocument: any, documentFieldName: string, documentFieldValue: string) { + update(selectedNode: SelectedNode, collectionName: CollectionsEnum, updatedDocument: any, documentFieldName: string, documentFieldValue: string) { return new Promise((resolve, reject) => { try { if (!selectedNode || !selectedNode.index) { @@ -172,7 +172,7 @@ export class DatabaseService { }); } - find(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, documentFieldName?: string, documentFieldValue?: string) { + find(selectedNode: SelectedNode, collectionName: CollectionsEnum, documentFieldName?: string, documentFieldValue?: string) { return new Promise((resolve, reject) => { try { if (!selectedNode || !selectedNode.index) { @@ -189,7 +189,7 @@ export class DatabaseService { }); } - remove(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, documentFieldName: string, documentFieldValue: string) { + remove(selectedNode: SelectedNode, collectionName: CollectionsEnum, documentFieldName: string, documentFieldValue: string) { return new Promise((resolve, reject) => { try { if (!selectedNode || !selectedNode.index) { @@ -209,7 +209,7 @@ export class DatabaseService { }); } - saveDatabase(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum) { + saveDatabase(selectedNode: SelectedNode, collectionName: CollectionsEnum) { const nodeIndex = +selectedNode.index; try { if (nodeIndex < 1) { @@ -250,17 +250,17 @@ export class DatabaseAdapter { private dbFilePath = ''; private userSessions = []; - constructor(public dbDirectoryPath: string, public selNode: CommonSelectedNode = null, public id: string = '') { + constructor(public dbDirectoryPath: string, public selNode: SelectedNode = null, public id: string = '') { this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index; // For backward compatibility Start const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json'; - if (selNode.ln_implementation === 'CLN' && fs.existsSync(oldFilePath)) { this.renameOldDB(oldFilePath, selNode); } + if (selNode.lnImplementation === 'CLN' && fs.existsSync(oldFilePath)) { this.renameOldDB(oldFilePath, selNode); } // For backward compatibility End this.insertSession(id); } - renameOldDB(oldFilePath: string, selNode: CommonSelectedNode = null) { - const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.ln_implementation + '-Offers.json'; + renameOldDB(oldFilePath: string, selNode: SelectedNode = null) { + const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.lnImplementation + '-Offers.json'; try { this.common.createDirectory(this.dbFilePath); const oldOffers: any = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8')); @@ -279,7 +279,7 @@ export class DatabaseAdapter { } catch (err) { throw new Error(JSON.stringify(err)); } - const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; + const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json'; try { if (!fs.existsSync(collectionFilePath)) { fs.writeFileSync(collectionFilePath, '[]'); @@ -291,17 +291,17 @@ export class DatabaseAdapter { const otherFiles = fs.readdirSync(this.dbFilePath); otherFiles.forEach((oFileName) => { let collectionValid = false; - switch (this.selNode.ln_implementation) { + switch (this.selNode.lnImplementation) { case 'CLN': - collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); + collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false); break; case 'ECL': - collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); + collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false); break; default: - collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); + collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false); break; } if (oFileName.endsWith('.json') && !collectionValid) { @@ -327,7 +327,7 @@ export class DatabaseAdapter { saveData(collectionName: string, collectionData: any) { try { if (collectionData) { - const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; + const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json'; const tempFile = collectionFilePath + '.tmp'; fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2)); fs.renameSync(tempFile, collectionFilePath); diff --git a/server/utils/logger.ts b/server/utils/logger.ts index d0259407..37f8c7fb 100644 --- a/server/utils/logger.ts +++ b/server/utils/logger.ts @@ -17,16 +17,16 @@ export class LoggerService { msgStr = msgStr + '.\r\n'; } console.error(msgStr); - if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } break; case 'WARN': msgStr = prepMsgData(msgJSON, msgStr); - if (!msgJSON.selectedNode || msgJSON.selectedNode.log_level === 'WARN' || msgJSON.selectedNode.log_level === 'INFO' || msgJSON.selectedNode.log_level === 'DEBUG') { - if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (!msgJSON.selectedNode || msgJSON.selectedNode.settings.logLevel === 'WARN' || msgJSON.selectedNode.settings.logLevel === 'INFO' || msgJSON.selectedNode.settings.logLevel === 'DEBUG') { + if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } } break; @@ -34,17 +34,17 @@ export class LoggerService { case 'INFO': if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') { console.log(msgStr + '.\r\n'); - } else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'INFO') { + } else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'INFO') { msgStr = msgStr + '.\r\n'; console.log(msgStr); - if (msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } - } else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { + } else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') { msgStr = prepMsgData(msgJSON, msgStr); console.log(msgStr); - if (msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } } break; @@ -52,11 +52,11 @@ export class LoggerService { case 'DEBUG': if (!msgJSON.selectedNode) { console.log(msgStr + '.\r\n'); - } else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { + } else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') { msgStr = prepMsgData(msgJSON, msgStr); console.log(msgStr); - if (msgJSON.selectedNode.log_file) { - fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); + if (msgJSON.selectedNode.settings.logFile) { + fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { }); } } break; diff --git a/server/utils/webSocketServer.ts b/server/utils/webSocketServer.ts index 4b8f6a72..80f0187d 100644 --- a/server/utils/webSocketServer.ts +++ b/server/utils/webSocketServer.ts @@ -6,7 +6,7 @@ import { Logger, LoggerService } from './logger.js'; import { Common, CommonService } from './common.js'; import { verifyWSUser } from './authCheck.js'; import { EventEmitter } from 'events'; -import { CommonSelectedNode } from '../models/config.model.js'; +import { SelectedNode } from '../models/config.model.js'; export class RTLWebSocketServer { @@ -32,7 +32,7 @@ export class RTLWebSocketServer { }, 1000 * 60 * 60); // Terminate broken connections every hour public mount = (httpServer) => { - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' }); this.webSocketServer = new WebSocketServer({ noServer: true, path: this.common.baseHref + '/api/ws', verifyClient: (process.env.NODE_ENV === 'development') ? null : verifyWSUser }); httpServer.on('upgrade', (request, socket, head) => { if (request.headers['upgrade'] !== 'websocket') { @@ -48,7 +48,7 @@ export class RTLWebSocketServer { }); this.webSocketServer.on('connection', this.mountEventsOnConnection); this.webSocketServer.on('close', () => clearInterval(this.pingInterval)); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' }); }; public upgradeCallback = (websocket, request) => { @@ -62,13 +62,13 @@ export class RTLWebSocketServer { websocket.isAlive = true; websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null; websocket.clientNodeIndex = +protocols[1]; - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); websocket.on('error', this.sendErrorToAllLNClients); websocket.on('message', this.sendEventsToAllLNClients); websocket.on('pong', () => { websocket.isAlive = true; }); websocket.on('close', (code, reason) => { this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex); - this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); + this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); }); }; @@ -87,7 +87,7 @@ export class RTLWebSocketServer { this.connectToNodeClient(sessionId, currNodeIndex); } else { const selectedNode = this.common.findNode(currNodeIndex); - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' }); } }; @@ -102,8 +102,8 @@ export class RTLWebSocketServer { const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex); this.clientDetails.splice(foundClientIdx, 1); const prevSelectedNode = this.common.findNode(prevNodeIndex); - if (prevSelectedNode && prevSelectedNode.ln_implementation) { - switch (prevSelectedNode.ln_implementation) { + if (prevSelectedNode && prevSelectedNode.lnImplementation) { + switch (prevSelectedNode.lnImplementation) { case 'LND': this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex); break; @@ -132,8 +132,8 @@ export class RTLWebSocketServer { const currSelectedNode = this.common.findNode(currNodeIndex); foundClient = { index: currNodeIndex, sessionIds: [sessionId] }; this.clientDetails.push(foundClient); - if (currSelectedNode && currSelectedNode.ln_implementation) { - switch (currSelectedNode.ln_implementation) { + if (currSelectedNode && currSelectedNode.lnImplementation) { + switch (currSelectedNode.lnImplementation) { case 'LND': this.eventEmitterLND.emit('CONNECT', currNodeIndex); break; @@ -150,29 +150,29 @@ export class RTLWebSocketServer { } }; - public sendErrorToAllLNClients = (serverError, selectedNode: CommonSelectedNode) => { + public sendErrorToAllLNClients = (serverError, selectedNode: SelectedNode) => { try { this.webSocketServer.clients.forEach((client) => { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError }); if (+client.clientNodeIndex === +selectedNode.index) { client.send(serverError); } }); } catch (err) { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); } }; - public sendEventsToAllLNClients = (newMessage, selectedNode: CommonSelectedNode) => { + public sendEventsToAllLNClients = (newMessage, selectedNode: SelectedNode) => { try { this.webSocketServer.clients.forEach((client) => { if (+client.clientNodeIndex === +selectedNode.index) { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage }); client.send(newMessage); } }); } catch (err) { - this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); + this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); } };