diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index e3220387..c704feaa 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -44,7 +44,7 @@ jobs: echo "GITHUB REF TYPE: ${{ github.ref_type }}" echo "GITHUB REF NAME: ${{ github.ref_name }}" echo "EVENT INPUT VERSION: ${{ github.event.inputs.version }}" - echo "ENV VERSION: ${{ env.VERSION }}" + echo "ENV VERSION: $VERSION" - name: Build and push Docker image uses: docker/build-push-action@v5 diff --git a/.gitignore b/.gitignore index 47d9f83e..b89a3f21 100644 --- a/.gitignore +++ b/.gitignore @@ -21,10 +21,6 @@ # IDE - VSCode .vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json # misc /.angular/cache diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 6f15dc13..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "pwa-node", - "request": "launch", - "name": "Launch Program", - "skipFiles": [ - "/**" - ], - "env": { - "NODE_ENV": "development" - }, - "program": "${workspaceFolder}/rtl.js" - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index fdc25922..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "eslint.enable": true, - "eslint.validate": [ - "typescript", - "HTML" - ], - "eslint.options": { - "configFile": ".eslintrc.json" - }, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } -} diff --git a/backend/controllers/shared/RTLConf.js b/backend/controllers/shared/RTLConf.js index e7095146..f8c78b4f 100644 --- a/backend/controllers/shared/RTLConf.js +++ b/backend/controllers/shared/RTLConf.js @@ -96,43 +96,33 @@ export const getFile = (req, res, next) => { }; export const getApplicationSettings = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' }); - const confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; - fs.readFile(confFile, 'utf8', (errRes, data) => { - if (errRes) { - 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 appConfData = common.removeSecureData(JSON.parse(data)); - appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate; - appConfData.enable2FA = common.appConfig.enable2FA; - appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index); - common.appConfig.selectedNodeIndex = appConfData.selectedNodeIndex; - const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : ''; - jwt.verify(token, common.secret_key, (err, user) => { - if (err) { - // Delete unnecessary data for initial response (without security token) - const selNodeIdx = appConfData.nodes.findIndex((node) => node.index === appConfData.selectedNodeIndex) || 0; - delete appConfData.SSO.rtlCookiePath; - delete appConfData.SSO.cookieValue; - delete appConfData.SSO.logoutRedirectLink; - appConfData.secret2FA = ''; - appConfData.dbDirectoryPath = ''; - appConfData.nodes[selNodeIdx].authentication = new Authentication(); - delete appConfData.nodes[selNodeIdx].settings.bitcoindConfigPath; - delete appConfData.nodes[selNodeIdx].settings.lnServerUrl; - delete appConfData.nodes[selNodeIdx].settings.swapServerUrl; - delete appConfData.nodes[selNodeIdx].settings.boltzServerUrl; - delete appConfData.nodes[selNodeIdx].settings.enableOffers; - delete appConfData.nodes[selNodeIdx].settings.enablePeerswap; - delete appConfData.nodes[selNodeIdx].settings.channelBackupPath; - appConfData.nodes = [appConfData.nodes[selNodeIdx]]; - } - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: appConfData }); - res.status(200).json(appConfData); - }); + const appConfData = common.removeSecureData(JSON.parse(JSON.stringify(common.appConfig))); + appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate; + appConfData.enable2FA = common.appConfig.enable2FA; + appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index); + common.appConfig.selectedNodeIndex = appConfData.selectedNodeIndex; + const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : ''; + jwt.verify(token, common.secret_key, (err, user) => { + if (err) { + // Delete unnecessary data for initial response (without security token) + const selNodeIdx = appConfData.nodes.findIndex((node) => node.index === appConfData.selectedNodeIndex) || 0; + delete appConfData.SSO.rtlCookiePath; + delete appConfData.SSO.cookieValue; + delete appConfData.SSO.logoutRedirectLink; + appConfData.secret2FA = ''; + appConfData.dbDirectoryPath = ''; + appConfData.nodes[selNodeIdx].authentication = new Authentication(); + delete appConfData.nodes[selNodeIdx].settings.bitcoindConfigPath; + delete appConfData.nodes[selNodeIdx].settings.lnServerUrl; + delete appConfData.nodes[selNodeIdx].settings.swapServerUrl; + delete appConfData.nodes[selNodeIdx].settings.boltzServerUrl; + delete appConfData.nodes[selNodeIdx].settings.enableOffers; + delete appConfData.nodes[selNodeIdx].settings.enablePeerswap; + delete appConfData.nodes[selNodeIdx].settings.channelBackupPath; + appConfData.nodes = [appConfData.nodes[selNodeIdx]]; } + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: appConfData }); + res.status(200).json(appConfData); }); }; export const updateSelectedNode = (req, res, next) => { diff --git a/backend/controllers/shared/authenticate.js b/backend/controllers/shared/authenticate.js index 3dbf8a1e..7ffa4bb1 100644 --- a/backend/controllers/shared/authenticate.js +++ b/backend/controllers/shared/authenticate.js @@ -48,7 +48,7 @@ export const verifyToken = (twoFAToken) => !!(common.appConfig.secret2FA && comm 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.appConfig.SSO.rtlSso) { + 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.' }); @@ -103,7 +103,7 @@ 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.appConfig.SSO.rtlSso) { + 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 }); diff --git a/backend/models/config.model.js b/backend/models/config.model.js index c3cb8ead..9a66e2d4 100644 --- a/backend/models/config.model.js +++ b/backend/models/config.model.js @@ -1,6 +1,6 @@ export class SSO { - constructor(rtlSso, rtlCookiePath, logoutRedirectLink, cookieValue) { - this.rtlSso = rtlSso; + constructor(rtlSSO, rtlCookiePath, logoutRedirectLink, cookieValue) { + this.rtlSSO = rtlSSO; this.rtlCookiePath = rtlCookiePath; this.logoutRedirectLink = logoutRedirectLink; this.cookieValue = cookieValue; diff --git a/backend/utils/common.js b/backend/utils/common.js index bfc11e9e..d3994801 100644 --- a/backend/utils/common.js +++ b/backend/utils/common.js @@ -9,7 +9,7 @@ export class CommonService { this.logger = Logger; this.nodes = []; this.selectedNode = null; - this.ssoInit = { rtlSso: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' }; + this.ssoInit = { rtlSSO: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' }; this.appConfig = { defaultNodeIndex: 0, selectedNodeIndex: 0, rtlConfFilePath: '', dbDirectoryPath: join(dirname(fileURLToPath(import.meta.url)), '..', '..'), rtlPass: '', allowPasswordUpdate: true, enable2FA: false, secret2FA: '', SSO: this.ssoInit, nodes: [] }; this.port = 3000; this.host = ''; @@ -528,7 +528,7 @@ export class CommonService { const selNode = req.session.selectedNode; if (selNode && selNode.index) { this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup:', msg: JSON.stringify(this.removeSecureData(JSON.parse(JSON.stringify(this.appConfig)))) }); - 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: 'SSO: ' + this.appConfig.SSO.rtlSSO }); } }; this.filterData = (dataKey, lnImplementation) => { diff --git a/backend/utils/config.js b/backend/utils/config.js index 8267cc30..60f3d0d9 100644 --- a/backend/utils/config.js +++ b/backend/utils/config.js @@ -318,10 +318,10 @@ export class ConfigService { }; this.setSSOParams = (config) => { if (process?.env?.RTL_SSO) { - config.SSO.rtlSso = +process?.env?.RTL_SSO; + config.SSO.rtlSSO = +process?.env?.RTL_SSO; } else if (config.SSO && config.SSO.rtlSSO) { - config.SSO.rtlSso = config.SSO.rtlSSO; + config.SSO.rtlSSO = config.SSO.rtlSSO; } if (process?.env?.RTL_COOKIE_PATH) { config.SSO.rtlCookiePath = process?.env?.RTL_COOKIE_PATH; @@ -338,7 +338,7 @@ export class ConfigService { else if (config.SSO && config.SSO.logoutRedirectLink) { config.SSO.logoutRedirectLink = config.SSO.logoutRedirectLink; } - if (+config.SSO.rtlSso) { + if (+config.SSO.rtlSSO) { if (!config.SSO.rtlCookiePath || config.SSO.rtlCookiePath.trim() === '') { this.errMsg = 'Please set rtlCookiePath value for single sign on option!'; } diff --git a/server/controllers/shared/RTLConf.ts b/server/controllers/shared/RTLConf.ts index 7e3c7ae0..f698db4f 100644 --- a/server/controllers/shared/RTLConf.ts +++ b/server/controllers/shared/RTLConf.ts @@ -99,42 +99,33 @@ export const getFile = (req, res, next) => { export const getApplicationSettings = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' }); - const confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json'; - fs.readFile(confFile, 'utf8', (errRes, data) => { - if (errRes) { - 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 appConfData = common.removeSecureData(JSON.parse(data)); - appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate; - appConfData.enable2FA = common.appConfig.enable2FA; - appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index); - common.appConfig.selectedNodeIndex = appConfData.selectedNodeIndex; - const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : ''; - jwt.verify(token, common.secret_key, (err, user) => { - if (err) { - // Delete unnecessary data for initial response (without security token) - const selNodeIdx = appConfData.nodes.findIndex((node) => node.index === appConfData.selectedNodeIndex) || 0; - delete appConfData.SSO.rtlCookiePath; - delete appConfData.SSO.cookieValue; - delete appConfData.SSO.logoutRedirectLink; - appConfData.secret2FA = ''; - appConfData.dbDirectoryPath = ''; - appConfData.nodes[selNodeIdx].authentication = new Authentication(); - delete appConfData.nodes[selNodeIdx].settings.bitcoindConfigPath; - delete appConfData.nodes[selNodeIdx].settings.lnServerUrl; - delete appConfData.nodes[selNodeIdx].settings.swapServerUrl; - delete appConfData.nodes[selNodeIdx].settings.boltzServerUrl; - delete appConfData.nodes[selNodeIdx].settings.enableOffers; - delete appConfData.nodes[selNodeIdx].settings.enablePeerswap; - delete appConfData.nodes[selNodeIdx].settings.channelBackupPath; - appConfData.nodes = [appConfData.nodes[selNodeIdx]]; - } - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: appConfData }); - res.status(200).json(appConfData); - }); + const appConfData = common.removeSecureData(JSON.parse(JSON.stringify(common.appConfig))); + appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate; + appConfData.enable2FA = common.appConfig.enable2FA; + appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index); + common.appConfig.selectedNodeIndex = appConfData.selectedNodeIndex; + const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : ''; + jwt.verify(token, common.secret_key, (err, user) => { + if (err) { + // Delete unnecessary data for initial response (without security token) + const selNodeIdx = appConfData.nodes.findIndex((node) => node.index === appConfData.selectedNodeIndex) || 0; + delete appConfData.SSO.rtlCookiePath; + delete appConfData.SSO.cookieValue; + delete appConfData.SSO.logoutRedirectLink; + appConfData.secret2FA = ''; + appConfData.dbDirectoryPath = ''; + appConfData.nodes[selNodeIdx].authentication = new Authentication(); + delete appConfData.nodes[selNodeIdx].settings.bitcoindConfigPath; + delete appConfData.nodes[selNodeIdx].settings.lnServerUrl; + delete appConfData.nodes[selNodeIdx].settings.swapServerUrl; + delete appConfData.nodes[selNodeIdx].settings.boltzServerUrl; + delete appConfData.nodes[selNodeIdx].settings.enableOffers; + delete appConfData.nodes[selNodeIdx].settings.enablePeerswap; + delete appConfData.nodes[selNodeIdx].settings.channelBackupPath; + appConfData.nodes = [appConfData.nodes[selNodeIdx]]; } + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: appConfData }); + res.status(200).json(appConfData); }); }; diff --git a/server/controllers/shared/authenticate.ts b/server/controllers/shared/authenticate.ts index 607b2320..af1716b1 100644 --- a/server/controllers/shared/authenticate.ts +++ b/server/controllers/shared/authenticate.ts @@ -52,7 +52,7 @@ export const verifyToken = (twoFAToken) => !!(common.appConfig.secret2FA && comm 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.appConfig.SSO.rtlSso) { + 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.' }); @@ -100,7 +100,7 @@ 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.appConfig.SSO.rtlSso) { + 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 }); diff --git a/server/models/config.model.ts b/server/models/config.model.ts index ca53fbe0..c9761292 100644 --- a/server/models/config.model.ts +++ b/server/models/config.model.ts @@ -1,7 +1,7 @@ export class SSO { constructor( - public rtlSso?: number, + public rtlSSO?: number, public rtlCookiePath?: string, public logoutRedirectLink?: string, public cookieValue?: string diff --git a/server/utils/common.ts b/server/utils/common.ts index d3f8e34d..fa48031b 100644 --- a/server/utils/common.ts +++ b/server/utils/common.ts @@ -11,7 +11,7 @@ export class CommonService { public logger: LoggerService = Logger; public nodes: SelectedNode[] = []; public selectedNode: SelectedNode = null; - public ssoInit = { rtlSso: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' }; + 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, enable2FA: false, secret2FA: '', SSO: this.ssoInit, nodes: [] }; public port = 3000; public host = ''; @@ -542,7 +542,7 @@ export class CommonService { const selNode = req.session.selectedNode; if (selNode && selNode.index) { this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup:', msg: JSON.stringify(this.removeSecureData(JSON.parse(JSON.stringify(this.appConfig)))) }); - 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: 'SSO: ' + this.appConfig.SSO.rtlSSO }); } }; diff --git a/server/utils/config.ts b/server/utils/config.ts index a8abab3e..36456dfe 100644 --- a/server/utils/config.ts +++ b/server/utils/config.ts @@ -298,9 +298,9 @@ export class ConfigService { private setSSOParams = (config) => { if (process?.env?.RTL_SSO) { - config.SSO.rtlSso = +process?.env?.RTL_SSO; + config.SSO.rtlSSO = +process?.env?.RTL_SSO; } else if (config.SSO && config.SSO.rtlSSO) { - config.SSO.rtlSso = config.SSO.rtlSSO; + config.SSO.rtlSSO = config.SSO.rtlSSO; } if (process?.env?.RTL_COOKIE_PATH) { @@ -317,7 +317,7 @@ export class ConfigService { config.SSO.logoutRedirectLink = config.SSO.logoutRedirectLink; } - if (+config.SSO.rtlSso) { + if (+config.SSO.rtlSSO) { if (!config.SSO.rtlCookiePath || config.SSO.rtlCookiePath.trim() === '') { this.errMsg = 'Please set rtlCookiePath value for single sign on option!'; } else {