txlyre

txlyre pushed to master at txlyre/ugushian

8 hours ago

txlyre pushed to master at txlyre/ugushian

9 hours ago

txlyre synced commits to dependabot/npm_and_yarn/frontend/i18next-26.4.4 at txlyre/3x-ui from mirror

  • 8675e93d4d chore(deps): bump i18next from 26.4.3 to 26.4.4 in /frontend Bumps [i18next](https://github.com/i18next/i18next) from 26.4.3 to 26.4.4. - [Release notes](https://github.com/i18next/i18next/releases) - [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md) - [Commits](https://github.com/i18next/i18next/compare/v26.4.3...v26.4.4) --- updated-dependencies: - dependency-name: i18next dependency-version: 26.4.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]>
  • 608ef4e401 v3.10.2
  • 35b5e0989a fix(sponsor): fetch sponsor data from raw.githubusercontent.com The server-side fetch used sponsors.sanaei.dev, a hostname unique to 3x-ui. Without ECH it travels in plaintext SNI, so an on-path observer could tag a server as running the panel from that one connection. raw.githubusercontent.com is shared by countless tools and reveals nothing. The path stays inside TLS. The data source is unchanged: the same MHSanaei/sponsors repo. Refs #6824
  • b177b98ce8 feat(mtproto): expose mtg-multi's per-IP pending-handshake limit mtg-multi v1.16.0 adds [defense.pending-handshakes] max-per-ip, which closes new connections from an IP already holding that many unauthenticated handshakes, so one address cannot pin the workers other clients need. The MTProto inbound form now carries it as pendingHandshakesMaxPerIp; the key is written only when set above 0, so existing inbounds render a byte-identical config and are not restarted. A change to it moves the structural fingerprint and restarts the sidecar. dry-run is left out on purpose: it only feeds the pending_handshake_limit Prometheus metric, which the panel does not surface. The hint warns that clients behind carrier NAT share the limit.
  • 6bd1b8676a fix(link): read the XHTTP fields a vmess link carries inline (#6808) A vmess link has no extra blob: the sub emitter writes the XHTTP extra fields (session/seq/uplink placement, padding obfs, xmux, ...) at the top level of the vmess JSON. The Go importer only read xPaddingBytes, scMaxEachPostBytes and scMinPostsIntervalMs from there, so a vmess XHTTP inbound with, for example, sessionIDPlacement=header or xPaddingObfsMode came back from an outbound subscription or a client external link as an outbound that cannot connect. Read the same keys the TS importer already reads from vmess JSON, including the pre-rename sessionPlacement/sessionKey aliases.
  • View comparison for these 10 commits »

9 hours ago

txlyre synced new reference dependabot/npm_and_yarn/frontend/i18next-26.4.4 to txlyre/3x-ui from mirror

9 hours ago

txlyre synced commits to dependabot/npm_and_yarn/frontend/antd-6.6.6 at txlyre/3x-ui from mirror

  • ec2c189071 chore(deps): bump antd from 6.6.5 to 6.6.6 in /frontend Bumps [antd](https://github.com/ant-design/ant-design) from 6.6.5 to 6.6.6. - [Release notes](https://github.com/ant-design/ant-design/releases) - [Changelog](https://github.com/ant-design/ant-design/blob/master/CHANGELOG.en-US.md) - [Commits](https://github.com/ant-design/ant-design/compare/6.6.5...6.6.6) --- updated-dependencies: - dependency-name: antd dependency-version: 6.6.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]>
  • 608ef4e401 v3.10.2
  • 35b5e0989a fix(sponsor): fetch sponsor data from raw.githubusercontent.com The server-side fetch used sponsors.sanaei.dev, a hostname unique to 3x-ui. Without ECH it travels in plaintext SNI, so an on-path observer could tag a server as running the panel from that one connection. raw.githubusercontent.com is shared by countless tools and reveals nothing. The path stays inside TLS. The data source is unchanged: the same MHSanaei/sponsors repo. Refs #6824
  • b177b98ce8 feat(mtproto): expose mtg-multi's per-IP pending-handshake limit mtg-multi v1.16.0 adds [defense.pending-handshakes] max-per-ip, which closes new connections from an IP already holding that many unauthenticated handshakes, so one address cannot pin the workers other clients need. The MTProto inbound form now carries it as pendingHandshakesMaxPerIp; the key is written only when set above 0, so existing inbounds render a byte-identical config and are not restarted. A change to it moves the structural fingerprint and restarts the sidecar. dry-run is left out on purpose: it only feeds the pending_handshake_limit Prometheus metric, which the panel does not surface. The hint warns that clients behind carrier NAT share the limit.
  • 6bd1b8676a fix(link): read the XHTTP fields a vmess link carries inline (#6808) A vmess link has no extra blob: the sub emitter writes the XHTTP extra fields (session/seq/uplink placement, padding obfs, xmux, ...) at the top level of the vmess JSON. The Go importer only read xPaddingBytes, scMaxEachPostBytes and scMinPostsIntervalMs from there, so a vmess XHTTP inbound with, for example, sessionIDPlacement=header or xPaddingObfsMode came back from an outbound subscription or a client external link as an outbound that cannot connect. Read the same keys the TS importer already reads from vmess JSON, including the pre-rename sessionPlacement/sessionKey aliases.
  • View comparison for these 10 commits »

9 hours ago

txlyre synced new reference dependabot/npm_and_yarn/frontend/antd-6.6.6 to txlyre/3x-ui from mirror

9 hours ago

txlyre pushed to master at txlyre/ugushian

11 hours ago

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

1 day ago

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

1 day ago

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

  • 608ef4e401 v3.10.2
  • 35b5e0989a fix(sponsor): fetch sponsor data from raw.githubusercontent.com The server-side fetch used sponsors.sanaei.dev, a hostname unique to 3x-ui. Without ECH it travels in plaintext SNI, so an on-path observer could tag a server as running the panel from that one connection. raw.githubusercontent.com is shared by countless tools and reveals nothing. The path stays inside TLS. The data source is unchanged: the same MHSanaei/sponsors repo. Refs #6824
  • b177b98ce8 feat(mtproto): expose mtg-multi's per-IP pending-handshake limit mtg-multi v1.16.0 adds [defense.pending-handshakes] max-per-ip, which closes new connections from an IP already holding that many unauthenticated handshakes, so one address cannot pin the workers other clients need. The MTProto inbound form now carries it as pendingHandshakesMaxPerIp; the key is written only when set above 0, so existing inbounds render a byte-identical config and are not restarted. A change to it moves the structural fingerprint and restarts the sidecar. dry-run is left out on purpose: it only feeds the pending_handshake_limit Prometheus metric, which the panel does not surface. The hint warns that clients behind carrier NAT share the limit.
  • 6bd1b8676a fix(link): read the XHTTP fields a vmess link carries inline (#6808) A vmess link has no extra blob: the sub emitter writes the XHTTP extra fields (session/seq/uplink placement, padding obfs, xmux, ...) at the top level of the vmess JSON. The Go importer only read xPaddingBytes, scMaxEachPostBytes and scMinPostsIntervalMs from there, so a vmess XHTTP inbound with, for example, sessionIDPlacement=header or xPaddingObfsMode came back from an outbound subscription or a client external link as an outbound that cannot connect. Read the same keys the TS importer already reads from vmess JSON, including the pre-rename sessionPlacement/sessionKey aliases.
  • ff3f42ee2a fix(link): read fm and the mKCP fields from vmess links (#6809) #6480 taught the vless/trojan importers to rebuild the mKCP header and seed and left the vmess importers ignoring fm. The vmess emitter writes the finalmask as fm, the mKCP header as type and the seed as path, plus mtu/tti. Both importers dropped all of them, so a vmess mKCP inbound with a seed, a header or any finalmask UDP mask (salamander, ...) came back from an outbound subscription, a client external link or the outbound form's link import as an outbound that cannot connect. Feed those fields through the same finalmask and kcp helpers the url-param protocols use, in the Go and TS importers.
  • View comparison for these 10 commits »

1 day ago

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 »

1 day 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]>

2 days ago

txlyre pushed to master at txlyre/ugushian

2 days ago

txlyre pushed to master at txlyre/ugushian

2 days ago

txlyre pushed to master at txlyre/ugushian

2 days ago

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

3 days ago

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

3 days 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 »

3 days 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 »

3 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 »

3 days ago