2024-06-10 12:40:37 -07:00
|
|
|
import jwt from 'jsonwebtoken';
|
2021-12-29 18:08:41 -05:00
|
|
|
import * as fs from 'fs';
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
import { resolve, sep } from 'path';
|
2021-12-29 18:08:41 -05:00
|
|
|
import ini from 'ini';
|
|
|
|
|
import parseHocon from 'hocon-parser';
|
Replace deprecated request/request-promise with axios
request has been deprecated since 2020 with an unfixed SSRF advisory and
pins vulnerable copies of form-data (critical), qs, tough-cookie and
uuid - 8 of the 13 remaining production audit findings, none fixable by
version bumps (issue #1634, item 1).
All 36 backend files that imported request-promise now use a small
compatibility wrapper (server/utils/request.ts) backed by axios, which
is already a production dependency. The wrapper accepts the existing
options shape (qs, form - object or pre-encoded string, body,
baseUrl/uri, rejectUnauthorized, json), resolves with the response body
directly, and rejects with a plain object mirroring request-promise's
StatusCodeError/RequestError shape, so CommonService.handleError works
unchanged (ECONNREFUSED -> 503, Eclair StatusCodeError -> 500, nested
error body extraction). Auth headers are excluded from rejected errors
so they cannot leak into logs. Callers without json: true (block
explorer, currency rates) still get raw text bodies, and LND's
line-delimited /v2/router/send stream still surfaces as a string for
the existing parser.
Only behavioral code change: CLN verifyMessage used request-promise's
callback style and was ported to the same promise style as signMessage;
four Eclair handlers gained explicit returns to satisfy
noImplicitReturns once the import became typed.
Production npm audit drops from 13 findings (2 critical) to 6 low, all
in the crypto-browserify/elliptic chain tracked in #1634.
Verified against the docker regtest fixture with 43 API checks across
LND, Core Lightning and Eclair: reads, invoice creation, a routed LND
payment over the streaming endpoint, cross-implementation payments from
CLN and Eclair, message sign/verify, channel backup to disk, and
bad-invoice/node-unreachable error mapping. Lint and both production
builds are clean.
2026-07-19 12:08:05 -07:00
|
|
|
import request from '../../utils/request.js';
|
2021-12-29 18:08:41 -05:00
|
|
|
import { Database, DatabaseService } from '../../utils/database.js';
|
|
|
|
|
import { Logger, LoggerService } from '../../utils/logger.js';
|
|
|
|
|
import { Common, CommonService } from '../../utils/common.js';
|
|
|
|
|
import { WSServer } from '../../utils/webSocketServer.js';
|
2024-11-18 20:27:51 -08:00
|
|
|
import { Authentication } from '../../models/config.model.js';
|
2021-12-29 18:08:41 -05:00
|
|
|
|
|
|
|
|
const options = { url: '' };
|
|
|
|
|
const logger: LoggerService = Logger;
|
|
|
|
|
const common: CommonService = Common;
|
|
|
|
|
const wsServer = WSServer;
|
|
|
|
|
const databaseService: DatabaseService = Database;
|
2024-06-10 12:40:37 -07:00
|
|
|
// Set local block explorer URL after first API call
|
|
|
|
|
// if the selected node block explorer has working REST API suite
|
|
|
|
|
// otherwise set it to mempool.space
|
|
|
|
|
let blockExplorerUrl = '';
|
2021-12-29 18:08:41 -05:00
|
|
|
|
2024-06-10 12:40:37 -07:00
|
|
|
export const getExplorerFeesRecommended = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Recommended Fee Rates..' });
|
|
|
|
|
options.url = (blockExplorerUrl === '') ?
|
|
|
|
|
req.session.selectedNode.settings.blockExplorerUrl + '/api/v1/fees/recommended' :
|
|
|
|
|
blockExplorerUrl + '/api/v1/fees/recommended';
|
|
|
|
|
request(options).then((body) => {
|
|
|
|
|
blockExplorerUrl = req.session.selectedNode.settings.blockExplorerUrl;
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Recommended Fee Rates Received', data: body });
|
|
|
|
|
res.status(200).json(JSON.parse(body));
|
|
|
|
|
}).catch((errRes) => {
|
|
|
|
|
blockExplorerUrl = 'https://mempool.space';
|
|
|
|
|
options.url = blockExplorerUrl + '/api/v1/fees/recommended';
|
|
|
|
|
return request(options).then((body) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Recommended Fee Rates Received', data: body });
|
|
|
|
|
res.status(200).json(JSON.parse(body));
|
|
|
|
|
}).catch((errRes) => {
|
|
|
|
|
const errMsg = 'Get Recommended Fee Rates 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 });
|
|
|
|
|
});
|
|
|
|
|
});
|
2021-12-29 18:08:41 -05:00
|
|
|
};
|
|
|
|
|
|
2024-06-10 12:40:37 -07:00
|
|
|
export const getExplorerTransaction = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Transaction From Block Explorer..' });
|
|
|
|
|
options.url = (blockExplorerUrl === '') ?
|
|
|
|
|
req.session.selectedNode.settings.blockExplorerUrl + '/api/tx/' + req.params.txid :
|
|
|
|
|
blockExplorerUrl + '/api/tx/' + req.params.txid;
|
|
|
|
|
request(options).then((body) => {
|
|
|
|
|
blockExplorerUrl = req.session.selectedNode.settings.blockExplorerUrl;
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Transaction From Block Explorer Received', data: body });
|
|
|
|
|
res.status(200).json(JSON.parse(body));
|
|
|
|
|
}).catch((errRes) => {
|
|
|
|
|
blockExplorerUrl = 'https://mempool.space';
|
|
|
|
|
options.url = blockExplorerUrl + '/api/tx/' + req.params.txid;
|
|
|
|
|
return request(options).then((body) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Transaction From Block Explorer Received', data: body });
|
|
|
|
|
res.status(200).json(JSON.parse(body));
|
|
|
|
|
}).catch((errRes) => {
|
|
|
|
|
const errMsg = 'Get Transaction From Block Explorer 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 });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getCurrencyRates = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' });
|
|
|
|
|
options.url = 'https://blockchain.info/ticker';
|
|
|
|
|
request(options).then((body) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body });
|
|
|
|
|
res.status(200).json(JSON.parse(body));
|
|
|
|
|
}).catch((errRes) => {
|
|
|
|
|
const errMsg = 'Get Rates 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 });
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getFile = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' });
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
const channelBackupPath = req.session.selectedNode.settings.channelBackupPath;
|
|
|
|
|
let file = '';
|
|
|
|
|
if (req.query.path) {
|
|
|
|
|
// The UI only ever requests channel backup files; contain caller paths to the node's
|
|
|
|
|
// backup directory so this endpoint cannot read the config, macaroons or the SSO
|
|
|
|
|
// cookie (getConfig serves the config file masked; this must not bypass that).
|
|
|
|
|
const resolved = resolve(req.query.path);
|
|
|
|
|
if (resolved !== resolve(channelBackupPath) && !resolved.startsWith(resolve(channelBackupPath) + sep)) {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'WARN', fileName: 'RTLConf', msg: 'Blocked file read outside the channel backup directory', data: req.query.path });
|
|
|
|
|
const err = common.handleError({ statusCode: 403, message: 'Reading File Error', error: 'File path is outside the channel backup directory' }, 'RTLConf', 'Reading File Error', req.session.selectedNode);
|
|
|
|
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
|
|
|
|
}
|
|
|
|
|
file = resolved;
|
|
|
|
|
} else {
|
|
|
|
|
file = channelBackupPath + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak';
|
|
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel });
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file });
|
|
|
|
|
fs.readFile(file, 'utf8', (errRes, data) => {
|
2021-12-29 18:08:41 -05:00
|
|
|
if (errRes) {
|
2024-06-10 12:40:37 -07:00
|
|
|
if (errRes.code && errRes.code === 'ENOENT') { errRes.code = 'File Not Found!'; }
|
|
|
|
|
const errMsg = 'Reading File 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 });
|
2021-12-29 18:08:41 -05:00
|
|
|
} else {
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
// File contents can carry node credentials; never write them to the log.
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received' });
|
2024-06-10 12:40:37 -07:00
|
|
|
res.status(200).json(data);
|
2021-12-29 18:08:41 -05:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-10 12:40:37 -07:00
|
|
|
export const getApplicationSettings = (req, res, next) => {
|
2021-12-29 18:08:41 -05:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' });
|
2024-11-18 20:27:51 -08:00
|
|
|
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.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]];
|
2021-12-29 18:08:41 -05:00
|
|
|
}
|
2024-11-18 20:27:51 -08:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: appConfData });
|
|
|
|
|
res.status(200).json(appConfData);
|
2021-12-29 18:08:41 -05:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-10 12:40:37 -07:00
|
|
|
export const updateSelectedNode = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' });
|
|
|
|
|
const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.selectedNode ? +common.selectedNode.index : 1;
|
|
|
|
|
req.session.selectedNode = common.findNode(selNodeIndex);
|
|
|
|
|
common.selectedNode = req.session.selectedNode;
|
|
|
|
|
if (req.headers && req.headers.authorization && req.headers.authorization !== '') {
|
|
|
|
|
wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex);
|
|
|
|
|
if (req.params.prevNodeIndex !== '-1') {
|
|
|
|
|
databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id);
|
2021-12-29 18:08:41 -05:00
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
if (req.params.currNodeIndex !== '-1') {
|
|
|
|
|
databaseService.loadDatabase(req.session);
|
2021-12-29 18:08:41 -05:00
|
|
|
}
|
|
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
blockExplorerUrl = '';
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + req.session.selectedNode.lnNode || '' });
|
|
|
|
|
res.status(200).json(common.removeAuthSecureData(JSON.parse(JSON.stringify(req.session.selectedNode))));
|
2021-12-29 18:08:41 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getConfig = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Reading Configuration File..' });
|
|
|
|
|
let confFile = '';
|
|
|
|
|
let fileFormat = 'INI';
|
|
|
|
|
switch (req.params.nodeType) {
|
|
|
|
|
case 'ln':
|
2024-06-10 12:40:37 -07:00
|
|
|
confFile = req.session.selectedNode.authentication.configPath;
|
2021-12-29 18:08:41 -05:00
|
|
|
break;
|
|
|
|
|
case 'bitcoind':
|
2024-06-10 12:40:37 -07:00
|
|
|
confFile = req.session.selectedNode.settings.bitcoindConfigPath;
|
2021-12-29 18:08:41 -05:00
|
|
|
break;
|
|
|
|
|
case 'rtl':
|
|
|
|
|
fileFormat = 'JSON';
|
2024-06-10 12:40:37 -07:00
|
|
|
confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
2021-12-29 18:08:41 -05:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
confFile = '';
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-01-16 15:55:50 -05:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Node Type', data: req.params.nodeType });
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: confFile });
|
2021-12-29 18:08:41 -05:00
|
|
|
fs.readFile(confFile, 'utf8', (errRes, data) => {
|
|
|
|
|
if (errRes) {
|
|
|
|
|
const errMsg = 'Reading 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 {
|
|
|
|
|
let jsonConfig = {};
|
|
|
|
|
if (fileFormat === 'JSON') {
|
|
|
|
|
jsonConfig = JSON.parse(data);
|
|
|
|
|
} else {
|
|
|
|
|
fileFormat = 'INI';
|
2022-08-17 15:48:04 -07:00
|
|
|
data = data?.replace('color=#', 'color=');
|
2021-12-29 18:08:41 -05:00
|
|
|
jsonConfig = ini.parse(data);
|
2022-01-16 15:55:50 -05:00
|
|
|
if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) {
|
|
|
|
|
jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color;
|
|
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
if (req.params.nodeType === 'ln' && req.session.selectedNode.lnImplementation === 'ECL' && !jsonConfig['eclair.api.password']) {
|
2021-12-29 18:08:41 -05:00
|
|
|
fileFormat = 'HOCON';
|
|
|
|
|
jsonConfig = parseHocon(data);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
jsonConfig = common.maskPasswords(jsonConfig);
|
2022-08-17 15:48:04 -07:00
|
|
|
const responseJSON = (fileFormat === 'JSON') ? jsonConfig : ini.stringify(jsonConfig)?.replace('color=\\#', 'color=#');
|
2022-01-16 15:55:50 -05:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Configuration File Data Received', data: responseJSON });
|
2021-12-29 18:08:41 -05:00
|
|
|
res.status(200).json({ format: fileFormat, data: responseJSON });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-10 12:40:37 -07:00
|
|
|
export const updateNodeSettings = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Node Settings..' });
|
|
|
|
|
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
2026-05-14 11:51:10 +02:00
|
|
|
try {
|
|
|
|
|
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
|
|
|
|
const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index));
|
|
|
|
|
if (node && node.settings) {
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
// channelBackupPath anchors getFile's containment root and is documented as a
|
|
|
|
|
// config-file-only setting; accepting it from the API would let the caller being
|
|
|
|
|
// contained choose the containment base. Pin it to the server-held value.
|
|
|
|
|
const serverChannelBackupPath = node.settings.channelBackupPath;
|
2026-05-14 11:51:10 +02:00
|
|
|
node.settings = { ...node.settings, ...req.body.settings };
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
node.settings.channelBackupPath = serverChannelBackupPath;
|
2026-05-14 11:51:10 +02:00
|
|
|
if (node.authentication && req.body.authentication) {
|
|
|
|
|
if (req.body.authentication.boltzMacaroonPath) {
|
|
|
|
|
node.authentication.boltzMacaroonPath = req.body.authentication.boltzMacaroonPath;
|
|
|
|
|
} else {
|
|
|
|
|
delete node.authentication.boltzMacaroonPath;
|
|
|
|
|
}
|
|
|
|
|
if (req.body.authentication.swapMacaroonPath) {
|
|
|
|
|
node.authentication.swapMacaroonPath = req.body.authentication.swapMacaroonPath;
|
|
|
|
|
} else {
|
|
|
|
|
delete node.authentication.swapMacaroonPath;
|
|
|
|
|
}
|
2026-05-14 11:39:11 +02:00
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
}
|
2021-12-29 18:08:41 -05:00
|
|
|
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
2024-06-10 12:40:37 -07:00
|
|
|
const selectedNode = common.findNode(req.session.selectedNode.index);
|
|
|
|
|
if (selectedNode && selectedNode.settings) {
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
const serverChannelBackupPath = selectedNode.settings.channelBackupPath;
|
2026-05-14 10:32:38 +02:00
|
|
|
selectedNode.settings = { ...selectedNode.settings, ...req.body.settings };
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
selectedNode.settings.channelBackupPath = serverChannelBackupPath;
|
2026-05-14 11:39:11 +02:00
|
|
|
if (selectedNode.authentication && req.body.authentication) {
|
|
|
|
|
if (req.body.authentication.boltzMacaroonPath) {
|
|
|
|
|
selectedNode.authentication.boltzMacaroonPath = req.body.authentication.boltzMacaroonPath;
|
|
|
|
|
} else {
|
|
|
|
|
delete selectedNode.authentication.boltzMacaroonPath;
|
|
|
|
|
}
|
|
|
|
|
if (req.body.authentication.swapMacaroonPath) {
|
|
|
|
|
selectedNode.authentication.swapMacaroonPath = req.body.authentication.swapMacaroonPath;
|
|
|
|
|
} else {
|
|
|
|
|
delete selectedNode.authentication.swapMacaroonPath;
|
|
|
|
|
}
|
2026-05-14 10:32:38 +02:00
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
common.replaceNode(req, selectedNode);
|
|
|
|
|
}
|
|
|
|
|
let responseNode = JSON.parse(JSON.stringify(common.selectedNode));
|
|
|
|
|
responseNode = common.removeAuthSecureData(responseNode);
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Node Settings Updated', data: responseNode });
|
|
|
|
|
res.status(201).json(responseNode);
|
2021-12-29 18:08:41 -05:00
|
|
|
} catch (errRes) {
|
2024-06-10 12:40:37 -07:00
|
|
|
const errMsg = 'Update Node Settings Error';
|
2021-12-29 18:08:41 -05:00
|
|
|
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 });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-10 12:40:37 -07:00
|
|
|
export const updateApplicationSettings = (req, res, next) => {
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Application Settings..' });
|
|
|
|
|
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
2021-12-29 18:08:41 -05:00
|
|
|
try {
|
2026-05-14 10:32:38 +02:00
|
|
|
const oldConfig = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
|
|
|
|
const config = common.addSecureData(JSON.parse(JSON.stringify(req.body)));
|
2026-05-14 12:10:07 +02:00
|
|
|
const runtimeConfig = oldConfig;
|
2026-05-14 10:32:38 +02:00
|
|
|
Object.keys(config).forEach((key) => {
|
|
|
|
|
if (key !== 'nodes') {
|
|
|
|
|
runtimeConfig[key] = config[key];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (config.nodes && config.nodes.length > 0) {
|
|
|
|
|
const oldNodes = (common.appConfig.nodes && common.appConfig.nodes.length > 0) ? common.appConfig.nodes : (oldConfig.nodes || []);
|
|
|
|
|
const newNodesMap = new Map(config.nodes.map((node) => [node.index, node]));
|
|
|
|
|
const updatedAndExistingNodes = oldNodes.map((oldNode) => {
|
|
|
|
|
const newNode = newNodesMap.get(oldNode.index);
|
|
|
|
|
newNodesMap.delete(oldNode.index);
|
|
|
|
|
const node = newNode ? {
|
|
|
|
|
...oldNode,
|
|
|
|
|
...newNode,
|
|
|
|
|
authentication: { ...(oldNode.authentication || {}), ...(newNode.authentication || {}) },
|
|
|
|
|
settings: { ...(oldNode.settings || {}), ...(newNode.settings || {}) }
|
|
|
|
|
} : {
|
|
|
|
|
...oldNode,
|
|
|
|
|
authentication: { ...(oldNode.authentication || {}) },
|
|
|
|
|
settings: { ...(oldNode.settings || {}) }
|
|
|
|
|
};
|
|
|
|
|
return node;
|
|
|
|
|
});
|
|
|
|
|
const newOnlyNodes = [...newNodesMap.values()].map((newNode) => JSON.parse(JSON.stringify(newNode)));
|
|
|
|
|
runtimeConfig.nodes = [...updatedAndExistingNodes, ...newOnlyNodes];
|
|
|
|
|
}
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
const newAppConfig = JSON.parse(JSON.stringify({
|
2026-05-14 10:32:38 +02:00
|
|
|
...runtimeConfig,
|
|
|
|
|
selectedNodeIndex: config.selectedNodeIndex !== undefined ?
|
|
|
|
|
config.selectedNodeIndex : common.appConfig.selectedNodeIndex,
|
|
|
|
|
enable2FA: config.enable2FA !== undefined ?
|
|
|
|
|
config.enable2FA : common.appConfig.enable2FA,
|
|
|
|
|
allowPasswordUpdate: config.allowPasswordUpdate !== undefined ?
|
|
|
|
|
config.allowPasswordUpdate : common.appConfig.allowPasswordUpdate,
|
|
|
|
|
rtlConfFilePath: common.appConfig.rtlConfFilePath,
|
|
|
|
|
rtlPass: common.appConfig.rtlPass
|
|
|
|
|
}));
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
const fileConfig = JSON.parse(JSON.stringify(newAppConfig));
|
2026-05-14 10:32:38 +02:00
|
|
|
delete fileConfig.selectedNodeIndex;
|
|
|
|
|
delete fileConfig.enable2FA;
|
|
|
|
|
delete fileConfig.allowPasswordUpdate;
|
|
|
|
|
delete fileConfig.rtlConfFilePath;
|
|
|
|
|
delete fileConfig.rtlPass;
|
2026-05-14 12:10:07 +02:00
|
|
|
delete fileConfig.multiPass;
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
// Runtime-only SSO bearer; must not be persisted with the config.
|
|
|
|
|
if (fileConfig.SSO) { delete fileConfig.SSO.cookieValue; }
|
2026-05-14 10:32:38 +02:00
|
|
|
fileConfig.nodes?.forEach((node) => {
|
|
|
|
|
delete node.authentication?.options;
|
|
|
|
|
delete node.authentication?.runeValue;
|
|
|
|
|
});
|
Release 0.15.10 (#1665)
* Update version 0.15.10
* Update project dependencies to resolve Dependabot security alerts
Applies the fixes from the open Dependabot PRs (#1648, #1649, #1650) in a
single pass on the release branch, regenerating the lockfile from scratch.
axios 1.16.0 -> 1.18.1 was the only production exposure (10 advisories).
Transitive deps moved to their fixed in-range versions (fast-uri 3.1.4,
form-data, qs, tough-cookie, tar, del, globby); dev toolchain took safe
bumps (nodemon 3.1.14, eslint 9.39.5, @typescript-eslint 8.65.0).
Drops the unused protractor devDependency: no e2e directory, no config and
no e2e target in angular.json, but 100 packages and the deprecated request
stack behind it. That clears both critical advisories.
npm audit: 50 (2 critical) -> 29 (0 critical); production deps 1 -> 0.
Remaining findings are dev-only tooling needing an Angular 21 migration
rather than a version bump.
Verified: lint, 204 frontend specs, backend + frontend production builds,
and 19 API checks against the docker regtest fixture covering LND, Core
Lightning and Eclair (getinfo, channels, peers, invoices, payments and
forwarding history).
* Fill in PR number in release note (#1653)
* Harden login request validation (#1654)
Tightens server-side validation of authentication requests, guards the password-reset route behind an authenticated session, and wires the backend regression suite (test/backend/) into npm run test. Users with two-factor authentication enabled are encouraged to update promptly.
Verified: backend specs 12/12, lint green, frontend specs 204/204, and the full authentication matrix end-to-end on the docker regtest fixture.
* Reduce exposure of authentication secrets in logs and config responses (#1659)
* Reduce exposure of authentication secrets in logs and config responses
* Fill in PR number in release note (#1659)
* Harden redaction helpers and secret restore paths
* Pin deployment auth switches server-side and harden settings persistence
* Contain backup file reads and harden config persistence
* Pin backup containment root and preserve config file mode on save
* Update Angular framework packages to 20.3.27 (#1661)
* Update Angular framework packages to 20.3.27
Batches the three Dependabot PRs open against master for the Angular framework
(@angular/core #1658, @angular/compiler #1657, @angular/common #1655) into one
update on the release branch. The framework packages are pinned to exact
versions and their peer ranges require them to move together, so all nine
20.3.26 packages go to 20.3.27: animations, common, compiler, compiler-cli,
core, forms, platform-browser, platform-browser-dynamic and router.
Patch-level upstream fixes only, no advisories. The update stays inside Angular
20 - @angular/build and @angular/cli (20.3.32) and @angular/cdk/@angular/material
(20.2.14) are already at the top of their v20 lines - so it does not pull in the
Angular 21 migration tracked by #1650.
Rebuilt frontend/ for the new framework code. backend/ is unchanged, as no
server/ source moved.
* Fill in PR number in release note (#1661)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts Fixes #1630 (#1651)
* Bound remaining unbounded alias-resolution fan-outs in LND graph.ts and channels.ts
Fixes #1630
* Address review feedback: fix options race, error handling, release notes
* Improve release notes entry to cover full PR scope
* Address review feedback: per-task options copy, exclude qs from alias requests
* Stop logging the eclair auth header at DEBUG level (#1664)
* Stop logging the eclair auth header at DEBUG level
getChannels in the eclair channels controller logged its whole request
options object. Eclair authenticates with HTTP basic auth, so those
options carry the configured lnApiPassword in an authorization header -
raising an eclair node's logLevel to DEBUG wrote
"authorization":"Basic <base64>" into the node log file, which is a
recoverable form of the credential and is routinely shared when
debugging.
The log now carries only the request url and form, matching every other
DEBUG log in the controllers. This was the only site in server/ passing a
whole options object to the logger; the rest log options.form, .url,
.body or .qs, none of which hold credentials.
Present since 0.12.0 and only reachable by opting in to DEBUG (the
default log level is ERROR), but it contradicted the logging guarantee
stated for #1659.
Found by scanning node logs at DEBUG while verifying the 0.15.10 branch
against the regtest fixture. Regression test added in
test/backend/eclair-channels.test.mjs; it fails on the previous code with
"auth header key must not reach the node log".
* Fill in PR number in release note (#1664)
---------
Co-authored-by: Osuji <weezdomosuji@gmail.com>
2026-08-03 22:49:14 -07:00
|
|
|
// Persist atomically (temp file + rename, so a mid-write failure cannot truncate the
|
|
|
|
|
// config) and only then adopt the new runtime config, so a failed write leaves the
|
|
|
|
|
// process on the old one. The temp file inherits the existing file's mode so a
|
|
|
|
|
// hardened 0600 is not silently downgraded; a fresh file gets 0600. Symlinks and
|
|
|
|
|
// single-file bind mounts cannot be renamed over — fall back to an in-place write,
|
|
|
|
|
// which preserves inode and mode.
|
|
|
|
|
const tempConfigFile = RTLConfFile + '.tmp';
|
|
|
|
|
try {
|
|
|
|
|
fs.writeFileSync(tempConfigFile, JSON.stringify(fileConfig, null, 2), 'utf-8');
|
|
|
|
|
fs.chmodSync(tempConfigFile, fs.existsSync(RTLConfFile) ? (fs.statSync(RTLConfFile).mode & 0o777) : 0o600);
|
|
|
|
|
fs.renameSync(tempConfigFile, RTLConfFile);
|
|
|
|
|
} catch {
|
|
|
|
|
fs.rmSync(tempConfigFile, { force: true, recursive: true });
|
|
|
|
|
fs.writeFileSync(RTLConfFile, JSON.stringify(fileConfig, null, 2), 'utf-8');
|
|
|
|
|
}
|
|
|
|
|
common.appConfig = newAppConfig;
|
|
|
|
|
// removeSecureData clones, so the runtime config is untouched; it strips rtlPass,
|
|
|
|
|
// the TOTP seed, the SSO cookie and all per-node credentials symmetrically.
|
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Application Settings Updated', data: common.removeSecureData(newAppConfig) });
|
|
|
|
|
res.status(201).json(common.removeSecureData(newAppConfig));
|
2021-12-29 18:08:41 -05:00
|
|
|
} catch (errRes) {
|
2024-06-10 12:40:37 -07:00
|
|
|
const errMsg = 'Update Default Node Error';
|
2021-12-29 18:08:41 -05:00
|
|
|
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 });
|
|
|
|
|
}
|
|
|
|
|
};
|