captcha.js 1.8 KB
Newer Older
DCloud_JSON's avatar
DCloud_JSON 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
const {
  ERROR
} = require('../../common/error')

async function getNeedCaptcha ({
  uid,
  username,
  mobile,
  email,
  type = 'login',
  limitDuration = 7200000, // 两小时
  limitTimes = 3 // 记录次数
} = {}) {
  const db = uniCloud.database()
  const dbCmd = db.command
  // 当用户最近“2小时内(limitDuration)”登录失败达到3次(limitTimes)时。要求用户提交验证码
  const now = Date.now()
  const uniIdLogCollection = db.collection('uni-id-log')
  const userIdentifier = {
    user_id: uid,
    username,
    mobile,
    email
  }

  let totalKey = 0; let deleteKey = 0
  for (const key in userIdentifier) {
    totalKey++
    if (!userIdentifier[key] || typeof userIdentifier[key] !== 'string') {
      deleteKey++
      delete userIdentifier[key]
    }
  }

  if (deleteKey === totalKey) {
    throw new Error('System error') // 正常情况下不会进入此条件,但是考虑到后续会有其他开发者修改此云对象,在此处做一个判断
  }

  const {
    data: recentRecord
  } = await uniIdLogCollection.where({
study夏羽's avatar
study夏羽 已提交
42
    ip: this.getUniversalClientInfo().clientIP,
DCloud_JSON's avatar
DCloud_JSON 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    ...userIdentifier,
    type,
    create_date: dbCmd.gt(now - limitDuration)
  })
    .orderBy('create_date', 'desc')
    .limit(limitTimes)
    .get()
  return recentRecord.length === limitTimes && recentRecord.every(item => item.state === 0)
}

async function verifyCaptcha (params = {}) {
  const {
    captcha,
    scene
  } = params
  if (!captcha) {
    throw {
      errCode: ERROR.CAPTCHA_REQUIRED
    }
  }
  const payload = await this.uniCaptcha.verify({
study夏羽's avatar
study夏羽 已提交
64
    deviceId: this.getUniversalClientInfo().deviceId,
DCloud_JSON's avatar
DCloud_JSON 已提交
65 66 67 68 69 70 71 72 73 74 75 76
    captcha,
    scene
  })
  if (payload.errCode) {
    throw payload
  }
}

module.exports = {
  getNeedCaptcha,
  verifyCaptcha
}