提交 cc581c3f 编写于 作者: C chenruilong

Merge branch 'upgrade-weixin' into dev

# Conflicts:
#	uni_modules/uni-id-pages/components/uni-id-pages-fab-login/uni-id-pages-fab-login.vue
#	uni_modules/uni-id-pages/pages/userinfo/userinfo.vue
...@@ -4,5 +4,6 @@ unpackage/ ...@@ -4,5 +4,6 @@ unpackage/
node_modules/ node_modules/
.vite/ .vite/
uni_modules_tools/copy uni_modules_tools/copy
/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json /uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json
.idea
...@@ -26,9 +26,12 @@ ...@@ -26,9 +26,12 @@
"value": "smsCode", "value": "smsCode",
"text": "手机验证码" "text": "手机验证码"
}, { }, {
"value": "apple", "value": "apple",
"text": "苹果登录" "text": "苹果登录"
}] }, {
"value": "weixinMobile",
"text": "微信手机号登录"
}]
} }
}, },
onLoad() {}, onLoad() {},
...@@ -80,4 +83,4 @@ ...@@ -80,4 +83,4 @@
font-size: 18px; font-size: 18px;
color: #8f8f94; color: #8f8f94;
} }
</style> </style>
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
</template> </template>
<script> <script>
import config from '@/uni_modules/uni-id-pages/config.js' import config from '@/uni_modules/uni-id-pages/config.js'
//前一个窗口的页面地址。控制点击切换快捷登录方式是创建还是返回 //前一个窗口的页面地址。控制点击切换快捷登录方式是创建还是返回
import { import {
store, store,
mutations mutations
} from '@/uni_modules/uni-id-pages/common/store.js' } from '@/uni_modules/uni-id-pages/common/store.js'
const db = uniCloud.database(); const db = uniCloud.database();
const usersTable = db.collection('uni-id-users') const usersTable = db.collection('uni-id-users')
let allServicesList = [] let allServicesList = []
export default { export default {
computed: { computed: {
agreements() { agreements() {
...@@ -45,17 +45,17 @@ ...@@ -45,17 +45,17 @@
] ]
}, },
agree: { agree: {
get() { get() {
return this.getParentComponent().agree return this.getParentComponent().agree
}, },
set(agree) { set(agree) {
console.log('setAgree', agree); console.log('setAgree', agree);
return this.getParentComponent().agree = agree return this.getParentComponent().agree = agree
} }
} }
}, },
data() { data() {
return { return {
servicesList: [{ servicesList: [{
"id": "username", "id": "username",
"text": "账号登录", "text": "账号登录",
...@@ -127,11 +127,11 @@ ...@@ -127,11 +127,11 @@
"list": [] "list": []
}, },
"privacyTerms": { "privacyTerms": {
"defaultCheckBoxState": false, // 条款勾选框初始状态 默认值: true "defaultCheckBoxState": false, // 条款勾选框初始状态 默认值: true
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB "textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3 "termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意” "prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录” "suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [] "privacyItems": []
} }
} }
...@@ -147,14 +147,14 @@ ...@@ -147,14 +147,14 @@
let loginTypes = config.loginTypes let loginTypes = config.loginTypes
servicesList = servicesList.filter(item => { servicesList = servicesList.filter(item => {
// #ifndef APP // #ifndef APP
//非app端去掉apple登录 //非app端去掉apple登录
if (item.id == 'apple') { if (item.id == 'apple') {
return false return false
} }
// #endif // #endif
// #ifdef APP // #ifdef APP
//去掉非ios系统上的apple登录 //去掉非ios系统上的apple登录
if (item.id == 'apple' && uni.getSystemInfoSync().osName != 'ios') { if (item.id == 'apple' && uni.getSystemInfoSync().osName != 'ios') {
...@@ -196,7 +196,7 @@ ...@@ -196,7 +196,7 @@
// #ifndef H5 // #ifndef H5
return this.$parent; return this.$parent;
// #endif // #endif
// #ifdef H5 // #ifdef H5
return this.$parent.$parent; return this.$parent.$parent;
// #endif // #endif
...@@ -234,8 +234,8 @@ ...@@ -234,8 +234,8 @@
console.log('出乎意料的情况,path:' + path); console.log('出乎意料的情况,path:' + path);
} }
}, },
async login_before(type, navigateBack = true) { async login_before(type, navigateBack = true, options = {}) {
console.log(type); console.log(type);
//提示空实现 //提示空实现
if (["qq", if (["qq",
"xiaomi", "xiaomi",
...@@ -251,7 +251,7 @@ ...@@ -251,7 +251,7 @@
icon: 'none' icon: 'none'
}); });
} }
//检查当前环境是否支持这种登录方式 //检查当前环境是否支持这种登录方式
// #ifdef APP // #ifdef APP
let isAppExist = true let isAppExist = true
...@@ -272,66 +272,65 @@ ...@@ -272,66 +272,65 @@
}) })
}) })
// #endif // #endif
if ( if (
// #ifdef APP // #ifdef APP
!isAppExist !isAppExist
// #endif // #endif
//非app端使用了,app特有登录方式 //非app端使用了,app特有登录方式
// #ifndef APP // #ifndef APP
["univerify","apple"].includes(type) ["univerify","apple"].includes(type)
// #endif // #endif
) { ) {
return uni.showToast({ return uni.showToast({
title: '当前设备不支持此登录,请选择其他登录方式', title: '当前设备不支持此登录,请选择其他登录方式',
icon: 'none' icon: 'none'
}); });
} }
//判断是否需要弹出隐私协议授权框 //判断是否需要弹出隐私协议授权框
console.log(type, this.agree); console.log(type, this.agree);
let needAgreements = (config?.agreements?.scope || []).includes('register') let needAgreements = (config?.agreements?.scope || []).includes('register')
console.log({ console.log({
needAgreements needAgreements
}); });
if (type != 'univerify' && needAgreements && !this.agree) { if (type != 'univerify' && needAgreements && !this.agree) {
let agreementsRef = this.getParentComponent().$refs.agreements let agreementsRef = this.getParentComponent().$refs.agreements
return agreementsRef.popup(() => { return agreementsRef.popup(() => {
console.log(type, navigateBack); console.log(type, navigateBack);
this.login_before(type, navigateBack) this.login_before(type, navigateBack, options)
}) })
} }
// #ifdef H5 // #ifdef H5
if(type == 'weixin'){ if(type == 'weixin'){
// console.log('开始微信网页登录'); // console.log('开始微信网页登录');
let redirectUrl = location.protocol +'//'+ let redirectUrl = location.protocol +'//'+
document.domain + document.domain +
(window.location.href.includes('#')?'/#':'') + (window.location.href.includes('#')?'/#':'') +
'/uni_modules/uni-id-pages/pages/login/login-withoutpwd?is_weixin_redirect=true&type=weixin' '/uni_modules/uni-id-pages/pages/login/login-withoutpwd?is_weixin_redirect=true&type=weixin'
console.log('redirectUrl----',redirectUrl); console.log('redirectUrl----',redirectUrl);
let ua = window.navigator.userAgent.toLowerCase(); let ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger'){ if (ua.match(/MicroMessenger/i) == 'micromessenger'){
// console.log('在微信公众号内'); // console.log('在微信公众号内');
return window.open(`https://open.weixin.qq.com/connect/oauth2/authorize? return window.open(`https://open.weixin.qq.com/connect/oauth2/authorize?
appid=${config.appid.weixin.h5} appid=${config.appid.weixin.h5}
&redirect_uri=${encodeURIComponent(redirectUrl)} &redirect_uri=${encodeURIComponent(redirectUrl)}
&response_type=code &response_type=code
&scope=snsapi_userinfo &scope=snsapi_userinfo
&state=STATE&connect_redirect=1#wechat_redirect`); &state=STATE&connect_redirect=1#wechat_redirect`);
}else{ }else{
// console.log('非微信公众号内'); // console.log('非微信公众号内');
return location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=${config.appid.weixin.web} return location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=${config.appid.weixin.web}
&redirect_uri=${encodeURIComponent(redirectUrl)} &redirect_uri=${encodeURIComponent(redirectUrl)}
&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect` &response_type=code&scope=snsapi_login&state=STATE#wechat_redirect`
} }
} }
// #endif // #endif
uni.showLoading({ uni.showLoading({
mask: true mask: true
}) })
...@@ -397,6 +396,13 @@ ...@@ -397,6 +396,13 @@
} }
}) })
} }
if (type === 'weixinMobile') {
return this.login({
phoneCode: options.phoneNumberCode
}, type)
}
uni.login({ uni.login({
"provider": type, "provider": type,
"onlyAuthorize": true, "onlyAuthorize": true,
...@@ -422,14 +428,14 @@ ...@@ -422,14 +428,14 @@
} }
}) })
}, },
login(params, type) { //联网验证登录 login(params, type) { //联网验证登录
console.log('执行登录开始----'); console.log('执行登录开始----');
console.log({ console.log({
params, params,
type type
}); });
//toLowerCase //toLowerCase
let action = 'loginBy' + type.trim().toLowerCase().replace(type[0], type[0].toUpperCase()) let action = 'loginBy' + type.trim().replace(type[0], type[0].toUpperCase())
const uniIdCo = uniCloud.importObject("uni-id-co",{ const uniIdCo = uniCloud.importObject("uni-id-co",{
customUI:true customUI:true
}) })
...@@ -441,17 +447,17 @@ ...@@ -441,17 +447,17 @@
}); });
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
//如果是微信小程序端的微信登录,且为首次登录,就弹出获取微信昵称+头像用于绑定资料 //如果是微信小程序端的微信登录,且为首次登录,就弹出获取微信昵称+头像用于绑定资料
if (type == 'weixin' && result.type == "register") { if (['weixin', 'weixinMobile'].includes(type) && result.type == "register") {
mutations.loginSuccess({ mutations.loginSuccess({
...result, ...result,
showToast: false, showToast: false,
autoBack: false autoBack: false
}) })
return this.$refs.userProfile.open(result.uid) return this.$refs.userProfile.open(result.uid)
} }
// #endif // #endif
// #ifdef H5 // #ifdef H5
result.loginType = type result.loginType = type
// #endif // #endif
mutations.loginSuccess(result) mutations.loginSuccess(result)
}) })
...@@ -514,10 +520,10 @@ ...@@ -514,10 +520,10 @@
flex-wrap: wrap; flex-wrap: wrap;
width: 750rpx; width: 750rpx;
justify-content: space-around; justify-content: space-around;
position: fixed; position: fixed;
left: 0; left: 0;
} }
.item { .item {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
...@@ -536,7 +542,7 @@ ...@@ -536,7 +542,7 @@
height: 160rpx; height: 160rpx;
} }
} }
@media screen and (max-width: 690px) { @media screen and (max-width: 690px) {
.fab-login-box { .fab-login-box {
bottom: 10rpx; bottom: 10rpx;
...@@ -545,7 +551,7 @@ ...@@ -545,7 +551,7 @@
/* #endif */ /* #endif */
.logo { .logo {
width: 60rpx; width: 60rpx;
......
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
<!-- 顶部文字 --> <!-- 顶部文字 -->
<text class="title">请选择登录方式</text> <text class="title">请选择登录方式</text>
<!-- 快捷登录框 当url带参数时有效 --> <!-- 快捷登录框 当url带参数时有效 -->
<template v-if="['apple','weixin'].includes(type)"> <template v-if="['apple','weixin', 'weixinMobile'].includes(type)">
<text class="tip">将根据第三方账号服务平台的授权范围获取你的信息</text> <text class="tip">将根据第三方账号服务平台的授权范围获取你的信息</text>
<view class="quickLogin"> <view class="quickLogin">
<image @click="quickLogin" :src="imgSrc" mode="widthFix" class="quickLoginBtn"></image> <image v-if="type !== 'weixinMobile'" @click="quickLogin" :src="imgSrc" mode="widthFix" class="quickLoginBtn"></image>
<uni-id-pages-agreements scope="register" ref="agreements"></uni-id-pages-agreements> <button v-else type="primary" open-type="getPhoneNumber" @getphonenumber="quickLogin">微信授权手机号登录</button>
<uni-id-pages-agreements scope="register" ref="agreements"></uni-id-pages-agreements>
</view> </view>
</template> </template>
<template v-else> <template v-else>
...@@ -98,8 +99,16 @@ ...@@ -98,8 +99,16 @@
//#endif //#endif
}, },
methods: { methods: {
quickLogin() { quickLogin(e) {
this.$refs.uniFabLogin.login_before(this.type) let options = {}
if (e.detail?.code) {
options.phoneNumberCode = e.detail.code
}
if (this.type === 'weixinMobile' && !e.detail?.code) return
this.$refs.uniFabLogin.login_before(this.type, true, options)
}, },
toSmsPage() { toSmsPage() {
console.log('toSmsPage',this.agree); console.log('toSmsPage',this.agree);
...@@ -203,7 +212,7 @@ ...@@ -203,7 +212,7 @@
margin-top: -15px; margin-top: -15px;
margin-bottom: 20px; margin-bottom: 20px;
} }
@media screen and (min-width: 690px) { @media screen and (min-width: 690px) {
.quickLogin{ .quickLogin{
height: auto; height: auto;
......
...@@ -14,6 +14,16 @@ ...@@ -14,6 +14,16 @@
<uni-list-item v-if="hasPwd" class="item" @click="changePassword" title="修改密码" link> <uni-list-item v-if="hasPwd" class="item" @click="changePassword" title="修改密码" link>
</uni-list-item> </uni-list-item>
</uni-list> </uni-list>
<uni-list class="mt10">
<uni-list-item @click="bindThirdAccount('Weixin')" title="微信" link
:rightText="userInfo.wx_openid ? '已绑定': '未绑定' "></uni-list-item>
<uni-list-item @click="bindThirdAccount('QQ')" title="QQ" link
:rightText="userInfo.qq_openid ? '已绑定': '未绑定' "></uni-list-item>
<uni-list-item @click="bindThirdAccount('Alipay')" title="支付宝" link
:rightText="userInfo.ali_openid ? '已绑定': '未绑定' "></uni-list-item>
<uni-list-item @click="bindThirdAccount('Apple')" title="Apple" link
:rightText="userInfo.apple_openid ? '已绑定': '未绑定' "></uni-list-item>
</uni-list>
<uni-list class="mt10"> <uni-list class="mt10">
<uni-list-item @click="deactivate" title="注销账号" link="navigateTo"></uni-list-item> <uni-list-item @click="deactivate" title="注销账号" link="navigateTo"></uni-list-item>
</uni-list> </uni-list>
...@@ -33,16 +43,16 @@ ...@@ -33,16 +43,16 @@
const db = uniCloud.database(); const db = uniCloud.database();
const usersTable = db.collection('uni-id-users') const usersTable = db.collection('uni-id-users')
const uniIdCo = uniCloud.importObject("uni-id-co") const uniIdCo = uniCloud.importObject("uni-id-co")
import { import {
store, store,
mutations mutations
} from '@/uni_modules/uni-id-pages/common/store.js' } from '@/uni_modules/uni-id-pages/common/store.js'
export default { export default {
computed: { computed: {
userInfo() { userInfo() {
return store.userInfo return store.userInfo
} }
}, },
data() { data() {
return { return {
univerifyStyle: { univerifyStyle: {
...@@ -82,12 +92,12 @@ ...@@ -82,12 +92,12 @@
} }
}) })
}, },
logout(){ logout(){
mutations.logout() mutations.logout()
}, },
bindMobileSuccess(){ bindMobileSuccess(){
mutations.updateUserInfo() mutations.updateUserInfo()
}, },
changePassword(){ changePassword(){
uni.navigateTo({ uni.navigateTo({
url: '/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd', url: '/uni_modules/uni-id-pages/pages/userinfo/change_pwd/change_pwd',
...@@ -126,7 +136,7 @@ ...@@ -126,7 +136,7 @@
console.log(e.authResult); console.log(e.authResult);
uniIdCo.bindMobileByUniverify(e.authResult).then(res => { uniIdCo.bindMobileByUniverify(e.authResult).then(res => {
console.log(res); console.log(res);
mutations.updateUserInfo() mutations.updateUserInfo()
}).catch(e => { }).catch(e => {
console.log(e); console.log(e);
}).finally(e=>{ }).finally(e=>{
...@@ -143,29 +153,64 @@ ...@@ -143,29 +153,64 @@
}) })
}, },
bindMobileBySmsCode() { bindMobileBySmsCode() {
uni.navigateTo({ uni.navigateTo({
url: './bind-mobile/bind-mobile' url: './bind-mobile/bind-mobile'
}) })
}, },
setNickname(nickname) { setNickname(nickname) {
console.log(nickname); console.log(nickname);
if (nickname) { if (nickname) {
mutations.updateUserInfo({nickname}) mutations.updateUserInfo({nickname})
this.$refs.dialog.close() this.$refs.dialog.close()
} else { } else {
this.$refs.dialog.open() this.$refs.dialog.open()
} }
}, },
deactivate(){ deactivate(){
uni.navigateTo({ uni.navigateTo({
url:"/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate" url:"/uni_modules/uni-id-pages/pages/userinfo/deactivate/deactivate"
}) })
} },
async bindThirdAccount(provider) {
const uniIdCo = uniCloud.importObject("uni-id-co")
const bindField = {
weixin: 'wx_openid',
alipay: 'ali_openid',
apple: 'apple_openid',
qq: 'qq_openid'
}[provider.toLowerCase()]
if (this.userInfo[bindField]) {
await uniIdCo['unbind' + provider]()
await mutations.updateUserInfo()
} else {
uni.login({
provider: provider.toLowerCase(),
onlyAuthorize: true,
success: async e => {
const res = await uniIdCo['bind' + provider]({
code: e.code
})
if (res.errCode) {
uni.showToast({
title: res.errMsg || '绑定失败'
})
}
await mutations.updateUserInfo()
},
fail: async (err) => {
console.log(err);
uni.hideLoading()
}
})
}
}
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/uni_modules/uni-id-pages/common/login-page.scss"; @import "@/uni_modules/uni-id-pages/common/login-page.scss";
.uni-content { .uni-content {
...@@ -211,7 +256,7 @@ ...@@ -211,7 +256,7 @@
background-color: #FFFFFF; background-color: #FFFFFF;
width: 80%; width: 80%;
} }
.mt10{ .mt10{
margin-top: 10px; margin-top: 10px;
} }
......
...@@ -52,7 +52,11 @@ const LOG_TYPE = { ...@@ -52,7 +52,11 @@ const LOG_TYPE = {
BIND_WEIXIN: 'bind-weixin', BIND_WEIXIN: 'bind-weixin',
BIND_QQ: 'bind-qq', BIND_QQ: 'bind-qq',
BIND_APPLE: 'bind-apple', BIND_APPLE: 'bind-apple',
BIND_ALIPAY: 'bind-alipay' BIND_ALIPAY: 'bind-alipay',
UNBIND_WEIXIN: 'unbind-weixin',
UNBIND_QQ: 'unbind-qq',
UNBIND_ALIPAY: 'unbind-alipay',
UNBIND_APPLE: 'unbind-apple'
} }
const SMS_SCENE = { const SMS_SCENE = {
......
...@@ -30,7 +30,12 @@ const ERROR = { ...@@ -30,7 +30,12 @@ const ERROR = {
SET_INVITE_CODE_FAILED: 'uni-id-set-invite-code-failed', SET_INVITE_CODE_FAILED: 'uni-id-set-invite-code-failed',
INVALID_INVITE_CODE: 'uni-id-invalid-invite-code', INVALID_INVITE_CODE: 'uni-id-invalid-invite-code',
CHANGE_INVITER_FORBIDDEN: 'uni-id-change-inviter-forbidden', CHANGE_INVITER_FORBIDDEN: 'uni-id-change-inviter-forbidden',
BIND_CONFLICT: 'uni-id-bind-conflict' BIND_CONFLICT: 'uni-id-bind-conflict',
UNBIND_FAIL: 'uni-id-unbind-failed',
UNBIND_NOT_SUPPORTED: 'uni-id-unbind-not-supported',
UNBIND_UNIQUE_LOGIN: 'uni-id-unbind-unique-login',
UNBIND_PASSWORD_NOT_EXISTS: 'uni-id-unbind-password-not-exists',
UNBIND_MOBILE_NOT_EXISTS: 'uni-id-unbind-mobile-not-exists'
} }
function isUniIdError (errCode) { function isUniIdError (errCode) {
......
...@@ -62,5 +62,17 @@ module.exports = { ...@@ -62,5 +62,17 @@ module.exports = {
}, },
getAccountInfo: { getAccountInfo: {
auth: true auth: true
},
unbindWeixin: {
auth: true
},
unbindAlipay: {
auth: true
},
unbindQQ: {
auth: true
},
unbindApple: {
auth: true
} }
} }
...@@ -29,7 +29,8 @@ const { ...@@ -29,7 +29,8 @@ const {
loginByWeixin, loginByWeixin,
loginByAlipay, loginByAlipay,
loginByQQ, loginByQQ,
loginByApple loginByApple,
loginByWeixinMobile
} = require('./module/login/index') } = require('./module/login/index')
const { const {
logout logout
...@@ -41,7 +42,11 @@ const { ...@@ -41,7 +42,11 @@ const {
bindAlipay, bindAlipay,
bindApple, bindApple,
bindQQ, bindQQ,
bindWeixin bindWeixin,
unbindWeixin,
unbindAlipay,
unbindQQ,
unbindApple
} = require('./module/relate/index') } = require('./module/relate/index')
const { const {
updatePwd, updatePwd,
...@@ -74,7 +79,7 @@ const { ...@@ -74,7 +79,7 @@ const {
} = require('./module/dev/index') } = require('./module/dev/index')
module.exports = { module.exports = {
async _before() { async _before () {
const clientInfo = this.getClientInfo() const clientInfo = this.getClientInfo()
/** /**
* 检查clientInfo,无appId和uniPlatform时本云对象无法正常运行 * 检查clientInfo,无appId和uniPlatform时本云对象无法正常运行
...@@ -157,7 +162,7 @@ module.exports = { ...@@ -157,7 +162,7 @@ module.exports = {
// 挂载uni-captcha到this上,方便后续调用 // 挂载uni-captcha到this上,方便后续调用
this.uniCaptcha = uniCaptcha this.uniCaptcha = uniCaptcha
Object.defineProperty(this, 'uniOpenBridge', { Object.defineProperty(this, 'uniOpenBridge', {
get() { get () {
return require('uni-open-bridge-common') return require('uni-open-bridge-common')
} }
}) })
...@@ -181,7 +186,7 @@ module.exports = { ...@@ -181,7 +186,7 @@ module.exports = {
// 通用权限校验模块 // 通用权限校验模块
await this.middleware.accessControl() await this.middleware.accessControl()
}, },
_after(error, result) { _after (error, result) {
if (error) { if (error) {
// 处理中间件内抛出的标准响应对象 // 处理中间件内抛出的标准响应对象
if (error.errCode && getType(error) === 'object') { if (error.errCode && getType(error) === 'object') {
...@@ -363,6 +368,7 @@ module.exports = { ...@@ -363,6 +368,7 @@ module.exports = {
* @returns * @returns
*/ */
loginByApple, loginByApple,
loginByWeixinMobile,
/** /**
* 用户退出登录 * 用户退出登录
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#logout * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#logout
...@@ -545,5 +551,30 @@ module.exports = { ...@@ -545,5 +551,30 @@ module.exports = {
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-supported-login-type * @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#get-supported-login-type
* @returns * @returns
*/ */
getSupportedLoginType getSupportedLoginType,
/**
* 解绑微信
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-weixin
* @returns
*/
unbindWeixin,
/**
* 解绑支付宝
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-alipay
* @returns
*/
unbindAlipay,
/**
* 解绑QQ
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-qq
* @returns
*/
unbindQQ,
/**
* 解绑Apple
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-apple
* @returns
*/
unbindApple
} }
...@@ -35,7 +35,12 @@ const sentence = { ...@@ -35,7 +35,12 @@ const sentence = {
'uni-id-set-invite-code-failed': 'Set invite code failed', 'uni-id-set-invite-code-failed': 'Set invite code failed',
'uni-id-invalid-invite-code': 'Invalid invite code', 'uni-id-invalid-invite-code': 'Invalid invite code',
'uni-id-change-inviter-forbidden': 'Change inviter is not allowed', 'uni-id-change-inviter-forbidden': 'Change inviter is not allowed',
'uni-id-bind-conflict': 'This account has been bound' 'uni-id-bind-conflict': 'This account has been bound',
'uni-id-admin-exist-in-other-apps': 'Administrator is registered in other consoles',
'uni-id-unbind-failed': 'Please bind first and then unbind',
'uni-id-unbind-not-supported': 'Unbinding is not supported',
'uni-id-unbind-mobile-not-exists': 'This is the only way to login at the moment, please bind your phone number and then try to unbind',
'uni-id-unbind-password-not-exists': 'Please set a password first'
} }
module.exports = { module.exports = {
......
...@@ -35,7 +35,12 @@ const sentence = { ...@@ -35,7 +35,12 @@ const sentence = {
'uni-id-set-invite-code-failed': '设置邀请码失败', 'uni-id-set-invite-code-failed': '设置邀请码失败',
'uni-id-invalid-invite-code': '邀请码不可用', 'uni-id-invalid-invite-code': '邀请码不可用',
'uni-id-change-inviter-forbidden': '禁止修改邀请人', 'uni-id-change-inviter-forbidden': '禁止修改邀请人',
'uni-id-bind-conflict': '此账号已被绑定' 'uni-id-bind-conflict': '此账号已被绑定',
'uni-id-admin-exist-in-other-apps': '超级管理员已在其他控制台注册',
'uni-id-unbind-failed': '请先绑定后再解绑',
'uni-id-unbind-not-supported': '不支持解绑',
'uni-id-unbind-mobile-not-exists': '这是当前唯一登录方式,请绑定手机号后再尝试解绑',
'uni-id-unbind-password-not-exists': '请先设置密码在尝试解绑'
} }
module.exports = { module.exports = {
......
...@@ -86,4 +86,26 @@ module.exports = class Auth { ...@@ -86,4 +86,26 @@ module.exports = class Auth {
avatar avatar
} }
} }
async getPhoneNumber (accessToken, code) {
const url = `/wxa/business/getuserphonenumber?access_token=${accessToken}`
const { phoneInfo } = await this._requestWxOpenapi({
name: 'getPhoneNumber',
url,
data: {
code
},
options: {
method: 'POST',
dataAsQueryString: false,
headers: {
'content-type': 'application/json'
}
}
})
return {
purePhoneNumber: phoneInfo.purePhoneNumber
}
}
} }
...@@ -219,7 +219,8 @@ async function postLogin (params = {}) { ...@@ -219,7 +219,8 @@ async function postLogin (params = {}) {
user user
}) })
: {} : {}
) ),
passwordConfirmed: !!user.password
} }
} }
......
...@@ -5,8 +5,15 @@ const { ...@@ -5,8 +5,15 @@ const {
ERROR ERROR
} = require('../../common/error') } = require('../../common/error')
const { const {
userCollection userCollection, dbCmd, USER_IDENTIFIER
} = require('../../common/constants') } = require('../../common/constants')
const {
getUserIdentifier
} = require('../../lib/utils/account')
const {
batchFindObjctValue
} = require('../../common/utils')
const merge = require('lodash.merge') const merge = require('lodash.merge')
/** /**
...@@ -56,7 +63,100 @@ async function postBind ({ ...@@ -56,7 +63,100 @@ async function postBind ({
} }
} }
async function preUnBind ({
uid,
unBindAccount,
logType
}) {
const notUnBind = ['username', 'mobile', 'email']
const userIdentifier = getUserIdentifier(unBindAccount)
const condition = Object.keys(userIdentifier).reduce((res, key) => {
if (userIdentifier[key]) {
if (notUnBind.includes(key)) {
throw {
errCode: ERROR.UNBIND_NOT_SUPPORTED
}
}
res.push({
[key]: userIdentifier[key]
})
}
return res
}, [])
const currentUnBindAccount = Object.keys(userIdentifier).reduce((res, key) => {
if (userIdentifier[key]) {
res.push(key)
}
return res
}, [])
const { data: users } = await userCollection.where(dbCmd.and(
{ _id: uid },
dbCmd.or(condition)
)).get()
if (users.length <= 0) {
await this.middleware.uniIdLog({
data: {
user_id: uid
},
type: logType,
success: false
})
throw {
errCode: ERROR.UNBIND_FAIL
}
}
const [user] = users
const otherAccounts = batchFindObjctValue(user, Object.keys(USER_IDENTIFIER).filter(key => !notUnBind.includes(key) && !currentUnBindAccount.includes(key)))
let hasOtherAccountBind = false
for (const key in otherAccounts) {
if (otherAccounts[key]) {
hasOtherAccountBind = true
break
}
}
// 如果没有其他第三方登录方式
if (!hasOtherAccountBind) {
// 存在用户名或者邮箱但是没有设置过没密码就提示设置密码
if ((user.username || user.email) && !user.password) {
throw {
errCode: ERROR.UNBIND_PASSWORD_NOT_EXISTS
}
}
// 账号任何登录方式都没有就优先绑定手机号
if (!user.mobile) {
throw {
errCode: ERROR.UNBIND_MOBILE_NOT_EXISTS
}
}
}
}
async function postUnBind ({
uid,
unBindAccount,
logType
}) {
await userCollection.doc(uid).update(unBindAccount)
await this.middleware.uniIdLog({
data: {
user_id: uid
},
type: logType
})
return {
errCode: 0
}
}
module.exports = { module.exports = {
preBind, preBind,
postBind postBind,
preUnBind,
postUnBind
} }
...@@ -177,10 +177,22 @@ async function getWeixinCache ({ ...@@ -177,10 +177,22 @@ async function getWeixinCache ({
}) })
} }
async function getWeixinAccessToken () {
const weixinPlatform = getWeixinPlatform.call(this)
const appId = this.getClientInfo().appId
const cache = await this.uniOpenBridge.getAccessToken({
dcloudAppid: appId,
platform: 'weixin-' + weixinPlatform
})
return cache.access_token
}
module.exports = { module.exports = {
decryptWeixinData, decryptWeixinData,
getWeixinPlatform, getWeixinPlatform,
generateWeixinCache, generateWeixinCache,
getWeixinCache, getWeixinCache,
saveWeixinUserKey saveWeixinUserKey,
getWeixinAccessToken
} }
...@@ -15,5 +15,6 @@ module.exports = { ...@@ -15,5 +15,6 @@ module.exports = {
loginByEmailLink: require('./login-by-email-link'), loginByEmailLink: require('./login-by-email-link'),
loginByEmailCode: require('./login-by-email-code'), loginByEmailCode: require('./login-by-email-code'),
loginByFacebook: require('./login-by-facebook'), loginByFacebook: require('./login-by-facebook'),
loginByGoogle: require('./login-by-google') loginByGoogle: require('./login-by-google'),
loginByWeixinMobile: require('./login-by-weixin-mobile')
} }
const {
initWeixin
} = require('../../lib/third-party/index')
const {
getWeixinPlatform,
getWeixinAccessToken,
generateWeixinCache,
saveWeixinUserKey
} = require('../../lib/utils/weixin')
const {
ERROR
} = require('../../common/error')
const {
preUnifiedLogin,
postUnifiedLogin
} = require('../../lib/utils/unified-login')
const {
LOG_TYPE
} = require('../../common/constants')
const {
preBind,
postBind
} = require('../../lib/utils/relate')
/**
* 微信授权手机号登录
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-weixin-mobile
* @param {Object} params
* @param {String} params.phoneCode 微信手机号返回的code
* @param {String} params.inviteCode 邀请码
* @returns
*/
module.exports = async function (params = {}) {
const schema = {
phoneCode: 'string',
inviteCode: {
type: 'string',
required: false
}
}
this.middleware.validate(params, schema)
const { phoneCode, inviteCode } = params
const weixinApi = initWeixin.call(this)
let mobile
try {
const accessToken = await getWeixinAccessToken.call(this)
const mobileRes = await weixinApi.getPhoneNumber(accessToken, phoneCode)
mobile = mobileRes.purePhoneNumber
} catch (error) {
console.error(error)
await this.middleware.uniIdLog({
success: false,
type: LOG_TYPE.LOGIN
})
throw {
errCode: ERROR.GET_THIRD_PARTY_ACCOUNT_FAILED
}
}
const { type, user } = await preUnifiedLogin.call(this, {
user: {
mobile
}
})
let extraData = {
mobile_confirmed: 1
}
if (type === 'login') {
// 绑定手机号
if (!user.mobile_confirmed) {
const bindAccount = {
mobile
}
await preBind.call(this, {
uid: user._id,
bindAccount,
logType: LOG_TYPE.BIND_MOBILE
})
await postBind.call(this, {
uid: user._id,
bindAccount,
extraData: {
mobile_confirmed: 1
},
logType: LOG_TYPE.BIND_MOBILE
})
extraData = {
...extraData,
...bindAccount
}
}
}
return postUnifiedLogin.call(this, {
user,
extraData: {
...extraData
},
isThirdParty: false,
type,
inviteCode
})
}
...@@ -37,9 +37,19 @@ module.exports = async function (params = {}) { ...@@ -37,9 +37,19 @@ module.exports = async function (params = {}) {
role: 'admin' role: 'admin'
}).limit(1).get() }).limit(1).get()
if (getAdminRes.data.length > 0) { if (getAdminRes.data.length > 0) {
return { const [admin] = getAdminRes.data
errCode: ERROR.ADMIN_EXISTS, const appId = this.getClientInfo().appId
errMsg: this.t('uni-id-admin-exists')
if (!admin.dcloud_appid || (admin.dcloud_appid && admin.dcloud_appid.includes(appId))) {
return {
errCode: ERROR.ADMIN_EXISTS,
errMsg: this.t('uni-id-admin-exists')
}
} else {
return {
errCode: ERROR.ADMIN_EXISTS,
errMsg: this.t('uni-id-admin-exist-in-other-apps')
}
} }
} }
const { const {
......
...@@ -47,7 +47,7 @@ module.exports = async function (params = {}) { ...@@ -47,7 +47,7 @@ module.exports = async function (params = {}) {
} = getAlipayAccountResult } = getAlipayAccountResult
const bindAccount = { const bindAccount = {
apple_openid: openid ali_openid: openid
} }
await preBind.call(this, { await preBind.call(this, {
uid, uid,
......
...@@ -7,8 +7,10 @@ const { ...@@ -7,8 +7,10 @@ const {
} = require('../../common/constants') } = require('../../common/constants')
const { const {
decryptWeixinData, decryptWeixinData,
getWeixinCache getWeixinCache, getWeixinAccessToken
} = require('../../lib/utils/weixin') } = require('../../lib/utils/weixin')
const { initWeixin } = require('../../lib/third-party')
const { ERROR } = require('../../common/error')
/** /**
* 通过微信绑定手机号 * 通过微信绑定手机号
...@@ -16,6 +18,7 @@ const { ...@@ -16,6 +18,7 @@ const {
* @param {Object} params * @param {Object} params
* @param {String} params.encryptedData 微信获取手机号返回的加密信息 * @param {String} params.encryptedData 微信获取手机号返回的加密信息
* @param {String} params.iv 微信获取手机号返回的初始向量 * @param {String} params.iv 微信获取手机号返回的初始向量
* @param {String} params.code 微信获取手机号返回的code
* @returns * @returns
*/ */
module.exports = async function (params = {}) { module.exports = async function (params = {}) {
...@@ -26,30 +29,58 @@ module.exports = async function (params = {}) { ...@@ -26,30 +29,58 @@ module.exports = async function (params = {}) {
* 因此此接口不应直接使用客户端login获取的code,只能使用缓存的sessionKey * 因此此接口不应直接使用客户端login获取的code,只能使用缓存的sessionKey
*/ */
const schema = { const schema = {
encryptedData: 'string', encryptedData: {
iv: 'string' required: false,
type: 'string'
},
iv: {
required: false,
type: 'string'
},
code: {
required: false,
type: 'string'
}
} }
const { const {
encryptedData, encryptedData,
iv iv,
code
} = params } = params
this.middleware.validate(params, schema) this.middleware.validate(params, schema)
if ((!encryptedData && !iv) && !code) {
return {
errCode: ERROR.INVALID_PARAM
}
}
const uid = this.authInfo.uid const uid = this.authInfo.uid
const sessionKey = await getWeixinCache.call(this, { let mobile
uid, if (code) {
key: 'session_key' // 区分客户端类型 小程序还是App
}) const accessToken = await getWeixinAccessToken.call(this)
if (!sessionKey) { const weixinApi = initWeixin.call(this)
throw new Error('Session key not found') const res = await weixinApi.getPhoneNumber(accessToken, code)
mobile = res.purePhoneNumber
} else {
const sessionKey = await getWeixinCache.call(this, {
uid,
key: 'session_key'
})
if (!sessionKey) {
throw new Error('Session key not found')
}
const res = decryptWeixinData.call(this, {
encryptedData,
sessionKey,
iv
})
mobile = res.purePhoneNumber
} }
const {
purePhoneNumber: mobile
} = decryptWeixinData.call(this, {
encryptedData,
sessionKey,
iv
})
const bindAccount = { const bindAccount = {
mobile mobile
......
...@@ -5,5 +5,9 @@ module.exports = { ...@@ -5,5 +5,9 @@ module.exports = {
bindAlipay: require('./bind-alipay'), bindAlipay: require('./bind-alipay'),
bindApple: require('./bind-apple'), bindApple: require('./bind-apple'),
bindQQ: require('./bind-qq'), bindQQ: require('./bind-qq'),
bindWeixin: require('./bind-weixin') bindWeixin: require('./bind-weixin'),
unbindWeixin: require('./unbind-weixin'),
unbindAlipay: require('./unbind-alipay'),
unbindQQ: require('./unbind-qq'),
unbindApple: require('./unbind-apple')
} }
const {
preUnBind,
postUnBind
} = require('../../lib/utils/relate')
const {
LOG_TYPE, dbCmd
} = require('../../common/constants')
/**
* 解绑支付宝
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-alipay
* @returns
*/
module.exports = async function () {
const { uid } = this.authInfo
await preUnBind.call(this, {
uid,
unBindAccount: {
ali_openid: dbCmd.exists(true)
},
logType: LOG_TYPE.UNBIND_ALIPAY
})
return await postUnBind.call(this, {
uid,
unBindAccount: {
ali_openid: dbCmd.remove()
},
logType: LOG_TYPE.UNBIND_ALIPAY
})
}
const {
preUnBind,
postUnBind
} = require('../../lib/utils/relate')
const {
LOG_TYPE, dbCmd
} = require('../../common/constants')
/**
* 解绑apple
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-apple
* @returns
*/
module.exports = async function () {
const { uid } = this.authInfo
await preUnBind.call(this, {
uid,
unBindAccount: {
apple_openid: dbCmd.exists(true)
},
logType: LOG_TYPE.UNBIND_APPLE
})
return await postUnBind.call(this, {
uid,
unBindAccount: {
apple_openid: dbCmd.remove()
},
logType: LOG_TYPE.UNBIND_APPLE
})
}
const {
preUnBind,
postUnBind
} = require('../../lib/utils/relate')
const {
LOG_TYPE, dbCmd
} = require('../../common/constants')
const {
getQQPlatform
} = require('../../lib/utils/qq')
/**
* 解绑QQ
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-qq
* @returns
*/
module.exports = async function () {
const { uid } = this.authInfo
const { appId } = this.getClientInfo()
const qqPlatform = getQQPlatform.call(this)
await preUnBind.call(this, {
uid,
unBindAccount: {
qq_openid: dbCmd.or([
{
[qqPlatform]: dbCmd.exists(true)
},
{
[`${qqPlatform}_${appId}`]: dbCmd.exists(true)
}
]),
qq_unionid: dbCmd.exists(true)
},
logType: LOG_TYPE.UNBIND_QQ
})
return await postUnBind.call(this, {
uid,
unBindAccount: {
qq_openid: dbCmd.remove(),
qq_unionid: dbCmd.remove()
},
logType: LOG_TYPE.UNBIND_QQ
})
}
const {
preUnBind,
postUnBind
} = require('../../lib/utils/relate')
const {
LOG_TYPE, dbCmd
} = require('../../common/constants')
const {
getWeixinPlatform
} = require('../../lib/utils/weixin')
/**
* 解绑微信
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#unbind-weixin
* @returns
*/
module.exports = async function () {
const { uid } = this.authInfo
const weixinPlatform = getWeixinPlatform.call(this)
await preUnBind.call(this, {
uid,
unBindAccount: {
wx_openid: {
[weixinPlatform]: dbCmd.exists(true)
},
wx_unionid: dbCmd.exists(true)
},
logType: LOG_TYPE.UNBIND_WEIXIN
})
return await postUnBind.call(this, {
uid,
unBindAccount: {
wx_openid: dbCmd.remove(),
wx_unionid: dbCmd.remove()
},
logType: LOG_TYPE.UNBIND_WEIXIN
})
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册