Authored by 毕凯

Merge branch 'master' into release/6.0.2

@@ -121,11 +121,14 @@ module.exports = class extends global.yoho.BaseModel { @@ -121,11 +121,14 @@ module.exports = class extends global.yoho.BaseModel {
121 return {}; 121 return {};
122 } 122 }
123 123
124 - if (parseInt(order.attribute, 10) === 9) { 124 + let attribute = _.parseInt(order.attribute);
  125 +
  126 + if (attribute === 9 || attribute === 11) {
125 /* 预售商品,不能进行任何操作 */ 127 /* 预售商品,不能进行任何操作 */
126 orderBtn.push({ 128 orderBtn.push({
127 isAdvance: true 129 isAdvance: true
128 }); 130 });
  131 +
129 return {orderBtn: orderBtn}; 132 return {orderBtn: orderBtn};
130 } 133 }
131 134
@@ -204,8 +207,6 @@ module.exports = class extends global.yoho.BaseModel { @@ -204,8 +207,6 @@ module.exports = class extends global.yoho.BaseModel {
204 break; 207 break;
205 } 208 }
206 }); 209 });
207 -  
208 - return {orderBtn: orderBtn};  
209 } 210 }
210 211
211 /** 212 /**
@@ -62,12 +62,13 @@ module.exports = class extends global.yoho.BaseModel { @@ -62,12 +62,13 @@ module.exports = class extends global.yoho.BaseModel {
62 return {}; 62 return {};
63 } 63 }
64 64
65 - if (parseInt(order.attribute, 10) === 9) { 65 + let attribute = _.parseInt(order.attribute);
  66 +
  67 + if (attribute === 9 || attribute === 11) {
66 /* 预售商品,不能进行任何操作 */ 68 /* 预售商品,不能进行任何操作 */
67 orderBtn.push({ 69 orderBtn.push({
68 isAdvance: true 70 isAdvance: true
69 }); 71 });
70 - return {orderBtn: orderBtn};  
71 } 72 }
72 73
73 /* 倒计时时间 订单详情页倒计时不在同一级*/ 74 /* 倒计时时间 订单详情页倒计时不在同一级*/
@@ -228,10 +228,11 @@ const bind = { @@ -228,10 +228,11 @@ const bind = {
228 let refer = helpers.urlFormat('/passport/bind/success?type=bind'); 228 let refer = helpers.urlFormat('/passport/bind/success?type=bind');
229 229
230 if (result && result.code && result.code === 200 && result.data.uid) { 230 if (result && result.code && result.code === 200 && result.data.uid) {
231 - return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {  
232 - result.data.refer = refer;  
233 - return result;  
234 - }); 231 + return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key)
  232 + .then((authData) => {
  233 + result.data.refer = _.get(authData, 'refer') || refer;
  234 + return result;
  235 + });
235 } else { 236 } else {
236 return { code: 400, message: '绑定失败', data: '' }; 237 return { code: 400, message: '绑定失败', data: '' };
237 } 238 }
@@ -262,10 +263,11 @@ const bind = { @@ -262,10 +263,11 @@ const bind = {
262 let refer = helpers.urlFormat('/passport/bind/success', { sourceType: sourceType }); 263 let refer = helpers.urlFormat('/passport/bind/success', { sourceType: sourceType });
263 264
264 if (result && result.code && result.code === 200 && result.data.uid) { 265 if (result && result.code && result.code === 200 && result.data.uid) {
265 - return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {  
266 - result.data.refer = refer;  
267 - return result;  
268 - }); 266 + return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key)
  267 + .then((authData) => {
  268 + result.data.refer = _.get(authData, 'refer') || refer;
  269 + return result;
  270 + });
269 } else { 271 } else {
270 return { code: 400, message: '关联失败', data: '' }; 272 return { code: 400, message: '关联失败', data: '' };
271 } 273 }
@@ -8,8 +8,9 @@ @@ -8,8 +8,9 @@
8 const _ = require('lodash'); 8 const _ = require('lodash');
9 const passport = require('passport'); 9 const passport = require('passport');
10 10
11 -// const md5 = require('yoho-md5');  
12 const uuid = require('uuid'); 11 const uuid = require('uuid');
  12 +const url = require('url');
  13 +const moment = require('moment');
13 const co = Promise.coroutine; 14 const co = Promise.coroutine;
14 const cookie = global.yoho.cookie; 15 const cookie = global.yoho.cookie;
15 const helpers = global.yoho.helpers; 16 const helpers = global.yoho.helpers;
@@ -19,6 +20,8 @@ const cache = global.yoho.cache; @@ -19,6 +20,8 @@ const cache = global.yoho.cache;
19 const utils = require(global.utils); 20 const utils = require(global.utils);
20 const RegService = require('../models/reg-service'); 21 const RegService = require('../models/reg-service');
21 const AuthHelper = require('../models/auth-helper'); 22 const AuthHelper = require('../models/auth-helper');
  23 +const thirdAccount = require('../data/third-account.json');
  24 +const auth = require('../models/auth-helper');
22 25
23 const loginPage = `${config.siteUrl}/signin.html`; 26 const loginPage = `${config.siteUrl}/signin.html`;
24 27
@@ -50,9 +53,10 @@ function doPassportCallback(openId, nickname, sourceType, req, res) { @@ -50,9 +53,10 @@ function doPassportCallback(openId, nickname, sourceType, req, res) {
50 refer: refer 53 refer: refer
51 }); 54 });
52 } else if (result.code === 200 && result.data.uid) { 55 } else if (result.code === 200 && result.data.uid) {
53 - return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {  
54 - return refer;  
55 - }); 56 + return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key)
  57 + .then((authData) => {
  58 + return _.get(authData, 'refer') || refer;
  59 + });
56 } 60 }
57 }).then((redirectTo) => { 61 }).then((redirectTo) => {
58 return res.redirect(redirectTo); 62 return res.redirect(redirectTo);
@@ -63,6 +67,73 @@ function doPassportCallback(openId, nickname, sourceType, req, res) { @@ -63,6 +67,73 @@ function doPassportCallback(openId, nickname, sourceType, req, res) {
63 } 67 }
64 68
65 const common = { 69 const common = {
  70 + // 第三方登录有货逻辑
  71 + thirdLogin(req, res, next) {
  72 + let refer = req.get('referer');
  73 + let thirdRefer = req.cookies.third_refer;
  74 +
  75 + if (thirdRefer && !/signin|login|passport\/international/.test(refer)) {
  76 + res.clearCookie('third_refer', {
  77 + domain: 'yohobuy.com'
  78 + });
  79 + }
  80 +
  81 + // TODO 记录token并验证有效期或者实现oauth
  82 + if (req.query.yh_type &&
  83 + req.query.yh_sign &&
  84 + req.query.yh_time &&
  85 + req.query.yh_backurl) {
  86 + let reqTime = moment(req.query.yh_time);
  87 + let timeDiff = moment().diff(reqTime);
  88 +
  89 + if (!reqTime.isValid() ||
  90 + timeDiff >= 1000 * 60 * 5 || // 如果服务器之间大于5分钟验证失败
  91 + timeDiff < 0) {
  92 +
  93 + return res.json({
  94 + code: 401,
  95 + message: 'yh_time已过期或者格式错误'
  96 + });
  97 + }
  98 + let account = thirdAccount[req.query.yh_type];
  99 +
  100 + if (!account) {
  101 + return res.json({
  102 + code: 401,
  103 + message: 'yh_type验证失败'
  104 + });
  105 + }
  106 + let backurl = url.parse(req.query.yh_backurl);
  107 + let regDomain = new RegExp(`${account.domain.replace(/\./g, '\\.')}$`);
  108 +
  109 + if (!regDomain.test(backurl.host || '')) {
  110 + return res.json({
  111 + code: 401,
  112 + message: 'yh_backurl回调域名验证失败'
  113 + });
  114 + }
  115 + let signStr = auth.thirdSign(req.query, account.clientSecret);
  116 +
  117 + if (signStr.toLowerCase() !== req.query.yh_sign.toLowerCase()) {
  118 + return res.json({
  119 + code: 401,
  120 + message: 'yh_sign签名验证错误'
  121 + });
  122 + }
  123 + res.cookie('third_refer', refer, {
  124 + domain: 'yohobuy.com'
  125 + });
  126 + res.cookie('third_type', req.query.yh_type, {
  127 + domain: 'yohobuy.com'
  128 + });
  129 + res.cookie('third_backurl', req.query.yh_backurl, {
  130 + domain: 'yohobuy.com'
  131 + });
  132 +
  133 + req.query.from = req.query.yh_type;
  134 + }
  135 + next();
  136 + },
66 beforeLogin: (req, res, next) => { 137 beforeLogin: (req, res, next) => {
67 if (req.session.passwordWeak) { 138 if (req.session.passwordWeak) {
68 return res.redirect('/passport/password/resetpage'); 139 return res.redirect('/passport/password/resetpage');
@@ -297,10 +368,11 @@ const local = { @@ -297,10 +368,11 @@ const local = {
297 return res.json(passwordWeakReturn); 368 return res.json(passwordWeakReturn);
298 } 369 }
299 370
300 - AuthHelper.syncUserSession(user.uid, req, res, user.session_key).then(() => { 371 + AuthHelper.syncUserSession(user.uid, req, res, user.session_key).then((authData) => {
301 if (user.weakPassword) { 372 if (user.weakPassword) {
302 return res.json(passwordWeakReturn); 373 return res.json(passwordWeakReturn);
303 } else { 374 } else {
  375 + user.href = _.get(authData, 'refer', user.href);
304 res.json({ 376 res.json({
305 code: 200, 377 code: 200,
306 data: user 378 data: user
@@ -127,7 +127,7 @@ class Reg { @@ -127,7 +127,7 @@ class Reg {
127 return res.json(regMobileAesResult); 127 return res.json(regMobileAesResult);
128 } 128 }
129 129
130 - yield AuthHelper.syncUserSession(regMobileAesResult.data.uid, 130 + let authData = yield AuthHelper.syncUserSession(regMobileAesResult.data.uid,
131 req, res, regMobileAesResult.data.session_key); 131 req, res, regMobileAesResult.data.session_key);
132 132
133 // 返回跳转到来源页面 133 // 返回跳转到来源页面
@@ -156,7 +156,7 @@ class Reg { @@ -156,7 +156,7 @@ class Reg {
156 message: '注册成功', 156 message: '注册成功',
157 data: { 157 data: {
158 session: refer, 158 session: refer,
159 - href: '//m.yohobuy.com/activity/invite-reg', 159 + href: _.get(authData, 'refer') || '//m.yohobuy.com/activity/invite-reg',
160 msgDelivery: _.get(regMobileAesResult, 'data.msgDelivery', '') 160 msgDelivery: _.get(regMobileAesResult, 'data.msgDelivery', '')
161 } 161 }
162 }); 162 });
@@ -406,7 +406,7 @@ let setPassword = (req, res, next) => { @@ -406,7 +406,7 @@ let setPassword = (req, res, next) => {
406 resultCopy = result; 406 resultCopy = result;
407 407
408 return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key); 408 return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key);
409 - }).then(() => { 409 + }).then((authData) => {
410 if (!resultCopy) { 410 if (!resultCopy) {
411 return; 411 return;
412 } 412 }
@@ -438,7 +438,7 @@ let setPassword = (req, res, next) => { @@ -438,7 +438,7 @@ let setPassword = (req, res, next) => {
438 message: '注册成功', 438 message: '注册成功',
439 data: { 439 data: {
440 session: refer, 440 session: refer,
441 - href: '//m.yohobuy.com/activity/invite-reg', 441 + href: _.get(authData, 'refer') || '//m.yohobuy.com/activity/invite-reg',
442 msgDelivery: _.get(resultCopy, 'data.msgDelivery', '') 442 msgDelivery: _.get(resultCopy, 'data.msgDelivery', '')
443 } 443 }
444 }); 444 });
@@ -351,11 +351,11 @@ exports.check = (req, res, next) => { @@ -351,11 +351,11 @@ exports.check = (req, res, next) => {
351 }); 351 });
352 return AuthHelper.syncUserSession(info.data.uid, req, res, info.data.session_key); 352 return AuthHelper.syncUserSession(info.data.uid, req, res, info.data.session_key);
353 }) 353 })
354 - .then(() => { 354 + .then((authData) => {
355 res.json({ 355 res.json({
356 code: 200, 356 code: 200,
357 message: LOGIN_SUCCSS, 357 message: LOGIN_SUCCSS,
358 - redirect: utils.refererLimit(req.cookies.refer) 358 + redirect: _.get(authData, 'refer') || utils.refererLimit(req.cookies.refer)
359 }); 359 });
360 360
361 delete req.session.smsLogin; 361 delete req.session.smsLogin;
@@ -418,14 +418,14 @@ exports.password = (req, res, next) => { @@ -418,14 +418,14 @@ exports.password = (req, res, next) => {
418 resultCopy = result; 418 resultCopy = result;
419 419
420 return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key); 420 return AuthHelper.syncUserSession(result.data.uid, req, res, result.data.session_key);
421 - }).then(() => { 421 + }).then((authData) => {
422 if (!resultCopy) { 422 if (!resultCopy) {
423 return; 423 return;
424 } 424 }
425 res.json({ 425 res.json({
426 code: 200, 426 code: 200,
427 message: LOGIN_SUCCSS, 427 message: LOGIN_SUCCSS,
428 - redirect: utils.refererLimit(req.cookies.refer) 428 + redirect: _.get(authData, 'refer') || utils.refererLimit(req.cookies.refer)
429 }); 429 });
430 delete req.session.smsLogin; 430 delete req.session.smsLogin;
431 }).catch(next); 431 }).catch(next);
  1 +{
  2 + "mars": {
  3 + "clientSecret": "f30368d65fcad4a265074948a2a2e6e6",
  4 + "domain": "yohomars.com"
  5 + },
  6 + "activity": {
  7 + "clientSecret": "3bd815162342d9733f06ab6811082c64",
  8 + "domain": "yoho.cn"
  9 + }
  10 +}
@@ -6,6 +6,11 @@ const logger = global.yoho.logger; @@ -6,6 +6,11 @@ const logger = global.yoho.logger;
6 const sign = global.yoho.sign; 6 const sign = global.yoho.sign;
7 const api = global.yoho.API; 7 const api = global.yoho.API;
8 const uuid = require('uuid'); 8 const uuid = require('uuid');
  9 +const url = require('url');
  10 +const md5 = require('yoho-md5');
  11 +const moment = require('moment');
  12 +const querystring = require('querystring');
  13 +const thirdAccount = require('../data/third-account.json');
9 14
10 class Auth { 15 class Auth {
11 16
@@ -73,6 +78,54 @@ class Auth { @@ -73,6 +78,54 @@ class Auth {
73 return api.get('', param); 78 return api.get('', param);
74 } 79 }
75 80
  81 + static thirdSign(params, clientSecret) {
  82 + let secretParams = {},
  83 + secretStr = '';
  84 +
  85 + for (const k of Object.keys(params).sort()) {
  86 + if (k === 'yh_sign') {
  87 + continue;
  88 + }
  89 + secretParams[k] = params[k];
  90 + }
  91 + secretStr = _.join(_.map(secretParams, (v, k) => {
  92 + return `${k}=${v}`;
  93 + }), '&');
  94 + return md5(secretStr + clientSecret);
  95 + }
  96 +
  97 + static thirdLogin(req, res, uid) {
  98 + if (req.cookies.third_type && req.cookies.third_backurl && req.cookies.third_refer) {
  99 + let backurl = url.parse(req.cookies.third_backurl),
  100 + account = thirdAccount[req.cookies.third_type];
  101 +
  102 + let params = Object.assign({
  103 + yh_uid: uid,
  104 + yh_type: req.cookies.third_type,
  105 + yh_time: moment().format('YYYY-MM-DD HH:mm:ss')
  106 + }, querystring.parse(backurl.query));
  107 + let signStr = this.thirdSign(params, account.clientSecret);
  108 +
  109 + params.yh_sign = signStr;
  110 + let queryStr = _.join(_.map(params, (v, k) => {
  111 + return `${k}=${encodeURIComponent(v)}`;
  112 + }), '&');
  113 +
  114 + return {
  115 + refer: `${backurl.protocol}//${backurl.host}?${queryStr}`
  116 + };
  117 + }
  118 + res.clearCookie('third_type', {
  119 + domain: 'yohobuy.com'
  120 + });
  121 + res.clearCookie('third_backurl', {
  122 + domain: 'yohobuy.com'
  123 + });
  124 + res.clearCookie('third_refer', {
  125 + domain: 'yohobuy.com'
  126 + });
  127 + }
  128 +
76 static syncUserSession(uid, req, res, sessionKey) { 129 static syncUserSession(uid, req, res, sessionKey) {
77 let userId = { 130 let userId = {
78 toString: () => { 131 toString: () => {
@@ -132,6 +185,9 @@ class Auth { @@ -132,6 +185,9 @@ class Auth {
132 domain: 'yohobuy.com', 185 domain: 'yohobuy.com',
133 expires: new Date(Date.now() + 2592000000) // 有效期一年 186 expires: new Date(Date.now() + 2592000000) // 有效期一年
134 }); 187 });
  188 +
  189 + // 第三方登录逻辑
  190 + return this.thirdLogin(req, res, uid);
135 }); 191 });
136 } 192 }
137 } 193 }
@@ -203,6 +203,7 @@ router.get('/signin.html', @@ -203,6 +203,7 @@ router.get('/signin.html',
203 validateCode.load, 203 validateCode.load,
204 login.common.beforeLogin, 204 login.common.beforeLogin,
205 login.common.clearCookie, 205 login.common.clearCookie,
  206 + login.common.thirdLogin,
206 smsNew.smsLoginPage); // 短信验证码登录 207 smsNew.smsLoginPage); // 短信验证码登录
207 router.get('/reg.html', 208 router.get('/reg.html',
208 validateCode.load, 209 validateCode.load,
@@ -79,6 +79,7 @@ module.exports = () => { @@ -79,6 +79,7 @@ module.exports = () => {
79 } 79 }
80 } 80 }
81 81
  82 + res.locals.isLogin = Boolean(req.user.uid); // 用户是否登录
82 next(); 83 next();
83 }; 84 };
84 }; 85 };
@@ -72,6 +72,10 @@ @@ -72,6 +72,10 @@
72 var s = document.getElementsByTagName("script")[0]; 72 var s = document.getElementsByTagName("script")[0];
73 s.parentNode.insertBefore(hm, s); 73 s.parentNode.insertBefore(hm, s);
74 })(); 74 })();
  75 +
  76 + {{#if @root.isLogin}}
  77 + _hmt.push(['_setCustomVar', 1, 'login', true, 2]);
  78 + {{/if}}
75 }, 1000); 79 }, 1000);
76 }()); 80 }());
77 81
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <li><span class="hours">{{leftTime}}</span></li> 6 <li><span class="hours">{{leftTime}}</span></li>
7 </ul> 7 </ul>
8 {{else if isAdvance}} 8 {{else if isAdvance}}
9 - <span class="order-opt-info">*定金预售订单只能在APP端操作</span> 9 + <span class="order-opt-info">*订单只能在APP端操作</span>
10 {{else if refundApply}} 10 {{else if refundApply}}
11 <span class="btn refund">申请退款</span> 11 <span class="btn refund">申请退款</span>
12 {{else if modifyAddress}} 12 {{else if modifyAddress}}
This diff could not be displayed because it is too large.
1 { 1 {
2 "name": "m-yohobuy-node", 2 "name": "m-yohobuy-node",
3 - "version": "6.0.13", 3 + "version": "6.0.14",
4 "private": true, 4 "private": true,
5 "description": "A New Yohobuy Project With Express", 5 "description": "A New Yohobuy Project With Express",
6 "repository": { 6 "repository": {
@@ -425,3 +425,23 @@ @@ -425,3 +425,23 @@
425 } 425 }
426 } 426 }
427 } 427 }
  428 +
  429 +.is-mars-app {
  430 + .chose-panel {
  431 + .block {
  432 + &.chosed {
  433 + background-color: #89b374;
  434 + color: #fff;
  435 + border-color: #89b374;
  436 + }
  437 + }
  438 +
  439 + .btn-wrap {
  440 + .btn-sure,
  441 + .btn-sure-addtocart {
  442 + background-color: #89b374 !important;
  443 + color: #fff;
  444 + }
  445 + }
  446 + }
  447 +}