Files

112 lines
3.6 KiB
Markdown

# admin_panel
A TypeScript (Vite + React + Material UI, dark theme) admin panel that talks to
the `manager_api/http` server.
The compiled SPA is **embedded into the Go binary via `//go:embed`** — the
post-processed `dist/` directory is checked into the repo, so
`go build -tags with_admin_panel ./cmd/sing-box` produces a fully
self-contained binary with no Node.js required at compile time.
The `web/` directory holds the original TypeScript sources, which are only
needed when the panel itself is being modified. `make admin_panel_regen`
rebuilds `dist/` from those sources via `npm run build` followed by an
in-place post-processing step (`cmd/internal/admin_panel_pack`).
## Layout
```
service/admin_panel/
├── service.go # Go service (build tag: with_admin_panel, //go:embed dist)
├── service_stub.go # Stub when the tag is missing
├── service_test.go # Tests for the SPA handler
├── dist/ # Embedded SPA bytes (committed to git)
│ ├── index.html
│ ├── index.html.gz
│ └── assets/
│ ├── index-*.js
│ ├── index-*.js.gz
│ ├── index-*.css
│ ├── index-*.css.gz
│ └── inter-*.woff2
└── web/ # Vite + React TypeScript source (only needed to regen)
├── package.json
├── vite.config.ts
├── tsconfig.json
├── index.html
└── src/
├── main.tsx
├── App.tsx
├── theme.ts
├── api/{client,types}.ts
├── auth/AuthContext.tsx
├── components/{Layout,CrudPage}.tsx
└── pages/*.tsx
cmd/internal/admin_panel_pack/
└── main.go # Post-processor: drops .woff, rewrites CSS, pre-gzips text
```
## Building sing-box with the panel
`dist/` is committed, so any developer or CI machine can build a
self-contained binary with no Node.js / npm available:
```bash
go build -tags with_admin_panel ./cmd/sing-box
# or
make build_admin_panel
```
If the tag is omitted the service registers a stub that errors out on start.
## Regenerating dist/
Whenever the SPA source under `web/` is changed, run:
```bash
make admin_panel_regen
```
That target performs two steps:
1. `make admin_panel_web``npm install` + `npm run build` in `web/`,
producing `service/admin_panel/dist/`.
2. `make admin_panel_pack` — runs the
`cmd/internal/admin_panel_pack` post-processor, which:
- deletes the legacy `*.woff` (WOFF 1.0) fallback fonts; every browser
since 2014 reads WOFF2 natively, and shipping both formats roughly
doubles the embedded font payload;
- rewrites the bundled `*.css` to drop `,url(...).woff) format("woff")`
references so the @font-face rules don't point at files that aren't
shipped;
- drops a gzip-compressed `*.gz` companion next to every text-like
asset (.html, .css, .js, .svg, .json) at `gzip.BestCompression`. The
runtime serves those bytes verbatim with `Content-Encoding: gzip`
when the client advertises gzip support, and falls back to the raw
file otherwise.
After the post-processing pass, commit the resulting `dist/` directory
along with your source changes.
## Configuring sing-box
Add a service entry of type `admin-panel`:
```json
{
"services": [
{
"type": "admin-panel",
"tag": "admin",
"listen": "127.0.0.1",
"listen_port": 8081
}
]
}
```
The panel itself does not require any back-end auth: at sign-in the user
enters the URL and bearer key of a `manager-api` instance. Both are stored
only in the browser's `localStorage`.