Files
MC_Report/README.md

185 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MC Report System
游戏玩家投诉/建议/申诉系统。Web 端 + Paper 插件双端提交MySQL 存储JWT 鉴权,三级角色。
## 功能模块
| 模块 | 说明 |
|------|------|
| **举报** | 指定目标玩家或事项举报,可上传截图/视频≤50MB支持投诉管理员仅服主可见 |
| **建议** | 提交改进建议,仅服主处理 |
| **申诉** | 封禁申诉 + 结果申诉(对处理结果不满可提交一次,关联原工单) |
| **审批流** | 待处理→接单→处理中→待补充→已解决/已驳回→关闭7天自动关闭 |
| **接单制** | 管理员一人一单,可转单(带原因),处理备注(玩家不可见) |
| **投票** | 分组/子服管理,定时/不定时投票,盲投制,管理员 1.5 票权 |
| **更新内容** | Issues 风格,分状态(待定/计划中/已完成),讨论区,按时间/热度排序,分组筛选 |
| **通知** | SMTP 邮件 + Discord WebhookSSRF 防护),邮件模板自定义(编辑变量) |
| **导出** | CSVUTF-8 BOM导出工单/被举报人统计/操作日志(仅服主) |
| **插件** | Paper 1.20+,统一 `/report` 命令,游戏内注册/登录/举报/追踪 |
| **找回密码** | 邮箱验证1小时有效重置链接 |
| **安装向导** | Web 页面配置 MySQL 连接 + 创建服主账号 |
## 快速开始
```bash
npm install
node backend/server.js
# → 打开 http://localhost:3100/#/install
```
两步安装:填 MySQL 连接信息 → 建服主账号 → 重启生效。
## 默认端口
`3100`,可通过 `PORT=8080` 环境变量修改。
## 技术栈
| 层 | 技术 |
|----|------|
| 后端 | Node.js + Express + mysql2 |
| 前端 | Vanilla JS SPAHash路由+ Inter 字体 |
| 数据库 | MySQL ≥ 5.7 |
| 认证 | JWT256 位随机密钥72h 有效期) |
| 安全 | Helmet 7 + Rate Limit分路由限速+ XSS 过滤 + CSP + API Key 常量时间比对 + SSRF 防护 |
| 验证码 | SVG 混淆图片svg-captcha4 位字符 + 噪点 + 颜色变形) |
| 文件上传 | Multer + MIME + 魔数字节校验UUID 命名web 外存储 |
| 插件 | Paper API 1.20.4 + java.net.HttpURLConnection |
## 角色权限矩阵
| 操作 | 玩家 | 管理员 | 服主 |
|------|:--:|:--:|:--:|
| 提交工单 | ✅ | ✅ | ✅ |
| 查看工单 | 仅自己 | 待处理 + 自己接的 | 全部 |
| 查看详情 | 仅自己 | 待处理 + 自己接的 | 全部 |
| 接单认领 | — | 举报/申诉 | 全部 |
| 更新处理备注 | — | 自己接的 | 全部 |
| 变更状态 | — | 自己接的 | 全部 |
| 转单 | — | 自己接的 | 全部 |
| 回复工单 | 自己的 | ✅ | ✅ |
| 用户管理 | — | ✅ | ✅ |
| 邮件模板 | — | ✅ | ✅ |
| 通知配置 | — | ✅ | ✅ |
| 系统设置 | — | ✅ | ✅ |
| 导出数据 | — | — | ✅ |
| 投票/更新管理 | — | — | ✅ |
| 工单追加(未接单) | 自己的 | — | — |
## 审批流状态
```
待处理(pending) ──接单──→ 处理中(processing) ──→ 已解决(resolved)
│ │ ├── 已驳回(rejected)
│ 待补充(awaiting_info) └── 7天自动关闭(closed)
│ │
└── 结果申诉 ──→ 申诉中(appealing) ──服主处理──→ 原工单关闭
```
- `closed` 为终态,仅服主可操作
- 结果申诉仅一次,关联原工单,仅服主可见
## 注册来源
| 来源 | 标识 | UID 含义 |
|------|------|---------|
| 网易端 | `netease` | 网易 UID |
| 皮肤站 | `skin` | 皮肤站 UID / Minecraft UUID |
插件注册默认 `skin`
## 工单提交流程
1. 填写标题 + 游戏名 + UID登录后自动填充
2. 举报:选目标玩家 + 原因(内置选项或自定义)+ 可投诉管理员
3. 建议:填写建议内容
4. 申诉:填写封禁申诉理由
5. 上传附件(可选,图片/视频 ≤50MB最多5个
6. 提交 → 生成 tracking_tokenCookie 留存)
## 外部 API
| 端点 | 用途 | 认证 |
|------|------|------|
| `POST /api/external/auth/register` | 插件注册 | x-external-key |
| `POST /api/external/auth/login` | 插件登录 | x-external-key |
| `GET /api/external/my-tickets` | 我的工单(JWT) | x-external-key + Bearer |
| `GET /api/external/my-tickets/:id` | 工单详情(JWT) | x-external-key + Bearer |
| `POST /api/external/tickets` | 提交工单 | x-external-key |
| `GET /api/external/all-tickets` | 全部工单 | x-external-key |
| `GET /api/external/reported-players` | 被举报统计 | x-external-key |
| `GET /api/external/stats` | 统计 | x-external-key |
## 部署
```bash
# 环境变量
PORT=3100 CORS_ORIGIN=https://your-domain.com node backend/server.js
# PM2 持久化
pm2 start backend/server.js --name mc-report
# Nginx 反代(还需 include nginx.inc
proxy_pass http://127.0.0.1:3100;
```
## 插件命令
```
/report reg <密码> <邮箱> [用户名] 注册(默认用户=游戏名)
/report login <密码> [用户名] 登录
/report report [玩家] <原因> 举报
/report suggest <内容> 建议
/report track [id] 追踪工单
```
配置 `plugins/MCReport/config.yml` 填写 `api_url``external_key`
## 目录结构
```
├── backend/
│ ├── server.js # Express 入口
│ ├── db.js # MySQL 连接池 + 建表 + 迁移
│ ├── mailer.js # SMTP 邮件(缓存 transporter
│ ├── webhook.js # Discord WebhookSSRF 防护 + 10s 超时)
│ ├── middleware/
│ │ ├── auth.js # JWT惰性缓存 secret
│ │ ├── security.js # 限速 + XSS 递归 + API Key 常量时间比对
│ │ └── upload.js # 文件上传(仅读 256B 头验证魔数)
│ └── routes/
│ ├── auth.js # 注册/登录/验证/找回密码
│ ├── tickets.js # 工单核心(自动关闭 + 状态流转)
│ ├── install.js # 安装向导(含 api_key 生成)
│ ├── external.js # 外部 API插件 + Java 服务器)
│ ├── users.js # 用户管理(含 source 字段)
│ ├── settings.js # 站点设置 + 邮件模板编辑
│ ├── export.js # CSV 导出(服主专享)
│ ├── polls.js # 投票(分组/子服/定时)
│ ├── features.js # 更新内容Issues 风格 + 讨论)
│ ├── notifications.js # Webhook 配置
│ ├── captcha.js # SVG 验证码
│ └── uploads.js # 附件下载(鉴权)
├── public/ # 前端 SPA (16 页面)
├── mc-report-plugin/ # Paper 1.20+ 插件 (Maven)
├── nginx.inc # Nginx 额外配置
├── data/ # config.json + uploads/
├── README.md
└── package.json
```
## 安全
| 措施 | 实现 |
|------|------|
| JWT 秘钥 | 256 位随机,惰性缓存,无硬编码 fallback |
| API Key | 48 位随机,常量时间比对防时序攻击 |
| 限速 | 登录 8/min、注册 3/min、工单 10/min、全局 300/min |
| XSS | `sanitizeBody` 递归过滤 + `U.esc` 前端转义 |
| CSP | Helmet + `script-src-attr 'unsafe-inline'` |
| SQL 注入 | 全参数化查询 |
| 文件上传 | 扩展名 + MIME + 魔数(仅读 256B+ UUID 命名 |
| Webhook SSRF | DNS 解析后过滤内网 IP |
| 用户名枚举 | 注册/登录统一错误信息 |
| CORS | 环境变量控制 + localhost 自动放行 |