Second-pass on the SOCKS5 inbound scaffold (PR #4452). This commit ticks off two of the 'help wanted' items from the scaffold's TODO list and tightens the existing dispatcher so that adding a new protocol-without-link in the future is a one-line change instead of an audit through every switch. Backend (Go) ------------ * database/model/model.go: new IsSocksLike(p) helper that returns true for both 'socks' and 'mixed'. Mirrors the existing IsHysteria pattern (one helper, two underlying constants) so call sites don't have to re-list both protocols every time they need to treat 'this inbound speaks SOCKS5' uniformly. * database/model/model_test.go: - TestSocksProtocolConstant pins the wire value 'socks' so a future refactor can't silently rename it (which would orphan every stored inbound row). - TestIsSocksLike covers Socks, Mixed, every other declared protocol, the empty Protocol, and a wrong-case input. * sub/subService.go GetLink: - Replace bare string literals ('vmess', 'vless', …) with the typed model.* constants so a typo can't silently fall through. - Add an explicit link-less case for Socks/Mixed/HTTP/Tunnel/WireGuard with a comment explaining why we don't emit 'socks://…' URLs (follow-up #1 in the scaffold PR description). Frontend (JS/Vue) ----------------- * frontend/src/models/dbinbound.js: add 'isSocks' getter (pure SOCKS5 inbound) and 'isSocksLike' getter (Socks OR Mixed), matching the pattern used by isMixed/isHTTP/isWireguard above. * frontend/src/pages/inbounds/InboundInfoModal.vue: the existing 'Mixed' info block (auth/UDP/IP/accounts) now also renders for the new SOCKS protocol via isSocksLike, since Xray's mixed and socks inbounds accept the exact same settings keys. Without this, opening the info modal for a SOCKS inbound would show an empty body. Header comment updated to list SOCKS alongside Mixed/HTTP/Tunnel. Still outstanding from the scaffold's TODO list: - Xray runtime AddUser hooks (web/service/inbound.go) - Translations for the 'socks' label across all 13 locales - Routing UI protocol == socks helper |
||
|---|---|---|
| .. | ||
| src | ||
| .gitignore | ||
| api-docs.html | ||
| eslint.config.js | ||
| inbounds.html | ||
| index.html | ||
| login.html | ||
| nodes.html | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| settings.html | ||
| subpage.html | ||
| vite.config.js | ||
| xray.html | ||
3x-ui frontend
Vue 3 + Ant Design Vue 4 + Vite. Multi-page app — one HTML entry per
panel route — built into ../web/dist/ and embedded into the Go binary
via embed.FS.
Dev
npm install
npm run dev
Vite serves on http://localhost:5173/. API calls and /panel/* routes
proxy to the Go panel at http://localhost:2053/, so start the Go panel
first (go run main.go) and then Vite.
The proxy auto-rewrites /panel, /panel/settings, /panel/inbounds,
/panel/xray to the matching Vite-served HTML in dev mode (see
MIGRATED_ROUTES in vite.config.js), so the sidebar's
production-style links work without round-tripping through Go.
Production build
npm run build
Outputs to ../web/dist/ (HTML at the root, hashed JS/CSS under
assets/). The Go binary embeds this directory at compile time and
web/controller/dist.go serves the per-page HTML.
Lint
npm run lint
ESLint 10 with eslint.config.js (flat config) — vue3-recommended
plus a few rule overrides for the project's formatting style.
Layout
frontend/
├── *.html # Vite entry HTML, one per panel route
├── eslint.config.js
├── vite.config.js
└── src/
├── entries/ # Per-page bootstrap (createApp + mount)
├── pages/ # One folder per route, each with the page
│ ├── index/ # component + helpers + sub-components
│ ├── login/
│ ├── inbounds/
│ ├── xray/
│ ├── settings/
│ └── sub/
├── components/ # Cross-page Vue components
├── composables/ # Reusable reactive logic (useTheme, …)
├── api/ # Axios setup, CSRF interceptor
├── i18n/ # vue-i18n init (locales live in web/translation/)
├── models/ # Inbound, Outbound, Status, … domain classes
└── utils/ # HttpUtil, ObjectUtil, LanguageManager, …
Adding a new page
- Add
frontend/<page>.htmlreferencing/src/entries/<page>.js. - Add
src/entries/<page>.jsthat imports the page component and mounts it. - Add the page component under
src/pages/<page>/. - Register the entry in
rollupOptions.inputinvite.config.js. - If the page is reachable from the sidebar at
/panel/<route>, add it toMIGRATED_ROUTESso the dev proxy serves the Vite HTML. - Wire the Go controller to
serveDistPage(c, "<page>.html").