Merge pull request #2846 from antonilol/cookie
Add Bitcoin Core RPC cookie authentication option
This commit is contained in:
commit
a0a4ae611c
@ -40,7 +40,9 @@
|
|||||||
"PORT": 8332,
|
"PORT": 8332,
|
||||||
"USERNAME": "mempool",
|
"USERNAME": "mempool",
|
||||||
"PASSWORD": "mempool",
|
"PASSWORD": "mempool",
|
||||||
"TIMEOUT": 60000
|
"TIMEOUT": 60000,
|
||||||
|
"COOKIE": false,
|
||||||
|
"COOKIE_PATH": "/path/to/bitcoin/.cookie"
|
||||||
},
|
},
|
||||||
"ELECTRUM": {
|
"ELECTRUM": {
|
||||||
"HOST": "127.0.0.1",
|
"HOST": "127.0.0.1",
|
||||||
@ -60,7 +62,9 @@
|
|||||||
"PORT": 8332,
|
"PORT": 8332,
|
||||||
"USERNAME": "mempool",
|
"USERNAME": "mempool",
|
||||||
"PASSWORD": "mempool",
|
"PASSWORD": "mempool",
|
||||||
"TIMEOUT": 60000
|
"TIMEOUT": 60000,
|
||||||
|
"COOKIE": false,
|
||||||
|
"COOKIE_PATH": "/path/to/bitcoin/.cookie"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": true,
|
"ENABLED": true,
|
||||||
|
@ -41,7 +41,9 @@
|
|||||||
"PORT": 15,
|
"PORT": 15,
|
||||||
"USERNAME": "__CORE_RPC_USERNAME__",
|
"USERNAME": "__CORE_RPC_USERNAME__",
|
||||||
"PASSWORD": "__CORE_RPC_PASSWORD__",
|
"PASSWORD": "__CORE_RPC_PASSWORD__",
|
||||||
"TIMEOUT": 1000
|
"TIMEOUT": 1000,
|
||||||
|
"COOKIE": false,
|
||||||
|
"COOKIE_PATH": "__CORE_RPC_COOKIE_PATH__"
|
||||||
},
|
},
|
||||||
"ELECTRUM": {
|
"ELECTRUM": {
|
||||||
"HOST": "__ELECTRUM_HOST__",
|
"HOST": "__ELECTRUM_HOST__",
|
||||||
@ -61,7 +63,9 @@
|
|||||||
"PORT": 17,
|
"PORT": 17,
|
||||||
"USERNAME": "__SECOND_CORE_RPC_USERNAME__",
|
"USERNAME": "__SECOND_CORE_RPC_USERNAME__",
|
||||||
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
|
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
|
||||||
"TIMEOUT": 2000
|
"TIMEOUT": 2000,
|
||||||
|
"COOKIE": false,
|
||||||
|
"COOKIE_PATH": "__SECOND_CORE_RPC_COOKIE_PATH__"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": false,
|
"ENABLED": false,
|
||||||
|
@ -66,7 +66,9 @@ describe('Mempool Backend Config', () => {
|
|||||||
PORT: 8332,
|
PORT: 8332,
|
||||||
USERNAME: 'mempool',
|
USERNAME: 'mempool',
|
||||||
PASSWORD: 'mempool',
|
PASSWORD: 'mempool',
|
||||||
TIMEOUT: 60000
|
TIMEOUT: 60000,
|
||||||
|
COOKIE: false,
|
||||||
|
COOKIE_PATH: '/bitcoin/.cookie'
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(config.SECOND_CORE_RPC).toStrictEqual({
|
expect(config.SECOND_CORE_RPC).toStrictEqual({
|
||||||
@ -74,7 +76,9 @@ describe('Mempool Backend Config', () => {
|
|||||||
PORT: 8332,
|
PORT: 8332,
|
||||||
USERNAME: 'mempool',
|
USERNAME: 'mempool',
|
||||||
PASSWORD: 'mempool',
|
PASSWORD: 'mempool',
|
||||||
TIMEOUT: 60000
|
TIMEOUT: 60000,
|
||||||
|
COOKIE: false,
|
||||||
|
COOKIE_PATH: '/bitcoin/.cookie'
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(config.DATABASE).toStrictEqual({
|
expect(config.DATABASE).toStrictEqual({
|
||||||
|
@ -32,4 +32,5 @@ export interface BitcoinRpcCredentials {
|
|||||||
user: string;
|
user: string;
|
||||||
pass: string;
|
pass: string;
|
||||||
timeout: number;
|
timeout: number;
|
||||||
|
cookie?: string;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ const nodeRpcCredentials: BitcoinRpcCredentials = {
|
|||||||
user: config.CORE_RPC.USERNAME,
|
user: config.CORE_RPC.USERNAME,
|
||||||
pass: config.CORE_RPC.PASSWORD,
|
pass: config.CORE_RPC.PASSWORD,
|
||||||
timeout: config.CORE_RPC.TIMEOUT,
|
timeout: config.CORE_RPC.TIMEOUT,
|
||||||
|
cookie: config.CORE_RPC.COOKIE ? config.CORE_RPC.COOKIE_PATH : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default new bitcoin.Client(nodeRpcCredentials);
|
export default new bitcoin.Client(nodeRpcCredentials);
|
||||||
|
@ -8,6 +8,7 @@ const nodeRpcCredentials: BitcoinRpcCredentials = {
|
|||||||
user: config.SECOND_CORE_RPC.USERNAME,
|
user: config.SECOND_CORE_RPC.USERNAME,
|
||||||
pass: config.SECOND_CORE_RPC.PASSWORD,
|
pass: config.SECOND_CORE_RPC.PASSWORD,
|
||||||
timeout: config.SECOND_CORE_RPC.TIMEOUT,
|
timeout: config.SECOND_CORE_RPC.TIMEOUT,
|
||||||
|
cookie: config.SECOND_CORE_RPC.COOKIE ? config.SECOND_CORE_RPC.COOKIE_PATH : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default new bitcoin.Client(nodeRpcCredentials);
|
export default new bitcoin.Client(nodeRpcCredentials);
|
||||||
|
@ -78,6 +78,8 @@ interface IConfig {
|
|||||||
USERNAME: string;
|
USERNAME: string;
|
||||||
PASSWORD: string;
|
PASSWORD: string;
|
||||||
TIMEOUT: number;
|
TIMEOUT: number;
|
||||||
|
COOKIE: boolean;
|
||||||
|
COOKIE_PATH: string;
|
||||||
};
|
};
|
||||||
SECOND_CORE_RPC: {
|
SECOND_CORE_RPC: {
|
||||||
HOST: string;
|
HOST: string;
|
||||||
@ -85,6 +87,8 @@ interface IConfig {
|
|||||||
USERNAME: string;
|
USERNAME: string;
|
||||||
PASSWORD: string;
|
PASSWORD: string;
|
||||||
TIMEOUT: number;
|
TIMEOUT: number;
|
||||||
|
COOKIE: boolean;
|
||||||
|
COOKIE_PATH: string;
|
||||||
};
|
};
|
||||||
DATABASE: {
|
DATABASE: {
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
@ -207,6 +211,8 @@ const defaults: IConfig = {
|
|||||||
'USERNAME': 'mempool',
|
'USERNAME': 'mempool',
|
||||||
'PASSWORD': 'mempool',
|
'PASSWORD': 'mempool',
|
||||||
'TIMEOUT': 60000,
|
'TIMEOUT': 60000,
|
||||||
|
'COOKIE': false,
|
||||||
|
'COOKIE_PATH': '/bitcoin/.cookie'
|
||||||
},
|
},
|
||||||
'SECOND_CORE_RPC': {
|
'SECOND_CORE_RPC': {
|
||||||
'HOST': '127.0.0.1',
|
'HOST': '127.0.0.1',
|
||||||
@ -214,6 +220,8 @@ const defaults: IConfig = {
|
|||||||
'USERNAME': 'mempool',
|
'USERNAME': 'mempool',
|
||||||
'PASSWORD': 'mempool',
|
'PASSWORD': 'mempool',
|
||||||
'TIMEOUT': 60000,
|
'TIMEOUT': 60000,
|
||||||
|
'COOKIE': false,
|
||||||
|
'COOKIE_PATH': '/bitcoin/.cookie'
|
||||||
},
|
},
|
||||||
'DATABASE': {
|
'DATABASE': {
|
||||||
'ENABLED': true,
|
'ENABLED': true,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
var http = require('http')
|
var http = require('http')
|
||||||
var https = require('https')
|
var https = require('https')
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
|
||||||
var JsonRPC = function (opts) {
|
var JsonRPC = function (opts) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -55,7 +56,13 @@ JsonRPC.prototype.call = function (method, params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use HTTP auth if user and password set
|
// use HTTP auth if user and password set
|
||||||
if (this.opts.user && this.opts.pass) {
|
if (this.opts.cookie) {
|
||||||
|
if (!this.cachedCookie) {
|
||||||
|
this.cachedCookie = readFileSync(this.opts.cookie).toString();
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
requestOptions.auth = this.cachedCookie;
|
||||||
|
} else if (this.opts.user && this.opts.pass) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
requestOptions.auth = this.opts.user + ':' + this.opts.pass
|
requestOptions.auth = this.opts.user + ':' + this.opts.pass
|
||||||
}
|
}
|
||||||
@ -93,7 +100,7 @@ JsonRPC.prototype.call = function (method, params) {
|
|||||||
reject(err)
|
reject(err)
|
||||||
})
|
})
|
||||||
|
|
||||||
request.on('response', function (response) {
|
request.on('response', (response) => {
|
||||||
clearTimeout(reqTimeout)
|
clearTimeout(reqTimeout)
|
||||||
|
|
||||||
// We need to buffer the response chunks in a nonblocking way.
|
// We need to buffer the response chunks in a nonblocking way.
|
||||||
@ -104,7 +111,7 @@ JsonRPC.prototype.call = function (method, params) {
|
|||||||
// When all the responses are finished, we decode the JSON and
|
// When all the responses are finished, we decode the JSON and
|
||||||
// depending on whether it's got a result or an error, we call
|
// depending on whether it's got a result or an error, we call
|
||||||
// emitSuccess or emitError on the promise.
|
// emitSuccess or emitError on the promise.
|
||||||
response.on('end', function () {
|
response.on('end', () => {
|
||||||
var err
|
var err
|
||||||
|
|
||||||
if (cbCalled) return
|
if (cbCalled) return
|
||||||
@ -113,6 +120,14 @@ JsonRPC.prototype.call = function (method, params) {
|
|||||||
try {
|
try {
|
||||||
var decoded = JSON.parse(buffer)
|
var decoded = JSON.parse(buffer)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
// if we authenticated using a cookie and it failed, read the cookie file again
|
||||||
|
if (
|
||||||
|
response.statusCode === 401 /* Unauthorized */ &&
|
||||||
|
this.opts.cookie
|
||||||
|
) {
|
||||||
|
this.cachedCookie = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (response.statusCode !== 200) {
|
if (response.statusCode !== 200) {
|
||||||
err = new Error('Invalid params, response status code: ' + response.statusCode)
|
err = new Error('Invalid params, response status code: ' + response.statusCode)
|
||||||
err.code = -32602
|
err.code = -32602
|
||||||
|
@ -164,7 +164,9 @@ Corresponding `docker-compose.yml` overrides:
|
|||||||
"PORT": 8332,
|
"PORT": 8332,
|
||||||
"USERNAME": "mempool",
|
"USERNAME": "mempool",
|
||||||
"PASSWORD": "mempool",
|
"PASSWORD": "mempool",
|
||||||
"TIMEOUT": 60000
|
"TIMEOUT": 60000,
|
||||||
|
"COOKIE": false,
|
||||||
|
"COOKIE_PATH": ""
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -177,6 +179,8 @@ Corresponding `docker-compose.yml` overrides:
|
|||||||
CORE_RPC_USERNAME: ""
|
CORE_RPC_USERNAME: ""
|
||||||
CORE_RPC_PASSWORD: ""
|
CORE_RPC_PASSWORD: ""
|
||||||
CORE_RPC_TIMEOUT: 60000
|
CORE_RPC_TIMEOUT: 60000
|
||||||
|
CORE_RPC_COOKIE: false
|
||||||
|
CORE_RPC_COOKIE_PATH: ""
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -231,7 +235,9 @@ Corresponding `docker-compose.yml` overrides:
|
|||||||
"PORT": 8332,
|
"PORT": 8332,
|
||||||
"USERNAME": "mempool",
|
"USERNAME": "mempool",
|
||||||
"PASSWORD": "mempool",
|
"PASSWORD": "mempool",
|
||||||
"TIMEOUT": 60000
|
"TIMEOUT": 60000,
|
||||||
|
"COOKIE": false,
|
||||||
|
"COOKIE_PATH": ""
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -244,6 +250,8 @@ Corresponding `docker-compose.yml` overrides:
|
|||||||
SECOND_CORE_RPC_USERNAME: ""
|
SECOND_CORE_RPC_USERNAME: ""
|
||||||
SECOND_CORE_RPC_PASSWORD: ""
|
SECOND_CORE_RPC_PASSWORD: ""
|
||||||
SECOND_CORE_RPC_TIMEOUT: ""
|
SECOND_CORE_RPC_TIMEOUT: ""
|
||||||
|
SECOND_CORE_RPC_COOKIE: false
|
||||||
|
SECOND_CORE_RPC_COOKIE_PATH: ""
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -41,7 +41,9 @@
|
|||||||
"PORT": __CORE_RPC_PORT__,
|
"PORT": __CORE_RPC_PORT__,
|
||||||
"USERNAME": "__CORE_RPC_USERNAME__",
|
"USERNAME": "__CORE_RPC_USERNAME__",
|
||||||
"PASSWORD": "__CORE_RPC_PASSWORD__",
|
"PASSWORD": "__CORE_RPC_PASSWORD__",
|
||||||
"TIMEOUT": __CORE_RPC_TIMEOUT__
|
"TIMEOUT": __CORE_RPC_TIMEOUT__,
|
||||||
|
"COOKIE": __CORE_RPC_COOKIE__,
|
||||||
|
"COOKIE_PATH": "__CORE_RPC_COOKIE_PATH__"
|
||||||
},
|
},
|
||||||
"ELECTRUM": {
|
"ELECTRUM": {
|
||||||
"HOST": "__ELECTRUM_HOST__",
|
"HOST": "__ELECTRUM_HOST__",
|
||||||
@ -61,7 +63,9 @@
|
|||||||
"PORT": __SECOND_CORE_RPC_PORT__,
|
"PORT": __SECOND_CORE_RPC_PORT__,
|
||||||
"USERNAME": "__SECOND_CORE_RPC_USERNAME__",
|
"USERNAME": "__SECOND_CORE_RPC_USERNAME__",
|
||||||
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
|
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
|
||||||
"TIMEOUT": __SECOND_CORE_RPC_TIMEOUT__
|
"TIMEOUT": __SECOND_CORE_RPC_TIMEOUT__,
|
||||||
|
"COOKIE": __SECOND_CORE_RPC_COOKIE__,
|
||||||
|
"COOKIE_PATH": "__SECOND_CORE_RPC_COOKIE_PATH__"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": __DATABASE_ENABLED__,
|
"ENABLED": __DATABASE_ENABLED__,
|
||||||
|
@ -43,6 +43,8 @@ __CORE_RPC_PORT__=${CORE_RPC_PORT:=8332}
|
|||||||
__CORE_RPC_USERNAME__=${CORE_RPC_USERNAME:=mempool}
|
__CORE_RPC_USERNAME__=${CORE_RPC_USERNAME:=mempool}
|
||||||
__CORE_RPC_PASSWORD__=${CORE_RPC_PASSWORD:=mempool}
|
__CORE_RPC_PASSWORD__=${CORE_RPC_PASSWORD:=mempool}
|
||||||
__CORE_RPC_TIMEOUT__=${CORE_RPC_TIMEOUT:=60000}
|
__CORE_RPC_TIMEOUT__=${CORE_RPC_TIMEOUT:=60000}
|
||||||
|
__CORE_RPC_COOKIE__=${CORE_RPC_COOKIE:=false}
|
||||||
|
__CORE_RPC_COOKIE_PATH__=${CORE_RPC_COOKIE_PATH:=""}
|
||||||
|
|
||||||
# ELECTRUM
|
# ELECTRUM
|
||||||
__ELECTRUM_HOST__=${ELECTRUM_HOST:=127.0.0.1}
|
__ELECTRUM_HOST__=${ELECTRUM_HOST:=127.0.0.1}
|
||||||
@ -63,6 +65,8 @@ __SECOND_CORE_RPC_PORT__=${SECOND_CORE_RPC_PORT:=8332}
|
|||||||
__SECOND_CORE_RPC_USERNAME__=${SECOND_CORE_RPC_USERNAME:=mempool}
|
__SECOND_CORE_RPC_USERNAME__=${SECOND_CORE_RPC_USERNAME:=mempool}
|
||||||
__SECOND_CORE_RPC_PASSWORD__=${SECOND_CORE_RPC_PASSWORD:=mempool}
|
__SECOND_CORE_RPC_PASSWORD__=${SECOND_CORE_RPC_PASSWORD:=mempool}
|
||||||
__SECOND_CORE_RPC_TIMEOUT__=${SECOND_CORE_RPC_TIMEOUT:=60000}
|
__SECOND_CORE_RPC_TIMEOUT__=${SECOND_CORE_RPC_TIMEOUT:=60000}
|
||||||
|
__SECOND_CORE_RPC_COOKIE__=${SECOND_CORE_RPC_COOKIE:=false}
|
||||||
|
__SECOND_CORE_RPC_COOKIE_PATH__=${SECOND_CORE_RPC_COOKIE_PATH:=""}
|
||||||
|
|
||||||
# DATABASE
|
# DATABASE
|
||||||
__DATABASE_ENABLED__=${DATABASE_ENABLED:=true}
|
__DATABASE_ENABLED__=${DATABASE_ENABLED:=true}
|
||||||
@ -188,6 +192,8 @@ sed -i "s!__CORE_RPC_PORT__!${__CORE_RPC_PORT__}!g" mempool-config.json
|
|||||||
sed -i "s!__CORE_RPC_USERNAME__!${__CORE_RPC_USERNAME__}!g" mempool-config.json
|
sed -i "s!__CORE_RPC_USERNAME__!${__CORE_RPC_USERNAME__}!g" mempool-config.json
|
||||||
sed -i "s!__CORE_RPC_PASSWORD__!${__CORE_RPC_PASSWORD__}!g" mempool-config.json
|
sed -i "s!__CORE_RPC_PASSWORD__!${__CORE_RPC_PASSWORD__}!g" mempool-config.json
|
||||||
sed -i "s!__CORE_RPC_TIMEOUT__!${__CORE_RPC_TIMEOUT__}!g" mempool-config.json
|
sed -i "s!__CORE_RPC_TIMEOUT__!${__CORE_RPC_TIMEOUT__}!g" mempool-config.json
|
||||||
|
sed -i "s!__CORE_RPC_COOKIE__!${__CORE_RPC_COOKIE__}!g" mempool-config.json
|
||||||
|
sed -i "s!__CORE_RPC_COOKIE_PATH__!${__CORE_RPC_COOKIE_PATH__}!g" mempool-config.json
|
||||||
|
|
||||||
sed -i "s!__ELECTRUM_HOST__!${__ELECTRUM_HOST__}!g" mempool-config.json
|
sed -i "s!__ELECTRUM_HOST__!${__ELECTRUM_HOST__}!g" mempool-config.json
|
||||||
sed -i "s!__ELECTRUM_PORT__!${__ELECTRUM_PORT__}!g" mempool-config.json
|
sed -i "s!__ELECTRUM_PORT__!${__ELECTRUM_PORT__}!g" mempool-config.json
|
||||||
@ -205,6 +211,8 @@ sed -i "s!__SECOND_CORE_RPC_PORT__!${__SECOND_CORE_RPC_PORT__}!g" mempool-config
|
|||||||
sed -i "s!__SECOND_CORE_RPC_USERNAME__!${__SECOND_CORE_RPC_USERNAME__}!g" mempool-config.json
|
sed -i "s!__SECOND_CORE_RPC_USERNAME__!${__SECOND_CORE_RPC_USERNAME__}!g" mempool-config.json
|
||||||
sed -i "s!__SECOND_CORE_RPC_PASSWORD__!${__SECOND_CORE_RPC_PASSWORD__}!g" mempool-config.json
|
sed -i "s!__SECOND_CORE_RPC_PASSWORD__!${__SECOND_CORE_RPC_PASSWORD__}!g" mempool-config.json
|
||||||
sed -i "s!__SECOND_CORE_RPC_TIMEOUT__!${__SECOND_CORE_RPC_TIMEOUT__}!g" mempool-config.json
|
sed -i "s!__SECOND_CORE_RPC_TIMEOUT__!${__SECOND_CORE_RPC_TIMEOUT__}!g" mempool-config.json
|
||||||
|
sed -i "s!__SECOND_CORE_RPC_COOKIE__!${__SECOND_CORE_RPC_COOKIE__}!g" mempool-config.json
|
||||||
|
sed -i "s!__SECOND_CORE_RPC_COOKIE_PATH__!${__SECOND_CORE_RPC_COOKIE_PATH__}!g" mempool-config.json
|
||||||
|
|
||||||
sed -i "s!__DATABASE_ENABLED__!${__DATABASE_ENABLED__}!g" mempool-config.json
|
sed -i "s!__DATABASE_ENABLED__!${__DATABASE_ENABLED__}!g" mempool-config.json
|
||||||
sed -i "s!__DATABASE_HOST__!${__DATABASE_HOST__}!g" mempool-config.json
|
sed -i "s!__DATABASE_HOST__!${__DATABASE_HOST__}!g" mempool-config.json
|
||||||
|
Loading…
x
Reference in New Issue
Block a user