Authored by 周少峰

Merge branch 'gray'

... ... @@ -25,15 +25,10 @@ const cache = global.yoho.cache;
let siteUrl = config.siteUrl.indexOf('//') === 0 ? 'http:' + config.siteUrl : config.siteUrl;
function getLoginStat(ip) {
let errorLoginKey = 'loginErrorIp:' + ip;
function getLoginStat(account) {
let errorLoginKey = 'account_errorlogin_' + account;
let accountKey = 'account_signin_' + account;
let cacheGet = [cache.get(errorLoginKey), cache.get(accountKey)];
return Promise.all(cacheGet).catch(() => {
return [0, 0];
});
return cache.get(errorLoginKey);
}
// 本地登录
... ... @@ -42,7 +37,6 @@ passport.use('local', new LocalStrategy({
passwordField: 'password',
passReqToCallback: true
}, (req, username, password, done) => {
let area = req.body.areaCode || '86';
if (_.isEmpty(password)) {
... ... @@ -51,40 +45,32 @@ passport.use('local', new LocalStrategy({
}
let shoppingKey = cookie.getShoppingKey(req);
let clientIp = req.yoho.clientIp;
let account = req.body.account;
let type = req.body.loginType;
let errorLoginKey = 'account_errorlogin_' + account;
let accountKey = 'account_signin_' + account;
let clientIp = req.yoho.clientIp;
let errorLoginKey = 'loginErrorIp:' + clientIp;
getLoginStat(account).then(times => {
let errLoginTimes = _.parseInt(times[0]) || 0;
let accountTimes = _.parseInt(times[1]) || 0;
getLoginStat(clientIp).then((times) => {
let errLoginTimes = _.parseInt(times) || 0;
if (accountTimes >= 10) {
done({message: '您的账号已被暂时锁定,请稍后再试'}, null);
} else {
return LoginApi.signin(type, area, username, password, shoppingKey, clientIp).then((result) => {
if (result.code && result.code === 200 && result.data.uid) {
cache.del(errorLoginKey).catch(() => {});
req.session.type = '';
done(null, result.data);
} else {
errLoginTimes = errLoginTimes + 1;
accountTimes = accountTimes + 1;
cache.set(errorLoginKey, errLoginTimes).catch(() => {});
cache.set(accountKey, accountTimes, 1800).catch(() => {});
cache.set(errorLoginKey, errLoginTimes, 3600).catch(() => {});
// 再次校验
if (accountTimes >= 10) {
done({message: '您的账号已被暂时锁定,请稍后再试'}, null);
} else if (errLoginTimes >= 3) {
if (errLoginTimes >= 1) {
req.session.type = 'needCaptcha';
done({
message: `您输入的密码及账户名不匹配,
是否<a href="${helpers.urlFormat('/passport/back/index')}" target="_blank">忘记密码?</a>`,
needCaptcha: true
needCaptcha: true,
type: type
});
} else {
done({
... ... @@ -95,7 +81,6 @@ passport.use('local', new LocalStrategy({
}
}
});
}
}).catch(e => {
logger.error('call the signin service fail,', e);
done('登录失败,请稍后重试', null);
... ...
... ... @@ -29,7 +29,7 @@ const checkAPI = (req, res) => {
};
const passwordRequired = (req, res, next) => {
if (req.body.loginType === 'password') {
if (req.session.type === 'needCaptcha' && req.body.loginType === 'password') {
return requiredAPI(req, res, next);
} else {
return next();
... ...
... ... @@ -54,7 +54,10 @@ const requiredAPI = (req, res, next) => {
if (!verifyCode) {
return res.send({
code: 405,
message: '未输入图形验证码,请输入图形验证码'
message: '未输入图形验证码,请输入图形验证码',
data: {
needCaptcha: true
}
});
}
... ... @@ -72,12 +75,18 @@ const requiredAPI = (req, res, next) => {
if (err) {
res.send({
message: '网络失败,请刷新图形验证码',
code: 405
code: 405,
data: {
needCaptcha: true
}
});
} else if (!success) {
res.send({
message: '图形验证失败, 请刷新图形验证码',
code: 405
code: 405,
data: {
needCaptcha: true
}
});
} else {
return next();
... ...
... ... @@ -29,7 +29,10 @@ const requiredAPI = (req, res, next) => {
return res.json({
code: 405,
message: '该验证码已失效,请刷新验证码'
message: '该验证码已失效,请刷新验证码',
data: {
needCaptcha: true
}
});
}
... ... @@ -39,7 +42,10 @@ const requiredAPI = (req, res, next) => {
} else {
return res.json({
code: 405,
message: '请将图形验证码翻转至正确方向'
message: '请将图形验证码翻转至正确方向',
data: {
needCaptcha: true
}
});
}
};
... ...
... ... @@ -98,7 +98,7 @@ const common = {
cache.get(errorLoginKey).then(errloginTimes => {
errloginTimes = parseInt(errloginTimes, 0) || 0;
if (!isNaN(errloginTimes) && errloginTimes >= 3) {
if (!isNaN(errloginTimes) && errloginTimes >= 1) {
result.data = {needCaptcha: true};
}
return res.json(result);
... ... @@ -171,7 +171,8 @@ const local = {
code: 400,
message: err.message,
data: {
needCaptcha: err.needCaptcha
needCaptcha: err.needCaptcha,
type: err.type
}
});
}
... ...
... ... @@ -55,7 +55,7 @@
</span>
</li>
<li class="clearfix password-login captcha-wrap">
<li class="clearfix password-login captcha-wrap hide">
</li>
<li class="relative clearfix sms-login hide">
... ...
... ... @@ -869,7 +869,7 @@ const _getMaterialDataBySizeInfo = (sizeInfo) => {
})),
washTips: {
tip: _.get(sizeInfo, 'washRemindTipsBo.remindTips', ''),
img: _.get(sizeInfo, 'washRemindTipsBo.img', '')
img: _.replace(_.get(sizeInfo, 'washRemindTipsBo.img', ''), 'http:', '')
}
};
};
... ...
... ... @@ -143,7 +143,7 @@
<span id="open-soon" class="buy-btn item-buy dis">即将开售</span>
{{/ openSoon}}
{{#if notForSale}}
<span class="buy-btn dis"> <i class="iconfont">&#xe61c;</i></span>
<span class="buy-btn dis"> <i class="iconfont">&#xe61c;</i></span>
{{/if}}
{{#if addToCart}}
<span id="add-to-cart" class="buy-btn item-buy add-to-cart"> <i class="iconfont">
... ...
{
"name": "yohobuy-node",
"version": "5.5.25",
"version": "5.5.28",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ...
... ... @@ -61,7 +61,7 @@ module.exports = function(imageUrl, opts) {
} else {
query = 'imageView2/2/interlace/1/q/' + (params.q || 75);
}
return uri + '?' + query;
return uri + '?' + query + '|imageslim';
} else {
return imageUrl;
}
... ...
... ... @@ -813,7 +813,7 @@ function actionCover() {
var containertop;
var length = '';
if (window.location.href === document.location.protocol + '://www.yohobuy.com/' &&
if (window.location.href === document.location.protocol + '//www.yohobuy.com/' &&
(typeof gender === 'undefined' || gender === '' || gender === null)) {
$.get('/guide', function(data) {
newMask = document.createElement('div');
... ...
... ... @@ -54,9 +54,15 @@ var $accountInput1 = $('#account1'),
},
// 图像验证码
passwordCaptchaImg = new Captcha('.captcha-wrap').init(),
$passwordCaptchaWrap = $('.captcha-wrap'),
passwordCaptchaImg = new Captcha('.captcha-wrap', {checkURI: ''}).init(),
isShowCaptchaImg = false,
getPasswordCaptchaImgVal = function() {
if (isShowCaptchaImg) {
return passwordCaptchaImg.getResults();
}
return '';
},
// 短信验证码
... ... @@ -288,7 +294,12 @@ accountChangeEvent.add(function(type) {
}
if (type === AccountLoginData.PasswordLogin.name) {
if (isShowCaptchaImg) {
$passwordCaptchaWrap.removeClass('hide');
passwordCaptchaImg.refresh();
} else {
$passwordCaptchaWrap.addClass('hide');
}
}
if (type === AccountLoginData.SMSLogin.name) {
... ... @@ -448,6 +459,16 @@ function validateAccountPasswordLocal() {
return defer.promise();
}
function needCaptcha() {
$.get('/passport/login/account', {
account: $accountInput1.val()
}).then(function(result) {
if (result.data && result.data.needCaptcha) {
showPasswordCaptchaImgPic(); // eslint-disable-line
}
});
}
function validateAccountSmsLocal() {
var account = currentLogin.getAccountVal(),
err;
... ... @@ -522,7 +543,17 @@ function validatePasswordLocal() {
/** ************************************************************************/
function refreshPasswordCaptchaImg() {
if (isShowCaptchaImg) {
return passwordCaptchaImg.refresh();
}
}
function validatePasswordCaptchaImg() {
if (isShowCaptchaImg) {
return passwordCaptchaImg.check();
}
return $.Deferred().resolve().promise(); // eslint-disable-line
}
/** ************************************************************************/
... ... @@ -734,6 +765,7 @@ function getDesktopLoginType() {
// 密码验证过程
function validateWithPasswordMode() {
return validateAccount()
.then(validatePasswordCaptchaImg)
.then(validatePasswordLocal);
}
... ... @@ -856,14 +888,19 @@ function loginAsync() {
}
} else {
if (currentLogin.type() === 'password') {
if (res.code === 405) {
if (res.code === 405 || (res.data && res.data.needCaptcha)) {
passwordCaptchaImg.showTip(res.message);
showPasswordCaptchaImgPic(); //eslint-disable-line
return;
}
showPasswordTip(res.message);
$passwordInput.addClass('error').val('');
if (res.data && res.data.needCaptcha) {
showPasswordCaptchaImgPic(); // eslint-disable-line
}
} else if (currentLogin.type() === 'sms') {
showCaptchaSmsTip('短信验证码错误');
$captchaSmsInput.addClass('error').val('');
... ... @@ -876,6 +913,16 @@ function loginAsync() {
});
}
function showPasswordCaptchaImgPic() {
if (isShowCaptchaImg) {
return;
}
isShowCaptchaImg = true;
$passwordCaptchaWrap.removeClass('hide');
passwordCaptchaImg.refresh();
}
function getReferForLogin() {
var vars = {},
hash,
... ... @@ -946,7 +993,7 @@ $(document).on('click', function(e) {
// 邮箱自动完成后失去焦点:仅进行本地格式验证格式;
mailAc($accountInput1, function() {
return currentLogin.validateAccountLocal();
return currentLogin.validateAccountLocal().then(needCaptcha);
});
// 密码输入框事件
... ... @@ -1034,13 +1081,13 @@ $PhoneLoginSwitcher.on('click', 'div', function() {
return;
}
accountChangeEvent.fire(type);
$this.addClass('selected');
$this.siblings().removeClass('selected');
$(AccountLoginData[type].ele).removeClass('hide');
$(AccountLoginData[type].hideEle).addClass('hide');
accountChangeEvent.fire(type);
});
// 切换登录模式:手机登录和二维码登录
... ...
... ... @@ -1265,7 +1265,8 @@ function loadConsult() {
var consultsTpl = require('hbs/product/consult-item.hbs');
var $consultsUl = $('#consults-ul'),
$consultNum = $('.consult-num'),
loadingConsults = false;
loadingConsults = false,
passFlag = true;
// 顾客咨询
function loadConsults(nowPage) {
... ... @@ -1399,17 +1400,17 @@ function loadConsult() {
learn: '及时了解回复内容'
};
var pass = true;
if (content === '') {
$textArea.attr('placeholder', '请输入咨询内容');
$textArea.addClass('err');
pass = false;
return;
}
if (pass === false) {
if (passFlag === false) {
return;
}
passFlag = false;
$.ajax({
type: 'POST',
url: '/product/detail/consult',
... ... @@ -1440,6 +1441,8 @@ function loadConsult() {
// 跳转登录页
location.href = data.data.refer;
}
passFlag = true;
});
});
... ...
... ... @@ -61,7 +61,7 @@ module.exports = {
} else {
query = 'imageView2/2/interlace/1/q/' + (params.q || 75);
}
return uri + '?' + query;
return uri + '?' + query + '|imageslim';
} else {
return '';
}
... ...