login-service.js 4.52 KB
'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 authcode = require(`${global.utils}/authcode`);
const AUTH_TIME = 2592000000;

const Promise = require('bluebird');

const cartService = require('./cart-service');
const userService = require('./user-service');
const api = require('./login-api');
const logger = global.yoho.logger;

const signin = (type, area, profile, password, shoppingKey, clientIp) => {
    let loginBy = {
        password: api.signinByPasswordWithAes,
        sms: api.signinBySMS,
        qrcode: api.signinByQrCode
    };

    return loginBy[type](area, profile, password, shoppingKey, clientIp);
};

const syncUserSession = (user, req, res) => {
    let uid = user.uid;
    let sessionKey = user.session_key;

    if (sessionKey) {
        cache.set(`java_session_key:${uid}`, sessionKey).catch(() => {
            logger.error('write session key fail');
        });
    }

    let uidObj = {
        toString() {
            return this.uid;
        },
        uid: uid,
        sessionKey: sessionKey,
        isValid() {
            return this.uid && this.sessionKey;
        }
    };

    return Promise.all([
        userService.profile(uidObj),
        cartService.goodsCount(uidObj),
        userService.checkNoCertEmailUser(uidObj).catch(err => logger(`checkNoCertEmailUser${uid}err: ${err}`))
    ]).spread((userInfo, count, isTipCert) => {
        let salt = uuid.v4().substr(0, 8);
        let saltedUid = uid + salt;

        let saltedToken = sign.makeToken(saltedUid);
        let publicToken = saltedToken + salt;

        let data = userInfo.data;
        let encryptionUid = aes.encryptionUid(data.uid);

        if (data) {
            let uidCookie =
                `${encodeURIComponent(data.profile_name)}::${encryptionUid}::${data.vip_info.title}::${saltedToken}`;
            let isStudent = data.vip_info.is_student || 0;

            res.cookie('_UID', uidCookie, {
                domain: config.cookieDomain
            });
            res.cookie('isStudent', isStudent, {
                domain: config.cookieDomain
            });

            res.cookie('_SESSION_KEY', authcode(sessionKey, '_SESSION_KEY', AUTH_TIME, 'encode'), {
                domain: config.cookieDomain
            });

            // 购物车中商品的数量
            res.cookie('_g', JSON.stringify({
                _k: cookie.getShoppingKey(req),
                _nac: count,
                _ac: 0,
                _c: 1
            }), {
                domain: config.cookieDomain
            });
        }

        req.session.TOKEN_ = publicToken;
        req.session.LOGIN_UID_ = uid;

        res.cookie('_TOKEN', publicToken, {
            domain: config.cookieDomain,
            httpOnly: true
        });

        // 弱密码设置
        if (user.canSkip && user.token) {
            req.session.canSkip = user.canSkip;
            req.session.CSToken = user.token;
        } else {
            delete req.session.canSkip;
            delete req.session.CSToken;
        }

        if (isTipCert && isTipCert.code === 200 && isTipCert.data) {
            return isTipCert.data.isNeedPopupRelated === 'Y';
        }

    });
};

const rememberAccount = (accountInfo, req, res) => {
    let aWeek = (new Date()).getTime() / 1000 + 504000; // 504000-一周
    let rememKey = md5(md5(accountInfo.account + accountInfo.password + accountInfo.area));

    res.cookie('isRemember', true, {
        maxAge: aWeek,
        domain: config.cookieDomain
    });
    res.cookie('remem', rememKey, {
        maxAge: aWeek,
        domain: config.cookieDomain
    });

    // if (!cache.get(rememKey)) {
    //     cache.set(rememKey, accountInfo, aWeek);
    // }
};

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,
    checkByQrCode: api.checkByQrCode,
    sendPasswordBySMS: api.sendPasswordBySMS,
    checkUserExitBySMS: api.checkUserExitBySMS,
    verifyPasswordBySMS: api.verifyPasswordBySMS,
    signinByOpenID: api.signinByOpenID
};