feat: add embedded web UI

Adds an optional web dashboard served by OpenGFW itself, enabled with a new
`web` section in the config file.

Backend (web package, decoupled from engine/io so it builds on any OS):
- hub.go collects statistics off the engine logger callbacks: atomic counters,
  two ring-buffered time series (10s and 1min buckets), top N hosts/blocked
  destinations/rules/analyzers, and a 512 entry event buffer fanned out to
  connected clients over SSE. Slow clients drop frames instead of blocking
  the engine.
- api.go exposes /api/v1 for info, meta, metrics, events, the SSE stream and
  ruleset read/validate/replace.
- auth.go implements password login with in-memory session tokens and login
  rate limiting. Mutating endpoints require the bearer token (the session
  cookie is only accepted for GET), which makes them CSRF-safe.
- cmd/web.go implements the rule manager: rules are compiled before anything
  is written, the file is replaced atomically and the engine is hot reloaded.
  The SIGHUP handler now shares that same path.
- web/devserver serves the UI with synthetic traffic for frontend work on
  machines where the engine itself cannot be built.

Frontend (web/frontend, Vue 3 + Vite + Tailwind CSS v4 + Reka UI):
dashboard, live event feed with analyzer property inspection, visual and YAML
rule editors, analyzer overview and settings. Responsive down to phone sizes
with a bottom tab bar and bottom-sheet dialogs, plus light/dark themes and
English/Chinese translations.

The built UI in web/dist is committed and embedded with go:embed so that
`go build` works without Node; CI builds the frontend and checks that the
committed output is up to date.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mei
2026-07-27 08:09:11 +08:00
co-authored by Claude Opus 5
parent 393c29bd2d
commit 5a7722d1d2
94 changed files with 8534 additions and 23 deletions
+29
View File
@@ -30,6 +30,35 @@ jobs:
with:
install-go: false
web-ui:
name: Web UI
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
cache-dependency-path: web/frontend/package-lock.json
- name: Install dependencies
run: npm ci
working-directory: web/frontend
- name: Build
run: npm run build
working-directory: web/frontend
- name: Check that the embedded web/dist is up to date
run: |
git diff --exit-code -- web/dist ||
(echo "::error::web/dist is stale, run 'make web' and commit the result" && exit 1)
tests:
name: Tests
runs-on: ubuntu-latest
+13 -1
View File
@@ -24,6 +24,17 @@ jobs:
with:
go-version: "1.22"
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: web/frontend/package-lock.json
- name: Build web UI
run: npm ci && npm run build
working-directory: web/frontend
- name: Build
env:
GOOS: ${{ matrix.goos }}
@@ -31,7 +42,8 @@ jobs:
CGO_ENABLED: 0
run: |
mkdir -p build
go build -o build/OpenGFW-${GOOS}-${GOARCH} -ldflags "-s -w" .
go build -o build/OpenGFW-${GOOS}-${GOARCH} \
-ldflags "-s -w -X github.com/apernet/OpenGFW/cmd.appVersion=${GITHUB_REF_NAME} -X github.com/apernet/OpenGFW/cmd.appCommit=${GITHUB_SHA::7}" .
- name: Upload
uses: softprops/action-gh-release@v2