Authored by 徐炜

Merge remote-tracking branch 'origin/feature/security-fix' into feature/security-fix

... ... @@ -7,6 +7,7 @@
'use strict';
const model = require('../models');
const config = global.yoho.config;
exports.index = (req, res) => {
const channelType = req.path.substring(1) || 'men';
... ... @@ -15,7 +16,7 @@ exports.index = (req, res) => {
// 设置当前频道
res.cookie('_Channel', channelType, {
domain: '.yohoblk.com'
domain: config.cookieDomain
});
req.yoho.channel = channelType;
... ... @@ -26,4 +27,4 @@ exports.index = (req, res) => {
dataPage: channelType
}, result));
});
};
};
\ No newline at end of file
... ...
... ... @@ -6,6 +6,7 @@
'use strict';
const mcHandler = require('../models/menu-crumb-handler');
const addressModel = require('../models/address');
const cleanHtml = require(`${global.utils}/cleanHtml`);
const crypto = global.yoho.crypto;
const config = global.yoho.config;
... ... @@ -34,6 +35,7 @@ const index = (req, res, next) => {
resultData[i].default = resultData[i].is_default === 'Y';
resultData[i].mobile = resultData[i].mobile.replace(reg, '$1****$2');
resultData[i].id = crypto.encryption(config.crypto.common, resultData[i].address_id + '');
resultData[i].address = cleanHtml.htmlDecode(resultData[i].address);
}
resultData.leftLength = 7 - length;
resultData.length = length;
... ... @@ -61,6 +63,7 @@ const getAddressList = (req, res, next) => {
_.each(result.data, (d) => {
d.address_id = crypto.encryption(config.crypto.common, d.address_id + '');
d.address = cleanHtml.htmlDecode(d.address);
});
defaultAd && (defaultAd.focus = true);
... ... @@ -74,7 +77,7 @@ const getAddressList = (req, res, next) => {
*/
const addAddressData = (req, res, next) => {
let uid = req.user.uid;
let address = req.body.address;
let address = cleanHtml.htmlEncode(req.body.address);
let areaCode = req.body.area_code;
let consignee = req.body.consignee;
let mobile = req.body.mobile;
... ... @@ -97,7 +100,7 @@ const addAddressData = (req, res, next) => {
const updateAddressData = (req, res, next) => {
let id = crypto.decrypt(config.crypto.common, req.body.id);
let uid = req.user.uid;
let address = req.body.address;
let address = cleanHtml.htmlEncode(req.body.address);
let areaCode = req.body.area_code;
let consignee = req.body.consignee;
let mobile = req.body.mobile;
... ... @@ -162,4 +165,4 @@ module.exports = {
delAddressData,
setDefaultAddress,
getAddressData
};
};
\ No newline at end of file
... ...
... ... @@ -8,6 +8,7 @@
const mcHandler = require('../models/menu-crumb-handler');
const orderModel = require('../models/order');
const cleanHtml = require(`${global.utils}/cleanHtml`);
const _ = require('lodash');
const crypto = global.yoho.crypto;
const config = global.yoho.config;
... ... @@ -48,6 +49,16 @@ const detail = (req, res, next) => {
pageData.orderDetail.orderCodeM = crypto.encryption(config.crypto.common, pageData.orderDetail.orderCode);
}
// 转译
if (pageData.orderDetail) {
pageData.orderDetail.address = cleanHtml.htmlDecode(pageData.orderDetail.address);
pageData.orderDetail.allAddress = cleanHtml.htmlDecode(pageData.orderDetail.allAddress);
pageData.orderDetail.remark = cleanHtml.htmlDecode(pageData.orderDetail.remark);
if (pageData.orderDetail.invoice) {
pageData.orderDetail.invoice.title = cleanHtml.htmlDecode(pageData.orderDetail.invoice.title);
}
}
res.display('index', {
isMe: true,
page: 'order-detail',
... ... @@ -166,4 +177,4 @@ module.exports = {
getCancelOrderReason,
reAdd,
confirmReceive
};
};
\ No newline at end of file
... ...
... ... @@ -8,6 +8,7 @@
const mcHandler = require('../models/menu-crumb-handler');
const helpers = global.yoho.helpers;
const config = global.yoho.config;
const settingModel = require('../models/setting');
const accountModel = require('../models/account');
const passportHelper = require('../../passport/models/passport-helper');
... ... @@ -18,13 +19,15 @@ var path = require('path');
const uuid = require('uuid');
const os = require('os');
const _ = require('lodash');
const regMobile = /(\d{3})\d{4}(\d{4})/;// 正则匹配替换手机号码中间4位
const regEmail = /(\d{3})\d{4}/;// 正则匹配替换邮箱中间4位
const regMobile = /(\d{3})\d{4}(\d{4})/; // 正则匹配替换手机号码中间4位
const regEmail = /(\d{3})\d{4}/; // 正则匹配替换邮箱中间4位
const captchaUrl = helpers.urlFormat('/passport/images', {t: Date.now()});
const captchaUrl = helpers.urlFormat('/passport/images', {
t: Date.now()
});
// 根据type获取标题
const _getTitle = (type)=> {
const _getTitle = (type) => {
let typeName;
let proName;
let isModifyMobile = false;
... ... @@ -74,6 +77,18 @@ const _getTitle = (type)=> {
};
};
const cookieHelper = {
setVal(res, k, v, ops) {
res.cookie(k, v, Object.assign({
domain: config.cookieDomain,
httpOnly: true
}, ops));
},
getVal(req, k) {
return req.cookies[k];
}
}
/**
* 个人设置页面加载
*/
... ... @@ -132,11 +147,11 @@ const index = (req, res, next) => {
* @param res
* @param next
*/
const editUserInfo = (req, res, next)=> {
const editUserInfo = (req, res, next) => {
let uid = req.user.uid;
let query = req.body;
settingModel.editUserInfo(uid, query).then(result=> {
settingModel.editUserInfo(uid, query).then(result => {
res.send(result);
}).catch(next);
};
... ... @@ -149,13 +164,13 @@ const bindMobile = (req, res, next) => {
let uid = req.user.uid;
let type = req.params.type;
settingModel.getUserInfo(uid).then(result=> {
settingModel.getUserInfo(uid).then(result => {
if (result.info.verify_mobile !== '') {
mcHandler.getMeThumb().then((thumb) => {
let info = result.info;
info.ellipsisMobile = info.verify_mobile.replace(regMobile, '$1****$2');
info.checkCode = settingModel.cipheriv(info.uid + '.completeverify');
info.checkCode = req.csrfToken();
res.display('index', {
module: 'me',
... ... @@ -188,12 +203,12 @@ const bindEmail = (req, res, next) => {
let uid = req.user.uid;
let type = req.params.type;
settingModel.getUserInfo(uid).then(result=> {
settingModel.getUserInfo(uid).then(result => {
if (result.info.verify_email !== '') {
let info = result.info;
info.ellipsisEmail = info.verify_email.replace(regEmail, '$1****');
info.checkCode = settingModel.cipheriv(info.uid + '.completeverify');
info.checkCode = req.csrfToken();
mcHandler.getMeThumb().then((thumb) => {
res.display('index', {
... ... @@ -221,9 +236,8 @@ const bindEmail = (req, res, next) => {
/**
*step1 登录密码进行身份验证
*/
const modifyPassword = (req, res) => {
const modifyType = (req, res) => {
let type = req.params.type;
let checkCode = settingModel.cipheriv(req.user.uid + '.completeverify');
mcHandler.getMeThumb().then((thumb) => {
res.display('index', {
... ... @@ -239,7 +253,7 @@ const modifyPassword = (req, res) => {
proTitle: _getTitle(type).proName,
captchaUrl: captchaUrl,
isShowPassword: true,
checkCode: checkCode
checkCode: req.csrfToken()
}
});
});
... ... @@ -248,103 +262,107 @@ const modifyPassword = (req, res) => {
/*
* step2 操作界面-渲染页面
* */
const edit = (req, res)=> {
const edit = (req, res) => {
let type = req.params.type;
let code = settingModel.decipheriv(req.query.checkCode.split(' ').join('+'));
let codes = code.split('.');
if (parseInt(codes[0], 10) === req.user.uid && codes[1] === 'completeverify') {
let result = {
title: _getTitle(type).typeName,
proTitle: _getTitle(type).proName,
isShowMobile: _getTitle(type).isModifyMobile || _getTitle(type).isBindMobile,
isShowEmail: _getTitle(type).isModifyEmail || _getTitle(type).isBindEmail,
isShowPassword: _getTitle(type).isShowPassword
};
let checkCode = settingModel.cipheriv(req.user.uid + '.completeoperate');
mcHandler.getMeThumb().then((thumb) => {
res.display('index', {
module: 'me',
page: 'setting',
isMe: true,
content: Object.assign({
region: passportHelper.getCountry(),
location: '+86',
nav: mcHandler.getMeCrumb('个人设置'),
navigation: mcHandler.getSideMenu('个人设置'),
banner: thumb,
operateStep: true,
stepUrl: '/me/setting/step3/' + type,
captchaUrl: captchaUrl,
checkCode: checkCode
}, result)
});
});
if (Number(cookieHelper.getVal(req, type + "_STEP")) !== 1) {
res.redirect(helpers.urlFormat('/me/setting/step1/' + type));
return;
}
let result = {
title: _getTitle(type).typeName,
proTitle: _getTitle(type).proName,
isShowMobile: _getTitle(type).isModifyMobile || _getTitle(type).isBindMobile,
isShowEmail: _getTitle(type).isModifyEmail || _getTitle(type).isBindEmail,
isShowPassword: _getTitle(type).isShowPassword
};
mcHandler.getMeThumb().then((thumb) => {
res.display('index', {
module: 'me',
page: 'setting',
isMe: true,
content: Object.assign({
region: passportHelper.getCountry(),
location: '+86',
nav: mcHandler.getMeCrumb('个人设置'),
navigation: mcHandler.getSideMenu('个人设置'),
banner: thumb,
operateStep: true,
stepUrl: '/me/setting/step3/' + type,
captchaUrl: captchaUrl,
checkCode: req.csrfToken()
}, result)
});
});
};
/*
* step3 操作成功-渲染界面
* */
const success = (req, res)=> {
const success = (req, res) => {
let type = req.params.type;
let code = settingModel.decipheriv(req.query.checkCode.split(' ').join('+'));
let codes = code.split('.');
if (parseInt(codes[0], 10) === req.user.uid && codes[1] === 'completeoperate') {
let result = {
title: _getTitle(type).typeName,
proTitle: _getTitle(type).proName,
isModifyMobile: _getTitle(type).isModifyMobile,
isBindMobile: _getTitle(type).isBindMobile,
isModifyEmail: _getTitle(type).isModifyEmail,
isBindEmail: _getTitle(type).isBindEmail,
isShowPassword: _getTitle(type).isShowPassword
};
mcHandler.getMeThumb().then((thumb) => {
res.display('index', {
module: 'me',
page: 'setting',
isMe: true,
content: Object.assign({
region: passportHelper.getCountry(),
location: '+86',
nav: mcHandler.getMeCrumb('个人设置'),
navigation: mcHandler.getSideMenu('个人设置'),
banner: thumb,
successStep: true,
captchaUrl: captchaUrl
}, result)
});
});
let step = Number(cookieHelper.getVal(req, type + "_STEP")) || 0;
if (step !== 2) {
res.redirect(helpers.urlFormat('/me/setting/step' + (step + 1) + '/' + type));
return;
}
cookieHelper.setVal(res, type + "_STEP", 0, {
maxAge: -1
});
let result = {
title: _getTitle(type).typeName,
proTitle: _getTitle(type).proName,
isModifyMobile: _getTitle(type).isModifyMobile,
isBindMobile: _getTitle(type).isBindMobile,
isModifyEmail: _getTitle(type).isModifyEmail,
isBindEmail: _getTitle(type).isBindEmail,
isShowPassword: _getTitle(type).isShowPassword
};
mcHandler.getMeThumb().then((thumb) => {
res.display('index', {
module: 'me',
page: 'setting',
isMe: true,
content: Object.assign({
region: passportHelper.getCountry(),
location: '+86',
nav: mcHandler.getMeCrumb('个人设置'),
navigation: mcHandler.getSideMenu('个人设置'),
banner: thumb,
successStep: true,
captchaUrl: captchaUrl
}, result)
});
});
};
/*
* post1 第一步身份验证的post请求
* */
const validate1 = (req, res)=> {
co(function *() {
const validate1 = (req, res) => {
co(function*() {
let type = req.params.type;
let uid = req.user.uid;
let body = req.body;
let a;
if (type === 'password') {
let a = yield accountModel.verifyPwd(uid, body.password);
res.send(a);
a = yield accountModel.verifyPwd(uid, body.password);
} else if (type === 'mobile') {
let a = yield accountModel.checkVerifyMsg(body.code, body.mobile, body.area);
res.send(a);
a = yield accountModel.checkVerifyMsg(body.code, body.mobile, body.area);
} else if (type === 'email') {
let a = yield accountModel.sendVerifyEmail(uid, body.email);
a = yield accountModel.sendVerifyEmail(uid, body.email);
}
if (a) {
cookieHelper.setVal(res, req.body.type + "_STEP", 1);
res.send(a);
}
})();
... ... @@ -353,8 +371,8 @@ const validate1 = (req, res)=> {
/*
* post2 第二步具体操作的post请求
* */
const validate2 = (req, res)=> {
co(function *() {
const validate2 = (req, res) => {
co(function*() {
let type = req.params.type;
let uid = req.user.uid;
let body = req.body;
... ... @@ -362,18 +380,24 @@ const validate2 = (req, res)=> {
if (type === 'password') {
let a = yield accountModel.changePwd(uid, body.password);
res.send(a);
if (a.code === 200) {
cookieHelper.setVal(res, body.type + "_STEP", 2);
res.send(a);
}
} else if (type === 'mobile') {
let a = yield accountModel.checkVerifyMsg(body.code, body.mobile, body.area);
let b = yield accountModel.modifyVerifyMobile(uid, body.area, body.mobile);
let msg = [];
if (a.code === 200 && b.code === 200) {
cookieHelper.setVal(res, body.type + "_STEP", 2);
res.send({
code: 200,
data: {}
});
} else {
let msg = [];
if (a.code !== 200) {
msg.push('<p>图片验证:' + a.message + '</p>');
}
... ... @@ -413,12 +437,12 @@ function getfilePath(req, res, next) {
* @param req
* @param res
*/
const modifyHead = (req, res)=> {
const modifyHead = (req, res) => {
let uid = req.user.uid;
let bucket = 'yhb-head';
let filePath = req.filePath;
settingModel.modifyHead(uid, bucket, filePath).then(result=> {
settingModel.modifyHead(uid, bucket, filePath).then(result => {
res.send(result);
});
};
... ... @@ -428,11 +452,11 @@ module.exports = {
editUserInfo,
bindMobile,
bindEmail,
modifyPassword,
modifyType,
edit,
success,
validate1,
validate2,
getfilePath,
modifyHead
};
};
\ No newline at end of file
... ...
... ... @@ -33,52 +33,39 @@ const paymentTypeStr = {
// 订单操作按钮
const btnMap = {
all: [
{
isPayBtn: true,
name: '立即付款',
classStr: 'btn red pay-btn mr'
},
{
name: '取消订单',
classStr: 'btn white cancel-btn mr'
},
{
isEditBtn: true,
name: '修改订单',
classStr: 'btn white edit-btn'
}
],
cancel: [
{
name: '取消订单',
classStr: 'btn white cancel-btn'
}
],
edit: [
{
isEditBtn: true,
name: '修改订单',
classStr: 'btn white edit-btn'
}
],
complete: [
{
name: '确认收货',
classStr: 'btn complete-btn'
}
],
special: [
{
isEditBtn: true,
name: '修改订单',
classStr: 'btn white edit-btn mr'
},
{
name: '取消订单',
classStr: 'btn white cancel-btn'
}
]
all: [{
isPayBtn: true,
name: '立即付款',
classStr: 'btn red pay-btn mr'
}, {
name: '取消订单',
classStr: 'btn white cancel-btn mr'
}, {
isEditBtn: true,
name: '修改订单',
classStr: 'btn white edit-btn'
}],
cancel: [{
name: '取消订单',
classStr: 'btn white cancel-btn'
}],
edit: [{
isEditBtn: true,
name: '修改订单',
classStr: 'btn white edit-btn'
}],
complete: [{
name: '确认收货',
classStr: 'btn complete-btn'
}],
special: [{
isEditBtn: true,
name: '修改订单',
classStr: 'btn white edit-btn mr'
}, {
name: '取消订单',
classStr: 'btn white cancel-btn'
}]
};
const invoiceText = {
... ... @@ -196,20 +183,15 @@ const _convertAddress = (addressList, createTime) => {
* @return { [Object] }
*/
const _getStepByOrderStatus = st => {
let steps = [
{
stepStr: '1.提交订单'
},
{
stepStr: '2.商品出库'
},
{
stepStr: '3.等待收货'
},
{
stepStr: '4.交易完成'
}
];
let steps = [{
stepStr: '1.提交订单'
}, {
stepStr: '2.商品出库'
}, {
stepStr: '3.等待收货'
}, {
stepStr: '4.交易完成'
}];
let curStep = statusMap[st].step;
for (let i = 0; i < curStep; i++) {
... ... @@ -415,24 +397,19 @@ const getExpressInfo = (uid, code) => {
*/
const getOrderData = (uid, type, page) => {
const navBar = {
tabs: [
{
text: '全部订单',
typeStr: 'all'
},
{
text: '待付款',
typeStr: 'paying'
},
{
text: '待发货',
typeStr: 'willdeliver'
},
{
text: '待收货',
typeStr: 'delivering'
}
]
tabs: [{
text: '全部订单',
typeStr: 'all'
}, {
text: '待付款',
typeStr: 'paying'
}, {
text: '待发货',
typeStr: 'willdeliver'
}, {
text: '待收货',
typeStr: 'delivering'
}]
};
const emptyObject = {
... ... @@ -493,7 +470,9 @@ const getOrderData = (uid, type, page) => {
} : false;
return {
order: Object.assign(order, paginationOpts, {orderData: empty})
order: Object.assign(order, paginationOpts, {
orderData: empty
})
};
});
};
... ... @@ -538,7 +517,6 @@ const getOrderDetail = (uid, code) => {
if (detail.isCancel !== 'Y') {
detail.steps = _getStepByOrderStatus(st);
console.log(st);
statusMap[st].btns.forEach(function(btn) {
btns.push(btn);
});
... ... @@ -561,7 +539,7 @@ const getOrderDetail = (uid, code) => {
if (parseInt(detail.paymentType, 10) === 2 &&
(statusMap[st].valueStr === '备货中' ||
detail.statusStr === '备货中')) {
detail.statusStr === '备货中')) {
detail.btns = btnMap.special;
} else {
detail.statusStr = statusMap[st].valueStr;
... ... @@ -648,4 +626,4 @@ module.exports = {
getExpressInfo,
reAddCart,
confirmReceive
};
};
\ No newline at end of file
... ...
... ... @@ -62,20 +62,20 @@ router.get('/address/areas/:areaId', address.getAddressData);
router.get('/currency', auth, currency.index);
// 个人中心首页/个人设置
router.get('/setting', csrf, auth, setting.index);// 个人首页
router.post('/setting/editUserInfo', csrf, auth, setting.editUserInfo);// 修改接口
router.get('/setting', csrf, auth, setting.index); // 个人首页
router.post('/setting/editUserInfo', csrf, auth, setting.editUserInfo); // 修改接口
// 第一步
router.get('/setting/step1/:type', auth, setting.bindMobile, setting.bindEmail, setting.modifyPassword);
router.get('/setting/step1/:type', csrf, auth, setting.bindMobile, setting.bindEmail, setting.modifyType);
// 第一步post
router.post('/setting/step1/:type', auth, setting.validate1);
router.post('/setting/step1/:type', csrf, auth, setting.validate1);
// 第二步
router.get('/setting/step2/:type', auth, setting.edit);
router.get('/setting/step2/:type', csrf, auth, setting.edit);
// 第二步post
router.post('/setting/step2/:type', auth, setting.validate2);
router.post('/setting/step2/:type', csrf, auth, setting.validate2);
// 第三步
router.get('/setting/step3/:type', auth, setting.success);
... ... @@ -97,4 +97,4 @@ router.post('/collection/cancel', auth, favorite.cancel);
router.post('/collection/cancel/multi', auth, favorite.cancelMulti);
router.post('/collection/editorial/cancel', auth, favorite.editorialCancel);
module.exports = router;
module.exports = router;
\ No newline at end of file
... ...
... ... @@ -75,7 +75,8 @@ const common = {
refer = req.get('Referer');
}
refer && res.cookie('refer', encodeURI(refer), {
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
});
next();
},
... ... @@ -85,7 +86,11 @@ const common = {
*/
needCaptcha: (req, res, next) => {
let account = req.query.account;
let result = {code: 400, message: '', data: ''};
let result = {
code: 400,
message: '',
data: ''
};
const MAX_ALLOW_ERROR_LOGIN = 3;
if (account) {
... ... @@ -94,7 +99,9 @@ const common = {
cache.get(errorLoginKey).then(errloginTimes => {
errloginTimes = parseInt(errloginTimes, 0) || 0;
if (!isNaN(errloginTimes) && errloginTimes >= MAX_ALLOW_ERROR_LOGIN) {
result.data = {needCaptcha: true};
result.data = {
needCaptcha: true
};
}
res.json(result);
}).catch(next);
... ... @@ -111,7 +118,8 @@ const local = {
loginPage: (req, res) => {
// 设置登录有效时间30分钟, 防机器刷,cache不稳定,改为cookie
res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800, {
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
});
let loginMobile = _.trim(req.query.bindMobile || '');
... ... @@ -132,8 +140,12 @@ const local = {
defaultHeader: false,
passport: {
countryCode: loginCountryCode,
countryName: {text: defaultCountryName},
country: {list: countries},
countryName: {
text: defaultCountryName
},
country: {
list: countries
},
forgetPwd: helpers.urlFormat('/passport/back/index'),
fastReg: helpers.urlFormat('/passport/reg'),
weixinLogin: helpers.urlFormat('/passport/autosign/wechat'),
... ... @@ -159,7 +171,7 @@ const local = {
});
} else {
// 同步用户数据
co(function * () {
co(function*() {
let isRemember = req.body.isRemember === 'true';
let refer = req.cookies.refer;
... ... @@ -172,6 +184,9 @@ const local = {
}
refer = !BlockRedirectFilter.test(decodeURI(refer)) ? decodeURI(refer) : config.siteUrl;
if (!/www\.yohoblk\.com/.test(refer)) {
refer = config.siteUrl;
}
yield LoginService.syncUserSession(user.uid, req, res).then(() => {
res.json({
... ... @@ -326,4 +341,4 @@ module.exports = {
qq,
sina,
alipay
};
};
\ No newline at end of file
... ...
... ... @@ -56,20 +56,31 @@ let index = (req, res) => {
let refer = req.query.refer;
refer && res.cookie('refer', encodeURI(refer), {
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
});
res.display('reg/index', {
title: '新用户注册',
defaultHeader: false,
passport: {
country: {list: passportHelper.getCountry()},
country: {
list: passportHelper.getCountry()
},
location: '+86',
countryName: {text: '中国'},
captchaUrl: helpers.urlFormat('/passport/images', {t: Date.now()}),
itemUrl: helpers.urlFormat('/help', {id: 5}),
countryName: {
text: '中国'
},
captchaUrl: helpers.urlFormat('/passport/images', {
t: Date.now()
}),
itemUrl: helpers.urlFormat('/help', {
id: 5
}),
referUrl: refer,
loginUrl: helpers.urlFormat('/passport/login', {refer: refer}),
loginUrl: helpers.urlFormat('/passport/login', {
refer: refer
}),
regBtnText: '立即注册'
}
});
... ... @@ -292,4 +303,4 @@ module.exports = {
sendBindMsg,
msgCaptcha,
mobileRegister
};
};
\ No newline at end of file
... ...
... ... @@ -46,18 +46,21 @@ const syncUserSession = (uid, req, res) => {
req.session._USERNAME = name;
res.cookie('_UID', uidCookie, {
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
});
res.cookie('_USERNAME', name, {
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
});
}
req.session._TOKEN = token; // esline-disable-line
req.session._LOGIN_UID = uid; // esline-disable-line
res.cookie('_TOKEN', token, {
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
}); // esline-disable-line
});
... ... @@ -72,11 +75,13 @@ const rememberAccountAsync = (accountInfo, req, res) => {
res.cookie('isRemember', true, {
maxAge: aWeek,
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
});
res.cookie('remem', rememKey, {
maxAge: aWeek,
domain: config.cookieDomain
domain: config.cookieDomain,
httpOnly: true
});
return cache.set(rememKey, accountInfo);
... ... @@ -88,4 +93,4 @@ module.exports = {
signinByOpenIDAsync,
syncUserSession,
rememberAccountAsync
};
};
\ No newline at end of file
... ...
... ... @@ -17,7 +17,7 @@
<li>
<div>
<a class="btn btn-fixed-height" href="{{goShopping}}">开始购物</a>
<a class="btn btn-fixed-height" href="{{xssURI goShopping}}">开始购物</a>
</div>
</li>
</ul>
... ...
... ... @@ -16,7 +16,7 @@
<li>
<div>
<a class="btn btn-fixed-height" href="{{goShopping}}">开始购物</a>
<a class="btn btn-fixed-height" href="{{xssURI goShopping}}">开始购物</a>
</div>
</li>
</ul>
... ...
... ... @@ -7,6 +7,7 @@
'use strict';
const orderModel = require('../models/order');
const cleanHtml = require(`${global.utils}/cleanHtml`);
const _ = require('lodash');
... ... @@ -23,20 +24,19 @@ const index = (req, res, next) => {
// 设置头部路径索引focus
data.bcNavFocus = 2;
data.delivery_way = _.concat(_.find(data.delivery_way, {delivery_way_id: 1}));
data.delivery_way = _.concat(_.find(data.delivery_way, {
delivery_way_id: 1
}));
// 发票抬头
data.invoices.invoiceTitle = [
{
name: '个人',
value: 1,
myClass: 'personal'
},
{
name: '单位',
value: 2
}
];
data.invoices.invoiceTitle = [{
name: '个人',
value: 1,
myClass: 'personal'
}, {
name: '单位',
value: 2
}];
// 返回购物车链接
data.goCartLink = helper.urlFormat('/shopping/cart');
... ... @@ -49,20 +49,20 @@ const index = (req, res, next) => {
});
// 是否打印价格radio
data.printPriceRadio = [
{
value: '1',
name: '是'
},
{
value: '0',
name: '否',
checked: true
}
];
data.printPriceRadio = [{
value: '1',
name: '是'
}, {
value: '0',
name: '否',
checked: true
}];
if (data.delivery_address) {
data.delivery_address.address = cleanHtml.htmlDecode(data.delivery_address.address);
}
res.header('Cache-Control', 'no-store');
res.display('order', {
content: data,
defaultHeader: false
... ... @@ -96,6 +96,9 @@ const orderSub = (req, res, next) => {
other.address_id = crypto.decrypt(config.crypto.common, other.address_id);
}
other.remark = cleanHtml.htmlEncode(other.remark);
other.invoices_title = cleanHtml.htmlEncode(other.invoices_title);
orderModel.submit(req.user.uid, other).then(result => {
// 拼接地址
... ... @@ -112,4 +115,4 @@ module.exports = {
index,
compute,
orderSub
};
};
\ No newline at end of file
... ...
... ... @@ -9,6 +9,7 @@
const PayData = require('../models/pay');
const OrderData = require('../models/order');
const PayHelpers = require('../helpers/payment');
const cleanHtml = require(`${global.utils}/cleanHtml`);
const camelCase = global.yoho.camelCase;
const helpers = global.yoho.helpers;
const _ = require('lodash');
... ... @@ -36,6 +37,9 @@ const online = (req, res, next) => {
}
});
if (order.address) {
order.address = cleanHtml.htmlDecode(order.address);
}
if (amount > 0) {
res.display('pay', Object.assign({
... ... @@ -52,7 +56,9 @@ const online = (req, res, next) => {
cost: order.paymentAmount,
orderNum: order.orderCode,
coin: coin,
orderHref: helpers.urlFormat('/me/order/detail', {orderCode: order.orderCode}),
orderHref: helpers.urlFormat('/me/order/detail', {
orderCode: order.orderCode
}),
walkHref: helpers.urlFormat('/')
}
});
... ... @@ -121,7 +127,9 @@ const callback = (req, res) => {
cost: order.paymentAmount,
orderNum: order.orderCode,
coin: coin,
orderHref: helpers.urlFormat('/me/order/detail', {orderCode: order.orderCode}),
orderHref: helpers.urlFormat('/me/order/detail', {
orderCode: order.orderCode
}),
walkHref: helpers.urlFormat('/')
}
});
... ... @@ -135,4 +143,4 @@ module.exports = {
online,
callback,
toPay
};
};
\ No newline at end of file
... ...
... ... @@ -40,8 +40,6 @@ exports.serverError = () => {
logger.error(`error at path: ${req.url}`);
logger.error(err);
if (!res.headersSent) {
let renderErrPage;
if (req.xhr) {
return res.status(500).json({
code: 500,
... ... @@ -49,7 +47,7 @@ exports.serverError = () => {
});
}
renderErrPage = (result) => {
const renderErrPage = (result) => {
res.status(500).display('error/500', {
module: 'common',
page: 'error',
... ... @@ -65,4 +63,4 @@ exports.serverError = () => {
}
next(err);
};
};
};
\ No newline at end of file
... ...
... ... @@ -15,9 +15,9 @@ var $address = $('#addressDetail');
var $mobile = $('#mobile');
var $phone = $('#phone');
var addressForm = $('.form-group-address');
var currentLength = $('.a-table').find('tr').length - 1;// 当前地址条数
var leftLength = 7 - currentLength;// 还剩地址条数
var reg = new RegExp(/^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/);// 手机号码校验
var currentLength = $('.a-table').find('tr').length - 1; // 当前地址条数
var leftLength = 7 - currentLength; // 还剩地址条数
var reg = new RegExp(/^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/); // 手机号码校验
require('./me');
require('../plugins/check');
... ... @@ -26,7 +26,9 @@ require('yoho-jquery-placeholder');
$('[placeholder]').placeholder();
$(function() {
var address = cascadingAddress({el: '#address'});
var address = cascadingAddress({
el: '#address'
});
/**
* 公共方法
... ... @@ -61,14 +63,14 @@ $(function() {
info.consignee === '' ? $consignee.next().show() : $consignee.next().hide();
info.address === '' ? $address.next().show() : $address.next().hide();
typeof (info.area_code) === 'undefined' ?
addressForm.css('margin-bottom', '20px').find('.error-tips').show() :
typeof(info.area_code) === 'undefined' ?
addressForm.css('margin-bottom', '20px').find('.error-tips').show():
addressForm.css('margin-bottom', '70px').find('.error-tips').hide();
if (info.id) {
info.mobile === '' ? $mobile.next().show() : $mobile.next().hide();
if (info.consignee === '' || info.address === '' || info.mobile === '' ||
typeof (info.area_code) === 'undefined') {
typeof(info.area_code) === 'undefined') {
flag = false;
}
return flag;
... ... @@ -77,7 +79,7 @@ $(function() {
(!reg.test(info.mobile) ? $mobile.next().html('手机号码格式不对').show() : $mobile.next().hide());
if (info.consignee === '' || info.address === '' || info.mobile === '' || !reg.test(info.mobile) ||
typeof (info.area_code) === 'undefined') {
typeof(info.area_code) === 'undefined') {
flag = false;
}
return flag;
... ... @@ -144,7 +146,7 @@ $(function() {
if (Bll.check(info) === true) {
console.log(info.id);
// console.log(info.id);
// 新增
if (info.id === '') {
... ... @@ -292,8 +294,11 @@ $(function() {
$(this).find('.set').css('display', 'inline-block');
});
$('.table-body').on('mouseout',function(){
var tmpset=$(this).find('.set');
if(tmpset.css('display')== 'inline-block')tmpset.hide();
$('.table-body').on('mouseout', function() {
var tmpset = $(this).find('.set');
if (tmpset.css('display') === 'inline-block') {
tmpset.hide();
}
});
});
});
\ No newline at end of file
... ...
... ... @@ -53,7 +53,7 @@ function setExchangeEepress(eid, num) {
number: num
},
success: function(data) {
console.log(data);
// console.log(data);
if (data.code === 200) {
location.reload();
}
... ... @@ -81,8 +81,8 @@ $showExpress.on('click', '.reset-express', function() {
$editExpress.removeClass('hide');
});
console.log($('.reason-info').find('span').text().length);
//console.log($('.reason-info').find('span').text().length);
if (remark <= 5) {
$('.reason-info').hide();
}
}
\ No newline at end of file
... ...
... ... @@ -7,11 +7,11 @@ var dialog = require('../../plugins/dialog');
var _alert = dialog.Alert;
var regValidate = require('../../passport/common/mail-phone-regx');
var types = location.pathname.split('/');
var type = types[types.length - 1];// 界面操作类型
var type = types[types.length - 1]; // 界面操作类型
var $imgCaptchaInput = $('#captcha');
var second = 60;
var $sms = $('#send-code2');// 发送短信验证码按钮
var area = $('#country-code').text().substring(1) || '86';// 地区码
var $sms = $('#send-code2'); // 发送短信验证码按钮
var area = $('#country-code').text().substring(1) || '86'; // 地区码
// 发送短信后倒计时显示
var disableSMSBtn = function() {
second -= 1;
... ... @@ -126,13 +126,15 @@ $('#mobile-step2').click(function() {
data: {
code: code,
mobile: mobile,
area: area
area: area,
type: type,
_csrf: $('#checkCode').val()
},
success: function(data) {
if (data.code === 200) {
self.find('.tips-success').addClass('ok').show();
self.find('.tips-error').removeClass('notok').hide();
location.href = '/me/setting/step3/' + type + '?checkCode=' + $('#checkCode').val();
location.href = '/me/setting/step3/' + type;
} else {
new _alert(data.message).show();
self.find('.tips-success').removeClass('ok').hide();
... ... @@ -190,11 +192,13 @@ $('#step2-pwd').click(function() {
type: 'POST',
url: '/me/setting/step2/password',
data: {
password: password
password: password,
type: type,
_csrf: $('#checkCode').val()
},
success: function(data) {
if (data.code === 200) {
location.href = '/me/setting/step3/' + type + '?checkCode=' + $('#checkCode').val();
location.href = '/me/setting/step3/' + type;
} else {
new _alert(data.message).show();
}
... ... @@ -202,4 +206,4 @@ $('#step2-pwd').click(function() {
});
}
});
});
\ No newline at end of file
... ...
... ... @@ -7,14 +7,14 @@ var $imgCaptchaInput = $('#captcha');
var dialog = require('../../plugins/dialog');
var _alert = dialog.Alert;
var types = location.pathname.split('/');
var type = types[types.length - 1];// 界面操作类型
var type = types[types.length - 1]; // 界面操作类型
var area = $('#country-code').text().substring(1) || '86';
/**
* 手机号码验证
*/
var second = 60;
var $sms = $('#send-code');// 发送短信验证码按钮
var $sms = $('#send-code'); // 发送短信验证码按钮
// 发送短信后倒计时显示
var disableSMSBtn = function() {
second -= 1;
... ... @@ -71,11 +71,13 @@ $('#mobile-step1').click(function() {
data: {
code: code,
mobile: mobile,
area: area
area: area,
type: type,
_csrf: $('#checkCode').val()
},
success: function(data) {
if (data.code === 200) {
location.href = '/me/setting/step2/' + type + '?checkCode=' + $('#checkCode').val();
location.href = '/me/setting/step2/' + type;
} else {
// location.href = '/me/setting/step2/' + type + "?checkCode=" + $("#checkCode").val();
new _alert('验证码不正确!').show();
... ... @@ -127,11 +129,13 @@ $('#pwd-step1').click(function() {
type: 'POST',
url: '/me/setting/step1/password',
data: {
password: password
password: password,
type: type,
_csrf: $('#checkCode').val()
},
success: function(data) {
if (data.code === 200) {
location.href = '/me/setting/step2/' + type + '?checkCode=' + $('#checkCode').val();
location.href = '/me/setting/step2/' + type;
} else {
new _alert('登录密码校验错误!').show();
}
... ... @@ -151,7 +155,9 @@ $('#email-step1').click(function() {
type: 'POST',
url: '/me/setting/step1/email',
data: {
email: $('#real-email').val()
email: $('#real-email').val(),
type: type,
_csrf: $('#checkCode').val()
},
success: function(data) {
// todo 发送邮件
... ... @@ -166,4 +172,4 @@ $('#email-step1').click(function() {
}
});
}
});
});
\ No newline at end of file
... ...
... ... @@ -75,7 +75,7 @@ function shareBase(options) {
if (sharebox.length > 0) {
shareCon = '<i class="top"></i><div class="con"><p class="pic"><img src="' +
openUrl + '" /></p><h2>分享到微信朋友圈</h2><p class="w">打开微信使用“扫一扫“<br/>即可将网页分享到我的朋友圈。</p></div>';
openUrl + '" /></p><h2>分享到微信朋友圈</h2><p class="w">打开微信使用“扫一扫“<br/>即可将网页分享到我的朋友圈。</p></div>';
sharebox.find('div').length > 0 ? sharebox.show() : sharebox.html(shareCon).show();
}
} else {
... ... @@ -123,6 +123,6 @@ $('.weixin').mouseenter(function() {
});
$('.weixin').mouseleave(function() {
console.log(2);
// console.log(2);
$('.weixin-share-box').hide();
});
});
\ No newline at end of file
... ...
'use strict';
const re = new RegExp('(\r\n)|[&"\'<>]', 'g');
const htmlEntity = {
'&amp;': '\u0026',
'&quot;': '\u0022',
'&apos;': '\u0027',
'&lt;': '\u003c',
'&gt;': '\u003e'
};
exports.htmlDecode = function(txt) {
txt = txt || '';
return txt.replace(/((&(([a-z][a-z0-9]*)|(#[0-9]+)|(#x[0-9a-f]+));)|["'<>&])/gi, function(s) {
s = s || '';
const s1 = htmlEntity[s.toLowerCase()];
if (s1) {
s = s1;
}
return s;
});
};
exports.htmlEncode = function(str) {
str = str || '';
return str.replace(re, function(s) {
switch (s) {
case '&':
return '&amp;';
case '"':
return '&quot;';
case '\'':
return '&apos;';
case '<':
return '&lt;';
case '>':
return '&gt;';
default:
return s;
}
});
};
\ No newline at end of file
... ...