2319 Commits

Author SHA1 Message Date
Jacky
ba2bbe3ac2 fix: resolve concurrent map iteration and map write crash in sitecheck (#1661)
Fixed fatal error 'concurrent map iteration and map write' that caused
nginx-ui nodes to crash and become unresponsive.

The issue occurred when the sitecheck CollectSites() method iterated over
site.IndexedSites while the cache scanner's scanForSite() was concurrently
modifying the same map. This race condition caused sporadic crashes.

Solution:
- Added GetAllIndexedSites() function in internal/site/index.go that safely
  returns a snapshot copy of the IndexedSites map while holding the read lock
- Modified CollectSites() in internal/sitecheck/checker.go to use this
  thread-safe function instead of directly accessing the global map

Fixes #1673

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-05-06 11:28:57 +08:00
renovate[bot]
078a6764bd chore(deps): update all non-major dependencies (#1659)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-04 11:13:21 +08:00
Carm
a98bd9216b feat(cert): Optimize certificate application operations. (#1657)
* feat(cert): Optimize certificate application operations. #1602

* chore(lang): Add language context for new DNS application

* chore(lang): Add language context for new DNS application
2026-05-04 11:13:12 +08:00
0xJacky
0662353420 chore: prepare v2.3.10 v2.3.10 2026-04-28 12:36:18 +08:00
0xJacky
432a791cad chore: update translations 2026-04-28 03:55:36 +00:00
0xJacky
0301578295 fix(notification): render external notification placeholders 2026-04-28 09:05:52 +08:00
0xJacky
30908f3c28 chore: prepare v2.3.9 v2.3.9 2026-04-27 12:22:46 +08:00
0xJacky
4e4174d89a fix(backup): require secure session for restore 2026-04-27 11:53:31 +08:00
0xJacky
fd61e8ea6f fix(config): restrict executable nginx directives 2026-04-27 11:32:04 +08:00
Adamthereal
61185c26f4 test(middleware): add CSWSH hardening cases for CheckWebSocketOrigin (#1647)
Locks in the v2.3.5 origin-validation fix for CVE-2026-34403 / GHSA-78mf-482w-62qj
with named regression cases for every bypass class documented in the advisory:
subdomain confusion, suffix confusion, scheme downgrade, port mismatch, default-
port normalization, ws/wss scheme equivalence, case-insensitive host, IPv6 literal,
RFC 7239 Forwarded parsing, multi-valued X-Forwarded-Host, scheme-only / malformed
origin rejection, node_secret query fallback, empty-secret regression, trailing-
slash tolerance on configured trusted origins.

17 table-driven subtests in a new file; zero production code changes; no new
dependencies.

Co-authored-by: Panguard AI <support@panguard.ai>
2026-04-22 09:33:50 +08:00
0xJacky
3e411d38dd Harden config write paths 2026-04-21 22:40:50 +08:00
0xJacky
7864e378f5 chore: prepare v2.3.8 v2.3.8 2026-04-21 15:15:12 +08:00
0xJacky
28652c0f04 docs: document install secret locations 2026-04-21 14:03:29 +08:00
renovate[bot]
171bb52998 chore(deps): update pnpm.catalog.default uuid to v14 (#1643)
* Throttle auto cert retries and expose renewal errors

* chore(deps): update pnpm.catalog.default uuid to v14

---------

Co-authored-by: 0xJacky <me@jackyu.cn>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 23:52:15 +08:00
0xJacky
d25c9975d6 fix(analytic): avoid websocket keepalive race 2026-04-20 23:50:45 +08:00
0xJacky
57b6f982ec fix: preserve forwarded host for docker websocket checks 2026-04-20 23:39:22 +08:00
0xJacky
899c9f1995 fix(cert): throttle auto-renew retries and expose renewal errors 2026-04-20 23:19:50 +08:00
0xJacky
05e544c8f5 fix(upstream): separate http and websocket routes 2026-04-19 11:50:08 +08:00
0xJacky
f960a6bd78 docs: clarify docker access ports 2026-04-19 11:42:53 +08:00
0xJacky
25dea9f620 fix(setup): harden first-run installation flow 2026-04-18 23:47:45 +08:00
0xJacky
4d96c34991 enhance: polish sensitive value masking UI 2026-04-18 23:38:31 +08:00
0xJacky
80a6a7273d enhance: protect sensitive settings with 2FA reveal flow 2026-04-18 20:19:50 +08:00
0xJacky
a67285b713 chore: prepare v2.3.7 v2.3.7 2026-04-18 11:04:41 +00:00
0xJacky
7ed73f621a feat(analytic): implement WebSocket keepalive mechanism 2026-04-18 11:02:52 +00:00
0xJacky
b1b1596a4d chore: update .gitignore and remove settings.local.json 2026-04-18 08:08:03 +00:00
0xJacky
535c8efb38 fix(sitecheck): bound outbound connections and add global controls (#1608)
The site checker created a fresh http.Transport per request and per
EnhancedSiteChecker, with Go's default Happy-Eyeballs dialer. When
server_name entries resolved to ingress services returning many A
records (ngrok, AWS ALB, Cloudflare), each sweep opened enough flows
to exhaust conntrack tables on consumer routers (UniFi).

Introduce a package-level shared http.Transport with MaxConnsPerHost=2,
MaxIdleConnsPerHost=2 and FallbackDelay=-1 (disables IPv6 dial races),
plumb it through SiteChecker and EnhancedSiteChecker, and only build a
custom client when the per-site HealthCheckConfig truly diverges on
TLS. Reuse the response body fetched by the health check for favicon
extraction so each site is hit at most once per sweep, and dedupe sites
sharing the same host:port before fan-out.

Add a [site_check] settings section (Enabled, Concurrency, Interval-
Seconds) so operators can disable the checker entirely or tune the
sweep cadence; clamp Concurrency to [1, 20] and IntervalSeconds to
>=30. Document the new section in en, zh_CN and zh_TW guides and add
sidebar entries.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 16:06:06 +08:00
0xJacky
c38e0a28b8 fix(sites): honor configured healthcheck protocol (#1628)
The site healthcheck built its request URL from the indexed site URL
(e.g. http://example.com) and never rewrote the scheme to match the
user-configured HealthCheckConfig.Protocol. As a result, sites
configured for HTTPS were probed over HTTP and always shown as
unreachable. TestHealthCheck compounded the issue by using
siteConfig.Scheme (default "http") instead of req.Config.Protocol.

Introduce rewriteCheckURLScheme which aligns only the URL scheme with
the configured protocol while preserving path, query, and port, and
call it from CheckSiteWithConfig. TestHealthCheck now passes the stored
site URL and relies on the same rewrite, so the "Test" button exercises
the same code path as the scheduled checker.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 16:03:23 +08:00
0xJacky
50ccaaeb2f chore: update settings.local.json 2026-04-18 14:54:29 +08:00
0xJacky
329e8589e9 fix(cert): restore WebSocket connection for certificate issuance (#1630)
`ObtainCert.job()` called `issueCert()` synchronously after `step.value++`,
before Vue mounted `<ObtainCertLive>`, so `refObtainCertLive.value` was
null and the optional-chain call silently no-oped — no log entry, no
WebSocket connection, progress stuck at 0%. Add an `await nextTick()`
so the live component is mounted before its method is invoked.

Also harden the long-token WebSocket fallback: switch the frontend to
URL-safe base64 (avoids `+` being decoded as a space in query strings)
and accept both URL-safe and standard base64 in `getTokenWS` for
backward compatibility.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-18 14:54:29 +08:00
renovate[bot]
513d5d6fbb chore(deps): update all non-major dependencies (#1641)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-18 13:29:01 +08:00
Tema Smirnov
32d5ce0018 fix(app): embed generated assets with underscore names (#1640) 2026-04-18 08:59:45 +08:00
0xJacky
b01ea55ed6 chore: update deps 2026-04-17 19:36:03 +08:00
renovate[bot]
f73aabb59b chore(deps): update softprops/action-gh-release action to v3 (#1632)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 16:44:03 +08:00
the fire inside me
89c1fdfb44 fix upstream (#1637) 2026-04-15 23:26:19 +08:00
renovate[bot]
20538d9c7b chore(deps): update all non-major dependencies (#1634)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-15 01:15:44 +00:00
renovate[bot]
335fc66c90 chore(deps): update pnpm.catalog.default marked to v18 (#1626)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
v2.3.6
2026-04-08 09:52:13 +08:00
0xJacky
863f36179c chore: prepare v2.3.6 2026-04-04 15:44:07 +00:00
0xJacky
f8019e68b9 feat(ngx-config-editor): enhance location and directive handling with unique keys
- Introduced unique key generation for locations and directives using WeakMap to improve item identification in draggable lists.
- Updated the `item-key` binding in `LocationEditor.vue` and `DirectiveEditor.vue` to utilize the new key generation functions.
- Refactored the NgxConfig store to include a reset function, ensuring a clean state for ngxConfig when needed.
- Enhanced the `SiteAdd.vue` component to reset the ngxConfigStore during initialization.
2026-04-04 14:28:56 +00:00
0xJacky
0b0f854f9b feat(backup): enhance backup and restore functionality with crypto secret handling
- Added tests to verify backup and restore processes when the crypto secret changes, ensuring hash verification passes.
- Updated `writeManifestFiles` and `verifyBackupManifest` functions to accept an AES key for improved security.
- Implemented fallback mechanism for verifying manifest signatures using both AES-derived and legacy signing keys.
- Enhanced the overall robustness of the backup and restore system to handle legacy signatures and different crypto secrets.
2026-04-04 14:26:34 +00:00
renovate[bot]
edf92e4ffe chore(deps): update all non-major dependencies (#1623)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-04 11:06:43 +08:00
Jacky
d454a2a9d2 fix(mcp): prevent panic on nil interface conversion for tool arguments (#1622)
* fix(mcp): prevent panic on nil interface conversion for tool arguments

Add safe argument extraction helper functions in internal/mcp/args.go
that handle nil values gracefully instead of panicking on direct type
assertions.

This fixes the issue where MCP config tools panic with:
'interface conversion: interface {} is nil, not string'
when called via Claude Desktop with protocol version 2025-11-25.

Affected tools:
- nginx_config_list
- nginx_config_get
- nginx_config_add
- nginx_config_modify
- nginx_config_rename
- nginx_config_mkdir
- nginx_config_history
- nginx_config_enable

Fixes #36ec

Co-authored-by: Jacky <me@jackyu.cn>

* Add required argument validation to MCP config handlers to prevent data loss

The safe argument extraction helpers (mcp.GetString, etc.) return zero values
for nil/missing arguments, which could cause silent data loss. This adds
explicit validation for required arguments in:

- config_modify: validate relative_path and content
- config_add: validate name and content
- config_rename: validate orig_name and new_name
- config_mkdir: validate folder_name

This follows the same pattern already used in handleNginxConfigEnable.

* Add required argument validation to config_get and config_history handlers

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-04-04 10:51:50 +08:00
0xJacky
9f1b9bbbba refactor(ws): implement SafeWebSocketWriter for serialized access
- Introduced SafeWebSocketWriter to ensure thread-safe writes to WebSocket connections.
- Updated WebSocket handling in certificate issuance, revocation, Nginx log tailing, and system upgrades to use the new writer.
- Enhanced WebSocket client management in the site navigation module for improved message handling and connection stability.
2026-04-04 02:01:20 +00:00
Simon Zöllner
b9e1951423 Fix #1619, WebSocket check fails during initial setup on custom ports (#1620)
* enhance(ws): improve session security

* Fix #1619, WebSocket check fails during initial setup on custom ports in docker

---------

Co-authored-by: 0xJacky <me@jackyu.cn>
2026-04-04 09:50:48 +08:00
0xJacky
d895c4a336 enhance(ws): improve session security 2026-04-04 09:48:18 +08:00
0xJacky
7d9887bfe8 fix: enhance WebSocket origin validation for trusted node requests 2026-04-03 11:31:41 +08:00
0xJacky
02931d6c31 feat: enhance TLS certificate handling and server configuration 2026-04-02 22:44:10 +08:00
renovate[bot]
f290060e55 chore(deps): update all non-major dependencies (#1612)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-02 11:04:57 +08:00
renovate[bot]
314efd0c25 chore(deps): update pnpm.catalog.default @antfu/eslint-config to v8 (#1617)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-02 11:00:27 +08:00
0xJacky
fb37c94276 feat: implement short token endpoint for WebSocket authentication
- Added `InitTokenRouter` to define the `/token/short` endpoint for issuing short tokens.
- Created `IssueShortToken` function to handle short token generation and response.
- Updated WebSocket middleware to require short token for authentication, preventing CSWSH attacks.
- Modified user store and login handling to integrate short token functionality.
- Enhanced documentation to reflect changes in WebSocket security requirements.
2026-04-02 00:06:04 +08:00
renovate[bot]
f89f8ff822 chore(deps): update pnpm.catalog.default unplugin-vue-components to v32 (#1605)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-28 11:13:41 +08:00