Authored by 梁志锋

Merge remote-tracking branch 'remotes/origin/feature/passport' into release/4.8

@@ -56,7 +56,7 @@ passport.use(new LocalStrategy({ @@ -56,7 +56,7 @@ passport.use(new LocalStrategy({
56 56
57 let shoppingKey = cookie.getShoppingKey(req); 57 let shoppingKey = cookie.getShoppingKey(req);
58 58
59 - AuthHelper.signin(area, username, password, shoppingKey).then((result) => { 59 + AuthHelper.signinAes(area, username, password, shoppingKey).then((result) => {
60 if (result.code && result.code === 200 && result.data.uid) { 60 if (result.code && result.code === 200 && result.data.uid) {
61 done(null, result.data); 61 done(null, result.data);
62 } else { 62 } else {
@@ -104,5 +104,7 @@ passport.use('qq', new QQStrategy({ @@ -104,5 +104,7 @@ passport.use('qq', new QQStrategy({
104 passport.use('alipay', new AlipayStrategy({ 104 passport.use('alipay', new AlipayStrategy({
105 partner: '2088701661478015', 105 partner: '2088701661478015',
106 key: 'kcxawi9bb07mzh0aq2wcirsf9znusobw', 106 key: 'kcxawi9bb07mzh0aq2wcirsf9znusobw',
107 - callbackURL: `${siteUrl}/passport/login/alipay/callback`  
108 -})); 107 + return_url: `${siteUrl}/passport/login/alipay/callback`
  108 +}), (profile, done) => {
  109 + done(null, profile);
  110 +});
@@ -120,7 +120,7 @@ const setNewPasswordByEmailAPI = (req, res) => { @@ -120,7 +120,7 @@ const setNewPasswordByEmailAPI = (req, res) => {
120 data: SIGN_IN 120 data: SIGN_IN
121 }; 121 };
122 122
123 - service.modifyPasswordByEmailAsync(pwd, code) 123 + service.modifyPasswordByEmailAsyncAes(pwd, code)
124 .then(result => { 124 .then(result => {
125 if (result.includes('history.back')) { 125 if (result.includes('history.back')) {
126 data.code = 400; 126 data.code = 400;
@@ -281,9 +281,8 @@ const setNewPasswordByMobileAPI = (req, res, next) => { @@ -281,9 +281,8 @@ const setNewPasswordByMobileAPI = (req, res, next) => {
281 let areaCode = req.body.areaCode || '86'; 281 let areaCode = req.body.areaCode || '86';
282 let newPwd = req.body.password || ''; 282 let newPwd = req.body.password || '';
283 283
284 - service.modifyPasswordByMobileAsync(phoneNum, token, newPwd, areaCode) 284 + service.modifyPasswordByMobileAsyncAes(phoneNum, token, newPwd, areaCode)
285 .then(result => { 285 .then(result => {
286 - console.log(result);  
287 if (result.code === 200) { 286 if (result.code === 200) {
288 res.json({ 287 res.json({
289 code: 200, 288 code: 200,
@@ -35,7 +35,7 @@ const bind = { @@ -35,7 +35,7 @@ const bind = {
35 35
36 res.render('bind/index', { 36 res.render('bind/index', {
37 bindIndex: true, // js标识 37 bindIndex: true, // js标识
38 - backUrl: helpers.urlFormat('/signin.html'), // 返回的URL链接 38 + backUrl: helpers.urlFormat('passport/login'), // 返回的URL链接
39 showHeaderImg: true, // 控制显示头部图片 39 showHeaderImg: true, // 控制显示头部图片
40 isPassportPage: true, // 模板中模块标识 40 isPassportPage: true, // 模板中模块标识
41 sourceType: sourceType, // 第三方登录来源 41 sourceType: sourceType, // 第三方登录来源
@@ -59,7 +59,7 @@ const bind = { @@ -59,7 +59,7 @@ const bind = {
59 let phoneNum = req.query.phoneNum; 59 let phoneNum = req.query.phoneNum;
60 60
61 res.render('bind/code', { 61 res.render('bind/code', {
62 - backUrl: helpers.urlFormat('/signin.html'), 62 + backUrl: helpers.urlFormat('passport/login'),
63 showHeaderImg: true, 63 showHeaderImg: true,
64 isPassportPage: true, 64 isPassportPage: true,
65 sourceType: sourceType, 65 sourceType: sourceType,
@@ -168,12 +168,16 @@ const bind = { @@ -168,12 +168,16 @@ const bind = {
168 }).then(result => { 168 }).then(result => {
169 let refer = req.cookies.refer; 169 let refer = req.cookies.refer;
170 170
171 - refer = refer ? decodeURI(refer) : helpers.urlFormat(); 171 + refer = refer ? decodeURI(refer) : helpers.urlFormat('/passport/bind/success?type=bind');
172 if (result && result.code && result.code === 200 && result.data.uid) { 172 if (result && result.code && result.code === 200 && result.data.uid) {
173 - AuthHelper.syncUserSession(result.data.uid, req, res);  
174 - result.data.refer = refer; 173 + return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
  174 + result.data.refer = refer;
  175 + return result;
  176 + });
  177 + } else {
  178 + return { code: 400, message: '绑定失败', data: '' };
175 } 179 }
176 - return result; 180 +
177 }).then(result => { 181 }).then(result => {
178 res.json(result); 182 res.json(result);
179 }).catch(next); 183 }).catch(next);
@@ -200,10 +204,14 @@ const bind = { @@ -200,10 +204,14 @@ const bind = {
200 let refer = helpers.urlFormat('/passport/bind/success', { sourceType: sourceType }); 204 let refer = helpers.urlFormat('/passport/bind/success', { sourceType: sourceType });
201 205
202 if (result && result.code && result.code === 200 && result.data.uid) { 206 if (result && result.code && result.code === 200 && result.data.uid) {
203 - AuthHelper.syncUserSession(result.data.uid, req, res);  
204 - result.data.refer = refer; 207 + return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
  208 + result.data.refer = refer;
  209 + return result;
  210 + });
  211 + } else {
  212 + return { code: 400, message: '关联失败', data: '' };
205 } 213 }
206 - return result; 214 +
207 }).then(result => { 215 }).then(result => {
208 res.json(result); 216 res.json(result);
209 }).catch(next); 217 }).catch(next);
@@ -212,11 +220,38 @@ const bind = { @@ -212,11 +220,38 @@ const bind = {
212 } 220 }
213 }, 221 },
214 222
  223 + passwordPage: (req, res) => {
  224 + let openId = req.query.openId;
  225 + let sourceType = req.query.sourceType;
  226 + let areaCode = req.query.areaCode || '86';
  227 + let phoneNum = req.query.phoneNum;
  228 + let code = req.query.code;
  229 +
  230 + res.render('bind/password', {
  231 + module: 'passport',
  232 + page: 'bind-password',
  233 + bindPwd: true, // js标识
  234 + backUrl: helpers.urlFormat('/passport/login'), // 返回的URL链接
  235 + showHeaderImg: true, // 控制显示头部图片
  236 + isPassportPage: true, // 模板中模块标识
  237 + sourceType: sourceType, // 第三方登录来源
  238 + openId: openId, // openId
  239 + areaCode: areaCode, // 国别码
  240 + phoneNum: phoneNum, // 国别码
  241 + code: code // 验证码
  242 + });
  243 + },
  244 +
215 successPage: (req, res) => { 245 successPage: (req, res) => {
  246 + let refer = req.cookies.refer;
  247 + let type = req.query.type;
  248 +
  249 + refer = refer ? decodeURI(refer) : helpers.urlFormat('/?go=1');
  250 +
216 res.render('bind/success', { 251 res.render('bind/success', {
217 isPassportPage: true, 252 isPassportPage: true,
218 - successTip: '恭喜您,第三方账号关联手机号码成功!',  
219 - goUrl: helpers.urlFormat(), 253 + successTip: type === 'bind' ? '恭喜您,第三方账号绑定手机号码成功!' : '恭喜您,第三方账号关联手机号码成功!',
  254 + goUrl: refer,
220 module: 'passport', 255 module: 'passport',
221 page: 'bind-success', 256 page: 'bind-success',
222 title: '绑定手机号' 257 title: '绑定手机号'
@@ -14,7 +14,7 @@ const log = global.yoho.logger; @@ -14,7 +14,7 @@ const log = global.yoho.logger;
14 const config = global.yoho.config; 14 const config = global.yoho.config;
15 const AuthHelper = require('../models/auth-helper'); 15 const AuthHelper = require('../models/auth-helper');
16 16
17 -const loginPage = `${config.siteUrl}/passport/login/index`; 17 +const loginPage = `${config.siteUrl}/passport/login`;
18 18
19 function doPassportCallback(openId, nickname, sourceType, req, res) { 19 function doPassportCallback(openId, nickname, sourceType, req, res) {
20 let shoppingKey = cookie.getShoppingKey(req); 20 let shoppingKey = cookie.getShoppingKey(req);
@@ -45,6 +45,8 @@ function doPassportCallback(openId, nickname, sourceType, req, res) { @@ -45,6 +45,8 @@ function doPassportCallback(openId, nickname, sourceType, req, res) {
45 }).then((redirectTo) => { 45 }).then((redirectTo) => {
46 return res.redirect(redirectTo); 46 return res.redirect(redirectTo);
47 }); 47 });
  48 + } else {
  49 + return Promise.reject('missing third party login openId or nickname');
48 } 50 }
49 } 51 }
50 52
@@ -55,7 +57,7 @@ const common = { @@ -55,7 +57,7 @@ const common = {
55 if (!refer) { 57 if (!refer) {
56 refer = req.get('Referer'); 58 refer = req.get('Referer');
57 } 59 }
58 - refer && !/signin|login/.test(refer) && res.cookie('refer', encodeURI(refer), { 60 + refer && !/signin|login|passport/.test(refer) && res.cookie('refer', encodeURI(refer), {
59 domain: 'yohobuy.com' 61 domain: 'yohobuy.com'
60 }); 62 });
61 next(); 63 next();
@@ -64,19 +66,30 @@ const common = { @@ -64,19 +66,30 @@ const common = {
64 66
65 const local = { 67 const local = {
66 loginPage: (req, res) => { 68 loginPage: (req, res) => {
  69 + // 先清除cookie
  70 + res.clearCookie('LE' + md5('_LOGIN_EXPIRE'), {
  71 + domain: 'yohobuy.com'
  72 + });
  73 +
67 // 设置登录有效时间30分钟, 防机器刷,cache不稳定,改为cookie 74 // 设置登录有效时间30分钟, 防机器刷,cache不稳定,改为cookie
68 res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800); 75 res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800);
69 76
70 // 清除cookie 77 // 清除cookie
71 - res.clearCookie('_UID');  
72 - res.clearCookie('_TOKEN'); 78 + res.clearCookie('_UID', {
  79 + domain: 'yohobuy.com'
  80 + });
  81 + res.clearCookie('_TOKEN', {
  82 + domain: 'yohobuy.com'
  83 + });
73 84
74 res.render('login', { 85 res.render('login', {
75 loginIndex: true, // 模板中使用JS的标识 86 loginIndex: true, // 模板中使用JS的标识
76 - backUrl: 'javascript:history.go(-1)', // eslint-disable-line // 返回的URL链接 87 +
  88 + // 返回的URL链接
  89 + backUrl: 'javascript:history.go(-1)', // eslint-disable-line
77 showHeaderImg: true, // 控制显示头部图片 90 showHeaderImg: true, // 控制显示头部图片
78 isPassportPage: true, // 模板中模块标识 91 isPassportPage: true, // 模板中模块标识
79 - registerUrl: '/reg.html', // 注册的URL链接 92 + registerUrl: '/passport/reg/index', // 注册的URL链接
80 aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接 93 aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接
81 weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接 94 weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接
82 qqLoginUrl: '/passport/login/qq', // 腾讯QQ登录的URL链接 95 qqLoginUrl: '/passport/login/qq', // 腾讯QQ登录的URL链接
@@ -203,8 +216,9 @@ const qq = { @@ -203,8 +216,9 @@ const qq = {
203 log.error(`qq authenticate error : ${JSON.stringify(err)}`); 216 log.error(`qq authenticate error : ${JSON.stringify(err)}`);
204 return res.redirect(loginPage); 217 return res.redirect(loginPage);
205 } 218 }
  219 +
206 let nickname = user.nickname; 220 let nickname = user.nickname;
207 - let openId = user.openid; 221 + let openId = user.id;
208 222
209 doPassportCallback(openId, nickname, 'qq', req, res).catch(next); 223 doPassportCallback(openId, nickname, 'qq', req, res).catch(next);
210 })(req, res, next); 224 })(req, res, next);
@@ -26,7 +26,7 @@ let index = (req, res) => { @@ -26,7 +26,7 @@ let index = (req, res) => {
26 26
27 res.render('reg/index', { 27 res.render('reg/index', {
28 title: '注册', 28 title: '注册',
29 - backUrl: 'javascript:history.go(-1)', // eslint-disable-line 29 + backUrl: 'javascript:history.go(-1)', // eslint-disable-line
30 headerText: '注册', // 头部信息 30 headerText: '注册', // 头部信息
31 isPassportPage: true, // 模板中模块标识 31 isPassportPage: true, // 模板中模块标识
32 areaCode: '+86', // 默认的区号 32 areaCode: '+86', // 默认的区号
@@ -235,14 +235,13 @@ let setPassword = (req, res, next) => { @@ -235,14 +235,13 @@ let setPassword = (req, res, next) => {
235 let shoppingKey = cookie.getShoppingKey(req); 235 let shoppingKey = cookie.getShoppingKey(req);
236 236
237 // 验证注册的标识码是否有效 237 // 验证注册的标识码是否有效
238 - RegService.regMobile(area, mobile, password, shoppingKey).then((result) => { 238 + RegService.regMobileAes(area, mobile, password, shoppingKey).then((result) => {
239 if (!result.code || result.code !== 200) { 239 if (!result.code || result.code !== 200) {
240 return Promise.reject(result); 240 return Promise.reject(result);
241 } 241 }
242 if (!result.data || !result.data.uid) { 242 if (!result.data || !result.data.uid) {
243 return Promise.reject(result); 243 return Promise.reject(result);
244 } 244 }
245 -  
246 return AuthHelper.syncUserSession(result.data.uid, req, res); 245 return AuthHelper.syncUserSession(result.data.uid, req, res);
247 }).then(() => { 246 }).then(() => {
248 // 返回跳转到来源页面 247 // 返回跳转到来源页面
  1 +/**
  2 + * 登录注册密码加密
  3 + * @author: wsl<shuiling.wang@yoho.cn>
  4 + * @date: 2016/07/07
  5 + */
  6 +
  7 +'use strict';
  8 +
  9 +const crypto = require('crypto');
  10 +
  11 +const aesPwd = (pwd) => {
  12 + let algorithm = 'aes-128-ecb';
  13 + let key = 'yoho9646yoho9646';
  14 + let clearEncoding = 'utf8';
  15 + let cipherEncoding = 'base64';
  16 + let iv = '';
  17 + let cipher = crypto.createCipheriv(algorithm, key, iv);
  18 + let cipherChunks = [];
  19 +
  20 + cipherChunks.push(cipher.update(pwd, clearEncoding, cipherEncoding));
  21 + cipherChunks.push(cipher.final(cipherEncoding));
  22 +
  23 + return cipherChunks.join('');
  24 +};
  25 +
  26 +module.exports = {
  27 + aesPwd
  28 +};
1 'use strict'; 1 'use strict';
2 - 2 +const aes = require('./aes-pwd');
3 const sign = global.yoho.sign; 3 const sign = global.yoho.sign;
4 const api = global.yoho.API; 4 const api = global.yoho.API;
5 5
@@ -20,6 +20,21 @@ class Auth { @@ -20,6 +20,21 @@ class Auth {
20 return api.post('', param); 20 return api.post('', param);
21 } 21 }
22 22
  23 + static signinAes(area, profile, password, shoppingKey) {
  24 + let param = {
  25 + method: 'app.passport.signinAES',
  26 + area: area,
  27 + profile: profile,
  28 + password: aes.aesPwd(password)
  29 + };
  30 +
  31 + if (shoppingKey) {
  32 + param.shopping_key = shoppingKey;
  33 + }
  34 +
  35 + return api.post('', param);
  36 + }
  37 +
23 static signinByOpenID(nickname, openId, sourceType, shoppingKey) { 38 static signinByOpenID(nickname, openId, sourceType, shoppingKey) {
24 let param = { 39 let param = {
25 nickname: nickname, 40 nickname: nickname,
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 6
7 7
8 const api = global.yoho.API; 8 const api = global.yoho.API;
  9 +const aes = require('./aes-pwd');
9 10
10 const YOHOBUY_URL = 'http://www.yohobuy.com/'; 11 const YOHOBUY_URL = 'http://www.yohobuy.com/';
11 12
@@ -66,6 +67,20 @@ const modifyPasswordByEmailAsync = (pwd, code) => { @@ -66,6 +67,20 @@ const modifyPasswordByEmailAsync = (pwd, code) => {
66 }; 67 };
67 68
68 /** 69 /**
  70 + * 根据邮箱验证码修改密码(调用新接口 采用AES密码加密)
  71 + *
  72 + * @param string pwd 新密码
  73 + * @param string code 邮箱验证码
  74 + */
  75 +const modifyPasswordByEmailAsyncAes = (pwd, code) => {
  76 + return api.get('', {
  77 + code: code,
  78 + newPwd: aes.aesPwd(pwd),
  79 + method: 'app.register.resetPwdByCodeAES'
  80 + });
  81 +};
  82 +
  83 +/**
69 * 通过手机找回密码 84 * 通过手机找回密码
70 * 85 *
71 * @param string mobile 手机号 86 * @param string mobile 手机号
@@ -113,12 +128,24 @@ const modifyPasswordByMobileAsync = (mobile, token, newpwd, area) => { @@ -113,12 +128,24 @@ const modifyPasswordByMobileAsync = (mobile, token, newpwd, area) => {
113 }); 128 });
114 }; 129 };
115 130
  131 +const modifyPasswordByMobileAsyncAes = (mobile, token, newpwd, area) => {
  132 + return api.get('', {
  133 + mobile: mobile,
  134 + token: token,
  135 + newpwd: aes.aesPwd(newpwd),
  136 + area: area,
  137 + method: 'app.register.changepwdByMobileCodeAES'
  138 + });
  139 +};
  140 +
116 module.exports = { 141 module.exports = {
117 getAreaDataAsync, 142 getAreaDataAsync,
118 sendCodeToEmailAsync, 143 sendCodeToEmailAsync,
119 modifyPasswordByEmailAsync, 144 modifyPasswordByEmailAsync,
  145 + modifyPasswordByEmailAsyncAes,
120 sendCodeToMobileAsync, 146 sendCodeToMobileAsync,
121 validateMobileCodeAsync, 147 validateMobileCodeAsync,
122 - modifyPasswordByMobileAsync 148 + modifyPasswordByMobileAsync,
  149 + modifyPasswordByMobileAsyncAes
123 }; 150 };
124 151
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 const util = require('util'); 9 const util = require('util');
10 const _ = require('lodash'); 10 const _ = require('lodash');
11 const md5 = require('md5'); 11 const md5 = require('md5');
12 -const Strategy = require('passport-strategy'); 12 +const passport = require('passport-strategy');
13 13
14 // 支付宝网关地址 14 // 支付宝网关地址
15 const ALIPAY_URL = 'https://mapi.alipay.com/gateway.do'; 15 const ALIPAY_URL = 'https://mapi.alipay.com/gateway.do';
@@ -30,52 +30,50 @@ function paramsToRaw(params) { @@ -30,52 +30,50 @@ function paramsToRaw(params) {
30 let keys = Object.keys(params); 30 let keys = Object.keys(params);
31 31
32 keys = keys.sort(); 32 keys = keys.sort();
33 - let newArgs = {}; 33 + let string = '';
34 34
35 keys.forEach((key) => { 35 keys.forEach((key) => {
36 - newArgs[key] = params[key]; 36 + string += '&' + key + '=' + params[key];
37 }); 37 });
38 38
39 - let string = '';  
40 -  
41 - for (let k of newArgs) {  
42 - string += '&' + k + '=' + newArgs[k];  
43 - }  
44 string = string.substr(1); 39 string = string.substr(1);
45 return string; 40 return string;
46 } 41 }
47 42
48 -function AlipayStrategy(options) {  
49 - Strategy.call(this); 43 +function AlipayStrategy(options, verify) {
  44 + if (typeof options === 'function') {
  45 + verify = options;
  46 + options = {};
  47 + }
  48 + options = options || {};
  49 + passport.Strategy.call(this);
50 this.name = 'alipay'; 50 this.name = 'alipay';
51 - this._passReqToCallback = options.passReqToCallback; 51 + this._verify = verify;
  52 + this._options = options;
52 } 53 }
53 54
54 -util.inherits(AlipayStrategy, Strategy); 55 +util.inherits(AlipayStrategy, passport.Strategy);
55 56
56 -AlipayStrategy.prototype.authenticate = (req, options) => {  
57 - if (req.query && req.query.is_success && req.query.sign && req.query.sign_type) {  
58 -  
59 - // sign check 57 +AlipayStrategy.prototype.authenticate = function(req, options) {
60 58
  59 + if (req.query && req.query.is_success && req.query.sign && req.query.sign_type) {
61 let query = req.query; 60 let query = req.query;
62 let sign = query.sign; 61 let sign = query.sign;
63 let signType = query.sign_type; 62 let signType = query.sign_type;
64 63
65 delete query.sign_type; 64 delete query.sign_type;
66 delete query.sign; 65 delete query.sign;
67 - let signString = paramsToRaw(query) + options.key; 66 + let signString = paramsToRaw(query) + this._options.key;
68 67
69 if (signType === 'MD5' && sign !== md5(signString)) { 68 if (signType === 'MD5' && sign !== md5(signString)) {
70 this.error('alipay callback sign check fail'); 69 this.error('alipay callback sign check fail');
71 this.fail('alipay callback sign check fail'); 70 this.fail('alipay callback sign check fail');
72 - return;  
73 } 71 }
74 72
75 if (req.query.is_success === 'T') { 73 if (req.query.is_success === 'T') {
76 let user = { 74 let user = {
77 userId: req.query.user_id, 75 userId: req.query.user_id,
78 - realName: req.query.realName, 76 + realName: req.query.real_name,
79 email: req.query.email 77 email: req.query.email
80 }; 78 };
81 79
@@ -85,12 +83,14 @@ AlipayStrategy.prototype.authenticate = (req, options) => { @@ -85,12 +83,14 @@ AlipayStrategy.prototype.authenticate = (req, options) => {
85 this.fail(req.error_code); 83 this.fail(req.error_code);
86 } 84 }
87 } else { 85 } else {
88 - let params = _.extends(defaultOptions, options); 86 + let params = _.assign(defaultOptions, this._options, options);
89 let signType = params.sign_type; 87 let signType = params.sign_type;
  88 + let key = params.key;
90 89
91 delete params.sign_type; 90 delete params.sign_type;
92 delete params.sign; 91 delete params.sign;
93 - let signString = paramsToRaw(params) + options.key; 92 + delete params.key;
  93 + let signString = paramsToRaw(params) + key;
94 94
95 if (signType === 'MD5') { 95 if (signType === 'MD5') {
96 params.sign = md5(signString); 96 params.sign = md5(signString);
@@ -101,4 +101,7 @@ AlipayStrategy.prototype.authenticate = (req, options) => { @@ -101,4 +101,7 @@ AlipayStrategy.prototype.authenticate = (req, options) => {
101 } 101 }
102 }; 102 };
103 103
104 -module.exports.Strategy = AlipayStrategy; 104 +exports = module.exports = AlipayStrategy;
  105 +
  106 +exports.Strategy = AlipayStrategy;
  107 +
@@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
8 'use strict'; 8 'use strict';
9 9
10 const api = global.yoho.API; 10 const api = global.yoho.API;
  11 +const aes = require('./aes-pwd');
11 12
12 const RegService = { 13 const RegService = {
13 getAreaData() { 14 getAreaData() {
@@ -94,6 +95,20 @@ const RegService = { @@ -94,6 +95,20 @@ const RegService = {
94 } 95 }
95 96
96 return api.post('', params); 97 return api.post('', params);
  98 + },
  99 + regMobileAes(area, mobile, password, shoppingKey) {
  100 + let params = {
  101 + method: 'app.passport.registerAES',
  102 + area: area,
  103 + profile: mobile,
  104 + password: aes.aesPwd(password)
  105 + };
  106 +
  107 + if (shoppingKey) {
  108 + params.shopping_key = shoppingKey;
  109 + }
  110 +
  111 + return api.post('', params);
97 } 112 }
98 }; 113 };
99 114
@@ -37,6 +37,10 @@ router.get('/login/sina/callback', login.sina.callback); @@ -37,6 +37,10 @@ router.get('/login/sina/callback', login.sina.callback);
37 router.get('/login/qq', login.common.beforeLogin, login.qq.login); 37 router.get('/login/qq', login.common.beforeLogin, login.qq.login);
38 router.get('/login/qq/callback', login.qq.callback); 38 router.get('/login/qq/callback', login.qq.callback);
39 39
  40 +// 支付宝登录
  41 +router.get('/login/alipay', login.common.beforeLogin, login.alipay.login);
  42 +router.get('/login/alipay/callback', login.alipay.callback);
  43 +
40 // 登录绑定 44 // 登录绑定
41 router.get('/bind/index', bind.indexPage); 45 router.get('/bind/index', bind.indexPage);
42 router.post('/bind/bindCheck', bind.bindCheck); 46 router.post('/bind/bindCheck', bind.bindCheck);
@@ -45,6 +49,7 @@ router.post('/bind/sendBindMsg', bind.sendBindMsg); @@ -45,6 +49,7 @@ router.post('/bind/sendBindMsg', bind.sendBindMsg);
45 router.post('/bind/bindMobile', bind.bindMobile); 49 router.post('/bind/bindMobile', bind.bindMobile);
46 50
47 router.post('/bind/relateMobile', bind.relateMobile); 51 router.post('/bind/relateMobile', bind.relateMobile);
  52 +router.get('/bind/password', bind.passwordPage);
48 router.get('/bind/success', bind.successPage); 53 router.get('/bind/success', bind.successPage);
49 54
50 router.post('/bind/changeCheck', bind.changeCheck); 55 router.post('/bind/changeCheck', bind.changeCheck);
  1 +require('./bind/password');
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 * @author: xuqi<qi.xu@yoho.cn> 3 * @author: xuqi<qi.xu@yoho.cn>
4 * @date: 2015/10/8 4 * @date: 2015/10/8
5 */ 5 */
6 -var $ = require('jquery'); 6 +var $ = require('yoho-jquery');
7 7
8 var $pwd = $('#pwd'), 8 var $pwd = $('#pwd'),
9 $btnSure = $('#btn-sure'); 9 $btnSure = $('#btn-sure');
@@ -14,8 +14,7 @@ var tip = require('../../plugin/tip'); @@ -14,8 +14,7 @@ var tip = require('../../plugin/tip');
14 var trim = $.trim; 14 var trim = $.trim;
15 var showErrTip = tip.show; 15 var showErrTip = tip.show;
16 16
17 -var nickname = $('#nickname').val(),  
18 - sourceType = $('#sourceType').val(), 17 +var sourceType = $('#sourceType').val(),
19 openId = $('#openId').val(), 18 openId = $('#openId').val(),
20 phoneNum = $('#phone-num').val(), 19 phoneNum = $('#phone-num').val(),
21 areaCode = $('#area-code').val().replace('+', ''), 20 areaCode = $('#area-code').val().replace('+', ''),
@@ -30,7 +29,6 @@ function startBind(password) { @@ -30,7 +29,6 @@ function startBind(password) {
30 phoneNum: phoneNum, 29 phoneNum: phoneNum,
31 openId: openId, 30 openId: openId,
32 sourceType: sourceType, 31 sourceType: sourceType,
33 - nickname: nickname,  
34 password: password, 32 password: password,
35 code: code 33 code: code
36 }, 34 },
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 @import "channel/index"; 9 @import "channel/index";
10 @import "product/index"; 10 @import "product/index";
11 @import "activity/index"; 11 @import "activity/index";
12 -  
13 -/* @import "passport/index"; */ 12 +@import "passport/index";
14 @import "guang/index"; 13 @import "guang/index";
15 @import "cart/chose-panel"; 14 @import "cart/chose-panel";
  15 +@import "me/index";
  1 +@import 'suggest';
  1 +.yoho-suggest-page {
  2 + width: 100%;
  3 + height: auto;
  4 +
  5 + /* 意见反馈头部 */
  6 + .suggest-header {
  7 + text-align: center;
  8 + color: #fff;
  9 + font-size: 26px;
  10 + line-height: 46px;
  11 + overflow: hidden;
  12 + padding-bottom: 20px;
  13 + background-image: linear-gradient(#383838, #505050);
  14 +
  15 + &:before {
  16 + content: '';
  17 + display: block;
  18 + background: url("/me/suggest/suggest-logo.png");
  19 + width: 104px;
  20 + height: 35px;
  21 + margin: 10px auto 15px;
  22 + }
  23 + }
  24 +
  25 + /* 意见反馈主体 */
  26 + .suggest-content {
  27 + border-top: 1px solid #e0e0e0;
  28 + }
  29 +
  30 + .suggest-item {
  31 + width: 100%;
  32 + color: #444;
  33 + border-top: 1px solid #e0e0e0;
  34 + border-bottom: 30px solid #f0f0f0;
  35 + overflow: hidden;
  36 +
  37 + .suggest-item-img {
  38 + width: 100%;
  39 + overflow: hidden;
  40 + > img {
  41 + margin: 0 auto;
  42 + display: block;
  43 + max-width: 100%;
  44 + }
  45 + }
  46 +
  47 + > h2 {
  48 + font-size: 38px;
  49 + margin: 30px 0 31px;
  50 + padding: 0 35px;
  51 + }
  52 +
  53 + > p {
  54 + font-size: 26px;
  55 + line-height: 48px;
  56 + padding: 0 35px;
  57 + }
  58 + }
  59 +
  60 + .suggest-type {
  61 + margin-top: 29px - 11px;
  62 + height: 88px;
  63 + line-height: 88px;
  64 + border-top: 1px solid #e0e0e0;
  65 + border-bottom: 1px solid #e0e0e0;
  66 + color: #b0b0b0;
  67 + font-size: 26px;
  68 + display: none;
  69 + text-align: center;
  70 +
  71 + > .active {
  72 + color: #444;
  73 + }
  74 +
  75 + &.show {
  76 + display: block;
  77 + }
  78 + }
  79 +
  80 + .suggest-active {
  81 + > div {
  82 + width: 50%;
  83 + height: 100%;
  84 + float: left;
  85 + text-align: left;
  86 + padding-left: 128px;
  87 + box-sizing: border-box;
  88 + }
  89 +
  90 + > div:nth-last-of-type(1) {
  91 + padding-left: 0;
  92 + padding-right: 128px;
  93 + text-align: right;
  94 + float: right;
  95 +
  96 + > span {
  97 +
  98 + display: inline-block;
  99 + height: 100%;
  100 + overflow: hidden;
  101 +
  102 + &:nth-of-type(1) {
  103 + transform: rotate(180deg);
  104 + }
  105 + }
  106 + }
  107 + }
  108 +
  109 + .suggest-bad {
  110 + > div {
  111 + > span {
  112 + display: inline-block;
  113 + height: 100%;
  114 + overflow: hidden;
  115 +
  116 + &:nth-of-type(1) {
  117 + transform: rotate(180deg);
  118 + }
  119 + }
  120 + }
  121 + }
  122 +
  123 + /* 发表意见 */
  124 + .create-new-suggest {
  125 + display: block;
  126 + width: 100%;
  127 + height: 88px;
  128 + line-height: 88px;
  129 + text-align: center;
  130 + font-size: 30px;
  131 + border-top: 30px solid #f0f0f0;
  132 + border-bottom: 30px solid #f0f0f0;
  133 + position: relative;
  134 +
  135 + .list-item {
  136 + padding: 0 35px;
  137 + }
  138 + .new-right {
  139 + float: right;
  140 + margin-left: 40px;
  141 + color: #e0e0e0;
  142 + }
  143 +
  144 + a {
  145 + color: #444;
  146 + display: inline-block;
  147 + }
  148 +
  149 + }
  150 +}
  151 +
  152 +/* 提交页面 */
  153 +.yoho-suggest-sub-page {
  154 + width: 100%;
  155 + background: #f0f0f0;
  156 +
  157 + .suggest-sub-form {
  158 + background: #fff;
  159 + width: 100%;
  160 +
  161 + #suggest-textarea {
  162 + box-sizing: border-box;
  163 + width: 100%;
  164 + max-width: 100%;
  165 + min-width: 100%;
  166 + height: 255px;
  167 + max-height: 255px;
  168 + min-height: 255px;
  169 + padding: 30px;
  170 + font-size: 26px;
  171 + line-height: 48px;
  172 + color: #000;
  173 + display: block;
  174 + background: #fff;
  175 + border: none;
  176 + outline: none;
  177 + resize: none;
  178 + }
  179 + }
  180 +
  181 + .img-form {
  182 + padding: 0 30px;
  183 + padding-top: 40px;
  184 + overflow: hidden;
  185 +
  186 + .upload-img-list {
  187 + float: left;
  188 +
  189 + > li {
  190 + display: block;
  191 + width: 130px;
  192 + height: 130px;
  193 + float: left;
  194 + margin-right: 30px;
  195 + background: resolve('common/loading.gif') center center no-repeat;
  196 + background-size: 50%;
  197 + position: relative;
  198 +
  199 + > img {
  200 + display: block;
  201 + width: 100%;
  202 + height: 100%;
  203 + overflow: hidden;
  204 + }
  205 +
  206 + > span {
  207 + display: block;
  208 + background: url("/me/suggest/sub_del.png");
  209 + width: 42px;
  210 + height: 42px;
  211 +
  212 + position: absolute;
  213 + top: -21px;
  214 + right: -21px;
  215 +
  216 + }
  217 + }
  218 + }
  219 +
  220 + .img-add {
  221 + display: block;
  222 + width: 130px;
  223 + height: 130px;
  224 + border: 1px dashed #e0e0e0;
  225 + position: relative;
  226 + text-indent: -1000px;
  227 + float: left;
  228 +
  229 + &:after {
  230 + content: '';
  231 + display: block;
  232 + background: url("/me/suggest/suggest-add.png");
  233 + width: 72px;
  234 + height: 72px;
  235 +
  236 + position: absolute;
  237 + top: 50%;
  238 + left: 50%;
  239 + margin-top: -36px;
  240 + margin-left: -36px;
  241 + }
  242 +
  243 + input[type="file"] {
  244 + position: absolute;
  245 + opacity: 0.2;
  246 + border: none;
  247 + outline: none;
  248 + display: block;
  249 +
  250 + width: 130px;
  251 + height: 130px;
  252 +
  253 + top: 0;
  254 + left: 0;
  255 + }
  256 + }
  257 + }
  258 +}
  259 +
  260 +/* dialog */
  261 +.dialog-wrapper {
  262 + background: hsla(0, 0%, 0%, 0.5);
  263 + position: fixed;
  264 + top: 0;
  265 + right: 0;
  266 + bottom: 0;
  267 + left: 0;
  268 + display: none;
  269 +
  270 + .dialog-box {
  271 + width: 540px;
  272 + border-radius: 20px;
  273 + background: hsla(100, 100%, 100%, 0.8);
  274 + position: absolute;
  275 + left: 50%;
  276 + margin-left: -270px;
  277 + font-size: 30px;
  278 + text-align: center;
  279 + color: #000;
  280 + }
  281 +
  282 + .dialog-content {
  283 + padding: 60px 30px;
  284 + }
  285 +
  286 + .dialog-footer {
  287 + border-top: 1px solid #ccc;
  288 + height: 88px;
  289 + line-height: 88px;
  290 +
  291 + > span {
  292 + display: block;
  293 + width: 50%;
  294 + height: 100%;
  295 + float: left;
  296 + box-sizing: border-box;
  297 +
  298 + &:nth-last-of-type(1) {
  299 + border-left: 1px solid #ccc;
  300 + color: #e01;
  301 + }
  302 + }
  303 +
  304 + > span:active {
  305 + background-color: #ccc;
  306 + }
  307 + }
  308 +}
@@ -79,6 +79,8 @@ body.passport-body { @@ -79,6 +79,8 @@ body.passport-body {
79 border-radius: 5PX; 79 border-radius: 5PX;
80 appearance: none; 80 appearance: none;
81 direction: rtl; 81 direction: rtl;
  82 + -webkit-appearance: none;
  83 +
82 &:focus { 84 &:focus {
83 outline: 0; 85 outline: 0;
84 border: none; 86 border: none;
@@ -2,28 +2,28 @@ @@ -2,28 +2,28 @@
2 color: #fefefe; 2 color: #fefefe;
3 3
4 .success-icon { 4 .success-icon {
5 - width: 74px;  
6 - height: 74px;  
7 - margin: 60px auto 30px; 5 + width: 74PX;
  6 + height: 74PX;
  7 + margin: 60PX auto 30PX;
8 background: resolve("passport/success.png"); 8 background: resolve("passport/success.png");
9 background-size: 100%; 9 background-size: 100%;
10 } 10 }
11 11
12 .success-tip { 12 .success-tip {
13 - padding: 10px;  
14 - font-size: 16px; 13 + padding: 10PX;
  14 + font-size: 16PX;
15 line-height: 1.5; 15 line-height: 1.5;
16 } 16 }
17 17
18 .go { 18 .go {
19 display: block; 19 display: block;
20 - margin: 30px auto;  
21 - width: 270px;  
22 - height: 40px;  
23 - font-size: 14px;  
24 - line-height: 40px; 20 + margin: 30PX auto;
  21 + width: 270PX;
  22 + height: 40PX;
  23 + font-size: 14PX;
  24 + line-height: 40PX;
25 color: #fff; 25 color: #fff;
26 background: rgba(255, 255, 255, 0.4); 26 background: rgba(255, 255, 255, 0.4);
27 - border-radius: 5px; 27 + border-radius: 5PX;
28 } 28 }
29 } 29 }