Commit graph

1345 commits

Author SHA1 Message Date
root
ef9e123fcc style: gofmt web/service/setting.go 2026-04-25 20:35:10 +08:00
root
25cf22d161 feat: support full mihomo template and multi-server for Clash Link
- Add splitTemplate() to split at proxies:/proxy-groups: markers (like mihomo-gen)
- Store clash_template.yaml and servers.yaml as files alongside x-ui.json
- Add Clash/Servers editors in Xray advanced config page
- Support multi-server proxy generation (each server × each client)
- Remove inline template editor from Clash settings panel
- Bump version to v1.7.2.1
2026-04-25 18:23:42 +08:00
root
67c4f6a1ad fix: update rate limit tests to use CF-Connecting-IP header
The middleware was changed to trust CF-Connecting-IP instead of
X-Real-IP/X-Forwarded-For, but the tests still used the old headers.
TestRateLimitMiddleware_DifferentIPsIndependent was failing because
all requests fell back to the same httptest RemoteAddr.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 15:14:02 +08:00
root
e035fb07a9 fix: trust Cloudflare CF-Connecting-IP for IP extraction
When behind Cloudflare CDN, RemoteAddr shows CF's IP, breaking rate
limiting and logging. Trust CF-Connecting-IP (set by CF, cannot be
spoofed by clients) and fall back to RemoteAddr for direct connections.
2026-04-25 11:45:07 +08:00
root
77d276da04 fix: add login rate limiting and prevent IP spoofing via headers
- Add RateLimitMiddleware(10/min) to POST /login (previously unprotected)
- Use RemoteAddr instead of X-Real-IP/X-Forwarded-For in getRemoteIp() and rate limiter
- Prevents brute-force login and rate-limit bypass via spoofed headers
2026-04-25 11:43:03 +08:00
root
61f7956af4 fix: unify master/worker connected nodes to single a-table
Replace worker's plain HTML table with the same a-table used by master,
fixing inconsistencies: missing role column, no error ellipsis, dead-code
empty state ternary, and duplicate a-empty elements.
2026-04-25 11:14:57 +08:00
root
5ce18ebfc1 fix: use explicit closing tags for a-empty components
Self-closing custom elements (<a-empty />) are invalid in HTML5
in-DOM templates. The browser treats them as opening tags, causing
subsequent sibling elements to become children. This made the
worker's node info table a child of the hidden <a-empty>, so it
never rendered when nodes.length > 0.
2026-04-25 10:45:23 +08:00
root
66de42f21b fix: node config save, dbType mismatch, and dark theme support
- ShouldBindJSON → ShouldBind with form tags (axios sends url-encoded)
- dbType dropdown value "mysql" → "mariadb" to match backend
- Replace inline styles with theme-aware CSS classes for dark mode
2026-04-25 10:19:41 +08:00
root
5bf2b5ef88 fix: replace v-else with v-if on node info table
v-else on <table> element was not recognized by Vue template compiler,
causing the worker node info table to never render. Use v-if="nodes.length > 0"
instead to ensure the table renders when data is available.
2026-04-25 09:49:32 +08:00
root
4e49f8c072 fix: replace a-descriptions with HTML table and fix ensureDefaultNodeSettings
- Replace a-descriptions/a-descriptions-item with plain HTML table in
  nodes.html — the components were missing from the antd.min.js bundle
  due to tree-shaking, causing the worker node view to render empty
- Fix ensureDefaultNodeSettings to write defaults to both "node" and
  "other" groups for backward compatibility (tests were failing)
2026-04-25 09:36:21 +08:00
root
db2c78d0bb fix: add error logging for node state writes and queries
Silent error swallowing made it impossible to diagnose why worker
couldn't see master's heartbeat. Now logs errors from:
- updateNodeState upsert failures
- writeStateToSharedMariaDB connection/write failures
- getNodeStatesShared query failures
- list endpoint shows state count in logs

Also improved First() call to not overwrite state on error.

Bump version to v1.6.5.
2026-04-24 22:08:00 +08:00
root
226bae2b2f fix: master heartbeat not visible to workers in shared MariaDB mode
When master uses SQLite locally, updateNodeState only wrote to local DB.
Workers querying shared MariaDB never saw the master's heartbeat.

Now master also writes its heartbeat to the shared MariaDB via a
temporary connection when MariaDB connection settings are configured.

Bump version to v1.6.4.
2026-04-24 21:29:57 +08:00
root
d733ff2af1 fix: add node settings to defaultValueMap and settingGroups
Node settings (nodeRole, nodeId, syncInterval, trafficFlushInterval)
now have defaults in the settings system. On fresh install, they are
automatically created in x-ui.json under the 'node' group. The
settingGroupAliases now look in 'node' first, then 'other' for
backward compatibility.
2026-04-24 20:57:12 +08:00
root
d5bf2858ce fix: query shared MariaDB for node states instead of local DB
In shared mode, the master may use SQLite locally while workers
write heartbeats to the shared MariaDB. The /list endpoint now
opens a temporary MariaDB connection to query node_states when
the local DB is not MariaDB.
2026-04-24 18:01:59 +08:00
root
a3d8e9c55c style: apply gofmt formatting 2026-04-24 17:44:02 +08:00
root
07fecdbf86 fix: add component includes and fix API paths in nodes page 2026-04-24 17:39:01 +08:00
root
678d35d303 fix: correct divider text and worker empty message in nodes page 2026-04-24 17:19:50 +08:00
root
7d75d02c1e feat: add nodes.html page with node list and config form 2026-04-24 17:13:35 +08:00
root
c09c618207 feat: add nodes menu item to sidebar 2026-04-24 17:10:46 +08:00
root
fc77154c8b feat: add i18n translations for node management 2026-04-24 17:10:42 +08:00
root
cb4b1eba85 feat: register NodeController routes and nodes page
- Add nodeController field and route group in api.go
- Add /panel/nodes page route in xui.go
- Verified node.go does not add duplicate checkAdmin middleware
2026-04-24 17:08:52 +08:00
root
16eb179eaf feat: add NodeController with list, getConfig, and updateConfig endpoints
Expose node management API endpoints for the cluster feature:
- GET /node/list — returns connected nodes with online status
- GET /node/config — returns current node + DB configuration
- POST /node/config — validates and persists node settings to x-ui.json
2026-04-24 17:06:11 +08:00
root
f5862abc2e feat: add CodeMirror YAML editor for Clash template and fix settings save button bug
- Replace plain textarea with CodeMirror editor (YAML syntax highlighting, line numbers, auto-indent) for Clash subscription template
- Fix confAlerts crash when subClashURI/subURI/subJsonURI is null/undefined (prevented save button from enabling)
- Add yaml.js CodeMirror mode asset
- Include docs and .gitignore cleanup
2026-04-24 16:15:22 +08:00
root
582037ae70 fix: settings save button and multiple UI bugs
- Fix duplicate :min attributes on a-input-number (webPort, subPort, tgCpu)
- Fix mismatched closing tags (a-input/a-switch instead of a-input-number)
- Fix twoFactorEnable toggle receiving MouseEvent instead of boolean
- Fix noise input handlers referencing undefined global `event`
- Add error handling to settings change detection polling loop
- Bump version to v1.5.4-beta
2026-04-24 15:44:48 +08:00
root
aadd8fdd89 style: apply gofmt formatting 2026-04-24 14:43:44 +08:00
root
288635adfc fix: Clash YAML injection, path validation, and default template
- Quote all YAML string values with %q to prevent injection
- Remove unused host parameter from GetClash
- Add backend path normalization for SubClashPath
- Log StreamSettings JSON unmarshal errors
- Expand template panel by default and provide default template
2026-04-24 14:35:28 +08:00
root
11cdb07e89 feat: add Clash YAML subscription endpoint with template injection
Add /clash/:subid endpoint that returns complete Clash YAML config.
User provides full template (DNS, routing, proxy-groups, rules) in
settings, panel generates proxies from inbound/client data and injects
via proxies: [] placeholder replacement.

- New SubClashService reads template, generates vmess/vless/trojan/ss
  proxy entries with transport (ws/grpc/h2/tcp/httpupgrade), TLS, and
  Reality support
- Settings: subClashEnable, subClashPath, subClashURI, subClashTemplate
- UI: Clash settings tab, QR code on subpage, Desktop dropdown with
  clash-verge:// deep link preferring Clash URL
- Version bump to v1.5.2-beta
2026-04-24 11:25:10 +08:00
root
1a02ebb024 fix: MariaDB JSON_EACH compatibility for subscription and traffic queries
Replace SQLite-only JSON_EACH with DB-type branching (JSON_TABLE for
MariaDB) in subscription, client traffic, and migration queries.
Bump version to v1.5.1.
2026-04-24 10:16:48 +08:00
root
51f17922fa fix: resolve shared-mode traffic flush blocked by stale inboundId=0 delta
The traffic-pending.json file could contain a stale client traffic delta
with inboundId=0 (created before the InboundId resolution fix). When
flushToDatabase tried to INSERT this into client_traffics, it violated
the foreign key constraint fk_inbounds_client_stats, causing the entire
transaction to roll back and blocking ALL traffic from being written to
MariaDB.

- Skip deltas with InboundID==0 in flushToDatabase with a warning log
- Share a single TrafficPendingStore between XrayTrafficJob and the
  flush loop to eliminate a race condition from dual file instances
- Add test for zero InboundID skip behavior
2026-04-24 02:56:23 +08:00
root
99e2e6c2e2 fix: resolve client traffic InboundId from DB in shared mode, set online clients
In shared mode the Xray API returns InboundId=0 for client traffic.
Collect() now looks up the real InboundId from the client_traffics table
by email, and skips unknown emails with a warning. Also computes and
sets online clients in XrayTrafficJob since addClientTraffic is bypassed.
2026-04-24 02:29:02 +08:00
Sora39831
e50b2f471d feat: improve mariadb flow, db settings init, and traffic flush 2026-04-15 16:58:49 +08:00
Sora39831
87282dde33 feat: add durable traffic deltas and shared flush loop 2026-04-10 15:25:16 +08:00
Sora39831
3cfa554786 feat: add cache-backed worker sync and heartbeat loops 2026-04-10 15:15:42 +08:00
Sora39831
34b9f01d0a feat: guard shared writes and bump version transactionally 2026-04-10 11:22:49 +08:00
Sora39831
135ef32477 Add panel domain persistence 2026-04-09 21:39:39 +08:00
Sora39831
8e9e36e1b8 Fix turnstile tab re-render and bump version 2026-04-08 15:34:50 +08:00
Sora39831
8a43a516ac Fix turnstile reload after auth tab switch 2026-04-08 15:18:00 +08:00
Sora39831
ae08f4a50f fix: separate register turnstile layout 2026-04-07 17:32:57 +08:00
Sora39831
b921ed740c chore: add generated fingerprinted assets 2026-04-07 17:17:41 +08:00
Sora39831
5ad2203f24 build: generate fingerprinted assets before compile 2026-04-07 16:43:18 +08:00
Sora39831
cfb169d2fb refactor: resolve template assets through manifest helper 2026-04-07 16:41:55 +08:00
Sora39831
e6752e04db feat: load fingerprinted asset manifest 2026-04-07 12:24:33 +08:00
Sora39831
faeb8dd244 feat: add asset generation command 2026-04-07 12:08:10 +08:00
Sora39831
05ece0bd8e feat: add fingerprinted asset generator 2026-04-07 11:59:25 +08:00
Sora39831
cc6d3daa3a fix: harden migration and setting writes 2026-04-07 02:12:02 +08:00
Sora39831
e298996d77 Harden admin access for panel APIs 2026-04-06 22:12:38 +08:00
Sora39831
6131c55882 fix dashboard and inbounds load failure states 2026-04-06 21:51:33 +08:00
Sora39831
537c73c1b2 fix settings and xray load failure regressions 2026-04-06 21:22:33 +08:00
Sora39831
266f368b07 fix remaining modal state leaks 2026-04-06 21:03:50 +08:00
Sora39831
6564cf8202 fix settings and xray page state leaks 2026-04-06 21:02:58 +08:00