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)
这个提交包含在:
@@ -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) => {
|
||||||
|
|||||||
@@ -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' }))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户