txlyre

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

  • f8b72de995 fix(node-sync): write only changed client rows in the node traffic merge Every 5s node merge rewrote one client_traffics row and one node_client_traffics baseline per (inbound, client) pair the node reported, even when nothing had moved: a client is reported once per inbound it is on, and idle clients every tick. On top of that each inbound's SyncInbound wrote its own per-inbound values onto the shared clients record, so a client on a flow and a non-flow inbound (or on a WireGuard tunnel plus any other inbound) had its record flipped back and forth twice per merge. With 7 nodes and ~20k client links that is tens of thousands of statements per tick, all inside transactions on the single serialized writer, holding row locks for seconds. A renew of a client on 38 inbounds takes one writer turn per inbound, queued behind those merges each time, and outlived the 30s HTTP write timeout even though it committed; last_sub_fetch updates waited on the same locks. The merge now computes the row its UPDATE would leave, mirroring the SQL merge expressions, and skips the write when nothing changes; the baseline upsert is skipped when the node counter has not moved. The record's per-inbound fields get one owner each, so repeated syncs agree: flow is settled to the effective flow (lowest-id link carrying one) for clients whose links changed, and WireGuard/AmneziaWG peer fields come from the client's lowest-id tunnel. A repeated unchanged snapshot now writes no client row; one active client writes two. Verified beyond make verify: the CI Postgres lane, the merge and flow tests run against PostgreSQL 16, and make node-e2e. Closes #6815
  • 6f1dd0d757 feat(sponsors): drop the sidebar slot and simplify the Sponsors page The sidebar no longer carries a sponsor card. The backend stops serving the "sidebar" slot, so a sponsors.json entry that still lists it keeps only its other slots and one listing nothing else is dropped. Its rotation, three-sponsor cap and collapsed-rail logo rendering go with it. The Sponsors page now lists only real sponsors: the "Your brand here" card shows only as the empty state instead of sitting in the grid and repeating the header's Become a sponsor button, and the Available placements section and its slot-occupancy helper are removed. Cards are larger, two per row on wide screens. Unused i18n keys are dropped from every locale.
  • 319e693276 fix(sponsor): keep long sponsor copy inside every slot The Sponsors page card sized its body to max-content because the title never wrapped, so a long title spilled out of the card onto the next one. The compact card (sidebar, login) put logo, copy and close button in one row, leaving the copy ~110px of the 220px sidebar and clamping it to two lines; the dashboard banner cut its title to a single line. Titles and descriptions now wrap, breaking unbroken strings too. The compact card stacks logo and tag above copy that spans the full card width, keeping a bounded height in the sidebar with a 2-line title and 4-line description clamp and the full copy in the link tooltip.
  • View comparison for these 3 commits »

7 hours ago

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

  • 61885c9126 fix(sub): isolate Incy subscription routing from Happ headers (#6810) * sub: isolate Incy subscription routing from Happ headers The resolved Incy line is written to the body only when IsIncyClient matches the subscription User-Agent, Incy routing is enabled, and the resolved text is non-blank. ApplyCommonHeaders computes that same Incy check once and, for a matching client, skips the Happ routing-header block, leaving Routing-Enable, the Happ Routing value, and the JSON routing header unset. ApplyIncyHeaders is called with that incyClient flag. The new test requests the subscription as INCY/1.0.0/ios and as Happ/1.2.0 and expects the Incy response to end with the incy:// line and to have empty Routing headers, and the Happ response to keep the happ:// Routing header with Routing-Enable true and no incy:// line in the body. Fixes #6062 * fix(sub): keep the shared JSON routing profile for INCY clients The INCY isolation wrapped the whole Routing block, JSON fallback included, in !incyClient. INCY therefore lost the subJsonRoutingRules profile that #6402 sends as the Routing header so Happ and INCY fetch the geo files the baked rules reference, on the raw, JSON and Clash endpoints alike, while every other client kept it, incy:// deeplinks included. INCY accepts a routing link of any scheme in that header (docs.incy.cc/en/routing), so only the Happ tab is Happ-only: an INCY request now reads it as blank and falls back to the shared profile, as the setting text promises. Where the raw body carries INCY's own profile the header is dropped, because INCY ranks a Routing header above a base64 body line (docs.incy.cc/en/app-management) and the shared profile would override it, which is #6062 again. --------- Co-authored-by: Matt Van Horn <455140+[email protected]> Co-authored-by: MHSanaei <[email protected]>

16 hours ago

txlyre pushed to master at txlyre/ugushian

18 hours ago

txlyre pushed to master at txlyre/ugushian

19 hours ago

txlyre pushed to master at txlyre/ugushian

21 hours ago

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

1 day ago

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

1 day ago

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

  • 74c3cc3882 fix(database): blank boolean-era verifyPeerCertByName values on hosts A host's verify_peer_cert_by_name must only hold a server name an operator typed. The column started life as a boolean, and the migration that was meant to discard those values runs after AutoMigrate, which has already cast the column to text: SQLite's table rebuild stores 0/1 as "0"/"1", and Postgres' USING col::text stores "false"/"true". The migration then sees a text column and leaves the values alone. Since 3.10.0 the JSON subscription lifts host TLS verification fields to the level xray reads, so that leftover "0" is now sent as the cert name to verify and clients such as Happ refuse the server certificate. A one-shot HostVerifyPeerCertByNameBoolFix seeder blanks exactly the four cast values on existing databases; real names are untouched. The Postgres variant joins the CI schema job, since that cast only happens there.
  • 6843583706 fix(xray): fall back to the userspace TUN where kernel TUN cannot be set up The core puts a WireGuard outbound on a kernel TUN whenever it holds CAP_NET_ADMIN and noKernelTun is unset, the default for a hand-added outbound. That needs a writable /proc/sys/net and /dev/net/tun, and where either is missing the core does not fall back: it aborts the whole start. The shipped docker-compose grants NET_ADMIN for fail2ban while Docker keeps /proc/sys read-only and exposes no /dev/net/tun, so one such outbound took every inbound down with the #6796 error; any unit or drop-in that keeps /proc/sys/net read-only did the same. xray.KernelTunBlocked probes once, from the panel process whose capabilities and mounts the core inherits, whether the core would pick a kernel TUN it cannot create. GetXrayConfig then sets noKernelTun on every WireGuard outbound, so cold starts and hot reloads both get it. Hosts that can create the device keep the kernel TUN. Verified with the pinned core's "run -test" on the generated config, in a NET_ADMIN container as docker-compose runs it and under systemd 257: the container and the v3.10.0 unit report blocked and pass on gVisor, the container fails with the #6796 error when the GetXrayConfig hook is bypassed, and the new unit keeps the kernel TUN. Refs #6796
  • 1f2738eda5 fix(systemd): let the WireGuard kernel TUN write rp_filter under the sandbox ProtectKernelTunables=yes (#6718) mounts all of /proc/sys read-only, and a WireGuard outbound in kernel-TUN mode zeroes net.ipv4.conf.all.rp_filter (and its ipv6 and per-device siblings) while Xray creates its handlers, so the core aborted with "failed to disable ipv4 rp_filter for all: ... read-only file system". The unit is reinstalled on every update, so a hand edit did not stick. Keep ProtectKernelTunables and reopen only /proc/sys/net. Turning the protection off (#6797) also lets the core start, but leaves kernel.core_pattern writable to the root panel, which turns any panel-level code execution into a way out of the whole sandbox. net.* is per network namespace and grants nothing beyond the CAP_NET_ADMIN the panel already holds. Verified on systemd 257 (Debian trixie) with the shipped unit and the pinned core: the v3.10.0 unit reproduces the error, the new one starts the kernel TUN, and kernel.core_pattern stays read-only for the service. Closes #6796
  • 097bb7646a fix(ci): move the issue analyst's static instructions out of the workflow GitHub evaluates a `with:` value holding ${{ }} as one expression and rejects the whole workflow when it passes 21,000 characters. The analyst prompt was 19,883; 6eeaaa91 took it to 21,389 and 99d971ff to 23,257, so since that push the file is invalid: no issue gets an analysis, and every push records a failed, job-less run named after the file. actionlint does not check this limit, which is how it shipped. The static parts - repository context pointer, issue forms, how to investigate, resuming and maintainer-request modes, evidence discipline, the severity/confidence/verdict scales, the security exception, labels and closing, and the comment format - move verbatim to .github/claude/issue-analyst-instructions.md, which the prompt tells the analyst to read in full first, as it already does for issue-analyst-context.md. The prompt keeps everything that needs an expression or guards the run: the trigger mode, CURRENT ISSUE, the fenced untrusted data, RULES and the marker. It is now 5,597 characters. The stale "code changes happen when the maintainer mentions @claude" rule is replaced: no workflow here changes code, and @claude analyze now exists. TestBotPromptsFitGitHubExpressionLimit in bot_context_test.go reads every claude-*.yml and fails on a ${{ }} value over the limit; it is red on 99d971ff (23,257). The instructions file joins the analyst paths pinned by TestAnalystContextNamesRealPaths, and the file's header now names everything it pins. actionlint 1.7.7 passes.
  • 544907f4e2 v3.10.0
  • View comparison for these 10 commits »

1 day ago

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

  • c321933a54 perf: reduce traffic formatter allocations (#6790) Co-authored-by: Javier Guerrero <[email protected]> Co-authored-by: Copilot App <223556219+[email protected]>
  • d43e0c7ead fix(sub): default VLESS client encryption to none when the inbound has none stored (#6781) VLESS inbounds whose settings carry no "encryption" key (rows saved by panels before the field existed, or inbounds added over the API with only "decryption":"none", as the API docs example does) produced a JSON subscription outbound with "encryption": "". Xray refuses to load that config ("VLESS users: please add/set \"encryption\":\"none\" for every user"), so every VLESS entry of the JSON subscription was unusable. The share link left the parameter out instead. Treat a missing or empty value as "none" for both outputs, matching the frontend inbound schema default and the docs link generator.
  • View comparison for these 2 commits »

2 days ago

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

  • f55938ba0a fix(amneziawg): respect tunnel MTU when writing UDP replies (#6780) * fix(amneziawg): respect tunnel MTU when writing UDP replies Send replies through gVisor FindRoute/Route.WritePacket instead of WriteRawPacket so the network endpoints apply the tunnel MTU and fragment oversized IPv4/IPv6 datagrams. Preserve UDP checksums including the zero-complement IPv6 case and validate lengths before narrowing to uint16. Regression tests inspect and reassemble actual channel-backed TUN output at and above the MTU, verify checksums and exercise concurrent sources. * docs(review): put the tally before Design and name who can store a trigger
  • a4699696ef docs(review): put the tally before Design and name who can store a trigger
  • 5939fda397 fix(ci): let the PR review save its body, and scope the write-check bypass Run 38187893539 reviewed PR #6784 in full but posted nothing: the model's Write to /tmp/review.md was refused. Claude Code checks file permissions against Edit(path) rules only and never consults a Write(path) rule, so the allow rule was dead - and so were the Write(//home/**) and Write(//opt/**) deny rules meant to keep $GITHUB_ENV out of reach. All three are Edit rules now; a local headless run confirms Write(path) is refused, Edit(path) lets the file through, and an Edit deny still blocks a Write under it. allowed_non_write_users="*" skipped the action's write-permission check for every actor and warned each run. Only a pull_request_target from a fork needs it; an `@claude review` requester is already OWNER/MEMBER/COLLABORATOR and passes the action's own check.
  • 9130f6dd75 feat(ci): make the PR review judge the claim and never post code The review only hunted defects: a correct fix got no word on whether the reported problem was real or actually solved, and a feature got no design feedback. The comment now opens with a verdict for every kind of change - for a fix, whether the failure exists on base, whether the head removes its root cause (checked against the issue-analyst's analysis) and whether the test proves it; for a feature, whether it overlaps what the panel already has, which deployment shapes it misses, and a prose-only Design section; for refactor, perf, dependency bumps, docs and CI, a question of their own. The trace scales to the change, so a typo is not traced like a runtime change. It also searches for duplicate merged or in-flight work, and runs at high effort since settling whether a bug is real takes tracing base and head. No code may appear anywhere in the comment, and the model no longer holds a write token. The workflow is three jobs: `prepare` (ack, pin the head, skip a reviewed PR), `review` (read-only token; the model writes /tmp/review.md) and `post` (no model, no checkout), which strips any fenced block, keeps the Reviewed head marker the skip relies on, and only then posts one plain comment. Before, `gh api` with a pull-requests: write token could touch any PR in the repository, `sed -i` could write $GITHUB_ENV, and the inline-comment tool told the model to use suggestion blocks. Concurrency stays on the review job: at workflow level any unrelated comment on the PR would replace a pending review in the queue. Restores three guards the earlier claude-bot review had: all author-controlled input, including text inside the checked-out code, is data and a diff adding text aimed at a reviewer or bot is a HIGH finding; a blocking finding tags the repository owner; and a diff too large to read whole has a reading order and must name what went unread.
  • dbfa369632 fix(frontend): close panel update confirmation before progress (#6766) * fix(frontend): close panel update confirmation promptly * chore(ci): rerun flaky checks
  • View comparison for these 21 commits »

2 days ago

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

  • c7d89ceac2 feat(outbounds): TLS for XDRIVE outbounds xray-core 26.10.10 dials an XDRIVE outbound's storage API with the stream's tlsSettings: their SNI, uTLS fingerprint and ALPN are what the API sees, which is the point of fronting it. canEnableTls kept XDRIVE out of the TLS-capable networks, so the security picker never offered TLS and switching a TLS outbound to XDRIVE silently reset it to none. canEnableOutboundTls admits a TLS-eligible protocol on xdrive and backs both the picker and the network-change cascade. Inbounds keep the plain predicate: their tlsSettings carry server certificates, not a client hello. Also restores the plain oxfmt / oxlint --fix lint-staged commands, reverting da6872a3: that hook change was not wanted.
  • ef4bda4e06 feat(inbounds): TUN adapter type and auto-system options xray-core 26.9 added three TUN settings the inbound form could not set: - desc, the tunnel type a new Wintun adapter is created with on Windows. The settings schema did not list it, so the parse stripped it and a value entered as JSON vanished on the next save; - autoSystemDnsToGateway (Linux), which points systemd-resolved at the TUN gateway; - autoSystemWfpBlockLeak (Windows), whose dns / misconfigtun filters keep traffic from leaking past the TUN. The tooltips name the platform each one acts on and what it needs, since the core refuses to build or start the TUN otherwise.
  • b6c859f5b9 feat(xray): edit Lua DNS and routing scripts xray-core 26.10.10 can hand DNS and routing to Lua: dns.script and routing.script name a .lua file (absolute, or found next to the Xray binary) that defines HandleDNSQuery / HandleRoute, and a DNS server's id is how a DNS script picks it. The keys round-tripped through the JSON template but had no field. - DNS: a Lua Script field, and an ID field in the server modal; - Basics: a Routing Script field beside the routing strategy; - Routing: a warning above the rules while a script is set, since the core then routes only through the script and skips every rule, the panel's api rule included. The descriptions say the script must still send the api inbound to the api outbound, and that Xray will not start if the file is missing. An empty field drops the key, because the core rejects an empty path.
  • 1c050f872a feat(finalmask): header-custom variables, sudoku UDP mask and noise reset ranges xray-core 26.6 grew the finalmask surface the editor could not express, and the finalmask watch drops any key without a registered field, so a config written by hand lost these keys on the next save: - header-custom items can capture their bytes into a variable, reuse one or emit a transform expression; a Kind select keeps each item to exactly one kind, as the core requires, and only parsed JSON reaches transform; - TCP header-custom gains the errors group (the reply sent when a client group does not match), UDP header-custom its prefix/standalone mode; - sudoku is offered as a UDP mask, and share links keep it in fm=; - the noise reset is an Int32Range, so it now takes "60-120" as well. The new golden fixture is saved unchanged by the outbound editor and built by xray-core in TestGoldenStreamFixturesBuildInXray.
  • View comparison for these 4 commits »

2 days ago

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

  • ec0a57fc4f fix(finalmask): hop client UDP through the udphop mask xray-core 26.9.9 dropped finalmask.quicParams.udpHop for the client-only "udphop" UDP mask {mode, interval, remoteIPs, remotePorts}. The panel kept writing the old key, so hysteria/xhttp outbounds and JSON-subscription clients silently stopped hopping ports. An inbound keeps quicParams.udpHop: it is panel metadata advertised as the link's mport, and a udphop mask on a listener fails with "udphop: client only". The conversion (maskcompat.UpgradeLegacyUDPHop, intervalRemote mode) runs only where a client config is produced: - UDPHopClientMaskFix seeder over hosts, sub-JSON finalmask, cached outbound-subscription outbounds and template outbounds (never inbounds); - GetXrayConfig heals template outbounds at build time; - the JSON subscription upgrades each generated client stream; - the Go and frontend link importers upgrade a legacy fm= param. The finalmask editor gains a side prop: the client side lifts the dead key on mount and offers a udphop mask editor (also for xhttp's HTTP/3 dial); the inbound side keeps the UDP Hop switch, labelled as advertised.
  • 00aaef386f fix(inbounds): accept masque in the inbound protocol validator The inbound add and update handlers bind the body into model.Inbound and validate Protocol against a oneof list that predates MASQUE, so every save of a MASQUE inbound from the panel or the API failed validation even though the rest of the stack (b04039c2) handles the protocol. Add masque to the list and regenerate the schemas and OpenAPI document that mirror it.
  • da6872a3b8 chore(frontend): let lint-staged pass commits that stage only generated files lint-staged hands every staged src/**/*.ts file to oxfmt and oxlint, but both ignore src/generated, so a commit whose only TypeScript change is a regenerated schema (a validator tag edit plus make gen) aborts with "Expected at least one target file". Tell both tools an empty selection is not an error.
  • 04cccef311 feat(warp): register WARP over MASQUE from the WARP modal xray-core's masque transport reaches Cloudflare WARP with an enrolled ECDSA P-256 key, the endpoint's public key and the assigned tunnel addresses, which only a WARP enrollment hands out. A new regMasque action on /panel/api/xray/warp/:action registers a separate WARP device and enrolls a secp256r1 key for the masque tunnel (the API revision and client version the WARP apps enroll MASQUE keys with). Enrolling replaces a device's WireGuard key, so it never touches the stored WireGuard registration. It returns the PEM key pair, the addresses and the endpoint, and the WARP modal turns them into a warp-masque outbound (HTTP/3, Cloudflare's MASQUE SNI), or refreshes the one already there.
  • b04039c2bd feat(xray): add the MASQUE protocol and transport xray-core v26.10.10 serves MASQUE: CONNECT-IP over HTTP/3 or HTTP/2, always behind TLS, as an inbound and an outbound protocol riding a dedicated "masque" transport. The panel could not create either. Inbound: MASQUE is a multi-user protocol whose users log in with their email and password over Basic auth. The panel keeps the client's "password" like trojan and GenXrayInboundConfig hands it to the core as "pass", so the full-config path, the live AddInbound path and node pushes all emit what the core reads; one user with an empty pass makes the core refuse the whole inbound. Live user adds build a masque.Account from either key, client-only changes diff per user so a new client does not drop every connected tunnel, and client creation, copy, validation and edits key on the password. The address pool and MTU get form fields, TLS is mandatory, and the port check follows the core's listener choice: HTTP/2 on TCP when the ALPN offers h2, HTTP/3 on UDP when it offers h3 or not h2. Nodes may host MASQUE from v3.9.1, the first panel release that knows to rename the password. MASQUE has no share-link format, so links and Clash skip it; the JSON subscription builds the client's masque outbound with its email and password, and the subscription allowlist now lets a subId see MASQUE inbounds at all. The IP-limit job, client pages and traffic tracking list the protocol. Outbound: the form edits the server, remote DNS, and the transport's host, path, Basic credentials, headers and WARP block (enrolled key, endpoint public key, tunnel addresses), which xray-core refuses next to user/pass. The outbound test probes it through the core, since its default HTTP/3 dial is UDP.
  • View comparison for these 9 commits »

3 days ago

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

  • 442b7fb163 chore(deps): bump github.com/valyala/fasthttp from 1.74.0 to 1.75.0 (#6767) Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) from 1.74.0 to 1.75.0. - [Release notes](https://github.com/valyala/fasthttp/releases) - [Commits](https://github.com/valyala/fasthttp/compare/v1.74.0...v1.75.0) --- updated-dependencies: - dependency-name: github.com/valyala/fasthttp dependency-version: 1.75.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>
  • f0016f6cf9 test: stop swapping http.DefaultTransport in the Happ network test (#6742) * test: stop swapping http.DefaultTransport in the Happ network test The Happ local-generation test replaced the http.DefaultTransport global to refuse sockets. resolvePublicIPsInBackground fires a fire-and-forget resolver (ServerService.GetStatus -> resolvePublicIPs -> getPublicIP), and that goroutine can outlive the test that scheduled it, so a later test writes the global while the resolver is reading it: a data race that `make race` (-shuffle=on) only reports when the status test happens to run first. Route the lookup transport through an atomic swap point and count in-flight lookups, so the test stubs its own path and waits for earlier resolvers to settle before installing it. That also stops another test's dials from landing in this test's zero-network tally. Reproduced on the parent commit with -shuffle=6 (read in getPublicIP, previous write in TestHappGenerateLocallyWithoutNetwork); the same seed is clean with this change, across repeats and for the whole package under -race. * test: prove the Happ network guard intercepts panel egress The PR review pointed out that HappService.Generate never reaches a stub installed only on the public-IP lookup, so the "zero network attempts" assertion could not fail. Move the override onto the panel's shared egress seam — getPublicIP and SettingService.NewProxiedHTTPClient — and gate the test on a canary request that must be refused and must move the tally, so a future outbound call from local generation is reported instead of passing unnoticed. * test(service): stop the cold-status test leaking a public-IP resolver The race CI hit (run 37345781756) came from TestCurrentStatusSamplesBeforeFirstTick: its CurrentStatus call starts resolvePublicIPsInBackground, a goroutine that makes real internet requests and outlives the test. On a runner without IPv6 every lookup waits out its 3s timeout, so the goroutine is still building clients from http.DefaultTransport when the Happ test swaps it. Pre-settling the IP cache keeps that test from starting the resolver at all, so no unit test reaches the internet or leaks the goroutine. This replaces the earlier panelEgressTransport / panelEgressLookups seam, which added test-only hooks to production code without removing the leak. Reproduced in golang:1.27-bookworm with egress routed to a blackhole (HTTPS_PROXY=http://10.255.255.1:9, -race -count=3 on the two tests): the same server.go:406 race as CI before, clean over -count=5 after. --------- Co-authored-by: MHSanaei <[email protected]>
  • 881f646d2c fix(clients): balance renewal form layout and mode guidance (#6672) * fix(clients): balance renewal form layout and mode guidance Move renewal out of the traffic-reset half-column so its help and preview no longer leave a tall empty area beside the reset selector. Keep the mode, active schedule field and renewal limit in equal desktop columns, stack them on small screens, and preserve the bulk form's stacked layout. Keep monthly traffic-reset controls together in their own row and allow the first-cutoff button to wrap without shrinking its click target. Show fixed-duration guidance only for interval renewal and the month-end boundary note only for monthly renewal. Synchronize all thirteen locales and the client docs, remove obsolete zero-value mode-switching tooltips, and cover the help transitions through the real client form. Keep preview markup and existing monthly copy intact so the independent date-display work in #6662 can merge without overlapping these edits. This is presentation-only: saved values, expiry selection, renewal and traffic-reset calculations, APIs and database formats are unchanged. * refactor(clients): drop the renewal CSS that #6662 made redundant #6662 landed the full-width preview Space and the wrapping first-cutoff Button as inline styles, so ClientRenewalFields.css and its wrapper div styled the same two elements a second time; both are removed. * test(tuic): wait for downstream association activity refresh The UDP lifecycle regression can receive its QUIC response before the server's sending goroutine updates the association timestamp. Reading the protected field once then mistakes a valid scheduling order for a missing refresh, intermittently failing the race-enabled CI job. Wait for lastActive to advance under the registry mutex, bounded by a one-second deadline, before checking idle reaping. Retain the payload, association ID, idle-survival and shutdown assertions so a missing activity update still fails the test. This only changes test synchronization. Production relay behavior, renewal logic, network timeouts and CI configuration remain unchanged. --------- Co-authored-by: JacktheRanger <219502738+[email protected]> Co-authored-by: MHSanaei <[email protected]>
  • View comparison for these 3 commits »

5 days ago

txlyre synced and deleted reference dependabot/go_modules/github.com/valyala/fasthttp-1.75.0 at txlyre/3x-ui from mirror

5 days ago

txlyre synced commits to dependabot/go_modules/github.com/valyala/fasthttp-1.75.0 at txlyre/3x-ui from mirror

  • 359baaaca4 chore(deps): bump github.com/valyala/fasthttp from 1.74.0 to 1.75.0 Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp) from 1.74.0 to 1.75.0. - [Release notes](https://github.com/valyala/fasthttp/releases) - [Commits](https://github.com/valyala/fasthttp/compare/v1.74.0...v1.75.0) --- updated-dependencies: - dependency-name: github.com/valyala/fasthttp dependency-version: 1.75.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]>
  • 257559c389 fix(update): leave TLS alone during panel updates The panel's web Update runs update.sh with stdin on /dev/null. On a panel with no certificate configured, config_after_update opened the SSL menu: read got EOF, the empty answer selected "Let's Encrypt for IP", x-ui was stopped and IP-certificate issuance ran, and its failure path rm -rf'd /root/cert/ip and the acme.sh state, deleting a pair other services may share. The URL printed afterwards was always https:// even when nothing was configured. When the public-IP lookup failed, the same run instead looped forever on an "enter your server IP" prompt it could never answer. An update now only updates the panel: the SSL setup path and the helpers only it used are removed from update.sh, the IP lookup falls back without prompting (it is only used for the printed URL), and the URL reports the scheme the panel actually serves. TLS stays configurable from the x-ui menu and install.sh. Supersedes #6667.
  • f217212247 web: overlay WireGuard peer public key from the inbound (#6751) The WireGuard branch now copies PublicKey from the matching inbound settings client. When that entry's KeepAlive is nil the peer keepalive is cleared, and when it is set the integer is copied into a new pointer. The dual-tunnel test seeds different keys and keepalives, checks that the shared row still has the AmneziaWG identity, and expects the emitted WireGuard peer to use the WireGuard public key and keepalive, including a case where the WireGuard settings entry has no keepalive and the peer omits it. Fixes #6731
  • 54d1712544 fix(clients): clarify renewal preview times and estimates (#6662) * fix(clients): clarify renewal preview times and estimates The preview rendered RFC3339 strings directly and labeled the server's Local zone without explaining which clock it represented. Its renewal count also looked like a record of renewals already performed. Display readable dates with an explicit UTC offset while preserving the server's wall time, per-date DST offset and fractional cutoff precision. Explain the panel/server timezone and read-only preview, and label the renewal count as estimated allowance consumption in all 13 locales. Let the first-cutoff button wrap on narrow screens and update the English and Chinese client documentation plus display/form regression coverage. This changes presentation only: renewal calculations, stored expiry values, API payloads and first-use behavior remain unchanged. * test(clients): remove redundant renewal preview copy checks The locale-only preview case repeated the Local timezone branch without covering a distinct behavior. Exact textContent comparisons after matching the same text with getByText also only pinned constant wording, contrary to the repository's testing guidance. Remove that duplicate case, its locale setup and the redundant copy assertions. Keep the UTC, per-boundary DST offset, fractional precision and original datetime checks, together with the existing real form-save tests. Production rendering, translations and renewal behavior are unchanged. --------- Co-authored-by: JacktheRanger <219502738+[email protected]>
  • b3f1cced70 fix(tuic): preserve IP destinations during sniffing (#6753) Keep sniffed TLS domains available for routing without replacing the destination address requested by the TUIC client. Add a regression assertion for the generated relay sniffing settings.
  • View comparison for these 10 commits »

5 days ago

txlyre synced new reference dependabot/go_modules/github.com/valyala/fasthttp-1.75.0 to txlyre/3x-ui from mirror

5 days ago

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

  • 257559c389 fix(update): leave TLS alone during panel updates The panel's web Update runs update.sh with stdin on /dev/null. On a panel with no certificate configured, config_after_update opened the SSL menu: read got EOF, the empty answer selected "Let's Encrypt for IP", x-ui was stopped and IP-certificate issuance ran, and its failure path rm -rf'd /root/cert/ip and the acme.sh state, deleting a pair other services may share. The URL printed afterwards was always https:// even when nothing was configured. When the public-IP lookup failed, the same run instead looped forever on an "enter your server IP" prompt it could never answer. An update now only updates the panel: the SSL setup path and the helpers only it used are removed from update.sh, the IP lookup falls back without prompting (it is only used for the printed URL), and the URL reports the scheme the panel actually serves. TLS stays configurable from the x-ui menu and install.sh. Supersedes #6667.

6 days ago

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

  • f217212247 web: overlay WireGuard peer public key from the inbound (#6751) The WireGuard branch now copies PublicKey from the matching inbound settings client. When that entry's KeepAlive is nil the peer keepalive is cleared, and when it is set the integer is copied into a new pointer. The dual-tunnel test seeds different keys and keepalives, checks that the shared row still has the AmneziaWG identity, and expects the emitted WireGuard peer to use the WireGuard public key and keepalive, including a case where the WireGuard settings entry has no keepalive and the peer omits it. Fixes #6731
  • 54d1712544 fix(clients): clarify renewal preview times and estimates (#6662) * fix(clients): clarify renewal preview times and estimates The preview rendered RFC3339 strings directly and labeled the server's Local zone without explaining which clock it represented. Its renewal count also looked like a record of renewals already performed. Display readable dates with an explicit UTC offset while preserving the server's wall time, per-date DST offset and fractional cutoff precision. Explain the panel/server timezone and read-only preview, and label the renewal count as estimated allowance consumption in all 13 locales. Let the first-cutoff button wrap on narrow screens and update the English and Chinese client documentation plus display/form regression coverage. This changes presentation only: renewal calculations, stored expiry values, API payloads and first-use behavior remain unchanged. * test(clients): remove redundant renewal preview copy checks The locale-only preview case repeated the Local timezone branch without covering a distinct behavior. Exact textContent comparisons after matching the same text with getByText also only pinned constant wording, contrary to the repository's testing guidance. Remove that duplicate case, its locale setup and the redundant copy assertions. Keep the UTC, per-boundary DST offset, fractional precision and original datetime checks, together with the existing real form-save tests. Production rendering, translations and renewal behavior are unchanged. --------- Co-authored-by: JacktheRanger <219502738+[email protected]>
  • b3f1cced70 fix(tuic): preserve IP destinations during sniffing (#6753) Keep sniffed TLS domains available for routing without replacing the destination address requested by the TUIC client. Add a regression assertion for the generated relay sniffing settings.
  • View comparison for these 3 commits »

6 days ago

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

  • c9207b6f3e feat(install): install PostgreSQL 18 from PGDG for new local databases The local PostgreSQL setup installed whatever the distro metapackage pointed at, so Ubuntu 22.04 got 14 (EOL Nov 2026), Debian 12 got 15 and EL9 got 13. Servers ended up on different majors, and a pg_dump backup taken on a newer server does not restore onto an older one. New installs now add the official PGDG repository and install PostgreSQL 18 (apt on Debian/Ubuntu, dnf on EL 8+ with the AppStream module disabled, postgresql-18 service and /var/lib/pgsql/18/data). Where PGDG has no build (Ubuntu 20.04, Debian 11, armhf/i386/s390x, EL7, Fedora, Amazon Linux, older EL point releases) the repository change is rolled back and the distro package is installed as before. A host that already has a cluster keeps it, so existing installs are never upgraded. x-ui.sh resolves the postgresql-18 unit on EL for start/stop/log and also removes the PGDG packages on purge. Verified in containers: Ubuntu 22.04/24.04, Debian 12, Rocky 8/9 and AlmaLinux 10 get 18.6; Ubuntu 20.04 falls back to 12 and Debian 12 armv7 to 15 with apt-get update still clean; Ubuntu 22.04 with an existing 14 cluster stays on 14. The CI PostgreSQL test set passes against postgres:18.
  • 6be3c438e1 fix(node): keep client traffic history when a node inbound is replaced When a node snapshot reports an inbound under a tag that matches neither the central tag nor an origin/port alias, SetRemoteTraffic adopts it as a new central inbound and, in the same tick, sweeps the old one. The sweep deleted the old inbound's client_traffics rows even though the snapshot still reported those emails under the new inbound. existingEmails was computed before the sweep, so the rows were not recreated that tick; on the next tick the inbound was no longer new, the rows came back seeded at 0/0 and the node baseline jumped to the node's totals. Quota accounting lost every byte the clients had used. The sweep now moves rows for emails the snapshot still reports to the inbound now carrying them, instead of deleting them. Only emails the node no longer reports at all lose their row, mirroring the existing baseline rule. The alias check also treated a master-created node inbound that had not been tag-matched yet (empty origin_node_guid) as foreign, so a renamed tag on its first sync replaced it instead of aliasing it. An empty origin now counts as this node. PostgreSQL lane not run locally; the change is a plain UPDATE through GORM. Closes #6749
  • d57dcf824b chore(deps): bump frontend and docs deps, clear npm audit findings Bump vite, oxlint/oxfmt, msw, jsdom and plugin-react in the frontend, and fumadocs, lucide-react, oxlint/oxfmt, postcss and pnpm in docs. npm audit reported seroval <=1.6.2 (critical) via solid-js, which the react-query devtools pull in pinned to ~1.5.4, and sprintf-js (no patched release) via remarkable's argparse@1. `npm audit fix --force` "fixed" both by downgrading swagger-ui-react to 3.23.3, which brings in far worse advisories. Instead override seroval/seroval-plugins to ^1.6.8 and give remarkable argparse@2; remarkable only requires argparse from its unused CLI entry, so the bundled library is unaffected. pnpm appends an exact-version minimumReleaseAgeExclude entry on every update of a too-fresh release and never prunes them. Drop the stale ones; keep only fumadocs 16.16.2 and oxlint/oxfmt, still inside the 1-day cutoff.
  • View comparison for these 3 commits »

1 week ago

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

  • 66ef5bbc05 fix(sub): emit host TLS verification at xray level in JSON subscription The JSON subscription flattens tlsSettings into xray's client shape before the per-host loop, then applyExternalProxyTLSToStream writes the host's echConfigList, verifyPeerCertByName, pinnedPeerCertSha256 and allowInsecure into the panel-only tlsSettings.settings map. Xray ignores that map, so a host's ECH (and its pins / verify name) never reached the client and connections through the host failed. After the host overrides are applied, lift that map through the same writer tlsData uses for the inbound's own TLS: fields land at the top of tlsSettings, pins are joined into the comma string xray parses, and allowInsecure is dropped exactly as it is for the inbound (removed from xray). The Clash renderer still reads the nested map and is unchanged. The helper-level subtest that pinned the nested location as the "json" shape is replaced by an end-to-end GetJson test on a host-backed inbound. Closes #6743
  • dd9569478e fix(node): ignore a node's stats for clients detached from the inbound Invariant: a node snapshot may move a master client's traffic state only for emails the reporting inbound's settings still list. A master detach calls the node's /detach endpoint, which keeps the stat row (keepTraffic), and the node's GetInbounds preloads ClientStats by inbound_id alone, so the node goes on reporting the detached email under that inbound. setRemoteTrafficLocked merged every reported entry: it copied the node's stale total onto the master's per-email row, after which the matching limits made the node's enable=false look genuine and latched the client disabled on the master. A master quota edit only reaches inbounds the client is attached to, so the next sync (every 5s) wrote the stale quota back. The same unchecked loop also created a fresh client_traffics row for a reported email the master no longer had once its tombstone expired. Snapshot entries are now gated on the inbound's settings.clients. When the settings cannot be parsed, membership is unknown and every entry is merged as before. Closes #6724
  • View comparison for these 2 commits »

1 week ago