/** * Created by yoho on 2016/11/23. */ 'use strict'; const _ = require('lodash'); const passport = require('passport'); const uuid = require('uuid'); const log = global.yoho.logger; const userModel = require('../models/user-service'); const config = global.yoho.config; const authcode = require(`${global.utils}/authcode`); const AUTH_TIME = 2592000000; const updateSessionKey = (res, sessionKey) => { if (sessionKey) { res.cookie('_SESSION_KEY', authcode(sessionKey, '_SESSION_KEY', AUTH_TIME, 'encode'), { domain: config.cookieDomain }); } }; function bindSuccess(res, type) { return res.render('home/user/bind-result', { module: 'home', page: 'bind-result', layout: false, type: type, bindResult: 'success', message: '绑定成功!' }); } function bindFail(res, message, type) { return res.render('home/user/bind-result', { module: 'home', page: 'bind-result', layout: false, type: type, bindResult: 'fail', bindResultMessage: message || '绑定失败,请稍后再试!' }); } const bind3party = (req, res, user) => { req.ctx(userModel).bind3partyAccount(req.user.uid, user) .then(ret => { if (ret && ret.code === 200) { updateSessionKey(res, _.get(ret, 'data.session_key', '')); return bindSuccess(res, user.sourceType); } return bindFail(res, ret && ret.message, user.sourceType); }) .catch(err => { return bindFail(res, err, user.sourceType); }); }; const wechat = { login: (req, res, next) => { req.session.authState = uuid.v4(); return passport.authenticate('home-wechat', { state: req.session.authState })(req, res, next); }, callback: (req, res, next) => { if (req.session && req.session.authState && req.session.authState === req.query.state) { passport.authenticate('home-wechat', (err, user) => { if (err) { log.error(`wechat authenticate error : ${JSON.stringify(err)}`); return bindFail(res, '微信登录失败,请稍后再试!', 'wechat'); } else { bind3party(req, res, { openId: user._json.unionid, // user._json.openid, unionId: user._json.unionid || user.id, nickname: user._json.nickname || user.displayName, sourceType: 'wechat', rawUser: user }); } })(req, res, next); } else { // return next(new Error('Wechat Auth State Mismatch')); return bindFail(res, '微信登录失败,请稍后再试!', 'wechat'); } } }; const sina = { login: (req, res, next) => { req.session.authState = uuid.v4(); return passport.authenticate('home-sina', { state: req.session.authState })(req, res, next); }, callback: (req, res, next) => { if (req.session && req.session.authState && req.session.authState === req.query.state) { passport.authenticate('home-sina', (err, user) => { if (err) { log.error(`sina authenticate error : ${JSON.stringify(err)}`); return bindFail(res, '新浪微博登录失败,请稍后再试!', 'sina'); } let nickname = _.trim(user.screen_name); let openId = user.id; bind3party(req, res, { openId: openId, nickname: nickname, sourceType: 'sina' }); })(req, res, next); } else { // return next(new Error('Sina Auth State Mismatch')); return bindFail(res, '微信登录失败,请稍后再试!', 'sina'); } } }; const qq = { login: (req, res, next) => { let type = req.query.type || 'yohobuy'; let authState = req.session.authState = (req.query.state || uuid.v4()) + '::' + type; return passport.authenticate('home-qq', { state: authState })(req, res, next); }, callback: (req, res, next) => { if (req.session && req.session.authState && req.session.authState === req.query.state) { passport.authenticate('home-qq', (err, user) => { if (err) { log.error(`qq authenticate error : ${JSON.stringify(err)}`); return bindFail(res, 'QQ登录失败,请稍后再试!', 'qq'); } let nickname = _.trim(user.nickname); let openId = user.id; bind3party(req, res, { openId: openId, nickname: nickname, sourceType: 'qq' }); })(req, res, next); } else { return bindFail(res, '微信登录失败,请稍后再试!', 'qq'); } } }; const alipay = { login: (req, res, next) => { return passport.authenticate('home-alipay')(req, res, next); }, callback: (req, res, next) => { passport.authenticate('home-alipay', (err, user) => { if (err) { log.error(`alipay authenticate error : ${JSON.stringify(err)}`); return bindFail(res, '支付宝登录失败,请稍后再试!', 'alipay'); } let nickname = _.trim(user.realName); let openId = user.userId; bind3party(req, res, { openId: openId, nickname: nickname, sourceType: 'alipay' }); })(req, res, next); } }; const douban = { login: (req, res, next) => { req.session.authState = uuid.v4() + '::bind'; return passport.authenticate('douban', { state: req.session.authState })(req, res, next); }, callback: (req, res, next) => { passport.authenticate('douban', (err, user) => { if (err) { log.error(`douban authenticate error : ${JSON.stringify(err)}`); return bindFail(res, '豆瓣登录失败,请稍后再试!', 'douban'); } let nickname = _.trim(user.displayName); let openId = user.id; bind3party(req, res, { openId: openId, nickname: nickname, sourceType: 'douban' }); })(req, res, next); } }; const renren = { login: (req, res, next) => { req.session.authState = uuid.v4(); return passport.authenticate('home-renren', { state: req.session.authState })(req, res, next); }, callback: (req, res, next) => { passport.authenticate('home-renren', (err, user) => { if (err) { log.error(`renren authenticate error : ${JSON.stringify(err)}`); return bindFail(res, '人人网登录失败,请稍后再试!', 'renren'); } let nickname = _.trim(user.displayName); let openId = user.id; bind3party(req, res, { openId: openId, nickname: nickname, sourceType: 'renren' }); })(req, res, next); } }; const cancelBind = (req, res) => { let type = req.params.type; if (!(req.get('Referer') || '').match(/yohobuy.com/)) { return res.send({ code: 501, message: '非法请求' }); } if (!type) { res.status(400).json({ code: 400, message: '解绑类型不正确!' }); } req.ctx(userModel).cancelBind3partyAccount(req.user.uid, type) .then(ret => { if (ret && ret.code === 200) { return res.send(ret); } return res.send({ code: 401 }); }) .catch(err => { res.send({ code: 401, message: err }); }); }; module.exports = { wechat: wechat, sina: sina, qq: qq, alipay: alipay, douban: douban, renren: renren, cancelBind, bindFail, bind3party };