# est-api

EST 本地部署的后端 API，包含两个子服务并通过统一入口启动：
- 根路径 `/`：平台框架接口（frameworkapi）
- 前缀 `/dsxapi`：DSX 模拟器相关接口（dsxapi）

## 快速启动
```bash
# 安装依赖
npm install

# 启动统一入口（默认监听 3000）
npm start
```
- 统一入口：`app.js`，将 `frameworkapi` 挂载到 `/`，`dsxapi` 挂载到 `/dsxapi`
- 端口：默认 `3000`


## 目录结构
- `/app.js` 统一入口，挂载两个子服务
- `/farmeworkapi/` 平台框架接口
  - `.env` 环境变量文件（子服务加载）
  - `farmeworkapi.js` 主入口
  - `license/` 存放许可证（.lic）
  - `pub.pem`/`priv.pem` 公钥/私钥；`license_issuer.html` 颁发页面
  - `network` 宿主机网络配置中转文件
- `/dsxapi/` DSX 模拟器接口
  - `dsxapi.js` 主入口
  - `competition_data/` 结束后持久化的比赛数据（.est）
  - `competition_tmp/` 比赛进行时的临时备份目录
  - `connection_maps/connectionMap.json` 连接映射持久化

## 配置与环境变量
仅 `farmeworkapi` 会加载其目录下 `.env`：
```ini
# Database configuration
DB_HOST=est_mysql
DB_PORT=3306
DB_USER=root
DB_PASSWORD=MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDQMYcjqnrMnr9G
DB_NAME=login

# SurveyKing_DB_NAME 
SurveyKing_DB_HOST=est_mysql
SurveyKing_DB_PORT=3306
SurveyKing_DB_USER=root
SurveyKing_DB_PASSWORD=MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDQMYcjqnrMnr9G
SurveyKing_DB_NAME=surveyking

# JWT configuration
JWT_SECRET=MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDQMYcjqnrMnr9G

# Server configuration
PORT=3000

```

## 路由与接口
以下路径均为统一入口下的最终路径。

### frameworkapi（前缀 `/`）
- `POST /login` AES(CBC) 加密的登录数据，成功返回 `token` 与用户等级
- `GET /check-auth`（鉴权）返回当前用户认证状态
- `POST /verify-token` 校验令牌有效性
- `GET /user-info`（鉴权）获取用户信息
- `GET /verify-admin`（鉴权）校验是否管理员
- `GET /admin/users`（鉴权）列出用户
- `POST /admin/users`（鉴权）新增/修改用户
- `DELETE /admin/users/:student_id`（鉴权）删除用户
- `GET /online-users`（鉴权）在线与历史统计
- `POST /update-activity`（鉴权）更新心跳/活跃时间
- `POST /logout`（鉴权）登出

许可证相关：
- `GET /public-key` 获取 RSA 公钥（用于前端加密）
- `GET /product-model` 返回产品型号（随许可证状态）
- `POST /upload-license` 上传 `.lic` 文件并验证（form-data）
- `GET /license-status` 许可证验证状态摘要
- `GET /license-info`（鉴权）许可证详细信息

网络配置：
- `GET /network-config`（鉴权）读取 `farmeworkapi/network`
- `POST /network-config`（鉴权）更新指定键：`BOOTPROTO`、`IPADDR`、`NETMASK`、`GATEWAY`、`DNS`
  - `BOOTPROTO` 仅支持 `dhcp` 或 `static`
  - `static` 时必须提供 `IPADDR`、`NETMASK`、`GATEWAY`、`DNS`

Survey 数据：
- `GET /survey-answers` 读取 SurveyKing 数据库中的问卷答案（具体查询参数以实现为准）

### dsxapi（前缀 `/dsxapi`）
连接映射：
- `GET /api/connectionMap?scene=XXX` 返回 `pass` 与指定场景合并后的映射
- `POST /api/connectionMap` 更新某场景映射（禁止修改 `pass`）
- `POST /api/initConnectionMap` 恢复到初始映射并持久化

比赛流程：
- `POST /api/competition/start` 开始比赛，返回 `UUID`，每分钟写入临时备份到 `competition_tmp/<UUID>/`
- `POST /api/competition/end` 结束比赛，写入编码 `.est` 文件到 `competition_data/`
- `GET /api/competition/status` 查询是否进行中及 `UUID`、开始时间
- `POST /api/competition/data` 上传统计数据（需携带 `UUID`、`fingerprint`、`data`）
- `GET /api/competition/data?UUID=...&fingerprint=...` 查询指定指纹数据（返回 `projects`）
- `GET /api/competition/data` 返回当前全部统计数据快照

## 日志
- `farmeworkapi/server.log` 常规日志；`farmeworkapi/admin.log` 管理员操作日志
- dsxapi 独立运行时在控制台输出重要提示与告警

## Docker 与挂载
- 挂载 `farmeworkapi/license/` 以便导入许可证
- 挂载 `farmeworkapi/network` 供网络配置接口读写
- 挂载 `/hardware_serial` 到容器内，提供硬件序列号以完成许可证绑定
- 可选择将 `dsxapi/competition_data/` 与 `dsxapi/competition_tmp/` 映射到持久卷

## Webpack 打包与混淆
本项目已集成基于 Webpack 的 Node 端打包与 JavaScript 混淆，适用于生产环境分发与提高代码可读性门槛。

### 前置条件
- 建议使用 Node.js 18 或 20。
- 安装依赖：`npm install`（包含开发依赖用于构建）。

### 构建与运行
- 构建（打包 + 混淆）：`npm run build`
- 运行打包版本：`npm run start:dist`
- 构建产物位置：`dist/`
  - 入口：`dist/server.js`
  - 资产：`.env`、`license/`、`network/`、`pub.pem`、`priv.pem`、`license_issuer.html`、`online_data.json`、`dsxapi/connection_maps`、`dsxapi/competition_data`、`dsxapi/competition_tmp`（已自动复制）

### 依赖说明
- 打包时使用了 `webpack-node-externals` 排除了 `node_modules`，因此部署环境仍需安装生产依赖：
  - 在部署机（或容器）执行：`npm ci --omit=dev`
  - 或者在项目根目录（含 `node_modules`）内直接运行 `node dist/server.js`

### 混淆策略
- 已启用 `webpack-obfuscator`，默认配置：开启字符串数组与 RC4 编码、数组旋转，关闭控制流扁平化以保证稳定性。


### 路径与持久化
- 打包后 `__dirname` 指向 `dist`，已通过复制插件将运行期必需文件复制到 `dist`，保持现有代码路径逻辑可用。
- 运行时写入（如 `server.log`、`admin.log`、`competition_tmp`/`competition_data`）默认位于 `dist` 下。生产中建议：
  - 使用外部挂载或卷持久化这些目录；或
  - 改为输出到标准输出并配置外部日志采集/轮转。



