From c56f6447a85334b340a1e5a3d8211b72e2634431 Mon Sep 17 00:00:00 2001 From: Sanaei Date: Thu, 30 Jul 2026 03:14:22 +0200 Subject: [PATCH] chore: refresh dependencies and modernize Go test idioms Frontend deps: @hookform/resolvers 5.4.3 -> 5.5.7, Storybook 10.5.4 -> 10.5.5 across the four packages we declare, globals 17.7.0 -> 17.8.0, and jsdom 29.1.1 -> 30.0.1. The jsdom major replaces its CSS and selector stack -- @asamuzakjp/css-color 5 -> 6, @asamuzakjp/dom-selector 7 -> 8, undici 7 -> 8, nwsapi and generational-cache folded into their parents, whatwg-url 17 nested underneath. Nothing in the Vitest suites reaches those directly and the whole frontend gate (typecheck, lint, tests, build, Storybook compile) is green. Panel frontend version to 0.6.0. Backend deps: mattn/go-sqlite3 1.14.48 -> 1.14.49 and valyala/fasthttp 1.72.0 -> 1.73.0, plus the golang.org/x/exp and genproto/googleapis/rpc indirect bumps that came with them. Go tests: modernize -fix output, covering range-over-int, sync.WaitGroup.Go in place of manual Add/Done pairs, maps.Copy, and Go 1.26 new(expr) for pointer-to-value in the forwarded-trust table. The storedAs helper is deleted instead of being left behind a //go:fix inline directive -- keeping it that way fails govet on the one call site the rewrite did not reach, and every caller now takes new(...) directly. Behaviour is unchanged. DnsTab: the hosts-sync effect tested dns while declaring dnsEnabled in its dependency array. Both carry the same truth value, so this is exhaustive-deps hygiene rather than a behaviour change. --- frontend/package-lock.json | 229 ++++++++++-------- frontend/package.json | 18 +- frontend/src/pages/xray/dns/DnsTab.tsx | 2 +- go.mod | 8 +- go.sum | 16 +- internal/database/backup_test.go | 2 +- internal/sub/external_subscription_test.go | 12 +- internal/sub/forwarded_trust_test.go | 14 +- .../web/service/golden_fixtures_xray_test.go | 5 +- internal/xray/api_users_e2e_test.go | 5 +- 10 files changed, 159 insertions(+), 152 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e9d6164f4..5fe3f8814 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,17 +1,17 @@ { "name": "3x-ui-frontend", - "version": "0.4.3", + "version": "0.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "3x-ui-frontend", - "version": "0.4.3", + "version": "0.6.0", "dependencies": { "@ant-design/icons": "^6.3.2", "@codemirror/lang-json": "^6.0.2", "@codemirror/theme-one-dark": "^6.1.3", - "@hookform/resolvers": "^5.4.3", + "@hookform/resolvers": "^5.5.7", "@noble/hashes": "^2.2.0", "@tanstack/react-query": "^5.101.4", "@tanstack/react-query-devtools": "^5.101.4", @@ -32,10 +32,10 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", - "@storybook/addon-a11y": "^10.5.4", - "@storybook/addon-docs": "^10.5.4", - "@storybook/addon-vitest": "^10.5.4", - "@storybook/react-vite": "^10.5.4", + "@storybook/addon-a11y": "^10.5.5", + "@storybook/addon-docs": "^10.5.5", + "@storybook/addon-vitest": "^10.5.5", + "@storybook/react-vite": "^10.5.5", "@testing-library/dom": "^10.4.1", "@testing-library/react": "^16.3.2", "@types/react": "^19.2.17", @@ -47,13 +47,13 @@ "eslint": "^10.8.0", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-react-hooks": "^7.1.1", - "globals": "^17.7.0", + "globals": "^17.8.0", "husky": "^9.1.7", - "jsdom": "^29.1.1", + "jsdom": "^30.0.1", "lint-staged": "^17.2.0", "msw": "^2.15.0", "playwright": "^1.62.0", - "storybook": "^10.5.4", + "storybook": "^10.5.5", "typescript": "6.0.3", "typescript-eslint": "^8.65.0", "vite": "8.1.5", @@ -165,56 +165,58 @@ } }, "node_modules/@asamuzakjp/css-color": { - "version": "5.1.11", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", - "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.5.tgz", + "integrity": "sha512-mbhpPMmnw/kwW19aRNmSUl1QzLbdGo1SCuE49BT98MNwqF6zaHb3o2owssFc/PEO/4t2UjqtCNwocuDtJornzA==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/generational-cache": "^1.0.1", - "@csstools/css-calc": "^3.2.0", - "@csstools/css-color-parser": "^4.1.0", + "@csstools/css-calc": "^3.2.1", + "@csstools/css-color-parser": "^4.1.9", "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0" + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.5.2" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.13.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, "node_modules/@asamuzakjp/dom-selector": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz", - "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.0.tgz", + "integrity": "sha512-UJLfKXBhrc8i1vH2eJXuYQMwlsLKWFw3O+CPqXSuVEiikeAim3UgrfWX0k4tA/X8cRFM8iZ7OaqBokFGbYusdg==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/generational-cache": "^1.0.1", - "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.2.1", - "is-potential-custom-element-name": "^1.0.1" + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.5.2" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "^22.13.0 || >=24.0.0" } }, - "node_modules/@asamuzakjp/generational-cache": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", - "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + "node": "20 || >=22" } }, - "node_modules/@asamuzakjp/nwsapi": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", - "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", - "dev": true, - "license": "MIT" - }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -1384,9 +1386,9 @@ } }, "node_modules/@hookform/resolvers": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.4.3.tgz", - "integrity": "sha512-jtS1DEvkT1ql8ImIDQL+UmkhEnDmt3Bp7Yt4q5XQpc0JiQ8b8+I7yT/KQze4gw9Ocmi9xa9ef6zxifizPgdp3A==", + "version": "5.5.7", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.5.7.tgz", + "integrity": "sha512-CyPCYV8/KlXfEXLWj8HHHhVsR/IZ6Ckm3b/a4fWtO/lRnRK1huqncb8LlAWrmpPRsse5glF5aVuDRMHEr3UGag==", "license": "MIT", "dependencies": { "@standard-schema/utils": "^0.3.0" @@ -1413,7 +1415,7 @@ "react-hook-form": "^7.55.0", "superstruct": ">=0.12.0", "typanion": "^3.3.2", - "valibot": "^1.0.0 || ^1.0.0-beta.4 || ^1.0.0-rc", + "valibot": ">=0.31.0 || ^1.0.0-beta.4 || ^1.0.0-rc", "vest": ">=3.0.0", "yup": "^1.0.0", "zod": "^3.25.0 || ^4.0.0" @@ -3631,9 +3633,9 @@ "license": "MIT" }, "node_modules/@storybook/addon-a11y": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.5.4.tgz", - "integrity": "sha512-UWdZtB7Dh1GjqxTPOrisUNDhDGF5pKGzZdzW9DSSHMBcAOx2dsTmXGzLSFprAz4LTT0OHCtKhxNqKK0JZJ0Y8g==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.5.5.tgz", + "integrity": "sha512-nsMnSRe7pzepXIkUUqI/rL7sp8juXOluyypU4Dz0UuYHhw/cKaxfzuO+3WJN5EtEr/gcnKYb4awxH/duPGavUw==", "dev": true, "license": "MIT", "dependencies": { @@ -3645,20 +3647,20 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.4" + "storybook": "^10.5.5" } }, "node_modules/@storybook/addon-docs": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.5.4.tgz", - "integrity": "sha512-2Z/x2pKEmXOCQjmttYzPuQBu9aWeMly8uEs3msrCTBLiHs/F7IlBFnMu0Z+T2Qvk0LEy8O93AlcPSP76aCcKjw==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.5.5.tgz", + "integrity": "sha512-0YpKlimS4XE0kQ8Maa5coeefQxdyDrBHg1wOP3WTPuBe4FolFSCDveR0ge2+vuUBk+fZfn2+l+3Q2jmAWaRGDg==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/csf-plugin": "10.5.4", + "@storybook/csf-plugin": "10.5.5", "@storybook/icons": "^2.0.2", - "@storybook/react-dom-shim": "10.5.4", + "@storybook/react-dom-shim": "10.5.5", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -3669,7 +3671,7 @@ }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.5.4" + "storybook": "^10.5.5" }, "peerDependenciesMeta": { "@types/react": { @@ -3678,9 +3680,9 @@ } }, "node_modules/@storybook/addon-vitest": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.5.4.tgz", - "integrity": "sha512-5lr81sgrbK3Tjjbstieg/yYj3jdtQYP70ihpOiN1TwogvFATY2/9eMT46FE5ioKtEFcfJRDcgJ2wSlmJKE+kZw==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/addon-vitest/-/addon-vitest-10.5.5.tgz", + "integrity": "sha512-Ymq9ErkSkYiIDuqpJ2+hE5GCQ5J6TCLOWhutqArvwaeAO+HAibM82XNExpJ1/kvPqk9y961GDPkv2W15I88JIw==", "dev": true, "license": "MIT", "dependencies": { @@ -3695,7 +3697,7 @@ "@vitest/browser": "^3.0.0 || ^4.0.0", "@vitest/browser-playwright": "^4.0.0", "@vitest/runner": "^3.0.0 || ^4.0.0", - "storybook": "^10.5.4", + "storybook": "^10.5.5", "vitest": "^3.0.0 || ^4.0.0" }, "peerDependenciesMeta": { @@ -3714,13 +3716,13 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.5.4.tgz", - "integrity": "sha512-eXdgow+brSzZrG3CnG18YwxZwEYNAZIh2G5qKwNoZf0uk2ZCPgLRQwtVAcd7BiiEDGnXUHm9pycAS+UiF4F4Mg==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.5.5.tgz", + "integrity": "sha512-dQoJ7gUl8y0z5rV9cE0mz6qTBNmN9R4GOLIZk98rJ8CwduNJOb9eGZXusDzzvnYcp8TnNkqDtyx4tXQSUDInPQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "10.5.4", + "@storybook/csf-plugin": "10.5.5", "ts-dedent": "^2.0.0" }, "funding": { @@ -3728,14 +3730,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.5.4", + "storybook": "^10.5.5", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@storybook/csf-plugin": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.5.4.tgz", - "integrity": "sha512-DSp5Z/eZlRnKq0KrKLJE6uoYf/Ysc+FP0Z5DVTGnOrie+z3tC0lNi9I4RB++EXkJeUDS9/4dxvJZVSWjhLlXxw==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.5.5.tgz", + "integrity": "sha512-/euibhRFqklYCZqUseokojmfYcQpXshVY2QmA1qCuxMz9SzVFD3iSTw+aFLTxpsJGGdcZJk8fnm/rEthLzZ9jA==", "dev": true, "license": "MIT", "dependencies": { @@ -3748,7 +3750,7 @@ "peerDependencies": { "esbuild": "*", "rollup": "*", - "storybook": "^10.5.4", + "storybook": "^10.5.5", "vite": "*", "webpack": "*" }, @@ -3785,14 +3787,14 @@ } }, "node_modules/@storybook/react": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.5.4.tgz", - "integrity": "sha512-tOxfVgbYcaVsArN8XTDkJfdsnsnHh1LxjRHVpJ/N+VEkz4FveK/XH3jOLV0YqgrG8yXza7+CteDP4FfPVQY/mw==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.5.5.tgz", + "integrity": "sha512-T2Xj0ey7a9RHU6coYLC0L5lhjcdyhLCs9wNv15FvHvgmrRobkynEV72kq5vGW8tFkahNWI1X9+GZPQ6r8Nm38w==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/react-dom-shim": "10.5.4", + "@storybook/react-dom-shim": "10.5.5", "react-docgen": "^8.0.2", "react-docgen-typescript": "^2.2.2" }, @@ -3805,7 +3807,7 @@ "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.5.4", + "storybook": "^10.5.5", "typescript": ">= 4.9.x" }, "peerDependenciesMeta": { @@ -3821,9 +3823,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.4.tgz", - "integrity": "sha512-YdlppEOReg8MvTECRNuf79gu2zL83JqKDHIR/65eS0M6y+ue9pkpfjYo7hZVIcyOcRd9npBDXMdt2kC92bCuaA==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.5.5.tgz", + "integrity": "sha512-PIk7N3LLrZIxfNxmkvmQN1d5UQ70XEedT8n0GhBiXnM6XL09xPGB8n8TZXeJBRYluKhDQcAyQeT0/OZmcDVQJg==", "dev": true, "license": "MIT", "funding": { @@ -3835,7 +3837,7 @@ "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.5.4" + "storybook": "^10.5.5" }, "peerDependenciesMeta": { "@types/react": { @@ -3847,16 +3849,16 @@ } }, "node_modules/@storybook/react-vite": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.5.4.tgz", - "integrity": "sha512-iw7EAA98n30vpf+ZSy2Ll4Ne7oyZ/lS6W22u5Sp5UOI2oAkYuklxIWjRIKGqpY0BHP+GqaGYtUGMZQnBqgul2g==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.5.5.tgz", + "integrity": "sha512-Uy7VV72kVSkw6aDTAPQupXUeZX5LF6e4zqNvTZ+36qxsXAkaFgw7HPEm7L1tsaRfiV+s9anU7UvX47tfJpYGuQ==", "dev": true, "license": "MIT", "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "^0.7.0", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "10.5.4", - "@storybook/react": "10.5.4", + "@storybook/builder-vite": "10.5.5", + "@storybook/react": "10.5.5", "empathic": "^2.0.0", "magic-string": "^0.30.0", "react-docgen": "^8.0.2", @@ -3870,7 +3872,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.5.4", + "storybook": "^10.5.5", "typescript": ">= 4.9.x", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, @@ -7165,7 +7167,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/fast-json-patch": { @@ -7531,9 +7533,9 @@ } }, "node_modules/globals": { - "version": "17.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", - "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", + "version": "17.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.8.0.tgz", + "integrity": "sha512-Zz/LMDZScFmkakeL2cTHzf+PbWKdpU3uclqkZT7TjDG58j5WPt0PpA+n9uPI24fZtlw07q0OtEi84K+umsRzqQ==", "dev": true, "license": "MIT", "engines": { @@ -8525,39 +8527,39 @@ } }, "node_modules/jsdom": { - "version": "29.1.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz", - "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==", + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.1.tgz", + "integrity": "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^5.1.11", - "@asamuzakjp/dom-selector": "^7.1.1", + "@asamuzakjp/css-color": "^6.0.5", + "@asamuzakjp/dom-selector": "^8.3.0", "@bramus/specificity": "^2.4.2", - "@csstools/css-syntax-patches-for-csstree": "^1.1.3", - "@exodus/bytes": "^1.15.0", + "@csstools/css-syntax-patches-for-csstree": "^1.1.7", + "@exodus/bytes": "^1.15.1", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.3.5", + "lru-cache": "^11.5.2", "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^6.0.1", - "undici": "^7.25.0", + "tough-cookie": "^6.0.2", + "undici": "^8.9.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", - "whatwg-url": "^16.0.1", + "whatwg-url": "^17.1.0", "xml-name-validator": "^5.0.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24.0.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" }, "peerDependencies": { - "canvas": "^3.0.0" + "canvas": "^3.2.3" }, "peerDependenciesMeta": { "canvas": { @@ -8575,6 +8577,21 @@ "node": "20 || >=22" } }, + "node_modules/jsdom/node_modules/whatwg-url": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz", + "integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.15.1", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^22.14.0 || >=24.0.0" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -10420,7 +10437,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -10967,9 +10984,9 @@ } }, "node_modules/storybook": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.5.4.tgz", - "integrity": "sha512-bmLxPsxVSPnbeiZqYQpozyNOiJXfk+pf7WfHZflvPkwT6Y+rvYz3Cj/D6H4Kf2jHpuDNiMXBKO3yawLN2OWirg==", + "version": "10.5.5", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.5.5.tgz", + "integrity": "sha512-UscBIBJDloUeqntukHOhP1a5W/vouePDJbzPSxj466WK801FZtzQiMffMtkjzJiWSuj20wfaYlB2QQKh9aOYAg==", "dev": true, "license": "MIT", "dependencies": { @@ -10989,7 +11006,7 @@ "recast": "^0.23.5", "semver": "^7.7.3", "use-sync-external-store": "^1.5.0", - "ws": "^8.18.0" + "ws": "^8.21.1" }, "bin": { "storybook": "dist/bin/dispatcher.js" @@ -11760,13 +11777,13 @@ } }, "node_modules/undici": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", - "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz", + "integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==", "dev": true, "license": "MIT", "engines": { - "node": ">=20.18.1" + "node": ">=22.19.0" } }, "node_modules/undici-types": { diff --git a/frontend/package.json b/frontend/package.json index de805f524..a89fde405 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "3x-ui-frontend", "private": true, - "version": "0.4.3", + "version": "0.6.0", "type": "module", "description": "3x-ui panel frontend (React 19 + Ant Design 6 + Vite 8).", "engines": { @@ -30,7 +30,7 @@ "@ant-design/icons": "^6.3.2", "@codemirror/lang-json": "^6.0.2", "@codemirror/theme-one-dark": "^6.1.3", - "@hookform/resolvers": "^5.4.3", + "@hookform/resolvers": "^5.5.7", "@noble/hashes": "^2.2.0", "@tanstack/react-query": "^5.101.4", "@tanstack/react-query-devtools": "^5.101.4", @@ -51,10 +51,10 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", - "@storybook/addon-a11y": "^10.5.4", - "@storybook/addon-docs": "^10.5.4", - "@storybook/addon-vitest": "^10.5.4", - "@storybook/react-vite": "^10.5.4", + "@storybook/addon-a11y": "^10.5.5", + "@storybook/addon-docs": "^10.5.5", + "@storybook/addon-vitest": "^10.5.5", + "@storybook/react-vite": "^10.5.5", "@testing-library/dom": "^10.4.1", "@testing-library/react": "^16.3.2", "@types/react": "^19.2.17", @@ -66,13 +66,13 @@ "eslint": "^10.8.0", "eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-react-hooks": "^7.1.1", - "globals": "^17.7.0", + "globals": "^17.8.0", "husky": "^9.1.7", - "jsdom": "^29.1.1", + "jsdom": "^30.0.1", "lint-staged": "^17.2.0", "msw": "^2.15.0", "playwright": "^1.62.0", - "storybook": "^10.5.4", + "storybook": "^10.5.5", "typescript": "6.0.3", "typescript-eslint": "^8.65.0", "vite": "8.1.5", diff --git a/frontend/src/pages/xray/dns/DnsTab.tsx b/frontend/src/pages/xray/dns/DnsTab.tsx index d37c38902..929bcf5c8 100644 --- a/frontend/src/pages/xray/dns/DnsTab.tsx +++ b/frontend/src/pages/xray/dns/DnsTab.tsx @@ -47,7 +47,7 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab const lastWrittenHostsRef = useRef(null); useEffect(() => { - if (!dns) { + if (!dnsEnabled) { lastWrittenHostsRef.current = '{}'; setHostsList([]); return; diff --git a/go.mod b/go.mod index 87a1c8236..57a1bc92f 100644 --- a/go.mod +++ b/go.mod @@ -13,14 +13,14 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/joho/godotenv v1.5.1 - github.com/mattn/go-sqlite3 v1.14.48 + github.com/mattn/go-sqlite3 v1.14.49 github.com/mymmrac/telego v1.11.1 github.com/nicksnyder/go-i18n/v2 v2.6.1 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/robfig/cron/v3 v3.0.1 github.com/shirou/gopsutil/v4 v4.26.6 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e - github.com/valyala/fasthttp v1.72.0 + github.com/valyala/fasthttp v1.73.0 github.com/xlzd/gotp v0.1.0 github.com/xtls/xray-core v1.260327.1-0.20260728075948-5ca6f4b7d4dc go.uber.org/atomic v1.11.0 @@ -99,7 +99,7 @@ require ( go.mongodb.org/mongo-driver/v2 v2.8.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/arch v0.29.0 // indirect - golang.org/x/exp v0.0.0-20260718201538-764159d718ef // indirect + golang.org/x/exp v0.0.0-20260727155853-b88d891fe743 // indirect golang.org/x/mod v0.38.0 // indirect golang.org/x/net v0.57.0 golang.org/x/sync v0.22.0 // indirect @@ -108,7 +108,7 @@ require ( golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446 // indirect golang.zx2c4.com/wireguard/windows v1.0.1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260724162435-b2f20204f0df // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 // indirect google.golang.org/protobuf v1.36.11 gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0 // indirect lukechampine.com/blake3 v1.4.1 // indirect diff --git a/go.sum b/go.sum index d999412d9..c81c56a83 100644 --- a/go.sum +++ b/go.sum @@ -129,8 +129,8 @@ github.com/lufia/plan9stats v0.0.0-20260627054121-477a66015f15 h1:YkjVPl/YH5XlJ+ github.com/lufia/plan9stats v0.0.0-20260627054121-477a66015f15/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= -github.com/mattn/go-sqlite3 v1.14.48 h1:7XHIgl0a8HwOaiK4E47ozLkST78rR9+OtNGx27D/TFs= -github.com/mattn/go-sqlite3 v1.14.48/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w= +github.com/mattn/go-sqlite3 v1.14.49 h1:B8jBHC3xhxZgxztrgruTuLucebnULQnx4W7cF7SAE9w= +github.com/mattn/go-sqlite3 v1.14.49/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w= github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -204,8 +204,8 @@ github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.72.0 h1:R7kYdoWhn1ye1fVpP+cDHDJwYm3NkwLliwgzJ/Abg7M= -github.com/valyala/fasthttp v1.72.0/go.mod h1:zsbLTYqcpIktdQytlVBwIjY9La5d6bs990nBxWg8efk= +github.com/valyala/fasthttp v1.73.0 h1:ocTOORnBWtJ+P8t/6wAjdkchMzdfHmWx2VD/DPbgZ7s= +github.com/valyala/fasthttp v1.73.0/go.mod h1:EtXQDHaR+5P18p8wqDRFpUhxr108Ga9mXvVJXHRrN2k= github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4= github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE= github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= @@ -250,8 +250,8 @@ golang.org/x/arch v0.29.0 h1:8sSET5wB0+exBm0FGmOtdHMqjlRdV2DRD3/IV6OZgho= golang.org/x/arch v0.29.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= -golang.org/x/exp v0.0.0-20260718201538-764159d718ef h1:LkZ48HFgy/TvhTI0bcWkjgFkgLyKUwcTbDjS0DUjw+A= -golang.org/x/exp v0.0.0-20260718201538-764159d718ef/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q= +golang.org/x/exp v0.0.0-20260727155853-b88d891fe743 h1:ex206bKw+v3K0dm3andkrIF+ijyQKJG1pLgwQ2PYdQM= +golang.org/x/exp v0.0.0-20260727155853-b88d891fe743/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q= golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= @@ -279,8 +279,8 @@ golang.zx2c4.com/wireguard/windows v1.0.1 h1:eOxiDVbywPC+ZQqvdCK7x+ZwWXKbYv50TtH golang.zx2c4.com/wireguard/windows v1.0.1/go.mod h1:+fbT3FFdX4zzYDLwJh5+HPEcNN/3HyNdzhNSVsQM+zs= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260724162435-b2f20204f0df h1:O3ig1i5WDDzsVzRp+cCdgelT9vXnlnOFdlEeFtL4HCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260724162435-b2f20204f0df/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 h1:mJiOtnGp0k/BcSgdu03G2NwnscCfCH+h2QKUBZr18KI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/internal/database/backup_test.go b/internal/database/backup_test.go index 621a9ebcf..6e2a35937 100644 --- a/internal/database/backup_test.go +++ b/internal/database/backup_test.go @@ -35,7 +35,7 @@ func TestBackupSQLiteProducesValidSnapshotDuringWrites(t *testing.T) { firstWrite := make(chan error, 1) writesDone := make(chan error, 1) go func() { - for i := 0; i < 128; i++ { + for i := range 128 { if err := db.Create(&model.Setting{Key: fmt.Sprintf("backup-write-%d", i), Value: value}).Error; err != nil { if i == 0 { firstWrite <- err diff --git a/internal/sub/external_subscription_test.go b/internal/sub/external_subscription_test.go index 3602d5d7a..0a6c51b29 100644 --- a/internal/sub/external_subscription_test.go +++ b/internal/sub/external_subscription_test.go @@ -43,11 +43,9 @@ func TestFetchSubscriptionLinksSharesConcurrentRefresh(t *testing.T) { results := make(chan []string, callers) var wg sync.WaitGroup for range callers { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { results <- fetchSubscriptionLinks(srv.URL) - }() + }) } time.Sleep(100 * time.Millisecond) @@ -123,11 +121,9 @@ func TestFetchSubscriptionLinksSharesStaleResultAfterRefreshFailure(t *testing.T results := make(chan []string, callers) var wg sync.WaitGroup for range callers { - wg.Add(1) - go func() { - defer wg.Done() + wg.Go(func() { results <- fetchSubscriptionLinks(staleURL) - }() + }) } time.Sleep(100 * time.Millisecond) diff --git a/internal/sub/forwarded_trust_test.go b/internal/sub/forwarded_trust_test.go index 83f1df87c..a0eb1d1c5 100644 --- a/internal/sub/forwarded_trust_test.go +++ b/internal/sub/forwarded_trust_test.go @@ -40,10 +40,6 @@ func setTrustedProxyCIDRs(t *testing.T, value string) { } } -func storedAs(value string) *string { - return &value -} - func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) { tests := []struct { name string @@ -65,7 +61,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) { }, { name: "empty stored value keeps trusting forwarded headers", - stored: storedAs(""), + stored: new(""), remoteAddr: "203.0.113.9:51000", wantScheme: "https", wantHost: "sub.example.net", @@ -74,7 +70,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) { }, { name: "stored shipped default keeps trusting forwarded headers", - stored: storedAs(service.DefaultTrustedProxyCIDRs), + stored: new(service.DefaultTrustedProxyCIDRs), remoteAddr: "203.0.113.9:51000", wantScheme: "https", wantHost: "sub.example.net", @@ -83,7 +79,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) { }, { name: "declared boundary ignores an origin outside it", - stored: storedAs("10.0.0.0/8"), + stored: new("10.0.0.0/8"), remoteAddr: "203.0.113.9:51000", wantScheme: "http", wantHost: "panel.example.com", @@ -92,7 +88,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) { }, { name: "declared boundary trusts an origin inside it", - stored: storedAs("10.0.0.0/8"), + stored: new("10.0.0.0/8"), remoteAddr: "10.1.2.3:44000", wantScheme: "https", wantHost: "sub.example.net", @@ -101,7 +97,7 @@ func TestResolveRequest_ForwardedHeaderTrust(t *testing.T) { }, { name: "declared boundary ignores an unparsable origin", - stored: storedAs("10.0.0.0/8"), + stored: new("10.0.0.0/8"), remoteAddr: "not-an-ip", wantScheme: "http", wantHost: "panel.example.com", diff --git a/internal/web/service/golden_fixtures_xray_test.go b/internal/web/service/golden_fixtures_xray_test.go index 77ce6c1f9..e60329822 100644 --- a/internal/web/service/golden_fixtures_xray_test.go +++ b/internal/web/service/golden_fixtures_xray_test.go @@ -8,6 +8,7 @@ import ( "crypto/x509/pkix" "encoding/json" "encoding/pem" + "maps" "math/big" "os" "path/filepath" @@ -256,9 +257,7 @@ func TestGoldenStreamFixturesBuildInXray(t *testing.T) { case "stream": stream = fixture case "security": - for key, value := range fixture { - stream[key] = value - } + maps.Copy(stream, fixture) case "sockopt": stream["sockopt"] = fixture case "finalmask": diff --git a/internal/xray/api_users_e2e_test.go b/internal/xray/api_users_e2e_test.go index 7399fc95f..5b5e1bf59 100644 --- a/internal/xray/api_users_e2e_test.go +++ b/internal/xray/api_users_e2e_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io" + "maps" "net" "net/http" "net/url" @@ -138,9 +139,7 @@ func panelUser(email string, fields map[string]any) map[string]any { "preSharedKey": "", "keepAlive": "", } - for k, v := range fields { - user[k] = v - } + maps.Copy(user, fields) return user }