txlyre

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 3af45c1462 fix: Add base-path meta tag for Cloudflare Rocket Loader compatibility When Cloudflare Rocket Loader is enabled, it interferes with inline scripts that set window.X_UI_BASE_PATH, causing the frontend to fail to configure the correct base URL for API calls. This results in 404 errors on the login page when calling /getTwoFactorEnable. Solution: Add meta name='base-path' tag to HTML (similar to csrf-token), update axios initialization to read from meta tag as fallback. Meta tags are not affected by CSP or Rocket Loader delays. Fixes #4393
  • 6badd829df Remove streamSettings for protocols that don't support it - Frontend: Only include streamSettings in toJson() for vmess, vless, trojan, shadowsocks, and hysteria protocols - Frontend: Hide Stream tab in Advanced section for unsupported protocols - Frontend: Clear streamSettings in Advanced tab when switching to unsupported protocols - Frontend: Add CodeMirror JSON editor to config view in index page with mobile responsive design - Backend: Add normalizeStreamSettings() to clear streamSettings for tunnel, mixed, http, tun, and wireguard protocols - Backend: Apply normalization in AddInbound() and UpdateInbound() - Backend: Add omitempty JSON tag to StreamSettings field to exclude null values from Xray config
  • View comparison for these 2 commits »

1 hour ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • b79abc8bc9 refactor: remove legacy advancedJson state
  • 05b68c3b13 fix: remove Auth password #4388
  • f3c7660f84 fix: correct Hysteria2 Obfs password label to Auth password (#4388) The Obfs password field in the Hysteria2 stream settings tab was incorrectly labeled. It binds to hysteriaSettings.auth (the server-wide authentication password), not to the salamander obfuscation password. Per Xray-core docs, Hysteria2 salamander obfuscation belongs in finalmask.udp[].salamander.password, which is correctly handled by the FinalMaskForm (UDP Masks section). Fixed the label to Auth password with an accurate tooltip explaining that salamander obfuscation is configured via the UDP Masks section below.
  • 9b0fd047cb fix: guard certificate and key against undefined before join
  • e4218a1029 feat: click QR to copy/save image instead of link text
  • View comparison for these 6 commits »

9 hours ago

txlyre synced commits to v3.0.2 at txlyre/3x-ui from mirror

17 hours ago

txlyre synced new reference v3.0.2 to txlyre/3x-ui from mirror

17 hours ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 1284756f8a fix(outbound): restore TLS, QUIC params and TCP masks when importing share links - fromHysteriaLink: parse security= URL param and populate stream.tls (SNI, fingerprint, ALPN, ECH) when security=tls; previously always forced security to 'none' - fromHysteriaLink: parse fm JSON param and populate both stream.finalmask.quicParams (drives the QUIC Params toggle in FinalMaskForm) and the mirrored stream.hysteria fields - fromParamLink (VLESS/Trojan/SS): parse fm JSON param and restore stream.finalmask (TCP masks, UDP masks, QUIC params) - fromVmessLink (VMess): same fm handling for the base64-JSON path Closes #4376
  • 1f052c0e8f fix: preserve TLS cert file paths when deploying inbound to remote node When creating a Hysteria (or any TLS-required) inbound from the central panel and deploying it to a remote node, sanitizeStreamSettingsForRemote was unconditionally stripping certificateFile / keyFile from the TLS settings. This left Xray on the remote node with a TLS block containing no certificate, causing Xray to crash and the inbounds page to hang. The fix: only strip cert file paths when inline certificate content (certificate / key arrays) is also present in the same entry — those file paths are then truly redundant. When only file paths are present the user explicitly entered paths that live on the remote node's filesystem; they are now passed through untouched. Fixes #4370
  • ae6f13b533 fix: also hide QR code for ML-KEM-768 links (too long for QR generation)
  • 1cf2582e6d fix: hide QR code for mldsa65 links (too long for QR generation)
  • eacb9f63b0 fix: protocol filter placeholder not showing on initial load (#4372)
  • View comparison for these 13 commits »

17 hours ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 21058eb63c fix(routing): make rule drag-and-drop work on mobile cards The pointermove handler looked up the drop target via el.closest('tr[data-row-key]'). That selector only matches the desktop a-table rows; the mobile branch renders each rule as a <div class="rule-card" data-row-key>, so on phones the lookup always returned null, dropTargetIndex stayed pinned to the start index, and the eventual drop was a no-op. Loosened the selector to [data-row-key] so both DOM shapes resolve.
  • 194de8869e feat(panel): add 'Edit' button to tables and enhance layout (#4355) - Move 'Edit' button from dropdown to the table since it's the most used action. Only for desktop. - Increase column widths for action keys in Inbounds, Balancers, Outbounds and Routing tables. - Slightly enhance layout for consistency.
  • 26accfd8f7 fix(qr): lock QR code modules to black-on-white across all themes AntD's <a-qrcode> defaults the module color to the active theme's text token. Under the dark and ultra-dark themes that text is a light gray, so the QR rendered low-contrast on the white canvas background and phones could not lock onto it. Pinned color="#000000" and bg-color="#ffffff" on every <a-qrcode> usage (share links in QrPanel, 2FA enrollment in TwoFactorModal, sub/json/clash codes on SubPage) so the contrast stays high regardless of panel theme.
  • 2551a673c3 fix(inbounds): refresh client rows live over websocket Two bugs combined to leave per-client traffic / remained / all-time columns stuck at stale numbers while only the inbound-level row and the online badge refreshed: 1. Backend (xray + node sync traffic jobs) only included the per-client array in the client_stats broadcast when activeEmails / touched was non-empty. Cycles with no client deltas — or any node sync that failed to fetch a snapshot — shipped only the inbound summary, so the frontend had nothing to merge for clients. Replaced both code paths with a single GetAllClientTraffics() snapshot per cycle; the broadcast now always carries the full client list. 2. Frontend mutated dbInbound.clientStats[i] in place. DBInbound is a plain class instance (not wrapped in reactive()), so Vue could not see the field-level changes and ClientRowTable's statsMap computed stayed cached forever. Added a statsVersion tick bumped on every merge and read inside statsMap so the computed re-evaluates and the template pulls fresh up/down/allTime/expiryTime each push. Removed the now-dead emailSet helper from node_traffic_sync_job and the activeEmails filter from xray_traffic_job.
  • ce4c42e09c feat(json): swap raw textareas for a CodeMirror 6 JsonEditor A new JsonEditor.vue component wraps CodeMirror 6 + lang-json with line numbers, JSON syntax highlighting, bracket matching, code folding, search (Ctrl+F), undo/redo, lint (red squiggle and gutter icon on invalid JSON), tab indent, and line wrapping. It is wired into the four raw-JSON spots that previously used <a-textarea class="json-editor">: the Xray Advanced Template tab, the Outbound JSON tab, the Balancer Observatory pane, and the Inbound Advanced tab (settings / streamSettings / sniffing). Chrome colors are driven by EditorView.theme so they win the specificity fight cleanly against CodeMirror's own injected styles. A single buildDarkTheme() factory yields a Dark+ palette (#1e1e1e background, #252526 active line, #2d2d30 panels) for the regular dark mode and a near-black variant (#0a0a0a / #141414 / #1f1f1f border) for ultra-dark — both pair with oneDarkHighlightStyle for the syntax colors. Light mode stays on basicSetup's default. CodeMirror lazy-loads as a ~17 kB gzipped chunk that only appears on the Xray/Inbounds bundles.
  • View comparison for these 10 commits »

1 day ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • adc262a238 fix(warp): set license against Cloudflare API and surface errors inline The license update was always failing because the Cloudflare response has no `success` field — the check rejected every successful PUT. On real errors (e.g. "Too many connected devices."), the toast leaked the raw URL + JSON body. Now the WARP API's error envelope is parsed into a clean message and shown inline next to the Update button.
  • 67b098dfd3 Add possibility to remove client email from sub (#4297)
  • 5543466fcc fix(forms): validate JSON tabs before applying or saving InboundFormModal: switching out of the Advanced tab now parses the three JSON textareas and rebuilds the structured Inbound via Inbound.fromJson, so the Basic tab reflects what was pasted. Invalid JSON keeps the user on Advanced with a specific parse error. XrayPage: Save now parses xraySetting upfront and snaps the user back to the Advanced tab on invalid JSON instead of letting the backend reject a generic blob.
  • b10a9f1de7 fix(inbounds): hide node UI when no enabled node exists The Deploy-to selector, node column, node stat row, and node filter all appeared whenever a node row existed in the DB. Local-only deployments with no nodes (or only disabled nodes) saw a dropdown that only had "Local Panel" and a filter that did nothing. useNodeList now exposes hasActive (any node with enable === true). Inbounds form and list gate node UI on hasActive instead of map size.
  • 4399fe2a85 add log rotate to 3xui.log file to avoid disk space consumption (#4277) * add log rotate to 3xui.log file to avoid disk space consumption
  • View comparison for these 18 commits »

1 day ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 210c25cf13 Bump Go module dependency versions Routine update of Go module dependencies and tidy: bump indirect deps (github.com/quic-go/quic-go v0.59.0→v0.59.1, github.com/sagernet/sing v0.8.9→v0.8.10, github.com/tklauser/go-sysconf v0.3.16→v0.4.0, github.com/tklauser/numcpus v0.11.0→v0.12.0), and update several golang.org/x modules (arch, exp, mod, net, tools) and google.golang.org/genproto. Removed duplicate require entries (x/crypto, x/sys, x/text) and updated go.sum to match the new versions.
  • 5dd7e44594 build(deps): bump golang.org/x/text from 0.36.0 to 0.37.0 (#4345) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.36.0 to 0.37.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.36.0...v0.37.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sanaei <[email protected]>
  • 4e4a8e9ff7 build(deps): bump golang.org/x/crypto from 0.50.0 to 0.51.0 (#4344) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.50.0 to 0.51.0. - [Commits](https://github.com/golang/crypto/compare/v0.50.0...v0.51.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.51.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sanaei <[email protected]>
  • 23970e72a7 build(deps): bump golang.org/x/sys from 0.43.0 to 0.44.0 (#4343) Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.43.0 to 0.44.0. - [Commits](https://github.com/golang/sys/compare/v0.43.0...v0.44.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-version: 0.44.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • 8bdb093d6e build(deps): bump actions/setup-node from 5 to 6 (#4342) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5 to 6. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sanaei <[email protected]>
  • View comparison for these 8 commits »

1 day ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 5fb36d34c9 fix(fail2ban): escape percent signs in 3x-ipl datepattern (#4328) * Update DockerEntrypoint.sh fix(fail2ban): escape percent signs in Docker datepattern * Update x-ui.sh fix(fail2ban): escape percent signs in x-ui datepattern
  • 4884a2972a fix(graphs): increase y-axis paddingLeft from 32 to 56 to prevent clipped labels (#4309)
  • 6e12329d9d feat(api-docs): enhance in-panel API documentation (#4312) * feat(api-docs): enhance API documentation with missing endpoints, search, collapse, and route sync test - Add 29 undocumented routes across 4 new sections (Settings, Xray Settings, Subscription Server, WebSocket) plus 4 missing Server API endpoints - Fix inaccuracies: history metric keys, node metric keys, VLESS enc description - Add response schemas to 15+ key endpoints - Add search bar and expand/collapse all controls to the docs page - Add collapsible endpoint sections with endpoint count - Add Go test (TestAPIRoutesDocumented) to verify all Go routes are documented * feat(api-docs): add JSON syntax highlighting and top-right copy button to code blocks * fix(api-docs): use distinct colors for JSON syntax highlighting (green strings, amber numbers) * feat(api-docs): add request body examples, error responses, WebSocket message types, and subscription response headers * fix(api-docs): use ClipboardManager.copyText instead of copy to fix API token copy button
  • 9f7e8178d4 fix: delete button missing after searching for a user (#4315) When searching for a user, the projected DBInbound only contains the matching clients, so isRemovable evaluated to alse (since a single match made clients.value.length === 1), hiding the Delete button. Pass the original total client count from the parent's clientCount prop and use it in the isRemovable check instead of the projected clients array length.
  • 60e6b12f4c fix(hysteria2): restore missing masquerade config in inbound form (#4316) * fix(hysteria2): restore missing masquerade config in inbound form Fixes #4303 The Hysteria2 Masquerade option was missing from the Stream settings tab after the v3.0.0 form rewrite. Added the UI form and ensured the masquerade block is passed through in subscription JSON generation.
  • View comparison for these 8 commits »

2 days ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 07bc74a521 feat(nodes): blur address column with eye-toggle, mirroring IndexPage IP card
  • f570b991e7 fix(api-docs): copy API token button
  • 80031e67cc feat(inbounds): restore copy-clients-between-inbounds modal The menu item, backend endpoint (POST /panel/api/inbounds/:id/copyClients), and i18n keys were already in place after the Vue3 migration, but the modal itself was never ported — clicking the menu just toasted "coming soon". Adds CopyClientsModal.vue: source inbound dropdown (multi-user inbounds except the target), per-client checkbox selection via a-table row-selection, optional Flow override when the target supports TLS flow, and result toasts for added/skipped/errors.
  • fdaa65ad7e Feat: clarify VLESS encryption auth selection (#4271) * feat(traffic_writer): enhance traffic writer with concurrency safety and state management * Revert "feat(traffic_writer): enhance traffic writer with concurrency safety and state management" This reverts commit e6760ae39629a592dec293197768f27ff0f5a578. * feat(vless): clarify VLESS encryption auth selection and enhance parsing logic
  • d86e87ed30 Fix: traffic writer restart freeze (#4265) * feat(traffic_writer): enhance traffic writer with concurrency safety and state management * Revert "feat(traffic_writer): enhance traffic writer with concurrency safety and state management" This reverts commit e6760ae39629a592dec293197768f27ff0f5a578. * feat(traffic_writer): enhance traffic writer with concurrency safety and state management * feat(web): implement panel-only start/stop methods for in-process restarts
  • View comparison for these 6 commits »

2 days ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 355bb4c9c0 feat(panel): xray metrics dashboard with observatory probe history Polls xray's /debug/vars on the 2s status tick, stores memstats and per-outbound observatory delay in the metric history ring buffer, and exposes them through a new XrayMetricsModal opened from the Charts card. Restructures the dashboard to consolidate uptime, usage, version, and Telegram link into stat-style or action-style cards consistent with the existing AntD aesthetic.
  • 9feeccffc0 fix(node): normalize base path during probe so missing trailing slash doesn't break status checks
  • cb962175c2 update translation
  • View comparison for these 3 commits »

3 days ago

txlyre synced commits to v3.0.1 at txlyre/3x-ui from mirror

3 days ago

txlyre synced new reference v3.0.1 to txlyre/3x-ui from mirror

3 days ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 8f3202f431 fix(traffic-writer): replace sync.Once with Start/Stop cycle so SIGHUP restart works After a SIGHUP-driven panel restart (which is exactly what the frontend triggers after a successful DB import via /panel/setting/restartPanel), the previous implementation deadlocked: 1. server.Stop() called StopTrafficWriter — cancels the context and waits for the consumer goroutine to exit. The goroutine dies. 2. server.Start() called StartTrafficWriter, but sync.Once had already fired, so it was a no-op. twQueue still pointed to the old channel with no consumer. 3. startTask() → RestartXray(true) → GetXrayConfig() → InboundService.AddTraffic(nil, nil) → submitTrafficWrite. The send to twQueue succeeded (buffer space) but <-req.done blocked forever because no goroutine was draining the channel. 4. RestartXray held the global xray lock for the entire hang, so every subsequent restart attempt from the panel UI also blocked on lock.Lock(). User-visible symptom: xray stopped silently after DB import and no panel action could revive it. Replace sync.Once with a mutex-guarded Start that spawns a fresh goroutine on each cycle, and a Stop that resets the package state so the next Start works. runTrafficWriter now takes its channels as parameters instead of reading package vars, so the old goroutine can't interfere with a new one if their lifetimes briefly overlap.
  • 0cb6568fd5 v3.0.1
  • 6a90f98412 feat(inbounds): add sub/client link endpoints; hide panel version on login - New GET /panel/api/inbounds/getSubLinks/:subId and /getClientLinks/:id/:email return the same protocol URLs the panel UI's Copy button emits, honouring X-Forwarded-Host / X-Forwarded-Proto. Documented in the API docs page. - Refactor: sub package no longer imports web. The embedded dist FS is injected via sub.SetDistFS, and the link generator is registered with the service layer via service.RegisterSubLinkProvider, avoiding the circular import the new endpoints would otherwise introduce. - Security: stop emitting window.X_UI_CUR_VER on login.html and drop the visible version chip from the login page, so the panel version is no longer pre-auth info disclosure. Authenticated pages still receive it. - Bump config/version.
  • 9318c2105f fix(xray): implement graceful shutdown for xray process and add tests (#4259)
  • e642f7324e feat(panel): in-panel API documentation page New /panel/api-docs route with a one-page reference covering every /panel/api/* endpoint (Auth, Inbounds, Server, Nodes, Custom Geo, Backup) plus a Bearer-token primer that reads the current token and exposes Show/Copy/Regenerate inline. Sidebar gets an API Docs entry right after Xray; the menu label is shared via menu.apiDocs across all 13 locales.
  • View comparison for these 7 commits »

3 days ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • b5479f3f30 feat(sidebar): pin Logout above trigger, inline 3-state theme cycle The desktop sider stretched to match the page height, so below lg (992px) where dashboard cards stack into one column the collapse trigger plus Logout slid off-screen. Pin the sider with `position: sticky; height: 100vh; align-self: flex-start` so the chrome stays viewport-tall. Split the menu into `.sider-nav` (flex: 1, scrollable) and `.sider-utility` so Logout sits directly above the 48px trigger reserved by padding-bottom. Replace the `<ThemeSwitch>` a-sub-menu with a single inline icon button next to the '3X-UI' brand (sun / moon / moon+star SVG). One click cycles Light -> Dark -> Ultra Dark -> Light. ThemeSwitch.vue removed since it is now inlined. Override AD-Vue dark Menu selected + hover/active state on the sider-nav, sider-utility, and drawer menus to use the same light-blue tint AD-Vue's light theme uses (rgba(64,150,255,0.2) / #4096ff). The default dark variant was too subtle against #252526, so the current page and Logout-on-hover barely distinguished themselves.
  • d8aedcdde4 fix(inbounds): bulk-delete keeps last client to satisfy backend constraint DelClient rejects the removal that would leave an inbound with zero clients (the constraint exists because Xray protocols need at least one client to keep the inbound functional). The bulk-delete flow fired one DelClient call per picked client in a loop, so picking every client meant the final iteration always errored out with "no client remained in Inbound" and surfaced as a red toast even though N-1 deletions had already gone through. Now confirmBulkDelete detects the "all selected" case up front, drops the last client from the request, and surfaces the partial operation in the confirm dialog ("N-1 / N — last selected will remain. Delete the inbound to remove all."). The pre-existing single-row delete path and partial-selection bulk delete paths are untouched. If the only client in the inbound is selected, a Modal.warning explains the constraint instead of asking for confirm.
  • 5f3e9ed0ea feat(xray/nord): searchable server list + colored load tag, surface API errors Frontend (NordModal.vue): - Server selector gets show-search with the option label set to `${cityName} ${name} ${hostname}` so admins can find a specific server inside a 100+ entry country list by typing. - Each option renders the load as a colored a-tag (green <30%, orange 30-70%, red >70%) instead of plain text — quicker visual scan when sorting through servers in the dropdown. Backend (nord.go): - GetCountries / GetServers now check resp.StatusCode and return "NordVPN API error: <status>" on non-200, matching the pattern GetCredentials already used. Previously a 4xx/5xx body was returned as a "success" string and the frontend silently failed to parse it, surfacing only as an empty "No servers found". - GetCredentials drops its own ad-hoc 10s http.Client and reuses the shared nordHTTPClient (15s) — one client, one timeout.
  • 3e8a0eb93e fix(inbounds): paginate expanded client list, restore ID column, hide empty Remark - ClientRowTable now applies the General-Settings pageSize to its expanded client list. The 3.0 rewrite dropped pagination, so users with thousands of clients per inbound hit a 30-60s browser hang on expand (#4233). - ID column was marked responsive: ['xs'] so it was hidden on desktop; removed the restriction so it shows as the first column everywhere. - Remark column is now omitted entirely when no inbound has a non-empty remark, matching the existing Node-column pattern.
  • 4c2915586c fix(alpine): restart_xray uses rc-service; OpenRC reload reads pidfile contents `14. Restart Xray` failed on Alpine with `systemctl: command not found` — restart_xray was the only service action missing an Alpine branch. While fixing it, the OpenRC reload action was passing the pidfile path to `kill` instead of the PID inside it, so `rc-service x-ui reload` would have failed too.
  • View comparison for these 8 commits »

3 days ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 6d732d8d32 feat(inbounds): bulk-select clients + UX polish - ClientBulkModal: add `comment` and VLESS `reverseTag` fields so the bulk-add modal can set them on every generated client (matching the single-client form) - ClientRowTable: add multi-select checkboxes (desktop + mobile) with a tri-state select-all and a sticky bulk-action bar; emits a new `delete-clients` event so the parent can wipe the picked clients in one go. Hidden entirely when the inbound has only one client (the last one must stay) - ClientRowTable: new "Remained" column shows live remaining quota per client (∞ for unlimited, red when depleted) - InboundInfoModal: Remained cell now shows the ∞ tag when the client has no totalGB limit, matching how Total Usage already renders it - InboundsPage: add Online tag (+ per-bucket popovers listing client emails) to the summary card so it mirrors the per-inbound row, and wire an `onDeleteClients` handler that loops the existing single- delete endpoint then refreshes once - InboundList: forward the `delete-clients` event; hide empty remarks on both the desktop table (custom #bodyCell) and the mobile card - useInbounds: aggregate an `online` email list across all inbounds so the summary popover has data to render
  • e4900f1bd4 feat(install): add skip-SSL option for reverse-proxy / SSH-tunnel setups Adds a 4th choice to the install-time SSL prompt for users who terminate TLS elsewhere (nginx, Caddy, Traefik) or only reach the panel through an SSH tunnel — closes #3802. - Option 4 prints a clear warning, then optionally binds the panel to 127.0.0.1 via `x-ui setting -listenIP` so it's unreachable from the public internet - When the user binds to 127.0.0.1, print the same SSH port-forwarding command set that x-ui.sh's SSH_port_forwarding() already shows, so remote access is one ssh -L away - Track SSL_SCHEME so the final "Access URL:" line shows http:// when SSL is skipped, instead of misleadingly advertising https:// - Soften the section header from "(MANDATORY)" to "(RECOMMENDED)" and print "SSL Certificate: Skipped" when option 4 is chosen - Rework the SSL menu copy to a parallel "verb — what (constraint)" shape with a single Tip line focused on option 4's risks
  • 04828246fc feat(frontend): swap QRious for ant-design-vue's a-qrcode - Migrate SubPage, QrPanel and TwoFactorModal from a QRious canvas to <a-qrcode type="svg">, which renders the QR matrix as crispEdges SVG rectangles — pixel-perfect at any display size or DPR, no more white scan-line artifacts from non-integer canvas scaling - Drop the now-unused qrious dependency and its manualChunks entry - Default the panel to ultra-dark on first load (existing user preferences in localStorage are preserved) - Let the sub controller read subpage.html from web/dist/ first and fall back to the embedded copy, so Vite rebuilds in dev no longer require a Go recompile to refresh the asset hashes
  • c1efc48694 feat(frontend): refresh dark theme + redesign login page - Swap navy dark palette for VS Code Dark+ neutrals (#1e1e1e/#252526/ #2d2d30) across theme tokens, page backgrounds and DateTimePicker - Add brand header to the mobile drawer and desktop sider, and recolor the drawer body so it reads as one panel with the menu - Redesign login page with a centered card, cycling Hello/Welcome headline and per-theme animated gradient-blob backgrounds
  • f1760b0a28 feat(xray/balancer): restore observatory editor + auto-sync selectors The Vue3 migration dropped the Observatory / Burst Observatory section that used to sit under the balancer table. Without it, leastPing / leastLoad strategies had nowhere to populate Xray's required subjectSelector, so balancers that depended on probe data silently ran with an empty observer config. - Auto-seed and sync `observatory` for leastPing balancers and `burstObservatory` for leastLoad balancers (subjectSelector recomputed from every matching balancer's selector list). Drops the observatory when no matching strategy remains. - Defaults (probeURL, interval, connectivity, sampling) match the values the legacy panel shipped, themselves taken from the Xray docs at xtls.github.io/config/{observatory,burstobservatory}.html. - Surface both observatories under the table as a radio-switched JSON textarea so admins can tune probe settings inline without dropping into the full xray template tab.
  • View comparison for these 8 commits »

4 days ago

txlyre synced commits to v3.0.0 at txlyre/3x-ui from mirror

4 days ago

txlyre synced new reference v3.0.0 to txlyre/3x-ui from mirror

4 days ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 887fca86ec fix(fail2ban): escape % in 3x-ipl action date format (#4218) Fail2ban parses % as variable interpolation in action.d configs, so the unescaped %Y/%m/%d %H:%M:%S in the date command crashed fail2ban on startup. Double the %s in the heredoc so the rendered action file contains %% and fail2ban collapses it back to a literal % when invoking the shell command.
  • 6efc4b0665 Revert "perf(frontend): code-split heavy components to improve LCP" This reverts commit 444b05cac901ca2bd94013ceefc683095726e2d9.
  • 94a7dbfe3c fix(docker): pin frontend stage to BUILDPLATFORM and drop removed buildx input node:22-alpine has no manifest for linux/arm/v6, breaking multi-arch builds. Frontend output is static JS/CSS that doesn't need to be built per target arch — pin the stage to $BUILDPLATFORM so Vite always runs on the host. Also drop `install: true` from setup-buildx-action@v4 (input was removed).
  • e2649f98df fix(arch): correct x-ui service path (#4213)
  • 3d839e0ee1 v3.0.0
  • View comparison for these 12 commits »

4 days ago

txlyre synced commits to main at txlyre/3x-ui from mirror

  • 444b05cac9 perf(frontend): code-split heavy components to improve LCP Switch the inbounds-page modals, login page's theme switch, and the Persian date picker to defineAsyncComponent. They're not needed on first paint, so deferring them shrinks the initial bundle and lets the LCP element render sooner. Co-Authored-By: Claude Opus 4.7 <[email protected]>
  • f70e131dfe fix(nodes): bind form-encoded posts and skip node inbounds in central xray The Node model only carried `json:` tags, so when the panel's axios posted form-encoded bodies to /panel/api/nodes/add and /test, Gin's form binder produced a zero-valued Node — empty Name, empty Address, Port=0 — surfacing as "node name is required" and a probe URL of "https://:0/...". Add `form:` tags so add/test bind correctly. Also skip inbounds with NodeID set when building the central xray config; otherwise the central panel tried to listen on ports owned by node-managed inbounds and xray-core failed to start with a bind collision. Co-Authored-By: Claude Opus 4.7 <[email protected]>
  • 14165fc54d avoid reset in QueryStatsRequest (#4202)
  • View comparison for these 3 commits »

4 days ago