/** * 登录相关控制器 * * @author CaiAoLin * @date 2017/6/8 * @version */ const UserModel = require("../models/user_model"); const SettingModel = require("../models/setting_model"); const CompilationModel = require("../models/compilation_model"); const LogModel = require("../models/log_model"); const LogType = require("../../common/const/log_type_const"); const SMS = require('../models/sms'); const moment = require('moment'); // 验证码 const Captcha = require("../models/captcha"); let mongoose = require("mongoose"); let systemSettingModel = mongoose.model("system_setting"); const uuidV1 = require('uuid/v1'); class LoginController { async firstPage(request,response){ response.render('users/html/index', {}); } /** * 登录页面 * * @param {object} request * @param {object} response * @return {void} */ async index(request, response) { // 判断是否有带token和ssoID参数 if (request.query.ssoID !== undefined && request.query.token !== undefined) { let ssoID = request.query.ssoID; let token = request.query.token; let preferenceSetting = {}; let compilationList = []; try { let userModel = new UserModel(); // 调用接口验证登录信息 let responseData = await userModel.getInfoFromSSO2(ssoID, token); // 先判断返回值是否为未激活状态 if ( responseData === '-3') { throw '因邮箱未完成认证,账号未激活;去激活。'; } if ( responseData === '-2') { throw 'token已过期,请重新登录Z+获取'; } responseData = JSON.parse(responseData); if (typeof responseData !== 'object') { throw 'ssoId错误或token过期'; } if (responseData.length <= 0) { throw '接口返回数据错误'; } let userData = responseData[0]; // 判断用户是否开启了只使用短信登录 const userInfo = await userModel.findDataByAccount(userData.mobile); if (userInfo !== undefined && userInfo !== null && userInfo.isSmsLogin === 1) { let renderData = { mobile: userData.mobile, }; response.render('users/html/login-sms', renderData); return; } let sessionUser = { ssoId: userData.id, username: userData.username, email: userData.useremail, mobile: userData.mobile, qq: userData.qq, isUserActive: userData.isUserActive, token: uuidV1(), }; request.session.sessionUser = sessionUser; // 记录用户数据到数据库 let result = await userModel.markUser(sessionUser, request); // 获取偏好设置 let settingModel = new SettingModel(); preferenceSetting = await settingModel.getPreferenceSetting(request.session.sessionUser.id); if (!result) { throw '标记用户信息失败!'; } let compilationModel = new CompilationModel(); if (preferenceSetting.login_ask === 1 || preferenceSetting.select_version === ''){ preferenceSetting.login_ask = 1; compilationList = await compilationModel.getList(); } else { compilationList = []; } // 获取编办信息 let sessionCompilation = request.session.sessionCompilation; if (preferenceSetting.login_ask === 0 && !sessionCompilation && preferenceSetting.select_version !== '') { let compilationData = await compilationModel.getCompilationById(preferenceSetting.select_version); // 判断当前用户的是使用免费版还是专业版 let compilationVersion = await userModel.getVersionFromUpgrade(sessionUser.ssoId, preferenceSetting.select_version); request.session.compilationVersion = compilationVersion.version; request.session.sessionUser.compilationLock = compilationVersion.lock; request.session.sessionCompilation = compilationData; if(request.session.sessionUser.latest_used !== preferenceSetting.select_version) await userModel.updateLatestUsed(request.session.sessionUser.id,preferenceSetting.select_version); } let systemSetting = await systemSettingModel.findOne({}).lean(); request.session.systemSetting = systemSetting; request.session.online_start_time = +new Date(); console.log(`${request.session.sessionUser.real_name}--id:${request.session.sessionUser.id}--登录了系统`); if (preferenceSetting.login_ask === 1 || preferenceSetting.select_version === '') { let renderData = { versionData: compilationList, }; response.render('users/html/login-ver', renderData); } else { return response.redirect("/pm"); } } catch (error) { console.log(error) return response.redirect("/login"); } } else { let sessionUser = request.session.sessionUser; if (sessionUser !== undefined && sessionUser.ssoId >= 0) { return response.redirect("/pm"); } else { response.render('users/html/login', {}); } } } /** * 登录操作 * * @param {object} request * @param {object} response * @return {string} */ async login(request, response) { console.log("开始登录操作------------------"); let preferenceSetting = {}; let compilationList = []; try { let userModel = new UserModel(); let responseData = ''; if (request.body.account === undefined) { let mobile = request.body.mobile; let codeMsg = request.session.code; if (codeMsg !== undefined && request.body.code !== '') { console.log(codeMsg); const validMobile = codeMsg.split('_')[0]; const code = codeMsg.split('_')[1]; const time = codeMsg.split('_')[2]; if (validMobile !== mobile) { throw '短信验证码错误'; } if (Date.parse(new Date())/1000 > time+60*5 || request.body.code !== code) { throw '短信验证码错误或已过期'; } else { delete request.session.code; } } else { throw '短信验证码错误或已过期。'; } responseData = await userModel.getInfoFromSSOMobile(mobile); console.log("getInfoFromSSOMobile complete------------------"); } else { let account = request.body.account; let password = request.body.pw; // 调用接口验证登录信息 responseData = await userModel.getInfoFromSSO(account, password); console.log("getInfoFromSSO complete------------------"); } // 先判断返回值是否为未激活状态 if ( responseData === '-3') { throw '因邮箱未完成认证,账号未激活;去激活。'; } responseData = JSON.parse(responseData); if (typeof responseData !== 'object') { throw '邮箱/手机 或 密码错误'; } if (responseData.length <= 0) { throw '接口返回数据错误'; } // 正确登录后 存入session let userData = responseData[0]; if (userData.mobile === '') { return response.json({error: 2,ssoId: userData.id}); } //还要判断account是否是专业版用户 // let isPro = false; // const userInfo = await userModel.findDataByAccount(account); // // if (userInfo && userInfo.upgrade_list !== undefined) { // for (const ul of userInfo.upgrade_list) { // if (ul.isUpgrade === true) { // isPro = true; // break; // } // } // } // // 专业版短信验证码验证 // if (isPro) { // const codeMsg = request.session.code; // if (codeMsg !== undefined && request.body.code !== '') { // const code = codeMsg.split('_')[0]; // const time = codeMsg.split('_')[1]; // console.log(code); // console.log(request.body.code); // if (Date.parse(new Date())/1000 > time+60*5 || request.body.code !== code) { // return response.json({error: 3, msg: '验证码错误。'}); // } else { // delete request.session.code; // } // } else { // return response.json({error: 3, msg: '验证码错误。'}); // } // } // 判断极验验证码是否通过 // const captcha = new Captcha(); // const captchResult = await captcha.validate(request); // console.log(captchResult); // if (!captchResult) { // throw '极验验证码错误'; // } // 判断用户是否开启了只使用短信登录 const userInfo = await userModel.findDataByAccount(userData.mobile); console.log("判断用户是否开启了只使用短信登录 完成------------------"); if (request.body.mobile === undefined && request.body.code === undefined && userInfo !== undefined && userInfo !== null && userInfo.isSmsLogin === 1) { return response.json({error: 3, msg: '只能手机短信登录。', data: userData.mobile}); } // for (const ul of userInfo.upgrade_list) { // if (ul.isUpgrade === true) { // isPro = true; // break; // } // } // } let sessionUser = { ssoId: userData.id, company: userInfo.company, username: userData.username, email: userData.useremail, mobile: userData.mobile, qq: userData.qq, isUserActive: userData.isUserActive, newLogin:true, token: uuidV1(), }; request.session.sessionUser = sessionUser; // 记录用户数据到数据库 let result = await userModel.markUser(sessionUser, request); console.log("markUser 完成------------------"); // 获取偏好设置 let settingModel = new SettingModel(); preferenceSetting = await settingModel.getPreferenceSetting(request.session.sessionUser.id); console.log("获取偏好设置 完成------------------"); if (!result) { throw '标记用户信息失败!'; } let compilationModel = new CompilationModel(); if(preferenceSetting.login_ask === 1 || preferenceSetting.select_version === ''){ preferenceSetting.login_ask = 1; compilationList = await compilationModel.getList(); console.log("compilationList 完成------------------"); } else{ compilationList = []; } // 获取编办信息 let sessionCompilation = request.session.sessionCompilation; if (preferenceSetting.login_ask === 0 && !sessionCompilation && preferenceSetting.select_version !== '') { let compilationData = await compilationModel.getCompilationById(preferenceSetting.select_version); // 判断当前用户的是使用免费版还是专业版 let compilationVersion = await userModel.getVersionFromUpgrade(sessionUser.ssoId, preferenceSetting.select_version); console.log("当前用户的是使用免费版还是专业版 完成------------------"); request.session.compilationVersion = compilationVersion.version; request.session.sessionUser.compilationLock = compilationVersion.lock; request.session.sessionCompilation = compilationData; if(request.session.sessionUser.latest_used !== preferenceSetting.select_version) await userModel.updateLatestUsed(request.session.sessionUser.id,preferenceSetting.select_version); } // 登录异常短信提醒功能 const userinfo2 = await userModel.findDataByAccount(userData.mobile); if (userinfo2.isLoginValid === 1) { // 获取本次访问ip let ip = request.headers["x-real-ip"]? request.headers["x-real-ip"]:""; let logModel = new LogModel(); let logCount = await logModel.count(); logCount = logCount > 30 ? 30 : logCount; let page = 1; const loginList = await logModel.getLog(request.session.sessionUser.id, LogType.LOGIN_LOG, page, logCount); let messageFlag = true; for (const [index,log] of loginList.entries()) { if (log.message.ip === ip && index !== 0) { messageFlag = false; break; } } messageFlag = true; if (messageFlag) { // 发送短信 const Sms = new SMS(); const logInfo = loginList[0]; await Sms.sendLoginMsg(userData.mobile, request.session.sessionUser.real_name, moment(logInfo.create_time).format('YYYY-MM-DD'), moment(logInfo.create_time).format('HH:mm:ss'), logInfo.message.ip_info, logInfo.message.ip); console.log("sendLoginMsg 完成------------------"); // const msg = '【纵横云计价】您的账号(账号昵称:'+ request.session.sessionUser.real_name +')于' + moment(logInfo.create_time).format('YYYY-MM-DD HH:mm:ss') + '在' + logInfo.message.ip_info + '(' + logInfo.message.ip + ')' + '登录成功。纵横云计价提醒您,如果怀疑此次登录行为有异常,请及时修改账号密码。'; // console.log(msg); } } } catch (error) { console.log(error); return response.json({error: 1, msg: error}); } let systemSetting = await systemSettingModel.findOne({}).lean(); request.session.systemSetting = systemSetting; request.session.online_start_time = +new Date(); console.log(`${request.session.sessionUser.real_name}--id:${request.session.sessionUser.id}--登录了系统`); response.json({ error: 0, msg: '', login_ask: preferenceSetting.login_ask, compilation_list: JSON.stringify(compilationList), last_page: request.session.lastPage }); } /** * 验证码注册 * * @param {object} request * @param {object} response * @return {string} */ async captcha(request, response) { const captcha = new Captcha(); const res = await captcha.register(request); response.json(res); } /** * 判断用户是否是专业版用户 * @param request * @param response * @returns {Promise} */ // async accountIsPro(request, response) { // let res = { // error: 0, // msg: '', // result: false, // }; // try{ // const account = request.body.account; // const password = request.body.pw; // // // 根据邮箱或手机号获取账号信息 // let userModel = new UserModel(); // // 调用接口验证登录信息 // let responseData = await userModel.getInfoFromSSO(account, password); // // 先判断返回值是否为未激活状态 // if ( responseData === '-3') { // throw '因邮箱未完成认证,账号未激活;去激活。'; // } // responseData = JSON.parse(responseData); // if (typeof responseData !== 'object') { // throw '邮箱/手机 或 密码错误'; // } // // if (responseData.length <= 0) { // throw '接口返回数据错误'; // } // // // 正确登录后 存入session // let userData = responseData[0]; // // if (userData.mobile === '') { // return response.json({error: 2,ssoId: userData.id}); // } // // const userInfo = await userModel.findDataByAccount(account); // if (userInfo && userInfo.upgrade_list !== undefined) { // for (const ul of userInfo.upgrade_list) { // if (ul.isUpgrade === true) { // res.result = true; // res.data = userInfo.mobile; // break; // } // } // } else { // res.msg = '当前未存在此用户'; // } // } catch (err) { // res.error = 1; // res.msg = err; // } // // response.json(res); // } async regPage(request, response) { let userModel = new UserModel(); const err = request.session.regError; request.session.regError = undefined; let renderData = { err: err ? err : '', provinceList: userModel.province, }; response.render('users/html/user-reg', renderData); } async reg(request, response) { try { if (request.body.type === undefined || request.body.mobile === undefined || request.body.company === undefined || request.body.real_name === undefined || request.body.qq === undefined || request.body.province === undefined) { throw '参数有误'; } let userModel = new UserModel(); let responseData = ''; if (parseInt(request.body.type) === 2) { // 已注册sso但未注册大司空 responseData = await userModel.regForSSO(request.body.mobile, request.body.qq); } else if (parseInt(request.body.type) === 1 && request.body.password !== undefined) { // 都未注册 const name = request.body.real_name + '_' + request.body.mobile; responseData = await userModel.regForSSO(request.body.mobile, request.body.qq, request.body.password, name); } else { throw '参数有误'; } responseData = JSON.parse(responseData); if (typeof responseData !== 'object') { throw 'SSO报错'; } if (responseData.length <= 0) { throw '接口返回数据错误'; } // 正确登录后 存入session let userData = responseData[0]; // makeuser let addUserData = { ssoId: userData.id, company: request.body.company, username: userData.username, email: userData.useremail, mobile: userData.mobile, qq: userData.qq, isUserActive: userData.isUserActive, token: uuidV1(), real_name: request.body.real_name, province: request.body.province, }; const result = await userModel.addUser(addUserData); return response.redirect("/wap/checkuser?mobile=" + request.body.mobile); } catch (err) { console.log(err); request.session.regError = err; return response.redirect("/wap/reg"); } } async checkUser(request, response) { const renderData = { check: false, }; if (request.query.mobile !== undefined) { let userModel = new UserModel(); const userInfo = await userModel.findDataByAccount(request.query.mobile); renderData.check = true; renderData.mobile = request.query.mobile; renderData.userinfo = userInfo; } response.render('users/html/user-check', renderData); } async checkUserAjax(request, response) { let existUser = 0; try { if (request.body.mobile !== undefined && request.body.code !== undefined) { let mobile = request.body.mobile; let codeMsg = request.session.code; if (codeMsg !== undefined && request.body.code !== '') { console.log(codeMsg); const validMobile = codeMsg.split('_')[0]; const code = codeMsg.split('_')[1]; const time = codeMsg.split('_')[2]; if (validMobile !== mobile) { throw '短信验证码错误'; } if (Date.parse(new Date())/1000 > time+60*5 || request.body.code !== code) { throw '短信验证码错误或已过期'; } else { delete request.session.code; } } else { throw '短信验证码错误或已过期。'; } let userModel = new UserModel(); const userInfo = await userModel.findDataByAccount(mobile); existUser = userInfo ? 1 : 0; // 若未注册大司空,再判断是否已注册sso if (existUser === 0) { let responseData = await userModel.getInfoFromSSOAccount(mobile); if ( responseData === '-2') { throw '参数有误'; } if ( responseData === '-22') { existUser = 0; } responseData = JSON.parse(responseData); if (typeof responseData === 'object') { existUser = 2; } } } else { throw '参数有误'; } } catch (error) { console.log(error); return response.json({error: 1, msg: error}); } response.json({ error: 0, existUser, }); } } module.exports = LoginController;