weixin.js 2.9 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
const crypto = require('crypto')
const {
  userCollection
} = require('../../common/constants')
const {
  ERROR
} = require('../../common/error')
const {
  getOauthConfig
} = require('../../common/utils')
function decryptWeixinData ({
  encryptedData,
  sessionKey,
  iv
} = {}) {
  const oauthConfig = getOauthConfig({
    config: this.config,
    oatuhProivder: 'weixin',
    clientPlatform: this.clientPlatform,
    requiredItem: ['appid']
  })
  const decipher = crypto.createDecipheriv(
    'aes-128-cbc',
    Buffer.from(sessionKey, 'base64'),
    Buffer.from(iv, 'base64')
  )
  // 设置自动 padding 为 true,删除填充补位
  decipher.setAutoPadding(true)
  let decoded
  decoded = decipher.update(encryptedData, 'base64', 'utf8')
  decoded += decipher.final('utf8')
  decoded = JSON.parse(decoded)
  if (decoded.watermark.appid !== oauthConfig.appid) {
    throw new Error('Invalid wechat appid in decode content')
  }
  return decoded
}

function getWeixinPlatform () {
  const platform = this.clientPlatform
  const userAgent = this.getClientInfo().userAgent
  switch (platform) {
    case 'app':
    case 'app-plus':
      return 'app'
    case 'mp-weixin':
      return 'mp'
    case 'h5':
    case 'web':
      return userAgent.indexOf('MicroMessenger') > -1 ? 'h5' : 'web'
    default:
      throw new Error('Unsupported weixin platform')
  }
}

function generateWeixinCache ({
雪洛's avatar
雪洛 已提交
57
  openid,
DCloud_JSON's avatar
DCloud_JSON 已提交
58 59 60 61 62 63
  sessionKey, // 微信小程序用户sessionKey
  accessToken, // App端微信用户accessToken
  refreshToken, // App端微信用户refreshToken
  accessTokenExpired // App端微信用户accessToken过期时间
} = {}) {
  const platform = getWeixinPlatform.call(this)
雪洛's avatar
雪洛 已提交
64
  const appId = this.getClientInfo().appId
DCloud_JSON's avatar
DCloud_JSON 已提交
65 66 67 68 69 70
  let cache
  switch (platform) {
    case 'app':
    case 'h5':
    case 'web':
      cache = {
雪洛's avatar
雪洛 已提交
71
        openid,
DCloud_JSON's avatar
DCloud_JSON 已提交
72 73 74 75 76 77 78
        access_token: accessToken,
        refresh_token: refreshToken,
        access_token_expired: accessTokenExpired
      }
      break
    case 'mp':
      cache = {
雪洛's avatar
雪洛 已提交
79
        openid,
DCloud_JSON's avatar
DCloud_JSON 已提交
80 81 82 83 84 85 86 87
        session_key: sessionKey
      }
      break
    default:
      throw new Error('Unsupported weixin platform')
  }
  return {
    third_party: {
雪洛's avatar
雪洛 已提交
88
      [`${appId}_${platform}_weixin`]: cache
DCloud_JSON's avatar
DCloud_JSON 已提交
89 90 91 92 93 94 95 96 97 98
    }
  }
}

async function getWeixinCache ({
  uid,
  userRecord,
  key
} = {}) {
  const platform = getWeixinPlatform.call(this)
雪洛's avatar
雪洛 已提交
99
  const appId = this.getClientInfo().appId
DCloud_JSON's avatar
DCloud_JSON 已提交
100 101 102 103 104 105 106 107 108
  if (!userRecord) {
    const getUserRes = await userCollection.doc(uid).get()
    userRecord = getUserRes.data[0]
  }
  if (!userRecord) {
    throw {
      errCode: ERROR.ACCOUNT_NOT_EXISTS
    }
  }
雪洛's avatar
雪洛 已提交
109 110 111 112 113 114 115
  const thirdParty = userRecord && userRecord.third_party
  if (!thirdParty) {
    return
  }
  const weixinCacheOld = thirdParty[`${platform}_weixin`]
  const weixinCache = thirdParty[`${appId}_${platform}_weixin`]
  return (weixinCache && weixinCache[key]) || (weixinCacheOld && weixinCacheOld[key])
DCloud_JSON's avatar
DCloud_JSON 已提交
116 117 118 119 120 121 122 123
}

module.exports = {
  decryptWeixinData,
  getWeixinPlatform,
  generateWeixinCache,
  getWeixinCache
}