Authored by 李奇

客服安全漏洞修正

... ... @@ -8,6 +8,7 @@
'use strict';
const aes = require('./aes-pwd');
const common = require('../../../config/common');
const clientApi = require('../models/client-api');
const clientService = require('../models/client-service');
/**
... ... @@ -44,8 +45,88 @@ const domains = (req, res) => {
res.json(common.domains);
};
/**
* 消息记录
* @param req
* @param res
* @param next
*/
const history = (req, res, next) => {
const encId = aes.encryptionUid(req.user.uid);
const endTime = req.body.endTime;
clientApi.getMsgHistory(encId, endTime)
.then(result => {
res.json(result);
}).catch(next);
};
/**
* 评价
* @param req
* @param res
* @param next
*/
const saveEval = (req, res, next) => {
const params = {};
params.stars = req.body.stars;
params.promoter = req.body.promoter;
params.encryptedUid = req.body.encryptedUid;
params.conversationId = req.body.conversationId;
if (req.body.reasonIds) {
params.reasonIds = req.body.reasonIds;
}
if (req.body.reasonMsg) {
params.reasonMsg = req.body.reasonMsg;
}
clientApi.saveEval(params)
.then(result => {
res.json(result);
}).catch(next);
};
/**
* 评价原因
* @param req
* @param res
* @param next
*/
const queryReason = (req, res, next) => {
const cvId = req.body.conversationId;
clientApi.queryReason(cvId)
.then(result => {
res.json(result);
}).catch(next);
};
/**
* 留言
* @param req
* @param res
* @param next
*/
const saveMessage = (req, res, next) => {
const content = req.body.content;
const encId = req.body.encryptedUid;
const cvId = req.body.conversationId;
clientApi.saveMessage(content, encId, cvId)
.then(result => {
res.json(result);
}).catch(next);
};
module.exports = {
index,
domains
domains,
history,
saveEval,
queryReason,
saveMessage
};
... ...
... ... @@ -17,10 +17,13 @@ let api = new global.yoho.ApiBase(config.domains.imCs, {
// api urls
let urls = {
qas: '/api/helper/queryAllHelper',
csSetting: '/api/cs/queryByType',
makeEval: '/api/evalute/saveEvalute',
lastTen: '/api/order/queryLastTenOrder',
leaveMsg: '/api/leavemessage/saveLeavemessage',
msgHistory: '/api/conversationMessage/pageList',
csSetting: '/api/cs/queryByType',
qas: '/api/helper/queryAllHelper'
evalReason: '/api/evalute/queryReasonByConversationId'
};
/**
... ... @@ -30,8 +33,7 @@ let urls = {
* @return { Object } 最近10条订单
*/
const getLastTenOrders = (encryptedUid) => {
return api.get(urls.lastTen, {
method: '',
return api.post(urls.lastTen, {
encryptedUid
});
};
... ... @@ -42,9 +44,7 @@ const getLastTenOrders = (encryptedUid) => {
* @return { Object } 问答列表
*/
const getQas = () => {
return api.get(urls.qas, {
method: ''
});
return api.post(urls.qas, {});
};
/**
... ... @@ -54,7 +54,6 @@ const getQas = () => {
*/
const getCsSetting = (type) => {
return api.get(urls.csSetting, {
method: '',
type
});
};
... ... @@ -63,18 +62,66 @@ const getCsSetting = (type) => {
* 最近聊天记录
* @function getMsgHistory
* @param { string } encryptedUid 用户id
* @param { string } endTime 截止时间
* @return { Array } 历史聊天记录
*/
const getMsgHistory = (encryptedUid) => {
return api.get(urls.msgHistory, {
encryptedUid,
method: ''
});
const getMsgHistory = (encryptedUid, endTime) => {
let params = {
encryptedUid
};
if (endTime) {
params.endTime = endTime;
}
return api.post(urls.msgHistory, params, {timeout: 5000});
};
/**
* 保存评价
* @param params
* @returns {*}
*/
const saveEval = (params) => {
return api.post(urls.makeEval, params);
};
/**
* 评价原因
* @param cvId
* @returns {*}
*/
const queryReason = (cvId) => {
const params = {
conversationId: cvId
};
return api.post(urls.evalReason, params);
};
/**
* 留言
* @param content 内容
* @param encId 加密UID
* @param cvId 会话ID
* @returns {*}
*/
const saveMessage = (content, encId, cvId) => {
const params = {
content,
encryptedUid: encId,
conversationId: cvId
};
return api.post(urls.leaveMsg, params);
};
module.exports = {
getQas,
queryReason,
saveMessage,
getCsSetting,
saveEval,
getMsgHistory,
getLastTenOrders
};
... ...
... ... @@ -13,7 +13,11 @@ const cRoot = './controllers';
const client = require(`${cRoot}/client`);
// 在线客服
router.get('/client', auth, client.index); // 在线客服
router.get('/domains', auth, client.domains); // 域名配置
router.get('/client', auth, client.index); // 在线客服
router.get('/domains', auth, client.domains); // 域名配置
router.post('/history', auth, client.history); // 消息记录
router.post('/evaluate', auth, client.saveEval); // 评价
router.post('/leaveMsg', auth, client.saveMessage); // 留言
router.post('/queryReason', auth, client.queryReason);// 评价原因
module.exports = router;
... ...
... ... @@ -11,6 +11,7 @@ var $ = require('yoho-jquery'),
uuid = require('uuid'),
emojiMap = require('./emoji-map'),
editArea = require('./edit-area'),
serviceApi = require('./service-api'),
broswer = require('./broswer'),
socketChat = require('./socket-chat'),
socketConf = require('./socket-config');
... ... @@ -23,7 +24,6 @@ var allRTs,
assetsPrefix,
cursorPosition,
configDomains,
hasMore = true,
titleInterval,
$html = $('html'),
$window = $(window),
... ... @@ -51,20 +51,14 @@ var tipTpl = require('hbs/service/tip.hbs'),
var processInfo = {
scrollLoad: false,
loadingHistory: false,
hasMore: true,
manual: false,
completeClose: false, // 评价完成后关闭
promoter: 1, // 评论发起者 1:客户自己 2:客服
savedEval: false // 是否保存过评论
};
var key,
urls = {
makeEval: '/evalute/saveEvalute',
leaveMsg: '/leavemessage/saveLeavemessage',
msgHistory: '/conversationMessage/pageList',
evalReason: '/evalute/queryReasonByConversationId'
};
require('bootstrap');
require('../common');
require('blueimp-file-upload/js/jquery.iframe-transport');
... ... @@ -77,6 +71,7 @@ encryptedUid = $encryptedUid.val();
assetsPrefix = $assetsPrefix.val();
socketConfCM = socketConf.conversationMessage;
socketConfCM.encryptedUid = encryptedUid;
// 原始配置信息用于重新连线
originConf = JSON.parse(JSON.stringify(socketConf));
... ... @@ -354,7 +349,7 @@ function pageInit() {
/**
* 人工接入队列中
* @param message 内部消息对象
* @param message 内部消息对象
*/
function inQueue(message) {
systemTip(message.content);
... ... @@ -508,14 +503,12 @@ function pageInit() {
$evalModal.find('.discontent').empty().append(dom);
}
// todo
// 拉取评价原因
$.ajax({
type: 'GET',
url: urls.evalReason,
data: {
conversationId: socketConfCM.conversationId
},
success: function success(res) {
serviceApi.reason({
conversationId: socketConfCM.conversationId
})
.done(function(res) {
var data = res.data,
len = data.length;
... ... @@ -524,8 +517,7 @@ function pageInit() {
len && discontentHtml(len, data);
}
$evalModal.modal('show');
}
});
});
}
/**
... ... @@ -709,12 +701,12 @@ function pageInit() {
len = msgList.length;
if (msgList[0] && endTime === msgList[0].sendTime) {
hasMore = false;
processInfo.hasMore = false;
}
endTime = msgList[0] && msgList[0].sendTime;
if (hasMore) {
if (processInfo.hasMore) {
for (i = 0; i < len; i++) {
item = msgList[i];
item.chatMessage.newContent = emojiPrefix(item.chatMessage.newContent);
... ... @@ -770,6 +762,8 @@ function pageInit() {
$msgList.prepend(dom);
heightAfter = $msgList.height();
$panelMainBody.scrollTop(heightAfter - heightBefore);
processInfo.loadingHistory = false;
}
}
... ... @@ -782,24 +776,31 @@ function pageInit() {
encryptedUid: encryptedUid
};
if (processInfo.loadingHistory) {
return;
}
processInfo.loadingHistory = true;
if (endTime) {
data.endTime = endTime;
}
$.ajax({
type: 'GET',
url: urls.msgHistory,
data: data,
success: function(res) {
serviceApi.history(data)
.done(function(res) {
if (res && res.code === 200) {
if (hasMore) {
msgList = res.data && res.data.records || [];
if (processInfo.hasMore) {
msgList = res.data.records || [];
msgResolve(msgList);
}
$history.hide();
processInfo.scrollLoad = true;
} else {
processInfo.loadingHistory = false;
}
}
});
})
.fail(function() {
processInfo.loadingHistory = false;
});
}
// 用户信息获取并初始化socket连接
... ... @@ -852,23 +853,15 @@ function pageInit() {
return false;
}
$.ajax({
type: 'POST',
url: urls.leaveMsg,
data: {
content: val,
encryptedUid: encryptedUid,
conversationId: socketConfCM.newConversationId || socketConfCM.conversationId
},
success: function(res) {
if (res && res.code === 200) {
lMsg.modal('hide');
}
},
error: function() {
serviceApi.leaveMsg({
content: val,
encryptedUid: encryptedUid,
conversationId: socketConfCM.conversationId
})
.done(function() {})
.always(function() {
lMsg.modal('hide');
}
});
});
});
// 提交评价
... ... @@ -900,14 +893,9 @@ function pageInit() {
data.reasonMsg = reason;
}
$.ajax({
type: 'POST',
url: urls.makeEval,
data: data,
success: function(res) {
// 提交评价过后,不管是否成功都应该关闭弹框
serviceApi.evaluate(data)
.done(function(res) {
processInfo.promoter = 1;
mEval.modal('hide');
$btnEval.hide();
processInfo.savedEval = true;
... ... @@ -922,11 +910,10 @@ function pageInit() {
window.close();
}
}
},
error: function() {
})
.always(function() {
mEval.modal('hide');
}
});
});
});
// 根节点高度设置
... ... @@ -1181,9 +1168,13 @@ function pageInit() {
// 滚动加载更多
$panelMainBody.scroll(function() {
var loading = $panelMainBody.scrollTop() === 0;
var isLoadingArea = $panelMainBody.scrollTop() < 100;
processInfo.scrollLoad && loading && hasMore && fetchHistoryMsg();
isLoadingArea &&
processInfo.scrollLoad &&
!processInfo.loadingHistory &&
processInfo.hasMore &&
fetchHistoryMsg();
});
}
... ... @@ -1195,13 +1186,6 @@ function pageInit() {
success: function(domains) {
configDomains = domains;
// url前缀添加
for (key in urls) {
if (urls.hasOwnProperty(key)) {
urls[key] = configDomains.imCs + urls[key];
}
}
// 检查支持性
(function() {
if (!window.WebSocket) {
... ...
/**
* 前端Ajax请求封装
* @author LQ <qi.li@yoho.cn>
* @date 2017/03/14
*/
var $ = require('yoho-jquery');
var reqUrls = {
history: '/service/history',
evaluate: '/service/evaluate',
leaveMsg: '/service/leaveMsg',
reason: '/service/queryReason'
};
var _ajax = function(method, reqUrl, params) {
return $.ajax({
type: method || 'GET',
url: reqUrl,
data: params
});
};
/**
* 历史消息
* @param params 参数对象
*/
exports.history = function(params) {
return _ajax('POST', reqUrls.history, params);
};
/**
* 保存评价
* @param params 参数对象
*/
exports.evaluate = function(params) {
return _ajax('POST', reqUrls.evaluate, params);
};
/**
* 评价原因
* @param params 参数对象
*/
exports.reason = function(params) {
return _ajax('POST', reqUrls.reason, params);
};
/**
* 留言
* @param params 参数对象
*/
exports.leaveMsg = function(params) {
return _ajax('POST', reqUrls.leaveMsg, params);
};
... ...