Blame view

apps/passport/models/back-service.js 6.91 KB
htoooth authored
1 2 3 4 5 6
/**
 * Created by TaoHuang on 2016/6/14.
 */

'use strict';
htoooth authored
7
const Promise = require('bluebird');
htoooth authored
8 9 10
const co = Promise.coroutine;
const _ = require('lodash');
const moment = require('moment');
htoooth authored
11
htoooth authored
12
const helpers = global.yoho.helpers;
htoooth authored
13 14
const Api = require('./back-api');
const UserService = require('./user-service');
htoooth authored
15 16
const CaptchaImgService = require('./captcha-img-service');
王水玲 authored
17
const PassportHelper = require('./passport-helper');
htoooth authored
18
const backHelper = require('./back-helper');
htoooth authored
19
htoooth authored
20
const BACK_LEFT_BANNER_CODE = '3bbaf502c447a2ddad60879042e286d8'; // 找回密码左边的banner
htoooth authored
21
htoooth authored
22 23 24
module.exports = class extends global.yoho.BaseModel {
    constructor(ctx) {
        super(ctx);
htoooth authored
25
htoooth authored
26 27
        this.api = new Api(ctx);
        this.userService = new UserService(ctx);
htoooth authored
28
        this.captchaService = new CaptchaImgService(ctx);
王水玲 authored
29
        this.passportHelper = new PassportHelper(ctx);
htoooth authored
30
htoooth authored
31 32 33 34
        /**
         * 验证邮件验证码
         */
        this.checkEmailCodeAsync = this.api.checkEmailCodeAsync.bind(this.api);
htoooth authored
35
htoooth authored
36 37 38
        // 弱密码重置
        this.modPwdByCodeAsync = this.api.modPwdByCodeAsync.bind(this.api);
    }
htoooth authored
39
htoooth authored
40 41 42 43
    /**
     * 验证手机和邮箱输入正确性
     */
    validateEmailOrMobileAsync(userInput, areaCode) {
王水玲 authored
44 45
        let that = this;
htoooth authored
46 47 48
        return new Promise(function(resolve, rejected) {
            let result = {type: 'email', area: '', phone: ''};
王水玲 authored
49
            if (that.passportHelper.validator.isEmail(userInput)) {
htoooth authored
50 51 52 53 54
                result.type = 'email';
                result.area = '';
                result.phone = userInput;

                resolve(result);
王水玲 authored
55
            } else if (that.passportHelper.validator.isMobile(userInput)) {
htoooth authored
56 57 58 59 60 61 62 63
                result.type = 'mobile';
                result.area = areaCode;
                result.phone = userInput;

                resolve(result);
            } else {
                rejected('输入信息出错!');
            }
htoooth authored
64
htoooth authored
65
        });
htoooth authored
66
htoooth authored
67
    }
htoooth authored
68
htoooth authored
69 70 71 72 73 74 75 76 77
    /**
     * 查找用户
     */
    findUserAsync(type, phone, area) {
        return co(function* () {
            const MESSAGE = {
                mobile: '您输入的手机号码尚未注册!',
                email: '您输入的邮件账户尚未注册!',
                ok: '验证成功'
htoooth authored
78
            };
htoooth authored
79
htoooth authored
80 81 82 83
            const findBy = {
                email: this.userService.findByEmailAsync.bind(this.userService),
                mobile: _.rearg(this.userService.findByMobileAsync.bind(this.userService), [1, 0]) // 交换参数
            };
htoooth authored
84
htoooth authored
85
            const OK = {code: 200, message: MESSAGE.ok};
htoooth authored
86
htoooth authored
87
            const user = yield findBy[type](phone, area);
htoooth authored
88
htoooth authored
89 90 91 92 93
            if (_.isEmpty(user)) {
                return {
                    code: 402,
                    message: MESSAGE[type]
                };
htoooth authored
94
            }
htoooth authored
95 96 97 98 99 100 101 102

            return OK;
        }).bind(this)();
    }

    /**
     * 发送验证码到用户
     */
htoooth authored
103
    async sendCodeToUserAsync(type, mobile, areaCode, id, captcha) {
htoooth authored
104 105 106
        let sendTo = {
            email: this.api.sendCodeToEmailAsync.bind(this.api),
            mobile: this.api.sendCodeToMobileAsync.bind(this.api)
htoooth authored
107
        };
htoooth authored
108
htoooth authored
109 110 111 112 113 114
        let result = await sendTo[type](mobile, areaCode, id, captcha);
        let captchaNeeded = await this.captchaService.try();

        _.set(result, 'data.needCaptcha', captchaNeeded);

        return result;
htoooth authored
115
    }
htoooth authored
116
htoooth authored
117 118 119
    /**
     * 发送找回手机号短信
     */
htoooth authored
120 121
    async sendCodeToMobileAsync(areaCode, mobile, id, captcha) {
        let result = await this.api.sendCodeToMobileAsync(mobile, areaCode, id, captcha);
htoooth authored
122 123 124 125 126 127

        let captchaNeeded = await this.captchaService.try();

        _.set(result, 'data.needCaptcha', captchaNeeded);

        return result;
htoooth authored
128
    }
htoooth authored
129
htoooth authored
130 131 132 133
    /**
     * 获得首页的数据
     */
    indexPageDataAsync() {
王水玲 authored
134 135
        let that = this;
htoooth authored
136
        return co(function* () {
王水玲 authored
137 138
            let banner = yield that.passportHelper.getLeftBannerAsync(BACK_LEFT_BANNER_CODE);
            let countryList = that.passportHelper.getCountry();
htoooth authored
139
htoooth authored
140
            return {
htoooth authored
141 142 143 144 145 146 147 148
                back: {
                    coverHref: banner.url,
                    coverImg: banner.img,
                    countryCode: 86,
                    countryName: '中国',
                    captchaUrl: helpers.urlFormat('/passport/imagesNode', {t: moment().unix()}),
                    countryList: countryList
                }
htoooth authored
149
            };
htoooth authored
150
        })();
htoooth authored
151 152
    }
htoooth authored
153 154 155 156 157 158 159 160 161
    /**
     * 验证手机验证码
     */
    verifyCodyByMobileAsync(area, mobile, mobileCode) {
        const ERR = {
            code: 400,
            message: '验证码错误!',
            data: helpers.urlFormat('/passport/back/index')
        };
htoooth authored
162
htoooth authored
163 164 165 166 167
        return this.api.validateMobileCodeAsync(mobile, mobileCode, area)
            .then(result => {
                if (!(result.code && result.code === 200)) {
                    return ERR;
                }
htoooth authored
168
htoooth authored
169 170 171 172 173 174
                let data = {
                    mobile: mobile,
                    area: area,
                    token: result.data.token,
                    createdAt: moment().unix()
                };
htoooth authored
175
htoooth authored
176
                data.code = new Buffer(backHelper.makeToken(data)).toString('base64');
htoooth authored
177
htoooth authored
178 179 180 181 182 183
                return {
                    code: 200,
                    message: '验证成功',
                    data: helpers.urlFormat('/passport/back/backcode', data)
                };
            });
htoooth authored
184
htoooth authored
185
    }
htoooth authored
186
htoooth authored
187 188 189 190 191 192 193 194 195 196
    /**
     * 手机 token 合法性验证
     */
    authRequest(data, token) {
        if (!backHelper.validateToken(data, token)) {
            return {};
        }

        let existTime = moment.duration(60, 'minutes').asSeconds();
        let isExpired = (moment().unix() - data.createdAt) > existTime;
htoooth authored
197
htoooth authored
198 199 200 201
        if (isExpired) {
            return {};
        } else {
            return data;
htoooth authored
202
        }
htoooth authored
203
    }
htoooth authored
204
htoooth authored
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
    /**
     * 更新密码接口
     */
    updatePwdAsync(emailToken, mobileToken, newPassword) {
        return co(function* () {
            let result = {type: 'mobile', status: false};
            const ERR = {type: 'unknown', status: false};

            if (!_.isEmpty(mobileToken)) {
                if (!mobileToken.mobile || mobileToken.uid) {
                    return ERR;
                }

                let mobile = mobileToken.mobile;
                let area = mobileToken.area;
                let token = mobileToken.token;
                let modifyStatus = yield this.api.modifyPasswordByMobileAsyncAes(mobile, token, newPassword, area);

                if (!modifyStatus.code || modifyStatus.code !== 200) {
                    return ERR;
                }

                result.type = 'mobile';
                result.status = true;
            } else {
                let modifyStatus = yield this.api.modifyPasswordByEmailCodeAsyncAes(emailToken, newPassword);

                if (!modifyStatus.code || modifyStatus.code !== 200) {
                    return ERR;
                }

                result.type = 'email';
                result.status = true;
            }
htoooth authored
239
htoooth authored
240 241 242
            return result;
        }).bind(this)();
    }
htoooth authored
243
};