c4363deb46
feat: ticket create - sub-server selector
...
- ticket-create.js: added 子服务器 dropdown (group/server from
/polls/server-list, supports anonymous users), sends 'server' field
- tickets.js POST: accept server param, resolve 'group/server' or
alias/server_name from server_groups, store into tickets.server_name
- polls.js: new public GET /server-list (group_name+server_name only,
no auth required) for ticket create page
- verified: 13 checks (frontend/backend/db/column/syntax)
2026-08-21 22:02:06 +08:00
e1cdff2b4a
security: backend validation for all inputs
...
- router.param('id'): all :id path params must be positive ints
(tickets/features/polls/auth/users; external/bans/notifications already
had parseInt - now consistent)
- notifications: type enum + webhook URL format + SSRF (isPrivateUrl
exported) + events whitelist + active boolean check on PUT
- bans: type enum + player_name length
- external: all-tickets type/status enums, bans status/type enums,
page/limit floor protection, ticket field length caps, clients active
boolean + id validation
- verified: 28 checks (syntax + validation coverage)
2026-08-21 20:10:05 +08:00
8c5ce78fd0
chore: add AGPLv3 copyright header to all source files
...
- 52 JS files (backend + public/js): header with
Copyright (C) 2026 Sea Network Technology Studio
Author: CangLan <admin@sea-studio.top >
+ AGPLv3 notice
- idempotent (skips if header present), all syntax-checked
2026-08-19 20:27:05 +08:00
65edbaf157
refactor: session-based external auth, dynamic sources, drop netease UID
...
Auth (external API):
- ID: 16-digit random (non-sequential); Secret: SeaReport- + 32 hex
- POST /auth/session: ID+Secret -> Bearer SESSION (24h, single-session,
old session invalidated on re-issue, disabled client invalidates)
- clientAuth now validates Bearer SESSION via api_sessions JOIN api_clients
Sources (dynamic, no default, open-source friendly):
- sources table + CRUD route (/api/sources, owner; delete guarded by usage)
- users/user_identities.source ENUM -> VARCHAR, seeded netease/skin
- register/admin create/identity bind: validate against enabled sources
- UI: 来源管理 page; source dropdowns loaded dynamically everywhere
(register, dashboard identity, users admin, bans), labels dynamic
UID removal:
- game_uid/reporter_game_uid no longer required (db default '', validations
dropped, frontend fields optional)
Docs: EXTERNAL-API.md session flow + new credential format; API.md updated
Verified: 37 checks (syntax, session logic, source CRUD, UID removal, docs)
2026-08-19 20:08:06 +08:00
559970c5b7
feat: one account can bind both netease + skin identities
...
- db: user_identities table (UNIQUE user_id+source), migrate backfill from users
- auth: GET/POST/DELETE /api/auth/identities - bind/unbind/list identities
(netease requires UID, one per source, name uniqueness, keep >=1)
- register/external/plugin/admin-created users auto-write primary identity
- tickets: submit uses selected identity (validated belongs to user)
- dashboard: 我的身份 card with bind/unbind UI
- ticket-create: identity selector when >1 identity
2026-08-17 01:17:09 +08:00
6e9101a506
fix: deploy crash + multiple bug fixes + cleanup
...
- server.js: fix getSiteName() returning string when not installed causing
'getSiteName(...).then is not a function' crash on homepage (deploy blocker)
- server.js: auto-load business routes after install completes (no restart needed),
HTML cache keyed by api_key
- install: validate db name/email/password, trigger route loading after complete
- app.js: fix forgot/reset/verify pages rendering HomePage (missing page mapping)
- verify.js: support URL token auto-verification for external registration links
- auth: new email_code template for 6-digit code, reset_password template
(forgot-password was using verify_email template)
- upload.js: fix MP4 magic-bytes check using undefined buf variable
- tickets.js: status enum validation, anonymous submission rate limit
- security.js: XSS whitelist preserves email template HTML, strips scripts,
blocks javascript:/data: hrefs; CORS reject returns 403
- bans.js: allow clearing reason/duration, status enum validation
- users.js: fix req.user.role ReferenceError in create user modal
- home.js: tracking results now have detail view button
- .gitignore: ignore data/ (db credentials), logs, session files, temp scripts
2026-08-16 21:21:25 +08:00
5497de9aac
feat: batch ticket operations (close/delete/change status)
2026-07-17 21:55:15 +08:00
96e55d8715
feat: anonymous ticket reply via tracking cookie
2026-07-17 14:16:21 +08:00
9e5967d6ea
fix: reuse tracking cookie for multiple anonymous submissions
2026-07-17 14:14:02 +08:00
8d9e154ce1
fix: restrict PUT /tickets to admin's own claims (enforce claim system)
2026-07-13 18:19:28 +08:00
532efb962f
fix: HIGH+MEDIUM bugs from full audit - listen error, JWT, upload, mailer, webhook
2026-07-13 03:49:02 +08:00
8ae02dd115
fix: add appealing to active_count, limit check, export processing count
2026-07-12 23:28:52 +08:00
6fa1a65843
fix: admin cant view admin_complaint/result_appeal via URL, appeal close also closes parent
2026-07-12 21:02:21 +08:00
f87411b3b4
feat: auto-close resolved/rejected after 7 days, closed only owner can modify
2026-07-12 18:15:10 +08:00
33078855cb
feat: appealing status, auto-close parent on appeal resolved, closed=final
2026-07-12 17:42:42 +08:00
7bd23b6bcf
fix: result_appeal had wrong respContent label
2026-07-12 17:34:02 +08:00
10b6ff94ed
feat: admin complaint (owner only) + result appeal (one per ticket, owner only)
2026-07-12 15:19:09 +08:00
247a4e851d
feat: MC Report System - MySQL + Express + Vanilla JS SPA
2026-07-12 01:23:19 +08:00