fix: resolve final audit issues

- firmware route: extract insertId from ResultSetHeader correctly
- admin device detail: add null check and flatten response to match
  frontend's expected field structure
- device command result: add ownership verification before finishing
  command (security fix)
这个提交包含在:
Guoguo
2026-04-29 06:02:18 -07:00
父节点 bb4b80f867
当前提交 62a63f9c9b
修改 3 个文件,包含 7 行新增6 行删除
+2 -2
查看文件
@@ -110,8 +110,8 @@ router.post('/devices/batch', requireAdmin, wrap(async (req, res) => {
router.get('/devices/:device_id', requireAdmin, wrap(async (req, res) => { router.get('/devices/:device_id', requireAdmin, wrap(async (req, res) => {
const result = await deviceDao.findByIdWithHistory(req.params.device_id) const result = await deviceDao.findByIdWithHistory(req.params.device_id)
if (!result) return res.json(fail(1005, 'DEVICE_NOT_FOUND')) if (!result || !result.device) return res.json(fail(1005, 'DEVICE_NOT_FOUND'))
res.json(ok(result)) res.json(ok(Object.assign({}, result.device, { binding_history: result.binding_history, recent_treatments: result.recent_treatments })))
})) }))
router.post('/devices/:device_id/unbind', requireAdmin, wrap(async (req, res) => { router.post('/devices/:device_id/unbind', requireAdmin, wrap(async (req, res) => {
+3 -2
查看文件
@@ -102,8 +102,9 @@ router.post('/device/command/result', requireUser, wrap(async (req, res) => {
const commandId = parseInt(req.body.command_id || req.body.seq, 10) const commandId = parseInt(req.body.command_id || req.body.seq, 10)
const success = req.body.success !== false const success = req.body.success !== false
if (!commandId) return res.json(fail(2001, 'command_id required')) if (!commandId) return res.json(fail(2001, 'command_id required'))
// commandDao.finish verifies device ownership via user binding const cmd = await commandDao.findByIdForUser(commandId, req.user.user_id)
await commandDao.finish(commandId, success, JSON.stringify(req.body), req.user.user_id) if (!cmd) return res.json(fail(1006, 'device_not_bound'))
await commandDao.finish(commandId, success, JSON.stringify(req.body))
res.json(ok({ message: 'success' })) res.json(ok({ message: 'success' }))
})) }))
+2 -2
查看文件
@@ -17,7 +17,7 @@ router.post('/admin/firmware', requireAdmin, wrap(async (req, res) => {
const version = String(req.body.version || '').trim() const version = String(req.body.version || '').trim()
const cosKey = String(req.body.cos_key || '').trim() const cosKey = String(req.body.cos_key || '').trim()
if (!version || !cosKey) return res.json(fail(2001, 'version and cos_key required')) if (!version || !cosKey) return res.json(fail(2001, 'version and cos_key required'))
const insertId = await firmwareDao.create({ const result = await firmwareDao.create({
version, version,
device_type: req.body.device_type || '', device_type: req.body.device_type || '',
cos_key: cosKey, cos_key: cosKey,
@@ -26,7 +26,7 @@ router.post('/admin/firmware', requireAdmin, wrap(async (req, res) => {
status: req.body.status === 0 ? 0 : 1 status: req.body.status === 0 ? 0 : 1
}) })
await logDao.write({ admin_id: req.admin.admin_id, action: 'admin_firmware_create', detail: '登记固件: ' + version, ip: req.ip }) await logDao.write({ admin_id: req.admin.admin_id, action: 'admin_firmware_create', detail: '登记固件: ' + version, ip: req.ip })
res.json(ok({ firmware_id: insertId })) res.json(ok({ firmware_id: result.insertId }))
})) }))
router.post('/admin/firmware/:firmware_id/status', requireAdmin, wrap(async (req, res) => { router.post('/admin/firmware/:firmware_id/status', requireAdmin, wrap(async (req, res) => {