fix: cross-audit fixes — file validation, type safety, dedup
- Avatar upload: whitelist image MIME types and extensions (jpg/png/gif/webp) - Normalize device_id to String for strict comparison in treatment sync - Add ORDER BY expire_time DESC to purchase/adminCreate subscription queries - Deduplicate readBearer: middleware imports from lib/auth.js - Parameterize createTrial INTERVAL instead of string concatenation - Add rate limiting (20/15min) to avatar upload and phone auth endpoints
这个提交包含在:
+10
-1
@@ -14,12 +14,19 @@ const userLoginLimiter = rateLimit({
|
||||
message: { code: 2001, message: 'too_many_attempts' }
|
||||
})
|
||||
const adminLoginLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 5,
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false,
|
||||
message: { code: 2001, message: 'too_many_attempts' }
|
||||
})
|
||||
const uploadLimiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 20,
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false,
|
||||
message: { code: 2001, message: 'too_many_attempts' }
|
||||
})
|
||||
|
||||
app.use(express.json())
|
||||
app.use((req, res, next) => {
|
||||
@@ -32,6 +39,8 @@ app.use((req, res, next) => {
|
||||
|
||||
app.use('/api/v1/auth/login', userLoginLimiter)
|
||||
app.use('/api/v1/admin/login', adminLoginLimiter)
|
||||
app.use('/api/v1/user/avatar', uploadLimiter)
|
||||
app.use('/api/v1/user/phone', uploadLimiter)
|
||||
|
||||
app.use(authMiddleware)
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户