feat(iter-v2): T01 partial - TOKEN_SECRET check, SQL param, export credential, docs
- S2: logs.ts LIMIT/OFFSET SQL parameterization (? placeholders) - S3: checkTokenSecret() startup validation, JWT_SECRET→TOKEN_SECRET in backup.ts - S3: Access Token expiry shortened to 2h (from 30d) - S4: Export download uses HMAC signed short-term token (/prepare endpoint) - S4: Frontend export.ts adapted for prepare-then-download flow - .env.example reorganized with security notes - Added PRD and architecture docs for iteration v2
This commit is contained in:
@@ -8,7 +8,7 @@ import path from 'path'
|
||||
|
||||
const router = Router()
|
||||
const BACKUP_DIR = process.env.BACKUP_DIR || '/var/backups/xiaocai'
|
||||
const JWT_SECRET = process.env.JWT_SECRET || 'xiaocai-secret'
|
||||
const TOKEN_SECRET = process.env.TOKEN_SECRET || 'xiaocai-token-secret-change-in-production'
|
||||
|
||||
// 所有路由都需要管理员权限(除了 :id/download 使用签名校验)
|
||||
router.use((req, res, next) => {
|
||||
@@ -42,7 +42,7 @@ router.get('/:id/download', async (req: AuthRequest, res: Response) => {
|
||||
}
|
||||
|
||||
// 校验 HMAC
|
||||
const expectedHmac = createHmac('sha256', JWT_SECRET)
|
||||
const expectedHmac = createHmac('sha256', TOKEN_SECRET)
|
||||
.update(`${backupId}:${timestamp}`)
|
||||
.digest('hex')
|
||||
if (hmac !== expectedHmac) {
|
||||
@@ -89,7 +89,7 @@ router.get('/', async (req: AuthRequest, res: Response) => {
|
||||
// 为每条记录生成下载令牌
|
||||
const listWithToken = list.map(item => {
|
||||
const timestamp = Date.now()
|
||||
const hmac = createHmac('sha256', JWT_SECRET)
|
||||
const hmac = createHmac('sha256', TOKEN_SECRET)
|
||||
.update(`${item.name}:${timestamp}`)
|
||||
.digest('hex')
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user