Authored by htoooth

Merge branch 'feature/qr-code-new' into release/5.2

# Conflicts:
#	config/common.js
... ... @@ -42,7 +42,6 @@ function doPassportCallback(req, res, user) {
return loginService.signinByOpenID(user.nickname, user.openId, user.sourceType, shoppingKey)
.then((result) => {
console.log(result);
if (result.code !== 200) {
return res.redirect(config.siteUrl);
}
... ... @@ -320,7 +319,7 @@ const local = {
});
}
let token = qrcode.substring(qrcode.indexOf('=') + 1);
let token = decodeURIComponent(qrcode.substring(qrcode.indexOf('=') + 1));
loginService.checkByQrCode(token).then((result) => {
if (_.isEmpty(result)) {
... ...
... ... @@ -50,14 +50,6 @@ const signinByQrCode = (__1, __2, code, shoppingKey) => { // eslint-disable-line
return api.post('', param);
};
const fetchByQrCode = () => {
let param = {
method: 'app.twoDimen.getCode'
};
return api.post('', param);
};
const checkByQrCode = (code) => {
let param = {
method: 'app.twoDimen.loginCheck',
... ... @@ -115,7 +107,6 @@ module.exports = {
signinByPasswordWithAes,
signinBySMS,
signinByQrCode,
fetchByQrCode,
checkByQrCode,
sendPasswordBySMS,
checkUserExitBySMS,
... ...
'use strict';
const md5 = require('md5');
const uuid = require('uuid');
const _ = require('lodash');
const aes = require('./aes-pwd');
const cache = global.yoho.cache;
const sign = global.yoho.sign;
const cookie = global.yoho.cookie;
const config = global.yoho.config;
const crypto = global.yoho.crypto;
const Promise = require('bluebird');
... ... @@ -86,11 +89,27 @@ const rememberAccount = (accountInfo, req, res) => {
// }
};
const fetchByQrCode = () => {
let code = {
qrcode: uuid.v4(),
time: new Date().getTime()
};
const encodeStr = _.flow(JSON.stringify, _.partial(crypto.encryption, null), encodeURIComponent);
return Promise.resolve({
data: {
code: encodeStr(code)
},
code: 200
});
};
module.exports = {
signin,
syncUserSession,
rememberAccount,
fetchByQrCode: api.fetchByQrCode,
fetchByQrCode,
checkByQrCode: api.checkByQrCode,
sendPasswordBySMS: api.sendPasswordBySMS,
checkUserExitBySMS: api.checkUserExitBySMS,
... ...
... ... @@ -24,14 +24,13 @@ router.get('/logout.html', login.local.logout);
// 本地登录
// 短信验证码
// router.post('/passport/login/sms/send', login.local.sms.send); // 发短信验证码
// router.post('/passport/login/sms/auth', login.local.sms.auth); // 验证短信验证码
// router.post('/passport/login/sms/checkuser', login.local.sms.checkUser); // 短信检查用户是否注册
router.post('/passport/login/password/checkuser', back.fakeGetUserInfoAPI);// 假的,密码登录检查用户是否注册
router.post('/passport/login/sms/send', login.local.sms.send); // 发短信验证码
router.post('/passport/login/sms/auth', login.local.sms.auth); // 验证短信验证码
router.post('/passport/login/sms/checkuser', login.local.sms.checkUser); // 短信检查用户是否注册
// 二维码登录
//router.post('/passport/login/qrcode/refresh', login.local.qrcode.refresh); // 刷新二维码
//router.post('/passport/login/qrcode/check', login.local.qrcode.check); // 验证二维码的状态
router.post('/passport/login/qrcode/refresh', login.local.qrcode.refresh); // 刷新二维码
router.post('/passport/login/qrcode/check', login.local.qrcode.check); // 验证二维码的状态
router.get('/passport/login', login.common.beforeLogin, login.local.loginPage);
router.post('/passport/login/auth', login.local.login);
... ...
... ... @@ -6,14 +6,10 @@
<ul class="login-ul">
<div class="switch-login-type" data-type="DesktopLogin">
{{#if qrcodeLogin}}
<div id="device-bg" class="type-mobile-bg"></div>
<div class="type-tip tip-title">
<div id="device-tip" style="margin-left: 15px;margin-top: 8px">扫码登录更安全</div>
</div>
{{^}}
<div id="device-bg"></div>
{{/if}}
</div>
<div class="desktop-login">
... ... @@ -31,12 +27,10 @@
</span>
</li>
<li class="relative hide">
<li class="relative">
<div class="switch">
<div class="left selected" data-type="PasswordLogin">普通登录</div>
{{#if smsLogin}}
<div class="right" data-type="SMSLogin">手机验证码登录</div>
{{/if}}
</div>
</li>
... ... @@ -61,7 +55,6 @@
</span>
</li>
{{#if smsLogin}}
<li class="relative clearfix sms-login hide">
<input id="account2" class="account input va" name="account2" value="{{bindMobile}}"
type="text"
... ... @@ -72,6 +65,17 @@
</span>
</li>
<li class="clearfix sms-captcha-img-wrap captcha-wrap sms-login hide">
<input id="sms-captcha-input" class="input va captcha" type="text" name="captcha" placeholder="图形验证码"
autocomplete="off" maxlength="4">
<img id="sms-captcha-img" class="captcha-img" alt="">
<a class="link change-captcha">换一张</a>
<span class="err-tip hide">
<i></i>
<em></em>
</span>
</li>
<li class="relative clearfix sms-login hide">
<input id="captcha-sms" class="input va captcha-sms-input" type="text" name="captcha"
placeholder="短信验证码"
... ... @@ -82,7 +86,6 @@
<em></em>
</span>
</li>
{{/if}}
<li class="clearfix captcha-wrap hide">
<input id="captcha" class="input va captcha" type="text" name="captcha" placeholder="图形验证码"
... ...
... ... @@ -62,16 +62,17 @@ module.exports = {
name: 'error',
level: 'error',
filename: 'logs/error.log',
handleExceptions: true
handleExceptions: true,
maxFiles: 7
},
udp: { // send by udp
measurement: 'yohobuy_node_log',
level: 'debug', // logger level
host: 'influxdblog.yohoops.org', // influxdb host
host: 'influxdblog.web.yohoops.org', // influxdb host
port: '4444' // influxdb port
},
console: {
level: 'info',
level: 'error',
colorize: 'all',
prettyPrint: true
}
... ... @@ -103,7 +104,7 @@ module.exports = {
}
},
apiCache: {
cache: false
cache: true
},
zookeeperServer: '192.168.102.168:2188'
};
... ... @@ -120,10 +121,10 @@ if (isProduction) {
master: ['memcache1.yohoops.org:12111', 'memcache2.yohoops.org:12111', 'memcache3.yohoops.org:12111'],
slave: ['memcache1.yohoops.org:12112', 'memcache2.yohoops.org:12112', 'memcache3.yohoops.org:12112'],
session: ['memcache1.yohoops.org:12111', 'memcache2.yohoops.org:12111', 'memcache3.yohoops.org:12111'],
poolSize: 25,
poolSize: 100,
reconnect: 5000,
timeout: 300,
retries: 1,
retries: 0,
retry: 3000
},
useOneapm: true,
... ... @@ -132,7 +133,7 @@ if (isProduction) {
open: false,
url: 'http://123.206.2.55/strategy'
},
zookeeperServer: '10.66.1.97:2181'
zookeeperServer: 'zookeeper.web.yohoops.org:2181'
});
} else if (isTest) {
Object.assign(module.exports, {
... ...
... ... @@ -69,6 +69,12 @@ var $accountInput1 = $('#account1'),
getCaptchaSmsTokenVal = function() { // 短信登录凭证
return $.trim($captchaSmsTokenHideInput.val());
},
$smsCaptchaImgWrapper = $('.sms-captcha-img-wrap'),
$smsCaptchaImgInput = $smsCaptchaImgWrapper.find('#sms-captcha-input'),
$smsCaptchaImgPic = $smsCaptchaImgWrapper.find('#sms-captcha-img'),
getSmsCaptchaImgVal = function() { // 短信登录图形验证码
return $.trim($smsCaptchaImgInput.val());
},
// 区域选择
$countryCodeInput = $('#country-code-hide'),
... ... @@ -101,6 +107,7 @@ var $accountTip1 = $accountInput1.siblings('.err-tip'),
$passwordTip = $passwordInput.siblings('.err-tip'),
$captchaImgTip = $captchaImgInput.siblings('.err-tip'),
$captchaSmsTip = $captchaSmsInput.siblings('.err-tip'),
$smsCaptchaImgTip = $smsCaptchaImgInput.siblings('.err-tip'),
$capsLock = $('#caps-lock');
var mailPhoneRegx = require('../common/mail-phone-regx'), // 邮箱格式验证
... ... @@ -109,6 +116,9 @@ var mailPhoneRegx = require('../common/mail-phone-regx'), // 邮箱格式验证
// 图像验证码URL
var CAPTCHA_IMG_URL = '/passport/imagesNode?t=';
// 刷新手机短信图形验证码
var refreshSmsImgCallBack = $.Callbacks(); // eslint-disable-line
// 记住我符号
var checkboxSymbol = {
checked: '&#xe612;',
... ... @@ -253,30 +263,34 @@ accountChangeEvent.add(function(type) {
// 重置状态
accountChangeEvent.add(function(type) {
//hideAccountTip1(); // eslint-disable-line
//hideAccountTip2(); // eslint-disable-line
//hideCaptchaImgTip(); // eslint-disable-line
//hideCaptchaSmsTip(); // eslint-disable-line
//hidePasswordTip(); // eslint-disable-line
//
//$passwordInput.val('');
//$captchaImgInput.val('');
//$captchaSmsInput.val('');
//$captchaSmsTokenHideInput.val('');
//
//if (type === AccountLoginData.QRCodeLogin.name) {
// $qrCodeOverLayer.empty();
// initQrCode(); // eslint-disable-line
//}
hideAccountTip1(); // eslint-disable-line
hideAccountTip2(); // eslint-disable-line
hideCaptchaImgTip(); // eslint-disable-line
hideCaptchaSmsTip(); // eslint-disable-line
hidePasswordTip(); // eslint-disable-line
hideSmsCaptchaImgTip(); // eslint-disable-line
$passwordInput.val('');
$captchaImgInput.val('');
$captchaSmsInput.val('');
$smsCaptchaImgInput.val('');
$captchaSmsTokenHideInput.val('');
if (type === AccountLoginData.QRCodeLogin.name) {
$qrCodeOverLayer.empty();
initQrCode(); // eslint-disable-line
}
});
// 保留已输入的帐号信息
accountChangeEvent.add(function(type) {
//if (type === AccountLoginData.SMSLogin.name) {
// $accountInput2.val($accountInput1.val());
//} else {
// $accountInput1.val($accountInput2.val());
//}
if (type === AccountLoginData.SMSLogin.name) {
$accountInput2.val($accountInput1.val());
$smsCaptchaImgPic.attr('src', CAPTCHA_IMG_URL + $.now());
} else {
$accountInput1.val($accountInput2.val());
}
});
desktopTipShowOnce.add(function() {
... ... @@ -287,6 +301,10 @@ mobileTipShowOnce.add(function() {
$deviceTips.removeClass('hide');
});
refreshSmsImgCallBack.add(function() {
$smsCaptchaImgPic.attr('src', CAPTCHA_IMG_URL + $.now());
});
/** ************************************************************************/
/* 加载自定义库 */
/** ************************************************************************/
... ... @@ -321,6 +339,7 @@ function hideAccountTip1() {
}
function showAccountTip2(msg) {
refreshSmsImgCallBack.fire();
return errTipShow($accountTip2, $accountInput2, msg);
}
... ... @@ -351,6 +370,7 @@ function hideCaptchaImgTip() {
/** ************************************************************************/
function showCaptchaSmsTip(msg) {
refreshSmsImgCallBack.fire();
return errTipShow($captchaSmsTip, $captchaSmsInput, msg);
}
... ... @@ -360,6 +380,17 @@ function hideCaptchaSmsTip() {
/** ************************************************************************/
function showSmsCaptchaImgTip(msg) {
refreshSmsImgCallBack.fire();
return errTipShow($smsCaptchaImgTip, $smsCaptchaImgInput, msg);
}
function hideSmsCaptchaImgTip() {
return errTipHide($smsCaptchaImgTip, $smsCaptchaImgInput);
}
/** ************************************************************************/
function showQrCodeFailTip(msg) {
hideQrCodeTip(); // eslint-disable-line
$qrCodeOverLayer.addClass('qrcode-overlay-fail');
... ... @@ -654,6 +685,70 @@ function sendCaptchaSmsAsync() {
}
/** ************************************************************************/
/* 短信验证图形验证 */
/** ************************************************************************/
function smsCaptchaImgLocal() {
var captcha = getSmsCaptchaImgVal(),
err;
var defer = $.Deferred(); // eslint-disable-line
if (captcha !== '') {
if (captcha.length !== 4) {
err = '请输入长度为4字符的验证码';
defer.reject();
} else {
defer.resolve();
}
} else {
err = '请输入验证码';
defer.reject();
}
if (defer.state() === 'resolved') {
hideSmsCaptchaImgTip();
} else {
showSmsCaptchaImgTip(err);
}
return defer.promise();
}
function smsCaptchaImgAsync() {
return $.ajax({
url: '/passport/captcha/img',
type: 'POST',
data: {
verifyCode: getSmsCaptchaImgVal()
}
}).then(function(result) {
var defer = $.Deferred(); // eslint-disable-line
if (result.code === 200) {
hideSmsCaptchaImgTip();
defer.resolve();
} else {
showSmsCaptchaImgTip('验证码不正确');
defer.reject();
}
return defer.promise();
});
}
function validateSmsCaptchaImg() {
smsCaptchaImgLocal()
.then(smsCaptchaImgAsync)
.then(hideSmsCaptchaImgTip);
}
/** ************************************************************************/
/* 二维码验证 */
/** ************************************************************************/
... ... @@ -753,8 +848,8 @@ function validateWithPasswordMode() {
// 短信验证过程
function validateWithSmsMode() {
return validateAccount()
.then(validateCaptchaSms)
.then(validateCaptchaImg);
.then(validateSmsCaptchaImg)
.then(validateCaptchaSms);
}
/** ************************************************************************/
... ... @@ -800,7 +895,8 @@ function prePasswordLoginWithValidate() {
function preSmsLoginWithValidate() {
return (function() {
var account = currentLogin.getAccountVal(),
password = getCaptchaSmsVal();
password = getCaptchaSmsVal(),
smsImg = getSmsCaptchaImgVal();
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -810,6 +906,12 @@ function preSmsLoginWithValidate() {
defer.reject();
}
if (smsImg === '') {
showSmsCaptchaImgTip('请输入图形证码');
defer.reject();
}
if (password === '') {
showCaptchaSmsTip('请输入短信验证码');
... ... @@ -844,7 +946,7 @@ function loginAsync() {
areaCode: getAreaCodeVal(),
account: currentLogin.getAccountVal(),
password: currentLogin.creditableToken(),
captcha: getCaptchaImgVal(),
captcha: currentLogin.type() === 'password' ? getCaptchaImgVal() : getSmsCaptchaImgVal(),
isRemember: getRememberMeVal(),
loginType: currentLogin.type()
}
... ... @@ -871,7 +973,6 @@ function loginAsync() {
} else if (currentLogin.type() === 'sms') {
showCaptchaSmsTip('短信验证码错误');
$captchaSmsInput.addClass('error').val('');
} else if (currentLogin.type() === 'qrcode') {
showQrCodeFailTip(QR_CODE_ERR.fail);
}
... ... @@ -891,27 +992,6 @@ function showCaptchaImgPic() {
$captchaImgWrapper.removeClass('hide');
}
// 检查有效用户,超过三次会有验证操作进行
function authUntilThreeTimesAsync() {
return $.ajax({
url: '/passport/login/account',
type: 'GET',
data: {
account: currentLogin.getAccountVal()
}
}).then(function(res) {
var defer = $.Deferred(); // eslint-disable-line
if (res.data && res.data.needCaptcha) {
defer.resolve();
} else {
defer.reject();
}
return defer.promise();
});
}
// 设置 refer 信息
function setRefer() {
var refer = queryString().refer || '', // eslint-disable-line
... ... @@ -973,17 +1053,6 @@ mailAc($accountInput1, function() {
return currentLogin.validateAccountLocal();
});
// 短信下手机输入框失去焦点:
// 1. 本地验证格式;2.服务器检查用户是否注册;3.始终检查验证用户次数
$accountInput2.on('blur', function() {
return currentLogin.validateAccountLocal().then(function() {
return currentLogin.validateAccountAsync()
.always(function() {
return authUntilThreeTimesAsync().then(showCaptchaImgPic);
});
});
});
// 密码输入框事件
$passwordInput.on('blur', function() {
validatePasswordLocal();
... ... @@ -1007,6 +1076,19 @@ $passwordInput.on('blur', function() {
// 图像验证码输入框事件
$captchaImgInput.on('blur', validateCaptchaImg);
/** ************************************************************************/
// 短信下手机输入框失去焦点:本地验证格式
$accountInput2.on('blur', function() {
return currentLogin.validateAccountLocal();
});
// 图形验证码失去焦点验证
$smsCaptchaImgInput.on('blur', function() {
validateSmsCaptchaImg();
});
// sms验证码输入框事件
$captchaSmsInput.on('blur', validateCaptchaSms);
... ... @@ -1049,6 +1131,11 @@ $captchaImgWrapper.on('click', '.change-captcha, .captcha-img', function() {
$captchaImgPic.attr('src', CAPTCHA_IMG_URL + $.now());
});
// 刷新短信图形验证码
$smsCaptchaImgWrapper.on('click', '.change-captcha, .captcha-img', function() {
$smsCaptchaImgPic.attr('src', CAPTCHA_IMG_URL + $.now());
});
// 切换登录模式:密码登录和短信登录
$PhoneLoginSwitcher.on('click', 'div', function() {
var $this = $(this),
... ... @@ -1073,38 +1160,34 @@ $deviceSwitcher.on('click', function() {
$parent = $this.parent(),
type = $parent.data('type');
// 二维码登录
//$deviceTips.addClass('hide'); // 提示一直隐藏
//
//$(deviceLoginData[type].ele).removeClass('hide');
//$(deviceLoginData[type].hideEle).addClass('hide');
//
//$parent.data('type', deviceLoginData[type].dataType);
//$parent.find('#device-tip').html(deviceLoginData[type].tipText);
//
//$this.removeClass(deviceLoginData[type].removeClass)
// .addClass(deviceLoginData[type].bgClass);
// end 二维码登录结束
$deviceTips.addClass('hide'); // 提示一直隐藏
$(deviceLoginData[type].ele).removeClass('hide');
$(deviceLoginData[type].hideEle).addClass('hide');
$parent.data('type', deviceLoginData[type].dataType);
$parent.find('#device-tip').html(deviceLoginData[type].tipText);
$this.removeClass(deviceLoginData[type].removeClass)
.addClass(deviceLoginData[type].bgClass);
if (type === 'DesktopLogin') {
//desktopTipShowOnce.fire();
desktopTipShowOnce.fire();
// 还原桌面登录方式
accountChangeEvent.fire(getDesktopLoginType());
//stopPollingQrCodeTimer();
stopPollingQrCodeTimer();
} else {
mobileTipShowOnce.fire();
accountChangeEvent.fire('QRCodeLogin');
refreshQrCodeAsync().then(pollingThisQrCodeStatusAsync);
}
//} else {
// mobileTipShowOnce.fire();
//
// accountChangeEvent.fire('QRCodeLogin');
//
// refreshQrCodeAsync().then(pollingThisQrCodeStatusAsync);
//}
});
// 鼠标移动到上面
// 鼠标移动到二维码上面
$qrCodeHoverPanel.hover(function() {
$qrCodeContainer.stop(false, true).animate({left: '-=65'}, {
complete: function() {
... ...