Authored by 李奇

change:修改

  1 +/**
  2 + *aes加解密
  3 + * @author: qi.li@yoho.cn
  4 + * @date: 2017/10/10
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const crypto = global.yoho.crypto;
  10 +
  11 +/**
  12 + * uid加密
  13 + **/
  14 +const encryptUid = (uid) => {
  15 + return crypto.encryption('yoho9646abcdefgh', uid + '');
  16 +};
  17 +
  18 +/**
  19 + * uid解密
  20 + **/
  21 +const decryptUid = (uid) => {
  22 + return crypto.decrypt('yoho9646abcdefgh', uid + '');
  23 +};
  24 +
  25 +module.exports = {
  26 + encryptUid,
  27 + decryptUid
  28 +};
@@ -3,11 +3,9 @@ @@ -3,11 +3,9 @@
3 * @author: leo <qi.li@yoho.cn> 3 * @author: leo <qi.li@yoho.cn>
4 * @date: 27/09/2017 4 * @date: 27/09/2017
5 */ 5 */
6 -const GET_COUPON_SUCCESS = '获取优惠券列表成功';  
7 -const RECEIVE_COUPON_SUCCESS = '成功领取优惠券';  
8 -const NEED_YH_AUTH = '请先授权登录有货';  
9 -const HELP_SUCCESS = '助力成功';  
10 - 6 +const _ = require('lodash');
  7 +const aes = require('./aes');
  8 +const expModel = require('../models/coupon-expansion');
11 9
12 const couponExp = { 10 const couponExp = {
13 11
@@ -16,35 +14,90 @@ const couponExp = { @@ -16,35 +14,90 @@ const couponExp = {
16 * @param req 14 * @param req
17 * @param res 15 * @param res
18 */ 16 */
19 - couponList(req, res) {  
20 - res.json({  
21 - code: 200,  
22 - message: GET_COUPON_SUCCESS 17 + couponList(req, res, next) {
  18 + const activityId = +req.query.activity_id;
  19 +
  20 + req.ctx(expModel).couponList(activityId)
  21 + .then(result => {
  22 + // 初始券数据
  23 + req.session._COUPONS = result.data.activityCouponInfoBoList;
  24 + res.json(result);
  25 + }).catch(next);
  26 + },
  27 +
  28 + /**
  29 + * 助力进度
  30 + * @param req
  31 + * @param res
  32 + */
  33 + progress(req, res) {
  34 + const uid = +req.session.yh_auth_uid;
  35 + const shareId = aes.encryptUid(uid); // 分享标识
  36 +
  37 + req.ctx(expModel).progress(uid).then(result => {
  38 + result.data.shareId = shareId;
  39 + res.json(result);
23 }); 40 });
24 }, 41 },
25 42
26 /** 43 /**
27 - * 领取优惠券 44 + * 生成分享标识
28 * @param req 45 * @param req
29 * @param res 46 * @param res
30 */ 47 */
31 - receiveCoupon(req, res) {  
32 - let yhAuth = req.session.yh_auth_logged;  
33 - let urlBefore = req.body.url_before_auth;  
34 -  
35 - if (yhAuth) {  
36 - res.json({  
37 - code: 200,  
38 - message: RECEIVE_COUPON_SUCCESS 48 + getShareId(req, res) {
  49 + req.ctx(expModel).progress(+req.session.yh_auth_uid)
  50 + .then(result => {
  51 + res.json(result);
39 }); 52 });
40 - } else {  
41 - req.session.url_before_auth = urlBefore; 53 + },
42 54
43 - res.json({  
44 - code: 401,  
45 - message: NEED_YH_AUTH 55 + /**
  56 + * 领取优惠券
  57 + * @param req
  58 + * @param res
  59 + */
  60 + receiveCoupon(req, res, next) {
  61 + let uid = +req.body.uid;
  62 + let isApp = req.body.isApp;
  63 +
  64 + // app登录后领券
  65 + if (isApp && uid) {
  66 + const coupons = req.session._COUPONS;
  67 +
  68 + let promises = _.map(_.filter(coupons, cp => !cp.user_send), item => {
  69 + return req.ctx(expModel).getCoupon(uid, item.couponId);
46 }); 70 });
  71 +
  72 + if (promises.length) {
  73 + Promise.all(promises).then(() => {
  74 + // const success = _.every(result, { code: 200 });
  75 + // if (!success) {
  76 + // // 领取失败、返回首页
  77 + // return res.status(301).redirect('//feature.yoho.cn/coupon-expansion');
  78 + // }
  79 +
  80 + // 设置优惠券状态
  81 + _.each(coupons, item => {
  82 + item.user_send = true;
  83 + });
  84 + req.session._COUPONS = coupons;
  85 +
  86 + // 进度页
  87 + res.status(301).redirect('//feature.yoho.cn/coupon-expansion/progress');
  88 + }).catch(next);
  89 + } else {
  90 + res.json({
  91 + code: 301,
  92 + data: {
  93 + url: '//feature.yoho.cn/coupon-expansion/progress'
  94 + },
  95 + message: '重定向'
  96 + });
  97 + }
47 } 98 }
  99 +
  100 + // TODO H5
48 }, 101 },
49 102
50 /** 103 /**
@@ -52,16 +105,36 @@ const couponExp = { @@ -52,16 +105,36 @@ const couponExp = {
52 * @param req 105 * @param req
53 * @param res 106 * @param res
54 */ 107 */
55 - yhLoginSuccess(req, res) {  
56 - let uid = req.query.yh_uid;  
57 - let url = req.session.url_before_auth; 108 + yhLoginSuccess(req, res, next) {
  109 + const uid = req.query.yh_uid;
  110 + const coupons = req.session._COUPONS;
58 111
59 req.session.yh_auth_uid = uid; 112 req.session.yh_auth_uid = uid;
60 req.session.yh_auth_logged = true; 113 req.session.yh_auth_logged = true;
61 114
62 - delete req.session.url_before_auth; 115 + let promises = _.map(_.filter(coupons, cp => !cp.user_send), item => {
  116 + return req.ctx(expModel).getCoupon(uid, item.couponId);
  117 + });
  118 +
  119 + Promise.all(promises).then(result => {
  120 + const success = _.every(result, { code: 200 });
  121 +
  122 + // TODO
  123 + if (!success) {
  124 + // 领取失败、返回首页
  125 + return res.status(301).redirect('//feature.yoho.cn/coupon-expansion');
  126 + }
  127 +
  128 + // 设置优惠券状态
  129 + _.each(coupons, item => {
  130 + item.user_send = true;
  131 + });
  132 + req.session._COUPONS = coupons;
  133 +
  134 + // 进度页
  135 + res.status(301).redirect('//feature.yoho.cn/coupon-expansion/progress');
  136 + }).catch(next);
63 137
64 - res.status(301).redirect(url);  
65 }, 138 },
66 139
67 /** 140 /**
@@ -69,11 +142,17 @@ const couponExp = { @@ -69,11 +142,17 @@ const couponExp = {
69 * @param req 142 * @param req
70 * @param res 143 * @param res
71 */ 144 */
72 - expandOne(req, res) {  
73 - res.json({  
74 - code: 200,  
75 - message: HELP_SUCCESS  
76 - }); 145 + friendHelp(req, res, next) {
  146 + const uid = parseInt(aes.decryptUid(req.body.shareId), 10);
  147 + const params = Object.assign({}, req.session._THIRD_LOGIN_INFO);
  148 +
  149 + params.uid = uid;
  150 + req.ctx(expModel).friendHelp(params)
  151 + .then(result => {
  152 + // req.session._THIRD_LOGIN_INFO = {};
  153 + res.json(result);
  154 + }).catch(next);
  155 +
77 } 156 }
78 }; 157 };
79 158
@@ -3,26 +3,58 @@ @@ -3,26 +3,58 @@
3 * @author: leo <qi.li@yoho.cn> 3 * @author: leo <qi.li@yoho.cn>
4 * @date: 27/09/2017 4 * @date: 27/09/2017
5 */ 5 */
6 -const mysqlCli = global.yoho.utils.mysqlCli;  
7 -  
8 -const TABLE_ACT_LOGIN_USER_LOG = 'act_login_user_log';  
9 -  
10 -class UserModel extends global.yoho.BaseModel { 6 +class expModel extends global.yoho.BaseModel {
11 constructor(ctx) { 7 constructor(ctx) {
12 super(ctx); 8 super(ctx);
13 } 9 }
14 - loginLog({uid, ip, loginTime, platform, referer}) {  
15 - return mysqlCli.insert(  
16 - `insert into ${TABLE_ACT_LOGIN_USER_LOG} (user_id, login_time, platform, ip, referer) values (:uid, :loginTime, :platform, :ip, :referer);`, // eslint-disable-line  
17 - { 10 +
  11 + couponList(id) {
  12 + return this.get({
  13 + data: {
  14 + method: 'app.activity.getActivityUserDesc',
  15 + activity_id: id
  16 + },
  17 + api: global.yoho.API,
  18 + param: {code: 200}
  19 + });
  20 + }
  21 +
  22 + getCoupon(uid, couponId) {
  23 + return this.get({
  24 + data: {
  25 + method: 'app.promotion.getCoupon',
  26 + uid,
  27 + couponId
  28 + },
  29 + api: global.yoho.API
  30 + });
  31 + }
  32 +
  33 + friendHelp({ uid, source, openId, nickname, headIco }) {
  34 + return this.get({
  35 + data: {
  36 + method: 'app.activity.friendhelp',
  37 + uid,
  38 + source,
  39 + open_id: openId,
  40 + nick_name: nickname,
  41 + head_ico: headIco
  42 + },
  43 + api: global.yoho.API,
  44 + param: {code: 200}
  45 + });
  46 + }
  47 +
  48 + progress(uid) {
  49 + return this.get({
  50 + data: {
18 uid, 51 uid,
19 - loginTime,  
20 - platform,  
21 - ip,  
22 - referer  
23 - }  
24 - ); 52 + method: 'app.activity.friendhelplog'
  53 + },
  54 + api: global.yoho.API,
  55 + param: {code: 200}
  56 + });
25 } 57 }
26 } 58 }
27 -module.exports = UserModel; 59 +module.exports = expModel;
28 60
@@ -9,7 +9,8 @@ const couponExp = require('./controllers/coupon-expansion'); @@ -9,7 +9,8 @@ const couponExp = require('./controllers/coupon-expansion');
9 9
10 router.get('/couponExp/couponList', couponExp.couponList); 10 router.get('/couponExp/couponList', couponExp.couponList);
11 router.post('/couponExp/receiveCoupon', couponExp.receiveCoupon); 11 router.post('/couponExp/receiveCoupon', couponExp.receiveCoupon);
  12 +router.get('/couponExp/progress', couponExp.progress);
12 router.get('/couponExp/yhLoginSuccess', couponExp.yhLoginSuccess); 13 router.get('/couponExp/yhLoginSuccess', couponExp.yhLoginSuccess);
13 -router.post('/couponExp/expandOne', couponExp.expandOne); 14 +router.post('/couponExp/friendHelp', couponExp.friendHelp);
14 15
15 module.exports = router; 16 module.exports = router;
@@ -13,12 +13,14 @@ const QQStrategy = require('passport-qq').Strategy; @@ -13,12 +13,14 @@ const QQStrategy = require('passport-qq').Strategy;
13 13
14 const config = global.yoho.config; 14 const config = global.yoho.config;
15 let siteUrl = config.siteUrl.indexOf('//') === 0 ? 'http:' + config.siteUrl : config.siteUrl; 15 let siteUrl = config.siteUrl.indexOf('//') === 0 ? 'http:' + config.siteUrl : config.siteUrl;
  16 +let weChatUrl = `${siteUrl}/passport/login/wechat/callback`;
  17 +let sinaUrl = `${siteUrl}/passport/login/sina/callback`;
16 18
17 // wechat 登录 19 // wechat 登录
18 passport.use('weixin', new WeixinStrategy({ 20 passport.use('weixin', new WeixinStrategy({
19 clientID: 'wx75e5a7c0c88e45c2', 21 clientID: 'wx75e5a7c0c88e45c2',
20 clientSecret: 'ce21ae4a3f93852279175a167e54509b', 22 clientSecret: 'ce21ae4a3f93852279175a167e54509b',
21 - callbackURL: `${siteUrl}/passport/login/wechat/callback`, 23 + callbackURL: `//m.yohobuy.com/passport/login/wechat/redirect?redirectUrl=${weChatUrl}`,
22 requireState: true, 24 requireState: true,
23 authorizationURL: 'https://open.weixin.qq.com/connect/oauth2/authorize', 25 authorizationURL: 'https://open.weixin.qq.com/connect/oauth2/authorize',
24 scope: 'snsapi_userinfo' 26 scope: 'snsapi_userinfo'
@@ -30,7 +32,7 @@ passport.use('weixin', new WeixinStrategy({ @@ -30,7 +32,7 @@ passport.use('weixin', new WeixinStrategy({
30 passport.use('sina', new SinaStrategy({ 32 passport.use('sina', new SinaStrategy({
31 clientID: '3739328910', 33 clientID: '3739328910',
32 clientSecret: '9d44cded26d048e23089e5e975c93df1', 34 clientSecret: '9d44cded26d048e23089e5e975c93df1',
33 - callbackURL: `${siteUrl}/passport/login/sina/callback`, 35 + callbackURL: `//m.yohobuy.com/passport/login/sina/redirect?redirectUrl=${sinaUrl}`,
34 requireState: false 36 requireState: false
35 }, (accessToken, refreshToken, profile, done) => { 37 }, (accessToken, refreshToken, profile, done) => {
36 done(null, profile); 38 done(null, profile);
@@ -9,9 +9,19 @@ const utils = global.yoho.utils; @@ -9,9 +9,19 @@ const utils = global.yoho.utils;
9 const AuthHelper = require('../models/auth-helper'); 9 const AuthHelper = require('../models/auth-helper');
10 const loginPage = `${config.siteUrl}/signin.html`; 10 const loginPage = `${config.siteUrl}/signin.html`;
11 11
12 -function doPassportCallback(openId, nickname, sourceType, req, res) { // eslint-disable-line  
13 - if (openId && nickname) {  
14 - // TODO 授权成功、实现助力 12 +function doPassportCallback(openId, nickname, source, req, res) { // eslint-disable-line
  13 + if (openId && nickname && source) {
  14 + req.session._THIRD_LOGIN_INFO = {
  15 + openId,
  16 + nickname,
  17 + source
  18 + };
  19 +
  20 + // 第三方登录
  21 + req.session._THIRD_LOGIN = true;
  22 + req.session._THIRD_LOGIN_SOURCE = source;
  23 +
  24 + res.status(301).redirect(`${req.session.cbUrl}`);
15 } else { 25 } else {
16 return Promise.reject('missing third party login openId or nickname'); 26 return Promise.reject('missing third party login openId or nickname');
17 } 27 }
@@ -133,73 +143,46 @@ const common = { @@ -133,73 +143,46 @@ const common = {
133 143
134 const wechat = { 144 const wechat = {
135 login: (req, res, next) => { 145 login: (req, res, next) => {
136 - // 设置为原链接标识originalUrl  
137 req.session.originalUrl = 'true'; 146 req.session.originalUrl = 'true';
138 req.session.authState = uuid.v4(); 147 req.session.authState = uuid.v4();
139 - delete req.session._WX_PASS_LOGIN; 148 + req.session.cbUrl = req.query.cbUrl;
140 149
141 return passport.authenticate('weixin', { 150 return passport.authenticate('weixin', {
142 state: req.session.authState 151 state: req.session.authState
143 })(req, res, next); 152 })(req, res, next);
144 }, 153 },
145 - callback: (req, res, next) => {  
146 - if (req.session && req.session.authState && req.session.authState === req.query.state) {  
147 - passport.authenticate('weixin', (err, user) => {  
148 - if (err || !user) {  
149 - log.error(`wechat authenticate error : ${JSON.stringify(err)}`);  
150 - return res.redirect(loginPage);  
151 - }  
152 - let nickname = user._json.nickname || user.displayName;  
153 - let openId = user._json.unionid || user.id; 154 + callback: (req, res) => {
  155 + const openId = req.query.openId;
  156 + const nickname = req.query.nickname;
154 157
155 - res.session._WX_OPENID = _.get(user, '_json.openid');  
156 - res.session._WX_UNIONID = _.get(user, '_json.unionid');  
157 - res.session._LOGIN_TYPE = 4;  
158 - doPassportCallback(openId, nickname, 'wechat', req, res).catch(next);  
159 - })(req, res, next);  
160 - } else {  
161 - log.error('Auth State Mismatch:' + req.originalUrl);  
162 - return res.redirect(loginPage);  
163 - } 158 + doPassportCallback(openId, nickname, 'qq', req, res);
164 } 159 }
165 }; 160 };
166 161
167 const sina = { 162 const sina = {
168 login: (req, res, next) => { 163 login: (req, res, next) => {
169 - // 设置为原链接标识originalUrl  
170 req.session.originalUrl = 'true'; 164 req.session.originalUrl = 'true';
171 req.session.authState = uuid.v4(); 165 req.session.authState = uuid.v4();
  166 + req.session.cbUrl = req.query.cbUrl;
  167 +
172 return passport.authenticate('sina', { 168 return passport.authenticate('sina', {
173 state: req.session.authState 169 state: req.session.authState
174 })(req, res, next); 170 })(req, res, next);
175 }, 171 },
176 - callback: (req, res, next) => {  
177 - if (req.session && req.session.authState && req.session.authState === req.query.state) {  
178 - passport.authenticate('sina', (err, user) => {  
179 - if (err || !user) {  
180 - log.error(`sina authenticate error : ${JSON.stringify(err)}`);  
181 - return res.redirect(loginPage);  
182 - }  
183 - let nickname = user.screen_name;  
184 - let openId = user.id; 172 + callback: (req, res) => {
  173 + const openId = req.query.openId;
  174 + const nickname = req.query.nickname;
185 175
186 - res.cookie('_LOGIN_TYPE', 2, {  
187 - domain: 'm.yohobuy.com'  
188 - });  
189 - doPassportCallback(openId, nickname, 'sina', req, res).catch(next);  
190 - })(req, res, next);  
191 - } else {  
192 - log.error('Auth State Mismatch:' + req.originalUrl);  
193 - return res.redirect(loginPage);  
194 - } 176 + doPassportCallback(openId, nickname, 'sina', req, res);
195 } 177 }
196 }; 178 };
197 179
198 const qq = { 180 const qq = {
199 login: (req, res, next) => { 181 login: (req, res, next) => {
200 - // 设置为原链接标识originalUrl  
201 req.session.originalUrl = 'true'; 182 req.session.originalUrl = 'true';
202 req.session.authState = uuid.v4(); 183 req.session.authState = uuid.v4();
  184 + req.session.cbUrl = req.query.cbUrl;
  185 +
203 return passport.authenticate('qq', { 186 return passport.authenticate('qq', {
204 state: req.session.authState 187 state: req.session.authState
205 })(req, res, next); 188 })(req, res, next);
@@ -210,15 +193,16 @@ const qq = { @@ -210,15 +193,16 @@ const qq = {
210 if (err) { 193 if (err) {
211 log.error(`qq authenticate error : ${JSON.stringify(err)}`); 194 log.error(`qq authenticate error : ${JSON.stringify(err)}`);
212 195
213 - // TODO 授权失败  
214 - // return res.redirect(loginPage); 196 + return res.json({
  197 + code: 500,
  198 + message: 'authenticate error'
  199 + });
215 } 200 }
216 201
217 let nickname = user.nickname; 202 let nickname = user.nickname;
218 let openId = user.id; 203 let openId = user.id;
219 204
220 - req.session._LOGIN_TYPE = 1; // 1: QQ授权登录  
221 - doPassportCallback(openId, nickname, 'qq', req, res).catch(next); 205 + doPassportCallback(openId, nickname, 'qq', req, res);
222 })(req, res, next); 206 })(req, res, next);
223 } else { 207 } else {
224 log.error('Auth State Mismatch:' + req.originalUrl); 208 log.error('Auth State Mismatch:' + req.originalUrl);
@@ -227,31 +211,7 @@ const qq = { @@ -227,31 +211,7 @@ const qq = {
227 } 211 }
228 }; 212 };
229 213
230 -const alipay = {  
231 - login: (req, res, next) => {  
232 - // 设置为原链接标识originalUrl  
233 - req.session.originalUrl = 'true';  
234 - return passport.authenticate('alipay')(req, res, next);  
235 - },  
236 - callback: (req, res, next) => {  
237 - passport.authenticate('alipay', (err, user) => {  
238 - if (err || !user) {  
239 - log.error(`alipay authenticate error : ${JSON.stringify(err)}`);  
240 - return res.redirect(loginPage);  
241 - }  
242 - let nickname = user.realName;  
243 - let openId = user.userId;  
244 -  
245 - res.cookie('_LOGIN_TYPE', 3, {  
246 - domain: 'm.yohobuy.com'  
247 - });  
248 - doPassportCallback(openId, nickname, 'alipay', req, res).catch(next);  
249 - })(req, res, next);  
250 - }  
251 -};  
252 -  
253 exports.common = common; 214 exports.common = common;
254 exports.wechat = wechat; 215 exports.wechat = wechat;
255 exports.sina = sina; 216 exports.sina = sina;
256 exports.qq = qq; 217 exports.qq = qq;
257 -exports.alipay = alipay;  
@@ -21,7 +21,7 @@ router.get('/login/wechat', login.wechat.login); @@ -21,7 +21,7 @@ router.get('/login/wechat', login.wechat.login);
21 router.get('/login/wechat/callback', login.wechat.callback); 21 router.get('/login/wechat/callback', login.wechat.callback);
22 22
23 // sina 23 // sina
24 -router.get('/login/sina', login.common.beforeLogin, login.sina.login); 24 +router.get('/login/sina', login.sina.login);
25 router.get('/login/sina/callback', login.sina.callback); 25 router.get('/login/sina/callback', login.sina.callback);
26 26
27 // qq 27 // qq
@@ -3,6 +3,7 @@ const _ = require('lodash'); @@ -3,6 +3,7 @@ const _ = require('lodash');
3 const {yoho} = global.yoho.utils; 3 const {yoho} = global.yoho.utils;
4 const {yohoSecret} = global.yoho.config; 4 const {yohoSecret} = global.yoho.config;
5 const UserModel = require('../models/user'); 5 const UserModel = require('../models/user');
  6 +const isProd = process.env.NODE_ENV === 'production';
6 7
7 const user = { 8 const user = {
8 getLoginUrl(req, res) { 9 getLoginUrl(req, res) {
@@ -27,7 +28,7 @@ const user = { @@ -27,7 +28,7 @@ const user = {
27 28
28 return res.json({ 29 return res.json({
29 code: 200, 30 code: 200,
30 - loginUrl: `https://m.yohobuy.com/signin.html?${queryStr}` 31 + loginUrl: `http${isProd ? 's' : ''}://m.yohobuy.com/signin.html?${queryStr}`
31 }); 32 });
32 }, 33 },
33 loginLog(req, res, next) { 34 loginLog(req, res, next) {