Commit graph

64 commits

Author SHA1 Message Date
Suheb
a005b687a7
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
Cosimo Ricciardi
a11179085b Add defensive guards for multi-node config updates 2026-07-19 22:01:23 -07:00
Cosimo Ricciardi
18a40ed183 Add defensive fallback for node map initialization 2026-07-19 22:01:23 -07:00
Cosimo Ricciardi
df52b9b77f Add defensive config handling for multi-node settings 2026-07-19 22:01:23 -07:00
Cosimo Ricciardi
bd0f515a6e Add defensive auth guards and cleanup iteration usage 2026-07-19 22:01:23 -07:00
Cosimo Ricciardi
40bd25d921 Address multi-node config auth preservation review 2026-07-19 22:01:23 -07:00
saubyk
030592ac23 Address review: fix logout -> re-login under session-bound CSRF tokens
Session-bound tokens broke re-login after logout: logoutUser destroys
the session, but the SPA navigated to the login page without a
document reload, so the surviving _csrf/XSRF-TOKEN cookies stayed
bound to the destroyed session id and the next login POST failed with
403 until a manual refresh. Hit both manual logout and the idle-timer
auto-logout.

Two coordinated fixes:

1. Frontend: the logout effect now performs a full document navigation
   to the login page (after the server logout completes, so the
   request is not aborted by the reload), which re-runs the handshake
   and mints a token bound to the fresh session. The logout reason
   previously travelled on the NgRx action stream, which cannot
   survive a reload - it is now handed over via sessionStorage (set
   after clearAll) and picked up and cleared by the login component.
   The SSO branch is unchanged (it already left the document).

2. Backend: the EBADCSRFTOKEN error path now re-mints the token for
   the current session before responding 403, so any client holding a
   stale token (e.g. after a server restart rotates the boot secret)
   self-heals on retry instead of looping on 403.

Verified on the fixture: reviewer's repro now shows login 200 ->
logout 200 -> stale-token login 403 (binding intact) with re-minted
cookies on the 403 -> retry 200; and the reload path (fresh GET /
after logout, what the full navigation does) logs in on the first
attempt. Both API suites, the CSRF battery, rtl.effects specs and the
full frontend suite pass; frontend and backend artifacts rebuilt.
2026-07-19 22:01:23 -07:00
saubyk
e617fbb561 Replace deprecated csurf with csrf-csrf
csurf has been deprecated since 2022 and pins an old cookie release
with a known advisory; npm's only fix is a downgrade (issue #1634,
item 2). csrf-csrf v4 implements the same double-submit-cookie pattern
with an HMAC-signed, session-bound token keyed on the existing boot
secret (common.secret_key).

The frontend contract is unchanged: the token still arrives via the
XSRF-TOKEN cookie/header and is echoed as x-xsrf-token (all token
sources csurf accepted are still read), the signed cookie keeps the
_csrf name (now httpOnly, secure:false to match the session cookie on
plain-HTTP deployments), doubleCsrfProtection attaches req.csrfToken
so app.ts keeps working, and the error code is EBADCSRFTOKEN - already
handled in app.ts. The websocket upgrade check in authCheck.ts now
routes through the shared middleware; upgrade requests are GETs, so
its pass-through semantics are unchanged.

One fix this surfaced: app.ts called req.csrfToken() twice (cookie and
header). Under csurf every token validated against a stable secret;
under csrf-csrf each first-visit call mints a new token, desyncing the
XSRF-TOKEN cookie from the _csrf cookie it must equal. The token is
now generated once per request.

Tokens are session-bound, so a token stolen from one session no longer
validates in another - a check csurf's cookie mode did not perform.

Production npm audit drops from 6 low findings to 4, all in the
crypto-browserify/elliptic chain tracked in #1634.

Verified against the docker regtest fixture: both API suites (43
checks across LND, CLN and Eclair) plus a dedicated CSRF battery -
valid-token auth, missing token 403, garbage token 403, cross-session
replay 403, token stability across requests, the XSRF-TOKEN response
header for Quickpay, and the websocket handshake. Lint and build are
clean.
2026-07-19 22:01:23 -07:00
saubyk
5d1f55a9c6 Address review: exempt LND subscription streams from the request timeout
The 10-minute timeout added for review feedback would have aborted
LND's long-poll subscription streams (/v2/invoices/subscribe and
/v2/router/track), which legitimately stay open until an invoice
settles or a payment resolves - breaking real-time notifications for
any invoice paid more than 10 minutes after creation.

The wrapper now honors a per-call options.timeout (0 disables the
bound, axios semantics; the 10-minute default still applies everywhere
else), and both subscription calls pass timeout: 0. They also copy the
options object instead of mutating it: addInvoice hands the
session-cached options to subscribeToInvoice, so setting the timeout
in place would have leaked an unbounded timeout to every subsequent
request for that node (getOptions resets form/body/qs but not
timeout).

Verified on the regtest fixture: with a websocket client connected as
alice's frontend, creating an invoice opens the subscription stream,
it survives idle, and paying it from the CLN node delivers the SETTLED
event over the websocket in real time. The per-call override was also
verified directly (timeout: 1000 aborts a slow upstream with
ECONNABORTED; timeout: 0 waits it out). Both API suites (31 read + 12
write checks) re-pass.
2026-07-19 22:01:23 -07:00
saubyk
1efaa24d72 Address review: CSV-encode array form fields and bound request timeout
Review feedback on #1638 flagged two issues in the wrapper:

1. Array form values (eclair's ignoreNodeIds on findroutebetweennodes)
   encoded as "ignoreNodeIds=a,b" via String(), and worse, an empty
   array produced "ignoreNodeIds=" which Eclair's pubkey list parser
   rejects - breaking the default findroute path that worked under
   request-promise (qs omitted empty arrays). Arrays are now omitted
   when empty and comma-joined when not, matching Eclair's CsvSeq list
   format. Verified against the fixture: route eclair->bob->carol is
   found with an empty ignore list and disappears when bob is ignored.
   Under request-promise's qs indexed encoding (ignoreNodeIds[0]=...)
   Eclair never matched the field name, so the ignore list was silently
   dropped; this change makes it effective for the first time.

2. The shared transport had no request timeout, so a hung upstream
   held connections open indefinitely. Added a 10-minute bound,
   sized to the slowest legitimate operations (LND's /v2/router/send
   streams up to timeout_seconds=600; slow CLN channel operations get
   req.setTimeout(600000) upstream).

Both API suites (31 read + 12 write checks) re-pass on the fixture.
2026-07-19 22:01:23 -07:00
saubyk
a8baba12bb 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 22:01:23 -07:00
saubyk
e0fce065d5 Address 2nd review: guard limiter callbacks, CLN postPeer aliases, one-shot done
Follow-up to the second #1629 review:

- F4: the limiter invokes its done callback outside the surrounding .then/.catch,
  so a throw in the response-send body became an unhandled rejection with no
  response (a 500 -> hang regression, notably on LND postPeer where the inner
  .catch was removed). Wrap each converted done body in try/catch that sends the
  error response, guarded by res.headersSent.
- F5: CLN postPeer re-listed peers but never resolved their aliases, so a freshly
  connected CLN peer came back with a raw node id (the frontend uses this response
  directly). Resolve aliases through the same bounded limiter, matching LND postPeer.
- F6: make runWithConcurrencyLimit fire 'done' exactly once via a one-shot guard,
  so multiple synchronous completions (e.g. non-function task elements) can't
  double-send the response.
2026-07-19 22:01:23 -07:00
saubyk
bd74132265 Address review: self-contained CLN getAlias, LND peers bound, limiter guard
Follow-up to the #1501 review (PR #1629):

- F1: CLN getAlias now builds its request from selNode.authentication.options
  instead of the shared module-level 'options'. That coupling meant a cold
  Peers/route lookup dereferenced a null 'options'; with the new limiter
  swallowing per-task throws, that returned 200 with every alias unset. Aliases
  now resolve regardless of call order, with a truncated-id fallback if auth
  options are somehow absent.
- F2: mirror the 20-way concurrency bound to LND peers (getPeers and postPeer),
  which had the same unbounded Promise.all alias fan-out. Eclair resolves
  aliases inline from a bulk nodes list, so it needs no change.
- F3: normalize runWithConcurrencyLimit's start count to at least 1 so a
  non-positive limit can't leave 'done' unfired and hang the response.
2026-07-19 22:01:23 -07:00
saubyk
fbd336a89b Bound CLN alias resolution on peers and route lookups (#1501)
RTL resolves peer aliases by calling listnodes once per peer. A prior fix
(1cec7b1) bounded this to 20 concurrent calls plus a cache for the channel
list, but the peers list and route lookup still used an unbounded Promise.all,
firing one request per peer at once. On nodes with many peers this overwhelms
clnrest and fails with 'Resource temporarily unavailable (os error 11)'
(EAGAIN), so aliases fall back to raw node IDs.

- peers.ts and network.ts getRoute now resolve aliases via
  runWithConcurrencyLimit(tasks, 20, ...), matching the channel list.
- Harden runWithConcurrencyLimit to call done() immediately for an empty task
  list; otherwise an empty peers/route set would never send a response.
- Give the alias cache a 6h TTL and a max size (evicting oldest) so aliases
  refresh without an RTL restart and the cache can't grow unbounded.
2026-07-19 22:01:23 -07:00
Matt Hill
42cb3c76e8 Fix setOptions cache poisoning when one node's auth load fails 2026-07-19 22:01:23 -07:00
ShahanaFarooqui
4613b889bf Add Disable Authentication option in the backend 2026-07-19 22:01:23 -07:00
ShahanaFarooqui
7340cb390a
Release 0.15.6 (#1506)
Fix for Resource temporarily unavailable error for CLN channel alias list
Security fix for npm vulnerabilities
2025-09-09 02:18:23 -07:00
ShahanaFarooqui
d51301adde
Release 0.15.4 (#1472)
* Fix for sso access key reading (#1469)
2024-11-18 20:27:51 -08:00
ShahanaFarooqui
a594606d27
Release 0.15.3 (#1467)
* Fix `Unknown command` error when disabling offers on CLN. ([#1443]) (#1451)
* Add missing SSO options to config (#1455)
* Fix for cln logic screen navigation (#1457)
* Transactions destination address display fix (#1458)
* cln delexpiredinvoices deprecation fix (#1459)
* Read LN_IMPLEMENTATION from environment (#1460)
* Add Fee Rate Information on Send Funds Modal (#1461)
* Artifact script fix (#1464)
* Add AMP toggle for LND Send Payments (#1466)

---------

Co-authored-by: Se7enZ <118189041+s373nZ@users.noreply.github.com>
2024-11-10 20:23:52 -08:00
ShahanaFarooqui
5a6b5f2cae
Check for authentication obj before delete operation #1415 (#1416) (#1417) 2024-06-20 13:26:21 -07:00
ShahanaFarooqui
22ab6d1154
Release 0.15.1 (#1406)
* rm .DS_Store

* Add watchfrontenddev command for npm

* Fix toggle issues in sidenav (pinning and on page refresh)

* Add copy-to-clipboard fallback if navigator.clipboard is not available (#1336)

* add copy-to-clipboard fallback if navigator.clipboard is not available

* amend copy fallback

* clipboard copy lint fixes and frontend build

* fix: add missing boltz state `transaction.lockupFailed` (#1349)

* fix: boltzd docs link (#1354)

* exit gracefully (#1356)

* allow for eclair updated relayed audit format (#1363)

* feat: add boltz service to cln (#1352)

* lint fix

* Request Params Cleanup

* cln: Boltz auto-send (#1366)

* Bug-fix (CLN Boltz): Hide claim tx id and routing fee for non-zero conf reverse swap

* cln: Boltz auto-send

- Added auto send option for Swap In
- Checking compatiblity with v2.0.0 and above

* Test import fixes

* Update help.component.ts (#1379)

Fixed broken link under "Help" -> "Node Settings"

* Backend config fix (#1382)

* Updating Common Application Configuration

* Fixed get RTL Conf

* Update Application Settings

* application and settings case change

* Unified config models

* Default node update

* 2FA and Password reset

* Final application settings update

* Config Settings and Authentication case fixed

* Node Setting Fix

* Fiat currency Symbol fix

* CLN: Fiat symbol fix

* All: Fiat symbol fix

* Update node settings

* Services UI fix

* CLN: Removed child node settings

* All: Removed child node settings

* Test fixes

* mempool links for onchain information (#1383)

* Tests fix

Tests fix

* UI for Block Explorer Configuration (#1385)

* Bump fee with mempool information (#1386)

* Mempool openchannel minfee (#1388)

Open channel model block if min fee is higher

* Show error on login screen if rune is incorrect and getinfo throws error (#1391)

* cln: Removed channel lookup call for update policy (#1392)

* ECL: On-chain Transactions, Invoice and Payments pagination (#1393)

Done most of the UI changes to accommodate pagination on transactions, payments and invoices tables but true pagination cannot be implemented till total number of records are missing from the API response.

Once the issue https://github.com/ACINQ/eclair/issues/2855 is fixed, I will uncomment pagination changes in the frontend.

* lnd: Onchain CPFP (#1394)

- UTXO label bug fix
- Warning on utxo label for "sweep" in text.

* Bug fixes after testing

* Testing bug fixes (#1401)

* Bug fix 2: lnd: Link channel point to explorer and show fee on close channel too

* lnd: explorer link on pending channels

* Node lookup link on view channel peer pubkey

* Testing bug fixes (#1402)

* Bug fix 2: lnd: Link channel point to explorer and show fee on close channel too

* lnd: explorer link on pending channels

* Node lookup link on view channel peer pubkey

* test fixes

* ng update to v18.0.x

* Updating install with  --legacy-peer-deps

---------

Co-authored-by: Grzegorz Kućmierz <gkucmierz@gmail.com>
Co-authored-by: lacksfish <lacksfish@gmail.com>
Co-authored-by: jackstar12 <62219658+jackstar12@users.noreply.github.com>
Co-authored-by: Kilian <19181985+kilrau@users.noreply.github.com>
Co-authored-by: Taylor King <taylorbradleyking@gmail.com>
Co-authored-by: Fishcake <128653975+fishcakeday@users.noreply.github.com>
Co-authored-by: Ant <72945059+2140data@users.noreply.github.com>
2024-06-10 12:40:37 -07:00
ShahanaFarooqui
475b47b7ea
Release 0.15.0 (#1334)
c-lightning-REST to clnrest migration.
2023-12-05 20:32:05 -08:00
ShahanaFarooqui
14fd866d1a Bug fix: Manage button link filter #1294 and Page Settings Error 2023-10-05 19:04:37 -07:00
ShahanaFarooqui
656ab99f88 Show loop version 2023-10-02 20:55:16 -07:00
ShahanaFarooqui
36e1d39170 Updated channels response columns and migrated pagesettings 2023-09-28 20:18:14 -07:00
ShahanaFarooqui
56e5558bf7 Offers Update #1206 2023-02-20 23:54:28 -08:00
ShahanaFarooqui
8e65dd2c9e Make db location configurable #1177
Make db location configurable #1177
2023-02-17 17:33:33 -08:00
ShahanaFarooqui
03dca70aa1 Updated error handling function
Updated error handling function
2023-02-17 14:58:59 -08:00
ShahanaFarooqui
d29a1fbdb8 Removing lint and strict typecheck 2022-12-27 19:04:23 -08:00
ShahanaFarooqui
5107c300eb 2FA Fix
2FA Fix
2022-12-27 18:05:42 -08:00
ShahanaFarooqui
4b29474f3e lint error fix & localhost to ip docs 2022-12-15 15:09:08 -08:00
ShahanaFarooqui
0e48676c5c Removed LN Config Auth for SSO 2022-12-13 21:41:44 -08:00
ShahanaFarooqui
670141a097 Table Sorting Fix 2022-12-12 19:02:07 -08:00
ShahanaFarooqui
893fcd964b Build and test error fixes 2022-11-29 13:30:58 -08:00
ShahanaFarooqui
7e40c4ea30 All Dependencies update 2022-11-28 20:42:17 -08:00
ShahanaFarooqui
dee4f75d3d ECL Removed Channel Type 2022-11-16 13:02:43 -08:00
ShahanaFarooqui
2c113030b4 Unannounced Channel Configuration #1036 2022-11-15 19:17:23 -08:00
ShahanaFarooqui
b505931c82 Removing channel type selection 2022-11-15 12:55:44 -08:00
ShahanaFarooqui
38a02839d6 Page Layout Finished 2022-11-03 14:31:09 -07:00
ShahanaFarooqui
c70911cdd3 CLN Manual Testing Done 2022-11-03 13:03:27 -07:00
ShahanaFarooqui
7fea447975 CLN Filter by selected column 2022-11-02 15:59:37 -07:00
ShahanaFarooqui
0a22082987 Bug fix: default config doesn't have password
Bug fix: default config doesn't have password
2022-11-02 08:59:58 -07:00
ShahanaFarooqui
a7c65268a5 DB Files error fix if indices are changed 2022-10-31 10:30:55 -07:00
ShahanaFarooqui
4d163a8216 db and ellipsis fix 2022-10-28 14:20:34 -07:00
ShahanaFarooqui
2e54ba92ac Fixed grid paddings 2022-10-28 09:41:38 -07:00
ShahanaFarooqui
7a0bd37d91 Validate Document First 2022-10-15 17:25:46 -07:00
ShahanaFarooqui
cfd8f095a3 DB Validations 2022-10-15 16:35:39 -07:00
ShahanaFarooqui
d6185dd409 Whole Setup Validation
Whole Setup Validation
2022-10-14 17:10:58 -07:00
ShahanaFarooqui
6945d084b4 Base Config Page
Base Config Page
2022-10-12 14:38:21 -07:00
ShahanaFarooqui
c9d389cbd7 Add Taproot Address Type #1075
Add Taproot Address Type #1075
2022-09-23 17:35:25 -07:00