From d7245725e2bc9faab962f9249793b698c5cc01f0 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Wed, 25 Jul 2018 10:29:26 +0200 Subject: [PATCH 1/3] fix(lnd): more robust homedir detection `os.userInfo().homedir` is an unreliable way to get the path to a user's home directory. Use `os.homedir` instead. Fix #596 --- app/lnd/config/index.js | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/app/lnd/config/index.js b/app/lnd/config/index.js index 67d32717..45d8b161 100644 --- a/app/lnd/config/index.js +++ b/app/lnd/config/index.js @@ -1,8 +1,9 @@ -// Cert will be located depending on your machine -// Mac OS X: /Users/user/Library/Application Support/Lnd/tls.cert +// Cert will be tlsCertPathated depending on your machine: +// +// Mac OS X: /Users/.../Library/Application Support/Lnd/tls.cert // Linux: ~/.lnd/tls.cert -// Windows: TODO find out where cert is located for windows machine -import { userInfo, platform } from 'os' +// Windows: C:\Users\...\AppData\Local\Lnd +import { homedir, platform } from 'os' import { dirname, join, normalize } from 'path' import Store from 'electron-store' import { app } from 'electron' @@ -24,37 +25,33 @@ const appRootPath = appPath.indexOf('default_app.asar') < 0 ? normalize(`${appPa // Get an electromn store named 'connection' in which the saved connection detailes are stored. const store = new Store({ name: 'connection' }) -// Get the name of the current platform which we can use to determine the location of various lnd resources. +// Get the name of the current platform which we can use to determine the tlsCertPathation of various lnd resources. const plat = platform() -let loc -let macaroonPath +// Get the OS specific default lnd data dir and binary name. +let lndDataDir let lndBin -let lndPath - switch (plat) { case 'darwin': - loc = 'Library/Application Support/Lnd/tls.cert' - macaroonPath = 'Library/Application Support/Lnd/admin.macaroon' + lndDataDir = join(homedir(), 'Library', 'Application Support', 'Lnd') lndBin = 'lnd' break case 'linux': - loc = '.lnd/tls.cert' - macaroonPath = '.lnd/admin.macaroon' + lndDataDir = join(homedir(), '.lnd') lndBin = 'lnd' break case 'win32': - loc = join('Appdata', 'Local', 'Lnd', 'tls.cert') - macaroonPath = join('Appdata', 'Local', 'Lnd', 'admin.macaroon') + lndDataDir = join(process.env.APPDATA, 'Local', 'Lnd') lndBin = 'lnd.exe' break default: break } +// Get the path to the lnd binary. +let lndPath if (isDev) { - const lndBinaryDir = dirname(require.resolve('lnd-binary/package.json')) - lndPath = join(lndBinaryDir, 'vendor', lndBin) + lndPath = join(dirname(require.resolve('lnd-binary/package.json')), 'vendor', lndBin) } else { lndPath = join(appRootPath, 'bin', lndBin) } @@ -70,8 +67,8 @@ export default { configPath: join(appRootPath, 'resources', 'lnd.conf'), rpcProtoPath: join(appRootPath, 'resources', 'rpc.proto'), host: typeof host === 'undefined' ? 'localhost:10009' : host, - cert: typeof cert === 'undefined' ? join(userInfo().homedir, loc) : cert, - macaroon: typeof macaroon === 'undefined' ? join(userInfo().homedir, macaroonPath) : macaroon + cert: typeof cert === 'undefined' ? join(lndDataDir, 'tls.cert') : cert, + macaroon: typeof macaroon === 'undefined' ? join(lndDataDir, 'admin.macaroon') : macaroon } } } From eb4fe31e27ae9d11c3ebd631b48d2d10c3673624 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Wed, 25 Jul 2018 10:48:22 +0200 Subject: [PATCH 2/3] fix(lnd): support tilde in connection params Expand the tilde character when used in connection parameters. Fix #596 --- app/lnd/config/index.js | 33 ++++++++++++++++++++++++--------- package.json | 1 + yarn.lock | 4 ++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/app/lnd/config/index.js b/app/lnd/config/index.js index 45d8b161..db8a740b 100644 --- a/app/lnd/config/index.js +++ b/app/lnd/config/index.js @@ -8,6 +8,7 @@ import { dirname, join, normalize } from 'path' import Store from 'electron-store' import { app } from 'electron' import isDev from 'electron-is-dev' +import untildify from 'untildify' // Get a path to prepend to any nodejs calls that are getting at files in the package, // so that it works both from source and in an asar-packaged mac app. @@ -22,9 +23,6 @@ import isDev from 'electron-is-dev' const appPath = app.getAppPath() const appRootPath = appPath.indexOf('default_app.asar') < 0 ? normalize(`${appPath}/..`) : '' -// Get an electromn store named 'connection' in which the saved connection detailes are stored. -const store = new Store({ name: 'connection' }) - // Get the name of the current platform which we can use to determine the tlsCertPathation of various lnd resources. const plat = platform() @@ -58,17 +56,34 @@ if (isDev) { export default { lnd: () => { - const cert = store.get('cert') - const host = store.get('host') - const macaroon = store.get('macaroon') + // Get an electromn store named 'connection' in which the saved connection detailes are stored. + const store = new Store({ name: 'connection' }) + + // Determine what hostname to use. + let host = store.get('host') + if (typeof host === 'undefined') { + host = 'localhost:10009' + } + + // Determine what cert to use. + let cert = store.get('cert') + if (typeof cert === 'undefined') { + cert = join(lndDataDir, 'tls.cert') + } + + // Determine what macaroon to use. + let macaroon = store.get('macaroon') + if (typeof macaroon === 'undefined') { + macaroon = join(lndDataDir, 'admin.macaroon') + } return { lndPath, configPath: join(appRootPath, 'resources', 'lnd.conf'), rpcProtoPath: join(appRootPath, 'resources', 'rpc.proto'), - host: typeof host === 'undefined' ? 'localhost:10009' : host, - cert: typeof cert === 'undefined' ? join(lndDataDir, 'tls.cert') : cert, - macaroon: typeof macaroon === 'undefined' ? join(lndDataDir, 'admin.macaroon') : macaroon + host, + cert: untildify(cert), + macaroon: untildify(macaroon) } } } diff --git a/package.json b/package.json index 0417115f..248ddb0b 100644 --- a/package.json +++ b/package.json @@ -277,6 +277,7 @@ "satoshi-bitcoin": "^1.0.4", "source-map-support": "^0.5.6", "split2": "^2.2.0", + "untildify": "^3.0.3", "validator": "^10.4.0" }, "main": "webpack.config.base.js", diff --git a/yarn.lock b/yarn.lock index 50b394e2..44c5f33d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11847,6 +11847,10 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +untildify@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" + unzip-response@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" From 02d0a5564df3924b60ccf50d1db934cd296453c9 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Wed, 25 Jul 2018 11:03:40 +0200 Subject: [PATCH 3/3] refactor(lnd): refactor lnd/config Refactor lnd/config for better readability. --- app/lnd/config/index.js | 69 +++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/app/lnd/config/index.js b/app/lnd/config/index.js index db8a740b..020b4626 100644 --- a/app/lnd/config/index.js +++ b/app/lnd/config/index.js @@ -1,8 +1,3 @@ -// Cert will be tlsCertPathated depending on your machine: -// -// Mac OS X: /Users/.../Library/Application Support/Lnd/tls.cert -// Linux: ~/.lnd/tls.cert -// Windows: C:\Users\...\AppData\Local\Lnd import { homedir, platform } from 'os' import { dirname, join, normalize } from 'path' import Store from 'electron-store' @@ -54,36 +49,44 @@ if (isDev) { lndPath = join(appRootPath, 'bin', lndBin) } -export default { - lnd: () => { - // Get an electromn store named 'connection' in which the saved connection detailes are stored. - const store = new Store({ name: 'connection' }) - - // Determine what hostname to use. - let host = store.get('host') - if (typeof host === 'undefined') { - host = 'localhost:10009' - } - - // Determine what cert to use. - let cert = store.get('cert') - if (typeof cert === 'undefined') { - cert = join(lndDataDir, 'tls.cert') - } +/** + * Get current lnd configuration. + * + * Cert and Macaroon will be at one of the following destinations depending on your machine: + * Mac OS X: ~/Library/Application Support/Lnd/tls.cert + * Linux: ~/.lnd/tls.cert + * Windows: C:\Users\...\AppData\Local\Lnd + * + * @return {object} current lnd configuration options. + */ +const lnd = () => { + // Get an electron store named 'connection' in which the saved connection detailes are stored. + const store = new Store({ name: 'connection' }) - // Determine what macaroon to use. - let macaroon = store.get('macaroon') - if (typeof macaroon === 'undefined') { - macaroon = join(lndDataDir, 'admin.macaroon') + /** + * Fetch a config option from the connection store. + * if undefined fallback to a path relative to the lnd data dir. + * + * @param {string} name name of property to fetch from the store. + * @param {string} path path relative to the lnd data dir. + * @return {string} config param or filepath relative to the lnd data dir. + */ + const getFromStoreOrDataDir = (name, file) => { + let path = store.get(name) + if (typeof path === 'undefined') { + path = join(lndDataDir, file) } + return untildify(path) + } - return { - lndPath, - configPath: join(appRootPath, 'resources', 'lnd.conf'), - rpcProtoPath: join(appRootPath, 'resources', 'rpc.proto'), - host, - cert: untildify(cert), - macaroon: untildify(macaroon) - } + return { + lndPath, + configPath: join(appRootPath, 'resources', 'lnd.conf'), + rpcProtoPath: join(appRootPath, 'resources', 'rpc.proto'), + host: store.get('host', 'localhost:10009'), + cert: getFromStoreOrDataDir('cert', 'tls.cert'), + macaroon: getFromStoreOrDataDir('macaroon', 'admin.macaroon') } } + +export default { lnd }