2019-04-06 02:52:00 +00:00
var os = require ( 'os' ) ;
2018-09-15 01:31:01 +00:00
var fs = require ( 'fs' ) ;
2019-03-31 15:39:41 +00:00
var platform = require ( 'os' ) . platform ( ) ;
2019-02-24 13:16:41 +00:00
var crypto = require ( 'crypto' ) ;
2019-05-07 01:56:11 +00:00
var hash = crypto . createHash ( 'sha256' ) ;
2019-01-01 16:26:51 +00:00
var common = require ( './common' ) ;
2019-01-01 20:47:32 +00:00
var path = require ( 'path' ) ;
2021-06-20 20:27:08 +00:00
var logger = require ( '../controllers/shared/logger' ) ;
2019-03-02 17:55:19 +00:00
var connect = { } ;
2019-04-06 02:52:00 +00:00
var errMsg = '' ;
2021-06-20 20:27:08 +00:00
var request = require ( 'request-promise' ) ;
2020-01-21 03:22:03 +00:00
var ini = require ( 'ini' ) ;
2020-10-12 22:43:16 +00:00
var parseHocon = require ( 'hocon-parser' ) ;
2019-07-28 18:00:15 +00:00
common . path _separator = ( platform === 'win32' ) ? '\\' : '/' ;
2019-01-01 16:26:51 +00:00
2019-04-06 02:52:00 +00:00
connect . setDefaultConfig = ( ) => {
var homeDir = os . userInfo ( ) . homedir ;
2019-03-17 21:53:25 +00:00
var macaroonPath = '' ;
2019-09-02 04:11:37 +00:00
var configPath = '' ;
2020-01-21 03:22:03 +00:00
var channelBackupPath = '' ;
2019-03-31 15:39:41 +00:00
switch ( platform ) {
case 'win32' :
2019-04-06 02:52:00 +00:00
macaroonPath = homeDir + '\\AppData\\Local\\Lnd\\data\\chain\\bitcoin\\mainnet' ;
2019-09-02 04:11:37 +00:00
configPath = homeDir + '\\AppData\\Local\\Lnd\\lnd.conf' ;
2019-11-14 04:09:14 +00:00
channelBackupPath = homeDir + '\\backup\\node-1' ;
2019-03-31 15:39:41 +00:00
break ;
case 'darwin' :
2019-04-06 02:52:00 +00:00
macaroonPath = homeDir + '/Library/Application Support/Lnd/data/chain/bitcoin/mainnet' ;
2019-09-02 04:11:37 +00:00
configPath = homeDir + '/Library/Application Support/Lnd/lnd.conf' ;
2019-11-14 04:09:14 +00:00
channelBackupPath = homeDir + '/backup/node-1' ;
2019-03-31 15:39:41 +00:00
break ;
case 'linux' :
2019-04-06 02:52:00 +00:00
macaroonPath = homeDir + '/.lnd/data/chain/bitcoin/mainnet' ;
2019-09-02 04:11:37 +00:00
configPath = homeDir + '/.lnd/lnd.conf' ;
2019-11-14 04:09:14 +00:00
channelBackupPath = homeDir + '/backup/node-1' ;
2019-03-31 15:39:41 +00:00
break ;
default :
macaroonPath = '' ;
2019-09-02 04:11:37 +00:00
configPath = '' ;
2019-11-14 04:09:14 +00:00
channelBackupPath = '' ;
2019-03-31 15:39:41 +00:00
break ;
2021-08-06 21:00:57 +00:00
}
2019-03-17 21:53:25 +00:00
return {
2020-01-20 16:15:04 +00:00
multiPass : "password" ,
port : "3000" ,
defaultNodeIndex : 1 ,
2019-03-17 21:53:25 +00:00
SSO : {
rtlSSO : 0 ,
2019-11-14 04:09:14 +00:00
rtlCookiePath : "" ,
logoutRedirectLink : ""
} ,
2020-01-20 16:15:04 +00:00
nodes : [
{
index : 1 ,
2020-01-21 03:22:03 +00:00
lnNode : "Node 1" ,
2021-08-06 21:00:57 +00:00
lnImplementation : "LND" ,
2020-01-20 16:15:04 +00:00
Authentication : {
macaroonPath : macaroonPath ,
configPath : configPath ,
} ,
Settings : {
userPersona : 'MERCHANT' ,
themeMode : "DAY" ,
themeColor : "PURPLE" ,
channelBackupPath : channelBackupPath ,
2021-08-06 21:00:57 +00:00
logLevel : "ERROR" ,
2020-08-18 14:34:40 +00:00
lnServerUrl : "https://localhost:8080" ,
2020-01-20 16:15:04 +00:00
fiatConversion : false
}
}
]
}
2019-03-17 21:53:25 +00:00
}
2019-02-16 22:43:12 +00:00
2019-04-06 02:52:00 +00:00
connect . normalizePort = val => {
2019-02-16 22:43:12 +00:00
var port = parseInt ( val , 10 ) ;
if ( isNaN ( port ) ) {
return val ;
2019-01-01 16:26:51 +00:00
}
2019-02-16 22:43:12 +00:00
if ( port >= 0 ) {
return port ;
}
return false ;
2019-01-01 16:26:51 +00:00
} ;
2018-09-15 01:31:01 +00:00
2020-01-22 00:18:34 +00:00
connect . replacePasswordWithHash = ( multiPassHashed ) => {
2021-06-20 20:27:08 +00:00
common . rtl _conf _file _path = process . env . RTL _CONFIG _PATH ? process . env . RTL _CONFIG _PATH : path . join ( _ _dirname , '..' ) ;
2020-01-20 16:15:04 +00:00
try {
2021-08-06 21:00:57 +00:00
RTLConfFile = common . rtl _conf _file _path + common . path _separator + 'RTL-Config.json' ;
2020-01-20 16:15:04 +00:00
var config = JSON . parse ( fs . readFileSync ( RTLConfFile , 'utf-8' ) ) ;
2020-01-22 00:18:34 +00:00
config . multiPassHashed = multiPassHashed ;
2020-01-20 16:15:04 +00:00
delete config . multiPass ;
fs . writeFileSync ( RTLConfFile , JSON . stringify ( config , null , 2 ) , 'utf-8' ) ;
console . log ( 'Please note that, RTL has encrypted the plaintext password into its corresponding hash.' ) ;
return config . multiPassHashed ;
} catch ( err ) {
errMsg = errMsg + '\nPassword hashing failed!' ;
2019-04-06 22:42:09 +00:00
}
2019-01-01 16:26:51 +00:00
}
2021-08-06 21:00:57 +00:00
connect . updateLogByLevel = ( ) => {
updateLogFlag = false ;
common . rtl _conf _file _path = process . env . RTL _CONFIG _PATH ? process . env . RTL _CONFIG _PATH : path . join ( _ _dirname , '..' ) ;
try {
RTLConfFile = common . rtl _conf _file _path + common . path _separator + 'RTL-Config.json' ;
var config = JSON . parse ( fs . readFileSync ( RTLConfFile , 'utf-8' ) ) ;
config . nodes . forEach ( ( node ) => {
2021-08-17 11:21:01 +00:00
if ( node . Settings . hasOwnProperty ( 'enableLogging' ) ) {
2021-08-06 21:00:57 +00:00
updateLogFlag = true ;
node . Settings . logLevel = node . Settings . enableLogging ? 'INFO' : 'ERROR' ;
delete node . Settings . enableLogging ;
}
} )
2021-08-17 11:21:01 +00:00
if ( updateLogFlag ) {
2021-08-06 21:00:57 +00:00
fs . writeFileSync ( RTLConfFile , JSON . stringify ( config , null , 2 ) , 'utf-8' ) ;
}
} catch ( err ) {
errMsg = errMsg + '\nLog level update failed!' ;
}
}
2020-01-20 16:15:04 +00:00
connect . validateNodeConfig = ( config ) => {
2021-08-06 21:00:57 +00:00
if ( ( process . env . RTL _SSO == 0 ) || ( typeof process . env . RTL _SSO === 'undefined' && + config . SSO . rtlSSO === 0 ) ) {
2020-01-22 00:44:42 +00:00
if ( config . multiPassHashed !== '' && config . multiPassHashed ) {
2019-11-06 17:39:55 +00:00
common . rtl _pass = config . multiPassHashed ;
2020-01-17 18:45:01 +00:00
} else if ( config . multiPass !== '' && config . multiPass ) {
2020-01-22 00:18:34 +00:00
common . rtl _pass = connect . replacePasswordWithHash ( hash . update ( config . multiPass ) . digest ( 'hex' ) ) ;
2019-04-06 02:52:00 +00:00
} else {
2020-01-20 16:15:04 +00:00
errMsg = errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json' ;
2019-04-06 02:52:00 +00:00
}
2020-03-19 01:48:53 +00:00
common . rtl _secret2fa = config . secret2fa ;
2019-05-07 01:56:11 +00:00
}
2020-01-21 22:04:26 +00:00
common . port = ( process . env . PORT ) ? connect . normalizePort ( process . env . PORT ) : ( config . port ) ? connect . normalizePort ( config . port ) : 3000 ;
2020-05-09 17:15:10 +00:00
common . host = ( process . env . HOST ) ? process . env . HOST : ( config . host ) ? config . host : null ;
2019-10-27 20:39:40 +00:00
if ( config . nodes && config . nodes . length > 0 ) {
config . nodes . forEach ( ( node , idx ) => {
common . nodes [ idx ] = { } ;
2020-07-07 17:57:15 +00:00
common . nodes [ idx ] . index = node . index ;
common . nodes [ idx ] . ln _node = node . lnNode ;
common . nodes [ idx ] . ln _implementation = ( process . env . LN _IMPLEMENTATION ) ? process . env . LN _IMPLEMENTATION : node . lnImplementation ? node . lnImplementation : 'LND' ;
if ( common . nodes [ idx ] . ln _implementation !== 'ECL' && process . env . MACAROON _PATH && process . env . MACAROON _PATH . trim ( ) !== '' ) {
2020-01-21 22:04:26 +00:00
common . nodes [ idx ] . macaroon _path = process . env . MACAROON _PATH ;
2021-08-06 21:00:57 +00:00
} else if ( common . nodes [ idx ] . ln _implementation !== 'ECL' && node . Authentication && node . Authentication . macaroonPath && node . Authentication . macaroonPath . trim ( ) !== '' ) {
2019-10-27 20:39:40 +00:00
common . nodes [ idx ] . macaroon _path = node . Authentication . macaroonPath ;
2020-07-07 17:57:15 +00:00
} else if ( common . nodes [ idx ] . ln _implementation !== 'ECL' ) {
2020-01-21 22:04:26 +00:00
errMsg = 'Please set macaroon path for node index ' + node . index + ' in RTL-Config.json!' ;
2019-10-27 20:39:40 +00:00
}
2019-04-06 02:52:00 +00:00
2020-07-12 19:47:42 +00:00
if ( common . nodes [ idx ] . ln _implementation === 'ECL' ) {
if ( process . env . LN _API _PASSWORD ) {
common . nodes [ idx ] . ln _api _password = process . env . LN _API _PASSWORD ;
} else if ( node . Authentication && node . Authentication . lnApiPassword ) {
common . nodes [ idx ] . ln _api _password = node . Authentication . lnApiPassword ;
} else {
common . nodes [ idx ] . ln _api _password = '' ;
}
}
2020-07-07 17:57:15 +00:00
if ( process . env . CONFIG _PATH ) {
common . nodes [ idx ] . config _path = process . env . CONFIG _PATH ;
} else if ( process . env . LND _CONFIG _PATH ) {
common . nodes [ idx ] . config _path = process . env . LND _CONFIG _PATH ;
} else if ( node . Authentication && node . Authentication . lndConfigPath ) {
common . nodes [ idx ] . config _path = node . Authentication . lndConfigPath ;
} else if ( node . Authentication && node . Authentication . configPath ) {
common . nodes [ idx ] . config _path = node . Authentication . configPath ;
} else {
common . nodes [ idx ] . config _path = '' ;
}
2020-07-17 00:44:55 +00:00
if ( common . nodes [ idx ] . ln _implementation === 'ECL' && common . nodes [ idx ] . ln _api _password === '' && common . nodes [ idx ] . config _path !== '' ) {
2020-07-12 19:47:42 +00:00
try {
let exists = fs . existsSync ( common . nodes [ idx ] . config _path ) ;
if ( exists ) {
try {
2020-10-12 22:43:16 +00:00
let configFile = fs . readFileSync ( common . nodes [ idx ] . config _path , 'utf-8' ) ;
let iniParsed = ini . parse ( configFile ) ;
common . nodes [ idx ] . ln _api _password = iniParsed [ 'eclair.api.password' ] ? iniParsed [ 'eclair.api.password' ] : parseHocon ( configFile ) . eclair . api . password ;
2020-07-12 19:47:42 +00:00
} catch ( err ) {
errMsg = errMsg + '\nSomething went wrong while reading config file: \n' + err ;
}
} else {
errMsg = errMsg + '\nInvalid config path: ' + common . nodes [ idx ] . config _path ;
2021-08-06 21:00:57 +00:00
}
2020-07-12 19:47:42 +00:00
} catch ( err ) {
errMsg = errMsg + '\nUnable to read config file: \n' + err ;
}
}
if ( common . nodes [ idx ] . ln _implementation === 'ECL' && common . nodes [ idx ] . ln _api _password === '' ) {
errMsg = errMsg + '\nPlease set config path Or api password for node index ' + node . index + ' in RTL-Config.json! It is mandatory for Eclair authentication!' ;
2020-07-07 17:57:15 +00:00
}
2021-08-06 21:00:57 +00:00
if ( process . env . LN _SERVER _URL && process . env . LN _SERVER _URL . trim ( ) !== '' ) {
2020-08-18 14:34:40 +00:00
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 ;
2021-08-06 21:00:57 +00:00
} else if ( process . env . LND _SERVER _URL && process . env . LND _SERVER _URL . trim ( ) !== '' ) {
2020-08-18 14:34:40 +00:00
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 ;
2021-08-06 21:00:57 +00:00
} else if ( node . Settings . lnServerUrl && node . Settings . lnServerUrl . trim ( ) !== '' ) {
2020-08-18 14:34:40 +00:00
common . nodes [ idx ] . ln _server _url = node . Settings . lnServerUrl . endsWith ( '/v1' ) ? node . Settings . lnServerUrl . slice ( 0 , - 3 ) : node . Settings . lnServerUrl ;
2021-08-06 21:00:57 +00:00
} else if ( node . Settings . lndServerUrl && node . Settings . lndServerUrl . trim ( ) !== '' ) {
2020-08-18 14:34:40 +00:00
common . nodes [ idx ] . ln _server _url = node . Settings . lndServerUrl . endsWith ( '/v1' ) ? node . Settings . lndServerUrl . slice ( 0 , - 3 ) : node . Settings . lndServerUrl ;
2019-10-27 20:39:40 +00:00
} else {
2020-01-21 22:04:26 +00:00
errMsg = errMsg + '\nPlease set LN Server URL for node index ' + node . index + ' in RTL-Config.json!' ;
2019-10-27 20:39:40 +00:00
}
2020-01-21 22:04:26 +00:00
common . nodes [ idx ] . user _persona = node . Settings . userPersona ? node . Settings . userPersona : 'MERCHANT' ;
common . nodes [ idx ] . theme _mode = node . Settings . themeMode ? node . Settings . themeMode : 'DAY' ;
common . nodes [ idx ] . theme _color = node . Settings . themeColor ? node . Settings . themeColor : 'PURPLE' ;
2021-08-06 21:00:57 +00:00
common . nodes [ idx ] . log _level = node . Settings . logLevel ? node . Settings . logLevel : 'ERROR'
2020-01-21 22:04:26 +00:00
common . nodes [ idx ] . fiat _conversion = node . Settings . fiatConversion ? ! ! node . Settings . fiatConversion : false ;
2021-08-06 21:00:57 +00:00
if ( common . nodes [ idx ] . fiat _conversion ) {
2020-01-10 03:50:02 +00:00
common . nodes [ idx ] . currency _unit = node . Settings . currencyUnit ? node . Settings . currencyUnit : 'USD' ;
}
2021-08-06 21:00:57 +00:00
if ( process . env . SWAP _SERVER _URL && process . env . SWAP _SERVER _URL . trim ( ) !== '' ) {
2020-08-18 14:34:40 +00:00
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 ;
2020-12-20 23:36:04 +00:00
common . nodes [ idx ] . swap _macaroon _path = process . env . SWAP _MACAROON _PATH ;
2021-08-06 21:00:57 +00:00
} else if ( node . Settings . swapServerUrl && node . Settings . swapServerUrl . trim ( ) !== '' ) {
2020-08-18 14:34:40 +00:00
common . nodes [ idx ] . swap _server _url = node . Settings . swapServerUrl . endsWith ( '/v1' ) ? node . Settings . swapServerUrl . slice ( 0 , - 3 ) : node . Settings . swapServerUrl ;
2020-12-20 23:36:04 +00:00
common . nodes [ idx ] . swap _macaroon _path = node . Authentication . swapMacaroonPath ? node . Authentication . swapMacaroonPath : '' ;
2020-08-18 14:34:40 +00:00
} else {
common . nodes [ idx ] . swap _server _url = '' ;
2020-12-20 23:36:04 +00:00
common . nodes [ idx ] . swap _macaroon _path = '' ;
2020-08-18 14:34:40 +00:00
}
2021-08-06 21:00:57 +00:00
if ( process . env . BOLTZ _SERVER _URL && process . env . BOLTZ _SERVER _URL . trim ( ) !== '' ) {
2021-02-21 19:02:31 +00:00
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 ;
common . nodes [ idx ] . boltz _macaroon _path = process . env . BOLTZ _MACAROON _PATH ;
2021-08-06 21:00:57 +00:00
} else if ( node . Settings . boltzServerUrl && node . Settings . boltzServerUrl . trim ( ) !== '' ) {
2021-02-21 19:02:31 +00:00
common . nodes [ idx ] . boltz _server _url = node . Settings . boltzServerUrl . endsWith ( '/v1' ) ? node . Settings . boltzServerUrl . slice ( 0 , - 3 ) : node . Settings . boltzServerUrl ;
common . nodes [ idx ] . boltz _macaroon _path = node . Authentication . boltzMacaroonPath ? node . Authentication . boltzMacaroonPath : '' ;
} else {
common . nodes [ idx ] . boltz _server _url = '' ;
common . nodes [ idx ] . boltz _macaroon _path = '' ;
}
2020-01-21 22:04:26 +00:00
common . nodes [ idx ] . bitcoind _config _path = process . env . BITCOIND _CONFIG _PATH ? process . env . BITCOIND _CONFIG _PATH : ( node . Settings . bitcoindConfigPath ) ? node . Settings . bitcoindConfigPath : '' ;
common . nodes [ idx ] . channel _backup _path = process . env . CHANNEL _BACKUP _PATH ? process . env . CHANNEL _BACKUP _PATH : ( node . Settings . channelBackupPath ) ? node . Settings . channelBackupPath : common . rtl _conf _file _path + common . path _separator + 'backup' + common . path _separator + 'node-' + node . index ;
2019-10-27 20:39:40 +00:00
try {
connect . createDirectory ( common . nodes [ idx ] . channel _backup _path ) ;
let exists = fs . existsSync ( common . nodes [ idx ] . channel _backup _path + common . path _separator + 'channel-all.bak' ) ;
if ( ! exists ) {
try {
var createStream = fs . createWriteStream ( common . nodes [ idx ] . channel _backup _path + common . path _separator + 'channel-all.bak' ) ;
createStream . end ( ) ;
} catch ( err ) {
console . error ( 'Something went wrong while creating backup file: \n' + err ) ;
}
2021-08-06 21:00:57 +00:00
}
2019-10-27 20:39:40 +00:00
} catch ( err ) {
2020-01-21 03:22:03 +00:00
console . error ( 'Something went wrong while creating the backup directory: \n' + err ) ;
2019-10-27 20:39:40 +00:00
}
2021-08-17 11:21:01 +00:00
common . nodes [ idx ] . log _file = common . rtl _conf _file _path + '/logs/RTL-Node-' + node . index + '.log' ;
const log _file = common . nodes [ idx ] . log _file ;
if ( fs . existsSync ( log _file ) ) {
fs . writeFile ( log _file , '' , ( ) => { } ) ;
} else {
try {
var dirname = path . dirname ( log _file ) ;
connect . createDirectory ( dirname ) ;
var createStream = fs . createWriteStream ( log _file ) ;
createStream . end ( ) ;
2019-04-06 02:52:00 +00:00
}
2021-08-17 11:21:01 +00:00
catch ( err ) {
console . error ( 'Something went wrong while creating log file ' + log _file + ': \n' + err ) ;
}
}
2019-10-27 20:39:40 +00:00
} ) ;
}
2019-04-06 02:52:00 +00:00
connect . setSSOParams ( config ) ;
2021-08-06 21:00:57 +00:00
if ( errMsg && errMsg . trim ( ) !== '' ) { throw new Error ( errMsg ) ; }
2019-04-06 02:52:00 +00:00
}
connect . setSSOParams = ( config ) => {
2021-08-06 21:00:57 +00:00
if ( process . env . RTL _SSO ) {
common . rtl _sso = process . env . RTL _SSO ;
} else if ( config . SSO && config . SSO . rtlSSO ) {
common . rtl _sso = config . SSO . rtlSSO ;
}
2021-02-21 19:02:31 +00:00
if ( process . env . RTL _COOKIE _PATH ) {
common . rtl _cookie _path = process . env . RTL _COOKIE _PATH ;
} else if ( config . SSO && config . SSO . rtlCookiePath ) {
common . rtl _cookie _path = config . SSO . rtlCookiePath ;
} else {
common . rtl _cookie _path = '' ;
}
2019-02-12 13:36:04 +00:00
2021-02-21 19:02:31 +00:00
if ( process . env . LOGOUT _REDIRECT _LINK ) {
common . logout _redirect _link = process . env . LOGOUT _REDIRECT _LINK ;
} else if ( config . SSO && config . SSO . logoutRedirectLink ) {
common . logout _redirect _link = config . SSO . logoutRedirectLink ;
}
2020-03-10 17:25:52 +00:00
2021-02-21 19:02:31 +00:00
if ( + common . rtl _sso ) {
2020-03-10 17:25:52 +00:00
if ( ! common . rtl _cookie _path || common . rtl _cookie _path . trim ( ) === '' ) {
2019-11-06 00:26:40 +00:00
errMsg = 'Please set rtlCookiePath value for single sign on option!' ;
} else {
connect . readCookie ( common . rtl _cookie _path ) ;
}
2019-02-12 13:36:04 +00:00
}
} ;
2019-04-06 02:52:00 +00:00
connect . createDirectory = ( dirname ) => {
2020-05-03 19:54:26 +00:00
const initDir = path . isAbsolute ( dirname ) ? path . sep : '' ;
dirname . split ( path . sep ) . reduce ( ( parentDir , childDir ) => {
const curDir = path . resolve ( parentDir , childDir ) ;
try {
2020-05-04 03:32:19 +00:00
if ( ! fs . existsSync ( curDir ) ) {
fs . mkdirSync ( curDir ) ;
}
2020-05-03 19:54:26 +00:00
} catch ( err ) {
if ( err . code !== 'EEXIST' ) {
if ( err . code === 'ENOENT' ) {
throw new Error ( ` ENOENT: No such file or directory, mkdir ' ${ dirname } '. Ensure that channel backup path separator is ' ${ ( platform === 'win32' ) ? '\\\\' : '/' } ' ` ) ;
} else {
throw err ;
}
2019-06-17 21:26:46 +00:00
}
2019-02-12 13:36:04 +00:00
}
2020-05-03 19:54:26 +00:00
return curDir ;
} , initDir ) ;
2019-02-12 13:36:04 +00:00
}
2019-04-06 02:52:00 +00:00
connect . readCookie = ( cookieFile ) => {
2019-02-12 13:36:04 +00:00
let exists = fs . existsSync ( cookieFile ) ;
if ( exists ) {
2019-11-06 00:26:40 +00:00
try {
common . cookie = fs . readFileSync ( cookieFile , 'utf-8' ) ;
} catch ( err ) {
console . error ( 'Something went wrong while reading cookie: \n' + err ) ;
throw new Error ( err ) ;
}
2019-02-12 13:36:04 +00:00
} else {
try {
var dirname = path . dirname ( cookieFile ) ;
2019-04-06 02:52:00 +00:00
connect . createDirectory ( dirname ) ;
2019-02-24 13:16:41 +00:00
fs . writeFileSync ( cookieFile , crypto . randomBytes ( 64 ) . toString ( 'hex' ) ) ;
2019-02-12 13:36:04 +00:00
common . cookie = fs . readFileSync ( cookieFile , 'utf-8' ) ;
}
2021-08-06 21:00:57 +00:00
catch ( err ) {
2019-11-06 17:39:55 +00:00
console . error ( 'Something went wrong while reading the cookie: \n' + err ) ;
2019-02-12 13:36:04 +00:00
throw new Error ( err ) ;
}
}
}
2019-04-06 02:52:00 +00:00
connect . refreshCookie = ( cookieFile ) => {
try {
fs . writeFileSync ( cookieFile , crypto . randomBytes ( 64 ) . toString ( 'hex' ) ) ;
common . cookie = fs . readFileSync ( cookieFile , 'utf-8' ) ;
}
2021-08-06 21:00:57 +00:00
catch ( err ) {
2019-04-06 02:52:00 +00:00
console . error ( 'Something went wrong while refreshing cookie: \n' + err ) ;
throw new Error ( err ) ;
}
2019-02-12 13:36:04 +00:00
}
2019-04-06 02:52:00 +00:00
connect . logEnvVariables = ( ) => {
2021-08-17 11:21:01 +00:00
if ( common . selectedNode && common . selectedNode . index ) {
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'PORT: ' + common . port } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'HOST: ' + common . host } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'SSO: ' + common . rtl _sso } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'DEFAULT NODE INDEX: ' + common . selectedNode . index } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'INDEX: ' + common . selectedNode . index } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'LN NODE: ' + common . selectedNode . ln _node } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'LN IMPLEMENTATION: ' + common . selectedNode . ln _implementation } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'FIAT CONVERSION: ' + common . selectedNode . fiat _conversion } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'CURRENCY UNIT: ' + common . selectedNode . currency _unit } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'LN SERVER URL: ' + common . selectedNode . ln _server _url } ) ;
logger . log ( { level : 'DEBUG' , fileName : 'Config Setup Variable' , msg : 'LOGOUT REDIRECT LINK: ' + common . logout _redirect _link + '\r\n' } ) ;
2019-02-14 02:31:26 +00:00
}
}
2019-06-19 01:02:29 +00:00
connect . getAllNodeAllChannelBackup = ( node ) => {
2019-07-28 18:00:15 +00:00
let channel _backup _file = node . channel _backup _path + common . path _separator + 'channel-all.bak' ;
2021-08-06 21:00:57 +00:00
let options = {
2019-09-02 04:11:37 +00:00
url : node . ln _server _url + '/channels/backup' ,
2019-06-19 01:02:29 +00:00
rejectUnauthorized : false ,
json : true ,
2021-08-06 21:00:57 +00:00
headers : { 'Grpc-Metadata-macaroon' : fs . readFileSync ( node . macaroon _path + '/admin.macaroon' ) . toString ( 'hex' ) }
2019-06-19 01:02:29 +00:00
} ;
2021-08-06 21:00:57 +00:00
request ( options ) . then ( function ( body ) {
fs . writeFile ( channel _backup _file , JSON . stringify ( body ) , function ( err ) {
2021-06-20 20:27:08 +00:00
if ( err ) {
if ( node . ln _node ) {
2021-08-06 21:00:57 +00:00
logger . log ( { level : 'ERROR' , fileName : 'Connect' , msg : 'Channel Backup Failed for Node ' + node . ln _node , error : err } ) ;
2019-06-19 01:02:29 +00:00
} else {
2021-08-06 21:00:57 +00:00
logger . log ( { level : 'ERROR' , fileName : 'Connect' , msg : 'Channel Backup Error' , error : err } ) ;
2019-06-19 01:02:29 +00:00
}
2021-06-20 20:27:08 +00:00
} else {
if ( node . ln _node ) {
2021-08-06 21:00:57 +00:00
logger . log ( { level : 'DEBUG' , fileName : 'Connect' , msg : 'Channel Backup Successful for Node' , data : node . ln _node } ) ;
2021-06-20 20:27:08 +00:00
} else {
2021-08-06 21:00:57 +00:00
logger . log ( { level : 'DEBUG' , fileName : 'Connect' , msg : 'Channel Backup Successful' } ) ;
2021-06-20 20:27:08 +00:00
}
}
} ) ;
} , ( err ) => {
2021-08-06 21:00:57 +00:00
logger . log ( { level : 'ERROR' , fileName : 'Connect' , msg : 'Channel Backup Response Error' , error : err } ) ;
2019-06-19 01:02:29 +00:00
} )
} ;
2019-06-19 01:24:40 +00:00
connect . setSelectedNode = ( config ) => {
2021-08-06 21:00:57 +00:00
if ( config . defaultNodeIndex ) {
2020-01-17 18:45:01 +00:00
common . selectedNode = common . findNode ( config . defaultNodeIndex ) ;
2019-06-19 01:24:40 +00:00
} else {
2020-01-17 18:45:01 +00:00
common . selectedNode = common . findNode ( common . nodes [ 0 ] . index ) ;
}
2019-06-19 01:24:40 +00:00
}
2020-01-23 02:18:58 +00:00
connect . modifyJsonMultiNodeConfig = ( confFileFullPath ) => {
2020-01-21 03:22:03 +00:00
RTLConfFile = common . rtl _conf _file _path + '/RTL-Multi-Node-Conf.json' ;
var config = JSON . parse ( fs . readFileSync ( RTLConfFile , 'utf-8' ) ) ;
if ( ! config . SSO ) { config . SSO = { } ; }
var newConfig = {
port : config . port ? config . port : 3000 ,
defaultNodeIndex : config . defaultNodeIndex ? config . defaultNodeIndex : 1 ,
SSO : {
rtlSSO : config . SSO . rtlSSO ? config . SSO . rtlSSO : 0 ,
rtlCookiePath : config . SSO . rtlCookiePath ? config . SSO . rtlCookiePath : "" ,
logoutRedirectLink : config . SSO . logoutRedirectLink ? config . SSO . logoutRedirectLink : ""
} ,
nodes : [ ]
} ;
2020-05-09 17:15:10 +00:00
if ( config . host ) {
newConfig . host = config . host ;
}
2021-08-06 21:00:57 +00:00
if ( config . nodes && config . nodes . length > 0 ) {
2020-01-21 03:22:03 +00:00
let newNode = { } ;
config . nodes . forEach ( ( node , idx ) => {
newNode = {
index : node . index ? node . index : ( idx + 1 ) ,
lnNode : node . lnNode ? node . lnNode : "Node " + ( idx + 1 ) ,
2021-08-06 21:00:57 +00:00
lnImplementation : node . lnImplementation ? node . lnImplementation : "LND" ,
2020-01-21 03:22:03 +00:00
Authentication : {
macaroonPath : node . Authentication . macaroonPath ? node . Authentication . macaroonPath : ''
} ,
Settings : {
userPersona : node . Settings . userPersona ? node . Settings . userPersona : "MERCHANT" ,
2021-08-06 21:00:57 +00:00
logLevel : node . Settings . logLevel ,
2020-01-21 03:22:03 +00:00
fiatConversion : node . Settings . fiatConversion ? node . Settings . fiatConversion : false
}
} ;
if ( node . Authentication . configPath ) {
newNode . Authentication . configPath = node . Authentication . configPath ;
} else if ( node . Authentication . lndConfigPath ) {
newNode . Authentication . configPath = node . Authentication . lndConfigPath ;
}
if ( node . Settings . theme ) {
var themeArr = node . Settings . theme . split ( "-" ) ;
if ( themeArr [ 2 ] ) { themeArr [ 1 ] = themeArr [ 1 ] + themeArr [ 2 ] ; } // For light-blue-gray
newNode . Settings . themeMode = ( themeArr [ 0 ] === "dark" ) ? "NIGHT" : "DAY" ;
newNode . Settings . themeColor = ( themeArr [ 1 ] === "blue" ) ? "INDIGO" : ( themeArr [ 1 ] === "pink" ) ? "PINK" : ( themeArr [ 1 ] === "green" || themeArr [ 1 ] === "teal" ) ? "TEAL" : "PURPLE" ;
} else {
newNode . Settings . themeMode = node . Settings . themeMode ? node . Settings . themeMode : "DAY" ;
newNode . Settings . themeColor = node . Settings . themeColor ? node . Settings . themeColor : "PURPLE" ;
}
if ( node . Settings . currencyUnit ) {
newNode . Settings . currencyUnit = node . Settings . currencyUnit ;
}
if ( node . Settings . bitcoindConfigPath ) {
newNode . Settings . bitcoindConfigPath = node . Settings . bitcoindConfigPath ;
}
if ( node . Settings . channelBackupPath ) {
newNode . Settings . channelBackupPath = node . Settings . channelBackupPath ;
}
if ( node . Settings . lnServerUrl ) {
2020-08-18 14:34:40 +00:00
newNode . Settings . lnServerUrl = node . Settings . lnServerUrl . endsWith ( '/v1' ) ? node . Settings . lnServerUrl . slice ( 0 , - 3 ) : node . Settings . lnServerUrl ;
2020-01-21 03:22:03 +00:00
} else if ( node . Settings . lndServerUrl ) {
2020-08-18 14:34:40 +00:00
newNode . Settings . lnServerUrl = node . Settings . lndServerUrl . endsWith ( '/v1' ) ? node . Settings . lndServerUrl . slice ( 0 , - 3 ) : node . Settings . lndServerUrl ;
2020-01-21 03:22:03 +00:00
}
newConfig . nodes . push ( newNode ) ;
} ) ;
}
2020-01-21 19:01:03 +00:00
newConfig . multiPassHashed = config . multiPassHashed ? config . multiPassHashed : config . multiPass ? hash . update ( config . multiPass ) . digest ( 'hex' ) : '' ;
fs . writeFileSync ( confFileFullPath , JSON . stringify ( newConfig , null , 2 ) , 'utf-8' ) ;
2020-01-21 03:22:03 +00:00
}
2020-01-23 02:18:58 +00:00
connect . modifyIniSingleNodeConfig = ( confFileFullPath ) => {
2020-01-21 03:22:03 +00:00
RTLConfFile = common . rtl _conf _file _path + '/RTL.conf' ;
var config = ini . parse ( fs . readFileSync ( RTLConfFile , 'utf-8' ) ) ;
if ( ! config . SSO ) { config . SSO = { } ; }
if ( ! config . Authentication ) { config . Authentication = { } ; }
if ( ! config . Settings ) { config . Settings = { } ; }
var newConfig = {
port : config . Settings . port ? config . Settings . port : 3000 ,
defaultNodeIndex : 1 ,
SSO : {
rtlSSO : config . SSO . rtlSSO ? config . SSO . rtlSSO : 0 ,
rtlCookiePath : config . SSO . rtlCookiePath ? config . SSO . rtlCookiePath : "" ,
logoutRedirectLink : config . SSO . logoutRedirectLink ? config . SSO . logoutRedirectLink : ""
} ,
nodes : [
{
index : 1 ,
lnNode : "Node 1" ,
2021-08-06 21:00:57 +00:00
lnImplementation : config . Settings . lnImplementation ? config . Settings . lnImplementation : "LND" ,
2020-01-21 03:22:03 +00:00
Authentication : {
macaroonPath : config . Authentication . macaroonPath ? config . Authentication . macaroonPath : ( config . Authentication . macroonPath ? config . Authentication . macroonPath : '' ) ,
configPath : config . Authentication . configPath ? config . Authentication . configPath : ( config . Authentication . lndConfigPath ? config . Authentication . lndConfigPath : '' ) ,
} ,
Settings : {
userPersona : config . Settings . userPersona ? config . Settings . userPersona : "MERCHANT" ,
2021-08-06 21:00:57 +00:00
logLevel : config . Settings . logLevel ? config . Settings . logLevel : 'ERROR' ,
2020-01-21 03:22:03 +00:00
fiatConversion : config . Settings . fiatConversion ? config . Settings . fiatConversion : false
}
}
]
} ;
if ( config . Settings . theme ) {
var themeArr = config . Settings . theme . split ( "-" ) ;
if ( themeArr [ 2 ] ) { themeArr [ 1 ] = themeArr [ 1 ] + themeArr [ 2 ] ; } // For light-blue-gray
newConfig . nodes [ 0 ] . Settings . themeMode = ( themeArr [ 0 ] === "dark" ) ? "NIGHT" : "DAY" ;
newConfig . nodes [ 0 ] . Settings . themeColor = ( themeArr [ 1 ] === "blue" ) ? "INDIGO" : ( themeArr [ 1 ] === "pink" ) ? "PINK" : ( themeArr [ 1 ] === "green" || themeArr [ 1 ] === "teal" ) ? "TEAL" : "PURPLE" ;
} else {
newConfig . nodes [ 0 ] . Settings . themeMode = config . Settings . themeMode ? config . Settings . themeMode : "DAY" ;
newConfig . nodes [ 0 ] . Settings . themeColor = config . Settings . themeColor ? config . Settings . themeColor : "PURPLE" ;
}
if ( config . Settings . currencyUnit ) {
newConfig . nodes [ 0 ] . Settings . currencyUnit = config . Settings . currencyUnit ;
}
2020-01-21 22:04:26 +00:00
2020-01-21 03:22:03 +00:00
if ( config . Settings . bitcoindConfigPath ) {
newConfig . nodes [ 0 ] . Settings . bitcoindConfigPath = config . Settings . bitcoindConfigPath ;
2021-08-06 21:00:57 +00:00
} else if ( config . Authentication . bitcoindConfigPath ) {
2020-01-21 22:04:26 +00:00
newConfig . nodes [ 0 ] . Settings . bitcoindConfigPath = config . Authentication . bitcoindConfigPath ;
2020-01-21 03:22:03 +00:00
}
2020-01-21 22:04:26 +00:00
2020-01-21 03:22:03 +00:00
if ( config . Settings . channelBackupPath ) {
newConfig . nodes [ 0 ] . Settings . channelBackupPath = config . Settings . channelBackupPath ;
}
if ( config . Settings . lnServerUrl ) {
2020-08-18 14:34:40 +00:00
newConfig . nodes [ 0 ] . Settings . lnServerUrl = config . Settings . lnServerUrl . endsWith ( '/v1' ) ? config . Settings . lnServerUrl . slice ( 0 , - 3 ) : config . Settings . lnServerUrl ;
2020-01-21 03:22:03 +00:00
} else if ( config . Settings . lndServerUrl ) {
2020-08-18 14:34:40 +00:00
newConfig . nodes [ 0 ] . Settings . lnServerUrl = config . Settings . lndServerUrl . endsWith ( '/v1' ) ? config . Settings . lndServerUrl . slice ( 0 , - 3 ) : config . Settings . lndServerUrl ;
2020-01-21 03:22:03 +00:00
} else if ( config . Authentication . lndServerUrl ) {
2020-08-18 14:34:40 +00:00
newConfig . nodes [ 0 ] . Settings . lnServerUrl = config . Authentication . lndServerUrl . endsWith ( '/v1' ) ? config . Authentication . lndServerUrl . slice ( 0 , - 3 ) : config . Authentication . lndServerUrl ;
2020-01-21 03:22:03 +00:00
}
2020-01-21 19:01:03 +00:00
newConfig . multiPassHashed = config . Authentication . rtlPassHashed ? config . Authentication . rtlPassHashed : config . Authentication . rtlPass ? hash . update ( config . Authentication . rtlPass ) . digest ( 'hex' ) : '' ;
fs . writeFileSync ( confFileFullPath , JSON . stringify ( newConfig , null , 2 ) , 'utf-8' ) ;
2020-01-21 03:22:03 +00:00
}
connect . upgradeConfig = ( confFileFullPath ) => {
try {
singleNodeConfFile = common . rtl _conf _file _path + '/RTL.conf' ;
multiNodeConfFile = common . rtl _conf _file _path + '/RTL-Multi-Node-Conf.json' ;
const singleNodeExists = fs . existsSync ( singleNodeConfFile ) ;
const multiNodeExists = fs . existsSync ( multiNodeConfFile ) ;
if ( ( singleNodeExists && multiNodeExists ) || ( ! singleNodeExists && multiNodeExists ) ) {
2020-01-23 02:18:58 +00:00
console . log ( 'Start...config migration for file ' + multiNodeConfFile ) ;
connect . modifyJsonMultiNodeConfig ( confFileFullPath ) ;
console . log ( 'End...config migration.' ) ;
2020-01-21 03:22:03 +00:00
} else if ( singleNodeExists && ! multiNodeExists ) {
2020-01-23 02:18:58 +00:00
console . log ( 'Start...config migration for file ' + singleNodeConfFile ) ;
connect . modifyIniSingleNodeConfig ( confFileFullPath ) ;
console . log ( 'End...config migration.' ) ;
2020-01-21 03:22:03 +00:00
} else if ( ! singleNodeExists && ! multiNodeExists ) {
if ( ! fs . existsSync ( confFileFullPath ) ) {
2020-01-23 02:18:58 +00:00
console . log ( 'Start...config creation at: ' + confFileFullPath ) ;
2020-01-21 19:01:03 +00:00
fs . writeFileSync ( confFileFullPath , JSON . stringify ( connect . setDefaultConfig ( ) , null , 2 ) , 'utf-8' ) ;
2020-01-23 02:18:58 +00:00
console . log ( 'End...config creation.' ) ;
2020-01-21 03:22:03 +00:00
}
}
2021-08-06 21:00:57 +00:00
} catch ( err ) {
2020-01-21 03:22:03 +00:00
console . error ( 'Something went wrong while upgrading the RTL config file: \n' + err ) ;
throw new Error ( err ) ;
}
}
2019-04-06 02:52:00 +00:00
connect . setServerConfiguration = ( ) => {
2020-01-20 16:15:04 +00:00
try {
2021-06-20 20:27:08 +00:00
common . rtl _conf _file _path = ( process . env . RTL _CONFIG _PATH ) ? process . env . RTL _CONFIG _PATH : path . join ( _ _dirname , '/..' ) ;
2021-08-06 21:00:57 +00:00
confFileFullPath = common . rtl _conf _file _path + common . path _separator + 'RTL-Config.json' ;
if ( ! fs . existsSync ( confFileFullPath ) ) {
2020-01-21 03:22:03 +00:00
connect . upgradeConfig ( confFileFullPath ) ;
2020-01-20 16:15:04 +00:00
}
var config = JSON . parse ( fs . readFileSync ( confFileFullPath , 'utf-8' ) ) ;
2021-08-06 21:00:57 +00:00
connect . updateLogByLevel ( ) ;
2020-01-20 16:15:04 +00:00
connect . validateNodeConfig ( config ) ;
connect . setSelectedNode ( config ) ;
connect . logEnvVariables ( ) ;
2021-08-06 21:00:57 +00:00
} catch ( err ) {
2020-01-20 16:15:04 +00:00
console . error ( 'Something went wrong while configuring the node server: \n' + err ) ;
throw new Error ( err ) ;
2019-04-06 02:52:00 +00:00
}
}
2019-03-31 15:39:41 +00:00
module . exports = connect ;