Commit Graph
63 Commits
Author SHA1 Message Date
naibaandcloudcode bba5a8c44a test(e2e): fix revoke empty-list crash and password-restore CSRF cascade
Two CI-only failures surfaced against a fresh backend DB:

- The revoke test read after.data.find(), but the list endpoint omits data
  entirely when the admin has zero tokens, throwing on undefined. Default to [].
- The password-change test's restore POST hit a 403: changing the password
  triggers a refresh-token that re-mints the nz-csrf cookie, so the X-CSRF-Token
  read just before the request can be stale. A failed restore left the admin on
  the rotated password and cascaded into cron/fm/visibility login failures.
  Add csrfRequest(), which retries once on 403 after re-reading the cookie, and
  use it for both profile mutations.

Verified 8/8 passing across repeated fresh-DB CI-mode runs.

Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
2026-05-31 08:45:19 +00:00
naibaandcloudcode 76b9eb6a54 test(e2e): send CSRF token on mutating requests and fix PAT UI selectors
The backend CSRF double-submit gate rejects unsafe methods unless
X-CSRF-Token mirrors the signed nz-csrf cookie. page.request bypasses the
SPA JS that does this, so every mutating E2E call got 403, failing the suite.

- Add csrfHeaders(page) helper that mirrors the nz-csrf cookie into the
  header, polling until the cookie is readable to avoid the post-login race.
- Apply it to all cookie-authenticated POST/PATCH/DELETE calls (the /mcp
  Bearer calls stay header-free since PAT requests are CSRF-exempt).
- loginAs waits for the nz-csrf cookie before returning.
- Fix the create-token dialog submit selector: the button is labelled
  'Create API token' (t('CreateApiToken')), not 'Create'.

Verified 8/8 passing across repeated CI-mode runs against a real backend.

Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
2026-05-31 08:17:15 +00:00
naibaandcloudcode c9bed85a91 fix(security): guard external hrefs and refine CSRF/auth-loading handling
- Add safeExternalHref(): only render http(s) URLs as clickable hrefs,
  blocking attacker-controlled template metadata from becoming
  javascript:/data: links.
- Refine CSRF header attachment and auth-loading state in the fetcher,
  api-tokens client, useAuth, and settings route.

Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
2026-05-31 05:51:39 +00:00
naibaandcloudcode 472174640a feat(settings): add reserved hosts field and surface NAT errors
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>
2026-05-31 02:04:47 +00:00
naibaandcloudcode 6f0d9b6637 feat(api-tokens): add PAT management UI, CSRF handling, and auth-loading fixes
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>
2026-05-30 15:56:53 +00:00
1f1df8e273 ci(e2e): bind Vite dev server to loopback
Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>

Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
2026-05-26 05:56:12 +00:00
3db5041c58 ci(e2e): prebuild dashboard before backend health check
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>
2026-05-26 05:36:09 +00:00
11e2f2ca80 ci(e2e): make backend stubs embeddable and keep vitest scoped
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>
2026-05-26 05:27:46 +00:00
naibaandcloudcode 84fac6d653 docs(e2e): describe how to run Playwright suite locally and read CI artifacts
Co-authored-by: cloudcode <cloudcode@users.noreply.github.com>
2026-05-26 04:36:03 +00:00
naibaandcloudcode bb6abeb9a6 ci: run Playwright e2e against a real Go backend in GitHub Actions
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>
2026-05-26 04:34:43 +00:00
naibaandcloudcode 22da4d74b8 test(e2e): add Playwright suite for auth + CSRF + visibility fixes
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>
2026-05-26 04:34:43 +00:00
naibaandcloudcode 266cd7d150 fix(fm): switch createFM to POST to match backend CSRF fix
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>
2026-05-26 04:07:52 +00:00
naibaandcloudcode b10d655d6e fix(cron): switch manual trigger to POST to match backend CSRF fix
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>
2026-05-26 04:00:15 +00:00
naiba 849d131382 feat: server transfer rotation 2026-05-25 10:15:24 +00:00
naibaandnaiba/CloudCode 2010d80914 fix: hide admin settings tabs for members
Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
2026-05-16 00:46:15 +08:00
naibaandnaiba/CloudCode 341a6fa666 fix: use Combobox for notification group selection in settings page
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.

Closes nezhahq/nezha#1174

Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
2026-03-01 01:11:37 +00:00
奶爸andnaiba d04c4a1784 fix: public_note validation rejects non-object JSON values, preventing second edit (#154)
Co-authored-by: naiba <naiba@users.noreply.github.com>
2026-02-19 14:30:10 +08:00
naiba 84ba33dac3 fix: server edit dialog submit button unresponsive after first save (#1132)
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.
2026-02-14 12:11:47 +08:00
naiba f5fd7c390c fix: immutable release 2026-01-01 11:58:11 +08:00
naiba 1a7e2ad37a chore: fix import 2025-10-09 09:48:07 +08:00
naiba ec6511bcb8 💩 f*ck react 2025-10-02 17:15:20 +08:00
naiba cb749c6d16 fix: Cannot read properties of undefined (reading 'displayName') 2025-10-02 15:26:31 +08:00
naiba 875750d74e chore: add locales 2025-08-23 21:09:54 +08:00
naiba 5f854c3dd0 feat: 批量转移服务器给其他用户 2025-06-16 23:44:30 +08:00
naiba 833d2d904c chore(i18n): add locale config options 2025-03-29 13:21:14 +08:00
naiba 0e4986cf92 feat(i18n): add locales 2025-03-27 19:11:56 +08:00
naiba f85cc2fde3 chore: update locale 2025-03-22 22:37:01 +08:00
naiba 30ae419cbd feat: disable nat 2025-01-21 22:21:52 +08:00
naiba d54372fb0c chore: add type 2024-12-30 21:15:17 +08:00
naiba 97a5deb648 feat: oauth2 登录 2024-12-28 23:50:24 +08:00
naiba 73bb668c83 fix: block button 2024-12-23 19:47:57 +08:00
naiba 5bd24668c7 fix: member role menu 2024-12-23 19:24:46 +08:00
naiba f16069f9b3 fix: typo & render error 2024-12-17 22:19:22 +08:00
naiba 5910c52021 feat: implement InjectContext for dynamic resource injection 2024-12-17 22:03:21 +08:00
naiba 855b5d4cc8 chore: refactor 2024-12-15 20:26:35 +08:00
naiba 271bdb7f50 chore: change key 2024-12-15 15:27:23 +08:00
naiba 8e45f8ca6f feat: 后台自定义代码 & 后端语言优先 2024-12-15 15:08:57 +08:00
naiba 830992a74d fix: animate man position 2024-12-15 10:57:47 +08:00
naiba b9a8651371 refactor: enum i18n 2024-12-14 10:39:07 +08:00
naiba ff6318c961 feat: api update 2024-12-10 22:19:31 +08:00
naiba d1fba95484 fix: local debug 2024-12-09 23:11:17 +08:00
naiba 36472035e1 fix: websocket 2024-12-02 23:51:24 +08:00
naiba df6c23af89 fix: websocket 2024-12-02 22:10:07 +08:00
naiba 51c0af6146 chore: i18n 2024-12-01 21:50:59 +08:00
naiba 3dc6da8ea9 fix: waf page 2024-11-30 21:31:55 +08:00
naiba 7463bbe3a6 feat: 优化复制安装命令提示 2024-11-30 20:14:49 +08:00
naiba 5c0c358255 fix: copy to clipboard 2024-11-30 17:08:47 +08:00
naiba eb044d42bc feat: 修改用户名,简化代码 2024-11-30 15:02:42 +08:00
naiba 35436e69bb feat: 调整安装脚本复制位置 2024-11-30 12:58:53 +08:00
naiba bcd5e721c2 Merge pull request #1 from uubulb/dev 2024-11-25 13:37:19 +08:00
naiba 34b7a67ab0 fix: logout & login page home button 2024-11-23 10:25:54 +08:00
naiba e06e9db383 rename 2024-11-23 01:18:01 +08:00
naiba 6166d9de3f chore: fetch depth 0 2024-11-20 22:32:02 +08:00
naiba 8ef8eb342c fix: build ignore error 2024-11-20 22:29:08 +08:00
naiba 1da323c7c1 release 2024-11-20 22:04:08 +08:00
naiba 55821320dc Merge pull request #2 from uubulb/dev
init service page
2024-11-15 23:06:26 +08:00
naiba f842d5aeec feat: auto generate api types 2024-11-09 00:07:21 +08:00
naiba 680dc219d3 feat: server table 1/10 2024-11-06 00:09:03 +08:00
naiba bfdae2838f feat: refresh token 2024-11-05 00:02:43 +08:00
naiba b1a0b607da feat: login & check user 2024-11-03 23:29:32 +08:00
naiba 772d66334e 🚧 server/service 2024-11-02 22:58:56 +08:00
naiba 017e6cfdcf login page 2024-11-02 22:34:43 +08:00
naiba d945ca97c1 🎉 init vite & shadcn-ui 2024-11-01 22:47:49 +08:00