fix: address critical security and data integrity issues from cross-audit

- Add expire_time > NOW() filter to findActive() preventing stale subscriptions
- Add express-rate-limit on login endpoints (user: 10/15min, admin: 5/15min)
- Add production guard for default admin credentials
- Fix BLE bindDevice userId encoding (uint32 instead of hexToBytes on numeric)
- Wrap adminCreate in transaction to prevent race condition
- Add settings cache invalidation after admin saves
- Read trial_days from settings instead of hardcoding 7
- Fix double JSON.stringify in commandDao.finish call
- Cancel stale pending bindings before creating new ones
- Reduce token refresh grace period from 3 days to 1 day
- Fix subscribe-success to fetch expiry from server (correct for renewals)
- Add keep-alive name property to DashboardView and SettingsView
- Fix BLE disconnect() to preserve listener registrations across reconnects
这个提交包含在:
Guoguo
2026-05-05 02:33:25 -07:00
父节点 031678c03f
当前提交 2eb38195f1
修改 17 个文件,包含 147 行新增45 行删除
+4 -1
查看文件
@@ -25,6 +25,9 @@ router.post('/device/bind', requireUser, wrap(async (req, res) => {
const device = await bindingDao.findDeviceExists(deviceId)
if (!device) return res.json(fail(1005, 'DEVICE_NOT_FOUND'))
// Cancel any stale pending bindings for this user before creating a new one
await bindingDao.cancelPending(req.user.user_id)
const bindToken = randomHex(8)
await bindingDao.createPending(req.user.user_id, deviceId, bindToken)
await logDao.write({ user_id: req.user.user_id, action: 'device_bind_request', detail: '申请绑定设备: ' + deviceId, ip: req.ip })
@@ -108,7 +111,7 @@ router.post('/device/command/result', requireUser, wrap(async (req, res) => {
if (!commandId) return res.json(fail(2001, 'command_id required'))
const cmd = await commandDao.findByIdForUser(commandId, req.user.user_id)
if (!cmd) return res.json(fail(1006, 'device_not_bound'))
await commandDao.finish(commandId, success, JSON.stringify(req.body))
await commandDao.finish(commandId, success, req.body)
res.json(ok({ message: 'success' }))
}))