mirror of
https://github.com/janoside/btc-rpc-explorer.git
synced 2026-08-13 12:33:13 +02:00
Support for reloading rpc credentials and reconnecting
Fixes #393 Smarter identification of auth type (usernamePassword/cookie); if using cookie auth, watch cookie file for changes and, if seen, reload and attempt rpc reconnect
This commit is contained in:
parent
c8301ad78b
commit
c5a147ff9f
3 changed files with 70 additions and 17 deletions
27
app.js
27
app.js
|
|
@ -872,8 +872,15 @@ expressApp.onStartup = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
expressApp.continueStartup = function() {
|
||||
let rpcCred = config.credentials.rpc;
|
||||
function connectToRpcServer() {
|
||||
// reload credentials, the main "config.credentials.rpc" can be stale
|
||||
// since the username/password can be sourced from the auth cookie
|
||||
// which changes each startup of bitcoind
|
||||
let credentialsForRpcConnect = config.credentials.loadFreshRpcCredentials();
|
||||
|
||||
debugLog(`RPC Credentials: ${JSON.stringify(utils.obfuscateProperties(credentialsForRpcConnect, ["password"]), null, 4)}`);
|
||||
|
||||
let rpcCred = credentialsForRpcConnect;
|
||||
debugLog(`Connecting to RPC node at [${rpcCred.host}]:${rpcCred.port}`);
|
||||
|
||||
let usernamePassword = `${rpcCred.username}:${rpcCred.password}`;
|
||||
|
|
@ -910,6 +917,22 @@ expressApp.continueStartup = function() {
|
|||
|
||||
// no timeout RPC client, for long-running commands
|
||||
global.rpcClientNoTimeout = jayson.Client.http(rpcClientNoTimeoutProperties);
|
||||
}
|
||||
|
||||
expressApp.continueStartup = function() {
|
||||
connectToRpcServer();
|
||||
|
||||
// if using cookie auth, watch for changes to the file and reconnect
|
||||
if (config.credentials.rpc.authType == "cookie") {
|
||||
debugLog(`RPC authentication is cookie based; watching for changes to the auth cookie file...`);
|
||||
|
||||
fs.watchFile(config.credentials.rpc.authCookieFilepath, (curr, prev) => {
|
||||
debugLog(`RPC auth cookie change detected; attempting reconnect...`);
|
||||
|
||||
connectToRpcServer();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// default values - after we connect via RPC, we update these
|
||||
global.txindexAvailable = false;
|
||||
|
|
|
|||
|
|
@ -35,15 +35,6 @@ const currentCoin = process.env.BTCEXP_COIN || "BTC";
|
|||
|
||||
const rpcCred = credentials.rpc;
|
||||
|
||||
if (rpcCred.cookie && !rpcCred.username && !rpcCred.password && fs.existsSync(rpcCred.cookie)) {
|
||||
console.log(`Loading RPC cookie file: ${rpcCred.cookie}`);
|
||||
|
||||
[ rpcCred.username, rpcCred.password ] = fs.readFileSync(rpcCred.cookie).toString().split(':', 2);
|
||||
|
||||
if (!rpcCred.password) {
|
||||
throw new Error(`Cookie file ${rpcCred.cookie} in unexpected format`);
|
||||
}
|
||||
}
|
||||
|
||||
const cookieSecret = process.env.BTCEXP_COOKIE_SECRET
|
||||
|| (rpcCred.password && crypto.createHmac('sha256', JSON.stringify(rpcCred))
|
||||
|
|
|
|||
|
|
@ -3,19 +3,58 @@
|
|||
const os = require('os');
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
const fs = require("fs");
|
||||
|
||||
const debug = require("debug");
|
||||
const debugLog = debug("btcexp:config");
|
||||
|
||||
const btcUri = process.env.BTCEXP_BITCOIND_URI ? url.parse(process.env.BTCEXP_BITCOIND_URI, true) : { query: { } };
|
||||
const btcAuth = btcUri.auth ? btcUri.auth.split(':') : [];
|
||||
|
||||
module.exports = {
|
||||
rpc: {
|
||||
|
||||
|
||||
|
||||
function loadFreshRpcCredentials() {
|
||||
let username = btcAuth[0] || process.env.BTCEXP_BITCOIND_USER;
|
||||
let password = btcAuth[1] || process.env.BTCEXP_BITCOIND_PASS;
|
||||
|
||||
let authCookieFilepath = btcUri.query.cookie || process.env.BTCEXP_BITCOIND_COOKIE || path.join(os.homedir(), '.bitcoin', '.cookie');
|
||||
|
||||
let authType = "usernamePassword";
|
||||
|
||||
if (!username && !password && fs.existsSync(authCookieFilepath)) {
|
||||
authType = "cookie";
|
||||
}
|
||||
|
||||
if (authType == "cookie") {
|
||||
debugLog(`Loading RPC cookie file: ${authCookieFilepath}`);
|
||||
|
||||
[ username, password ] = fs.readFileSync(authCookieFilepath).toString().trim().split(':', 2);
|
||||
|
||||
if (!password) {
|
||||
throw new Error(`Cookie file ${authCookieFilepath} in unexpected format`);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
host: btcUri.hostname || process.env.BTCEXP_BITCOIND_HOST || "127.0.0.1",
|
||||
port: btcUri.port || process.env.BTCEXP_BITCOIND_PORT || 8332,
|
||||
username: btcAuth[0] || process.env.BTCEXP_BITCOIND_USER,
|
||||
password: btcAuth[1] || process.env.BTCEXP_BITCOIND_PASS,
|
||||
cookie: btcUri.query.cookie || process.env.BTCEXP_BITCOIND_COOKIE || path.join(os.homedir(), '.bitcoin', '.cookie'),
|
||||
|
||||
authType: authType,
|
||||
|
||||
username: username,
|
||||
password: password,
|
||||
|
||||
authCookieFilepath: authCookieFilepath,
|
||||
|
||||
timeout: parseInt(btcUri.query.timeout || process.env.BTCEXP_BITCOIND_RPC_TIMEOUT || 5000),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
loadFreshRpcCredentials: loadFreshRpcCredentials,
|
||||
|
||||
rpc: loadFreshRpcCredentials(),
|
||||
|
||||
// optional: enter your api access key from ipstack.com below
|
||||
// to include a map of the estimated locations of your node's
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue