fix(customer): 联系人新增与跟进编辑补上归属校验
两个端点都只有 requirePermission('customer.edit'),而那只说明「这个人有权
编辑客户」,没说明「有权编辑**这一条**客户」。实测一个 sales_rep 账号:
GET /api/customers/4 → 404(读是隔离的)
POST /api/customers/4/contacts → 201(写进去了)
PATCH /api/customers/4/follow-ups/12 → 200
把「客户确认 3000 套订单」改成了「客户取消了订单」
也就是说一个销售能往看不见的客户里插联系人(还能把自己设成主联系人),
还能改写另一个销售客户的跟进历史。
两处都有对照组:紧挨着的 PATCH /contacts 和 POST /follow-ups 一直有这道
检查,所以是漏了而不是设计如此。补上后重放两个利用都是 403,归属人自己
仍然 201/200。
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
691f315341
commit
3e9fd2dc97
@@ -484,6 +484,13 @@ app.post('/api/customers/:id/contacts', auth.requirePermission('customer.edit'),
|
||||
try {
|
||||
const customer = getCustomer(req.params.id);
|
||||
if (!customer) return res.status(404).json({ error: '客户不存在' });
|
||||
/* customer.edit 只说明「这个人有权编辑客户」,没说明「有权编辑**这一条**客户」。
|
||||
少了这道归属校验,任何销售业务员猜个 id 就能往别人名下、甚至别组织的客户里
|
||||
插联系人(GET 同一条客户是 404,写却成功),还能把 is_primary 设成 1
|
||||
把自己变成主联系人。隔壁的 PATCH 一直有这道检查,这里是漏了。 */
|
||||
if (!customerAccess.canEdit(req.user, customer)) {
|
||||
return res.status(403).json({ error: '这条客户不在你名下,请先到客户公海领取' });
|
||||
}
|
||||
const name = String(req.body?.name || '').trim();
|
||||
if (!name) return res.status(400).json({ error: '联系人姓名不能为空' });
|
||||
const fields = ['customer_id', 'name', 'name_en', 'position', 'department', 'email', 'phone', 'whatsapp', 'wechat', 'is_primary', 'notes', 'created_at'];
|
||||
@@ -564,6 +571,13 @@ app.patch('/api/customers/:id/follow-ups/:followUpId', auth.requirePermission('c
|
||||
try {
|
||||
const customer = getCustomer(req.params.id);
|
||||
if (!customer) return res.status(404).json({ error: '客户不存在' });
|
||||
/* 同 POST 联系人:校验了「记录属于这条客户」不等于校验了「这条客户属于我」。
|
||||
漏了这道,别人能把我客户的跟进记录改写掉 —— 比如把
|
||||
「客户确认 3000 套订单」改成「客户取消了订单」,CRM 历史就被篡改了。
|
||||
POST /follow-ups 一直有这道检查,这里是漏了。 */
|
||||
if (!customerAccess.canEdit(req.user, customer)) {
|
||||
return res.status(403).json({ error: '这条客户不在你名下,请先到客户公海领取' });
|
||||
}
|
||||
const record = db.prepare('SELECT * FROM follow_up_records WHERE id = ? AND customer_id = ?').get(Number(req.params.followUpId), customer.id);
|
||||
if (!record) return res.status(404).json({ error: '跟进记录不存在' });
|
||||
const fields = [];
|
||||
|
||||
Reference in New Issue
Block a user