Add the reserved_hosts setting (input + i18n across all locales) so operators
behind a reverse proxy can declare public dashboard hostnames members must not
register as NAT domains (GHSA-x6fg-52vr-hj4w).
Show the backend error message on NAT create/update failure instead of a
generic "unexpected error", so a reserved-host rejection is explained.
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
Add an API tokens management route to create, list, and revoke PATs, showing
the plaintext token once on creation with scope and server-id selection.
Mirror the nz-csrf cookie into the X-CSRF-Token header on unsafe fetcher
methods (POST/PUT/PATCH/DELETE) for the server-side double-submit check, and
self-heal expired sessions via refresh-token without a recursive fetch loop.
Gate protected routes behind resolved auth state to avoid pre-auth SWR fetches,
and fix the login loading/race so stale probes cannot clobber the session.
Add i18n keys for the new screens across all locales.
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
The GitHub runner can spend more than the readiness window compiling go run ./cmd/dashboard, leaving dashboard.log empty while the backend has not started yet. Build the dashboard binary during preparation and health-check only the actual server startup. Keep README instructions aligned with CI.
Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
The dashboard embed pattern ignores hidden-only dist directories, so the CI backend stub must create visible index.html files. Keep the README in sync and exclude Playwright specs from Vitest so npm run test remains a unit-test command.
Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
Boot a fresh dashboard from nezhahq/nezha master inside the runner:
- Checkout admin-frontend and the backend repo into two paths.
- Generate the two embed stubs and swag docs so cmd/dashboard builds.
- Inject NZ_JWTSECRETKEY (env-first config story) and start the
backend on 127.0.0.1:8008 with a tmp SQLite db.
- Wait on /api/v1/setting before letting Playwright launch.
- Playwright config brings up Vite dev which proxies /api to 8008.
- Upload playwright-report and dashboard.log on failure for triage.
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
Covers the security fixes that landed across both repos:
- auth.spec.ts: login persists nz-jwt cookie and getProfile succeeds;
password change bumps TokenVersion + revokes the old cookie so the
pre-change JWT can no longer auth (regression guard for the
keyId+session backend rewrite).
- cron-csrf.spec.ts: POST /api/v1/cron/:id/manual succeeds while GET
is no longer routable (regression guard for the cron CSRF fix).
- fm-csrf.spec.ts: POST /api/v1/file is reachable while GET is no
longer routable (regression guard for the FM CSRF fix).
- visibility.spec.ts: an anonymous caller cannot see a server-group
that contains zero guest-visible servers (regression guard for the
server-group leak fix).
Fixtures wrap the noisy login + cleanup boilerplate. tsconfig is
scoped to tests/e2e so the suite stays out of the production tsc
project graph.
Playwright config starts the Vite dev server (npm run dev) and
expects a backend reachable at the URL Vite proxies to. CI workflow
follow-up commit wires the backend up.
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
Backend moves /api/v1/file from GET to POST so SameSite=Lax cookies
can no longer expose this state-changing endpoint to cross-site
CSRF. Update createFM() accordingly.
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
Backend GHSA-8qhj-4f8c-j8qg moves /api/v1/cron/:id/manual from GET to
POST so SameSite=Lax cookies no longer expose this state-changing
endpoint to cross-site CSRF. Update runCron() accordingly.
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
Settings page used a plain number input for ip_change_notification_group_id,
requiring users to manually enter a group ID. Replace it with a searchable
Combobox component (consistent with alert-rule/service/cron pages) and wrap
the settings route with NotificationProvider to load notification group data.
Closesnezhahq/nezha#1174
Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
Upgrade react-hook-form 7.63→7.71 to fix form.reset() race condition
that silently broke zod validation on subsequent submissions.
Reset form and public-note state (publicNoteObj/Raw/Mode/Errors)
from latest data when the edit dialog opens, preventing stale state
from a previous edit session.