| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- const {
- findUser
- } = require('./account')
- const {
- userCollection,
- LOG_TYPE
- } = require('../../common/constants')
- const {
- ERROR
- } = require('../../common/error')
- const {
- logout
- } = require('./logout')
- const PasswordUtils = require('./password')
- async function realPreLogin (params = {}) {
- const {
- user
- } = params
- const appId = this.getUniversalClientInfo().appId
- const {
- total,
- userMatched
- } = await findUser({
- userQuery: user,
- authorizedApp: appId
- })
- if (userMatched.length === 0) {
- if (total > 0) {
- throw {
- errCode: ERROR.ACCOUNT_NOT_EXISTS_IN_CURRENT_APP
- }
- }
- throw {
- errCode: ERROR.ACCOUNT_NOT_EXISTS
- }
- } else if (userMatched.length > 1) {
- throw {
- errCode: ERROR.ACCOUNT_CONFLICT
- }
- }
- const userRecord = userMatched[0]
- checkLoginUserRecord(userRecord)
- return userRecord
- }
- async function preLogin (params = {}) {
- const {
- user
- } = params
- try {
- const user = await realPreLogin.call(this, params)
- return user
- } catch (error) {
- await this.middleware.uniIdLog({
- success: false,
- data: user,
- type: LOG_TYPE.LOGIN
- })
- throw error
- }
- }
- async function preLoginWithPassword (params = {}) {
- const {
- user,
- password
- } = params
- try {
- const userRecord = await realPreLogin.call(this, params)
- const {
- passwordErrorLimit,
- passwordErrorRetryTime
- } = this.config
- const {
- clientIP
- } = this.getUniversalClientInfo()
- // 根据ip地址,密码错误次数过多,锁定登录
- let loginIPLimit = userRecord.login_ip_limit || []
- // 清理无用记录
- loginIPLimit = loginIPLimit.filter(item => item.last_error_time > Date.now() - passwordErrorRetryTime * 1000)
- let currentIPLimit = loginIPLimit.find(item => item.ip === clientIP)
- if (currentIPLimit && currentIPLimit.error_times >= passwordErrorLimit) {
- throw {
- errCode: ERROR.PASSWORD_ERROR_EXCEED_LIMIT
- }
- }
- const passwordUtils = new PasswordUtils({
- userRecord,
- clientInfo: this.getUniversalClientInfo(),
- passwordSecret: this.config.passwordSecret
- })
- const {
- success: checkPasswordSuccess,
- refreshPasswordInfo
- } = passwordUtils.checkUserPassword({
- password
- })
- if (!checkPasswordSuccess) {
- // 更新用户ip对应的密码错误记录
- if (!currentIPLimit) {
- currentIPLimit = {
- ip: clientIP,
- error_times: 1,
- last_error_time: Date.now()
- }
- loginIPLimit.push(currentIPLimit)
- } else {
- currentIPLimit.error_times++
- currentIPLimit.last_error_time = Date.now()
- }
- await userCollection.doc(userRecord._id).update({
- login_ip_limit: loginIPLimit
- })
- throw {
- errCode: ERROR.PASSWORD_ERROR
- }
- }
- const extraData = {}
- if (refreshPasswordInfo) {
- extraData.password = refreshPasswordInfo.passwordHash
- extraData.password_secret_version = refreshPasswordInfo.version
- }
- const currentIPLimitIndex = loginIPLimit.indexOf(currentIPLimit)
- if (currentIPLimitIndex > -1) {
- loginIPLimit.splice(currentIPLimitIndex, 1)
- }
- extraData.login_ip_limit = loginIPLimit
- return {
- user: userRecord,
- extraData
- }
- } catch (error) {
- await this.middleware.uniIdLog({
- success: false,
- data: user,
- type: LOG_TYPE.LOGIN
- })
- throw error
- }
- }
- function checkLoginUserRecord (user) {
- switch (user.status) {
- case undefined:
- case 0:
- break
- case 1:
- throw {
- errCode: ERROR.ACCOUNT_BANNED
- }
- case 2:
- throw {
- errCode: ERROR.ACCOUNT_AUDITING
- }
- case 3:
- throw {
- errCode: ERROR.ACCOUNT_AUDIT_FAILED
- }
- case 4:
- throw {
- errCode: ERROR.ACCOUNT_CLOSED
- }
- default:
- break
- }
- }
- async function thirdPartyLogin (params = {}) {
- const {
- user
- } = params
- return {
- mobileConfirmed: !!user.mobile_confirmed,
- emailConfirmed: !!user.email_confirmed
- }
- }
- async function postLogin (params = {}) {
- const {
- user,
- extraData,
- isThirdParty = false
- } = params
- const {
- clientIP
- } = this.getUniversalClientInfo()
- const uniIdToken = this.getUniversalUniIdToken()
- const uid = user._id
- const updateData = {
- last_login_date: Date.now(),
- last_login_ip: clientIP,
- ...extraData
- }
- const createTokenRes = await this.uniIdCommon.createToken({
- uid
- })
- const {
- errCode,
- token,
- tokenExpired
- } = createTokenRes
- if (errCode) {
- throw createTokenRes
- }
- if (uniIdToken) {
- try {
- await logout.call(this)
- } catch (error) {}
- }
- await userCollection.doc(uid).update(updateData)
- await this.middleware.uniIdLog({
- data: {
- user_id: uid
- },
- type: LOG_TYPE.LOGIN
- })
- return {
- errCode: 0,
- newToken: {
- token,
- tokenExpired
- },
- uid,
- ...(
- isThirdParty
- ? thirdPartyLogin({
- user
- })
- : {}
- ),
- passwordConfirmed: !!user.password
- }
- }
- module.exports = {
- preLogin,
- postLogin,
- checkLoginUserRecord,
- preLoginWithPassword
- }
|