Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello_uni-id-pages
提交
c16e922e
H
hello_uni-id-pages
项目概览
DCloud
/
hello_uni-id-pages
通知
1058
Star
33
Fork
43
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
4
列表
看板
标记
里程碑
合并请求
2
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello_uni-id-pages
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
4
Issue
4
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c16e922e
编写于
1月 16, 2023
作者:
DCloud_JSON
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
修复年前已知问题
上级
b55f807b
变更
38
展开全部
隐藏空白更改
内联
并排
Showing
38 changed file
with
2600 addition
and
2682 deletion
+2600
-2682
manifest.json
manifest.json
+1
-1
uni_modules/uni-captcha/changelog.md
uni_modules/uni-captcha/changelog.md
+5
-0
uni_modules/uni-captcha/components/uni-captcha/uni-captcha.vue
...odules/uni-captcha/components/uni-captcha/uni-captcha.vue
+2
-2
uni_modules/uni-captcha/components/uni-popup-captcha/uni-popup-captcha.vue
...aptcha/components/uni-popup-captcha/uni-popup-captcha.vue
+1
-1
uni_modules/uni-captcha/package.json
uni_modules/uni-captcha/package.json
+4
-7
uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/index.js
...ptcha/uniCloud/cloudfunctions/common/uni-captcha/index.js
+1
-1
uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/package.json
...a/uniCloud/cloudfunctions/common/uni-captcha/package.json
+1
-1
uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/config.js
...-captcha/uniCloud/cloudfunctions/uni-captcha-co/config.js
+17
-0
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
...uniCloud/cloudfunctions/common/uni-config-center/index.js
+1
-1
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
...loud/cloudfunctions/common/uni-config-center/package.json
+1
-1
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-ad/config.json
...loudfunctions/common/uni-config-center/uni-ad/config.json
+3
-0
uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/index.js
...mon/uniCloud/cloudfunctions/common/uni-id-common/index.js
+1
-1
uni_modules/uni-id-pages/changelog.md
uni_modules/uni-id-pages/changelog.md
+4
-0
uni_modules/uni-id-pages/common/store.js
uni_modules/uni-id-pages/common/store.js
+8
-1
uni_modules/uni-id-pages/package.json
uni_modules/uni-id-pages/package.json
+1
-1
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js
...d-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js
+214
-214
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js
...ges/uniCloud/cloudfunctions/uni-id-co/common/validator.js
+1
-1
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js
...i-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js
+616
-616
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js
...es/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js
+97
-97
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js
...ages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js
+240
-240
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js
...ges/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js
+49
-49
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js
...ges/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js
+164
-164
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/unified-login.js
...Cloud/cloudfunctions/uni-id-co/lib/utils/unified-login.js
+106
-106
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-email.js
...dfunctions/uni-id-co/module/account/reset-pwd-by-email.js
+128
-128
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-sms.js
...oudfunctions/uni-id-co/module/account/reset-pwd-by-sms.js
+128
-128
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/update-pwd.js
...oud/cloudfunctions/uni-id-co/module/account/update-pwd.js
+69
-69
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js
...niCloud/cloudfunctions/uni-id-co/module/admin/add-user.js
+121
-121
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js
...loud/cloudfunctions/uni-id-co/module/admin/update-user.js
+139
-139
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-sms.js
...oud/cloudfunctions/uni-id-co/module/login/login-by-sms.js
+99
-99
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js
...iCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js
+38
-38
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user.js
...cloudfunctions/uni-id-co/module/register/register-user.js
+68
-68
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-mp-weixin.js
...tions/uni-id-co/module/relate/bind-mobile-by-mp-weixin.js
+104
-104
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-sms.js
...udfunctions/uni-id-co/module/relate/bind-mobile-by-sms.js
+92
-92
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/set-push-cid.js
...oud/cloudfunctions/uni-id-co/module/utils/set-push-cid.js
+1
-1
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package-lock.json
...pages/uniCloud/cloudfunctions/uni-id-co/package-lock.json
+20
-171
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json
...i-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json
+2
-9
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
...oud/cloudfunctions/common/uni-open-bridge-common/index.js
+3
-1
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
...dfunctions/common/uni-open-bridge-common/weixin-server.js
+50
-9
未找到文件。
manifest.json
浏览文件 @
c16e922e
{
"name"
:
"uni-id-pages"
,
"appid"
:
""
,
"appid"
:
"
__UNI__HelloUniApp
"
,
"description"
:
""
,
"versionName"
:
"1.0.0"
,
"versionCode"
:
"100"
,
...
...
uni_modules/uni-captcha/changelog.md
浏览文件 @
c16e922e
## 0.6.4(2023-01-16)
-
修复 部分情况下APP端无法获取验证码的问题
## 0.6.3(2023-01-11)
-
修复 抖音小程序无法显示的Bug
-
修复 刷新时兼容 device_uuid
## 0.6.1(2022-06-23)
-
修复:部分返回值,不符合响应体规范的问题
## 0.6.0(2022-05-27)
...
...
uni_modules/uni-captcha/components/uni-captcha/uni-captcha.vue
浏览文件 @
c16e922e
...
...
@@ -62,7 +62,7 @@
}
else
{
uni
.
showToast
({
title
:
'
scene不能为空
'
,
icon
:
'
none
'
icon
:
'
none
'
});
}
},
...
...
@@ -88,7 +88,7 @@
.
catch
(
e
=>
{
uni
.
showToast
({
title
:
e
.
message
,
icon
:
'
none
'
icon
:
'
none
'
});
}).
finally
(
e
=>
{
this
.
loging
=
false
...
...
uni_modules/uni-captcha/components/uni-popup-captcha/uni-popup-captcha.vue
浏览文件 @
c16e922e
...
...
@@ -66,7 +66,7 @@
this
.
$refs
.
popup
.
close
()
},
confirm
()
{
if
(
!
this
.
val
||
this
.
val
.
length
<
4
){
if
(
!
this
.
val
){
return
uni
.
showToast
({
title
:
'
请填写验证码
'
,
icon
:
'
none
'
...
...
uni_modules/uni-captcha/package.json
浏览文件 @
c16e922e
{
"id"
:
"uni-captcha"
,
"displayName"
:
"uni-captcha"
,
"version"
:
"0.6.
1
"
,
"version"
:
"0.6.
4
"
,
"description"
:
"云端一体图形验证码组件"
,
"keywords"
:
[
"captcha"
,
...
...
@@ -14,11 +14,7 @@
"engines"
:
{
"HBuilderX"
:
"^3.1.0"
},
"dcloudext"
:
{
"category"
:
[
"uniCloud"
,
"云函数模板"
],
"dcloudext"
:
{
"sale"
:
{
"regular"
:
{
"price"
:
"0.00"
...
...
@@ -35,7 +31,8 @@
"data"
:
"无"
,
"permissions"
:
"无"
},
"npmurl"
:
""
"npmurl"
:
""
,
"type"
:
"unicloud-template-function"
},
"uni_modules"
:
{
"dependencies"
:
[],
...
...
uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/index.js
浏览文件 @
c16e922e
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha/package.json
浏览文件 @
c16e922e
{
"name"
:
"uni-captcha"
,
"version"
:
"0.
2.2
"
,
"version"
:
"0.
6.4
"
,
"description"
:
"uni-captcha"
,
"main"
:
"index.js"
,
"homepage"
:
"https://ext.dcloud.net.cn/plugin?id=4048"
,
...
...
uni_modules/uni-captcha/uniCloud/cloudfunctions/uni-captcha-co/config.js
0 → 100644
浏览文件 @
c16e922e
module
.
exports
=
{
"
image-captcha
"
:{
"
width
"
:
150
,
//图片宽度
"
height
"
:
44
,
//图片高度
"
background
"
:
"
#FFFAE8
"
,
//验证码背景色,设置空字符`''`不使用背景颜色
// "size": 4, //验证码长度,最多 6 个字符
// "noise": 4, //验证码干扰线条数
// "color": false, //字体是否使用随机颜色,当设置`background`后恒为`true`
// "fontSize": 40, //字体大小
// "ignoreChars": '', //忽略那些字符
// "mathExpr": false, //是否使用数学表达式
// "mathMin": 1, //表达式所使用的最小数字
// "mathMax": 9, //表达式所使用的最大数字
// "mathOperator": '' //表达式所使用的运算符,支持 `+`、`-`。不传随机使用
// "expiresDate":180 //验证码过期时间(s)
}
}
\ No newline at end of file
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
浏览文件 @
c16e922e
此差异已折叠。
点击以展开。
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
浏览文件 @
c16e922e
{
"name"
:
"uni-config-center"
,
"version"
:
"0.0.
2
"
,
"version"
:
"0.0.
3
"
,
"description"
:
"配置中心"
,
"main"
:
"index.js"
,
"keywords"
:
[],
...
...
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-ad/config.json
0 → 100644
浏览文件 @
c16e922e
{
"广告位id"
:
"密钥"
}
\ No newline at end of file
uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/index.js
浏览文件 @
c16e922e
此差异已折叠。
点击以展开。
uni_modules/uni-id-pages/changelog.md
浏览文件 @
c16e922e
## 1.0.40(2023-01-16)
-
更新依赖的 验证码插件
`uni-captcha`
版本的版本为 0.6.4 修复 部分情况下APP端无法获取验证码的问题
[
详情参考
](
https://ext.dcloud.net.cn/plugin?id=4048
)
-
修复 客户端token过期后,点击退出登录按钮报错的问题
-
uni-id-co 修复 updateUser 接口
`手机号`
和
`邮箱`
参数值为空字符串时,修改无效的问题
## 1.0.39(2022-12-28)
-
uni-id-co 修复 URL化时第三方登录无法获取 uniPlatform 参数
-
uni-id-co 修复 validator error
...
...
uni_modules/uni-id-pages/common/store.js
浏览文件 @
c16e922e
...
...
@@ -62,7 +62,14 @@ export const mutations = {
return
data
},
async
logout
()
{
await
uniIdCo
.
logout
()
// 1. 已经过期就不需要调用服务端的注销接口 2.即使调用注销接口失败,不能阻塞客户端
if
(
uniCloud
.
getCurrentUserInfo
().
tokenExpired
>
Date
.
now
()){
try
{
await
uniIdCo
.
logout
()
}
catch
(
e
){
console
.
error
(
e
);
}
}
uni
.
removeStorageSync
(
'
uni_id_token
'
);
uni
.
setStorageSync
(
'
uni_id_token_expired
'
,
0
)
uni
.
redirectTo
({
...
...
uni_modules/uni-id-pages/package.json
浏览文件 @
c16e922e
{
"id"
:
"uni-id-pages"
,
"displayName"
:
"uni-id-pages"
,
"version"
:
"1.0.
39
"
,
"version"
:
"1.0.
40
"
,
"description"
:
"云端一体简单、统一、可扩展的用户中心页面模版"
,
"keywords"
:
[
"用户管理"
,
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js
浏览文件 @
c16e922e
function
batchFindObjctValue
(
obj
=
{},
keys
=
[])
{
const
values
=
{}
for
(
let
i
=
0
;
i
<
keys
.
length
;
i
++
)
{
const
key
=
keys
[
i
]
const
keyPath
=
key
.
split
(
'
.
'
)
let
currentKey
=
keyPath
.
shift
()
let
result
=
obj
while
(
currentKey
)
{
if
(
!
result
)
{
break
}
result
=
result
[
currentKey
]
currentKey
=
keyPath
.
shift
()
}
values
[
key
]
=
result
}
return
values
}
function
getType
(
val
)
{
return
Object
.
prototype
.
toString
.
call
(
val
).
slice
(
8
,
-
1
).
toLowerCase
()
}
function
hasOwn
(
obj
,
key
)
{
return
Object
.
prototype
.
hasOwnProperty
.
call
(
obj
,
key
)
}
function
isValidString
(
val
)
{
return
val
&&
getType
(
val
)
===
'
string
'
}
function
isPlainObject
(
obj
)
{
return
getType
(
obj
)
===
'
object
'
}
function
isFn
(
fn
)
{
// 务必注意AsyncFunction
return
typeof
fn
===
'
function
'
}
// 获取文件后缀,只添加几种图片类型供客服消息接口使用
const
mime2ext
=
{
'
image/png
'
:
'
png
'
,
'
image/jpeg
'
:
'
jpg
'
,
'
image/gif
'
:
'
gif
'
,
'
image/svg+xml
'
:
'
svg
'
,
'
image/bmp
'
:
'
bmp
'
,
'
image/webp
'
:
'
webp
'
}
function
getExtension
(
contentType
)
{
return
mime2ext
[
contentType
]
}
const
isSnakeCase
=
/_
(\w)
/g
const
isCamelCase
=
/
[
A-Z
]
/g
function
snake2camel
(
value
)
{
return
value
.
replace
(
isSnakeCase
,
(
_
,
c
)
=>
(
c
?
c
.
toUpperCase
()
:
''
))
}
function
camel2snake
(
value
)
{
return
value
.
replace
(
isCamelCase
,
str
=>
'
_
'
+
str
.
toLowerCase
())
}
function
parseObjectKeys
(
obj
,
type
)
{
let
parserReg
,
parser
switch
(
type
)
{
case
'
snake2camel
'
:
parser
=
snake2camel
parserReg
=
isSnakeCase
break
case
'
camel2snake
'
:
parser
=
camel2snake
parserReg
=
isCamelCase
break
}
for
(
const
key
in
obj
)
{
if
(
hasOwn
(
obj
,
key
))
{
if
(
parserReg
.
test
(
key
))
{
const
keyCopy
=
parser
(
key
)
obj
[
keyCopy
]
=
obj
[
key
]
delete
obj
[
key
]
if
(
isPlainObject
(
obj
[
keyCopy
]))
{
obj
[
keyCopy
]
=
parseObjectKeys
(
obj
[
keyCopy
],
type
)
}
else
if
(
Array
.
isArray
(
obj
[
keyCopy
]))
{
obj
[
keyCopy
]
=
obj
[
keyCopy
].
map
((
item
)
=>
{
return
parseObjectKeys
(
item
,
type
)
})
}
}
}
}
return
obj
}
function
snake2camelJson
(
obj
)
{
return
parseObjectKeys
(
obj
,
'
snake2camel
'
)
}
function
camel2snakeJson
(
obj
)
{
return
parseObjectKeys
(
obj
,
'
camel2snake
'
)
}
function
getOffsetDate
(
offset
)
{
return
new
Date
(
Date
.
now
()
+
(
new
Date
().
getTimezoneOffset
()
+
(
offset
||
0
)
*
60
)
*
60000
)
}
function
getDateStr
(
date
,
separator
=
'
-
'
)
{
date
=
date
||
new
Date
()
const
dateArr
=
[]
dateArr
.
push
(
date
.
getFullYear
())
dateArr
.
push
((
'
00
'
+
(
date
.
getMonth
()
+
1
)).
substr
(
-
2
))
dateArr
.
push
((
'
00
'
+
date
.
getDate
()).
substr
(
-
2
))
return
dateArr
.
join
(
separator
)
}
function
getTimeStr
(
date
,
separator
=
'
:
'
)
{
date
=
date
||
new
Date
()
const
timeArr
=
[]
timeArr
.
push
((
'
00
'
+
date
.
getHours
()).
substr
(
-
2
))
timeArr
.
push
((
'
00
'
+
date
.
getMinutes
()).
substr
(
-
2
))
timeArr
.
push
((
'
00
'
+
date
.
getSeconds
()).
substr
(
-
2
))
return
timeArr
.
join
(
separator
)
}
function
getFullTimeStr
(
date
)
{
date
=
date
||
new
Date
()
return
getDateStr
(
date
)
+
'
'
+
getTimeStr
(
date
)
}
function
getDistinctArray
(
arr
)
{
return
Array
.
from
(
new
Set
(
arr
))
}
/**
* 拼接url
* @param {string} base 基础路径
* @param {string} path 在基础路径上拼接的路径
* @returns
*/
function
resolveUrl
(
base
,
path
)
{
if
(
/^https
?
:/
.
test
(
path
))
{
return
path
}
return
base
+
path
}
function
getVerifyCode
(
len
=
6
)
{
let
code
=
''
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
code
+=
Math
.
floor
(
Math
.
random
()
*
10
)
}
return
code
}
function
coverMobile
(
mobile
)
{
if
(
typeof
mobile
!==
'
string
'
)
{
return
mobile
}
return
mobile
.
slice
(
0
,
3
)
+
'
****
'
+
mobile
.
slice
(
7
)
}
function
getNonceStr
(
length
=
16
)
{
let
str
=
''
while
(
str
.
length
<
length
)
{
str
+=
Math
.
random
().
toString
(
32
).
substring
(
2
)
}
return
str
.
substring
(
0
,
length
)
}
try
{
require
(
'
lodash.merge
'
)
}
catch
(
error
)
{
console
.
error
(
'
uni-id-co缺少依赖,请在uniCloud/cloudfunctions/uni-id-co目录执行 npm install 安装依赖
'
)
throw
error
}
function
isMatchUserApp
(
userAppList
,
matchAppList
)
{
if
(
userAppList
===
undefined
||
userAppList
===
null
)
{
return
true
}
if
(
getType
(
userAppList
)
!==
'
array
'
)
{
return
false
}
if
(
userAppList
.
includes
(
'
*
'
))
{
return
true
}
if
(
getType
(
matchAppList
)
===
'
string
'
)
{
matchAppList
=
[
matchAppList
]
}
return
userAppList
.
some
(
item
=>
matchAppList
.
includes
(
item
))
}
module
.
exports
=
{
getType
,
isValidString
,
batchFindObjctValue
,
isPlainObject
,
isFn
,
getDistinctArray
,
getFullTimeStr
,
resolveUrl
,
getOffsetDate
,
camel2snakeJson
,
snake2camelJson
,
getExtension
,
getVerifyCode
,
coverMobile
,
getNonceStr
,
isMatchUserApp
}
function
batchFindObjctValue
(
obj
=
{},
keys
=
[])
{
const
values
=
{}
for
(
let
i
=
0
;
i
<
keys
.
length
;
i
++
)
{
const
key
=
keys
[
i
]
const
keyPath
=
key
.
split
(
'
.
'
)
let
currentKey
=
keyPath
.
shift
()
let
result
=
obj
while
(
currentKey
)
{
if
(
!
result
)
{
break
}
result
=
result
[
currentKey
]
currentKey
=
keyPath
.
shift
()
}
values
[
key
]
=
result
}
return
values
}
function
getType
(
val
)
{
return
Object
.
prototype
.
toString
.
call
(
val
).
slice
(
8
,
-
1
).
toLowerCase
()
}
function
hasOwn
(
obj
,
key
)
{
return
Object
.
prototype
.
hasOwnProperty
.
call
(
obj
,
key
)
}
function
isValidString
(
val
)
{
return
val
&&
getType
(
val
)
===
'
string
'
}
function
isPlainObject
(
obj
)
{
return
getType
(
obj
)
===
'
object
'
}
function
isFn
(
fn
)
{
// 务必注意AsyncFunction
return
typeof
fn
===
'
function
'
}
// 获取文件后缀,只添加几种图片类型供客服消息接口使用
const
mime2ext
=
{
'
image/png
'
:
'
png
'
,
'
image/jpeg
'
:
'
jpg
'
,
'
image/gif
'
:
'
gif
'
,
'
image/svg+xml
'
:
'
svg
'
,
'
image/bmp
'
:
'
bmp
'
,
'
image/webp
'
:
'
webp
'
}
function
getExtension
(
contentType
)
{
return
mime2ext
[
contentType
]
}
const
isSnakeCase
=
/_
(\w)
/g
const
isCamelCase
=
/
[
A-Z
]
/g
function
snake2camel
(
value
)
{
return
value
.
replace
(
isSnakeCase
,
(
_
,
c
)
=>
(
c
?
c
.
toUpperCase
()
:
''
))
}
function
camel2snake
(
value
)
{
return
value
.
replace
(
isCamelCase
,
str
=>
'
_
'
+
str
.
toLowerCase
())
}
function
parseObjectKeys
(
obj
,
type
)
{
let
parserReg
,
parser
switch
(
type
)
{
case
'
snake2camel
'
:
parser
=
snake2camel
parserReg
=
isSnakeCase
break
case
'
camel2snake
'
:
parser
=
camel2snake
parserReg
=
isCamelCase
break
}
for
(
const
key
in
obj
)
{
if
(
hasOwn
(
obj
,
key
))
{
if
(
parserReg
.
test
(
key
))
{
const
keyCopy
=
parser
(
key
)
obj
[
keyCopy
]
=
obj
[
key
]
delete
obj
[
key
]
if
(
isPlainObject
(
obj
[
keyCopy
]))
{
obj
[
keyCopy
]
=
parseObjectKeys
(
obj
[
keyCopy
],
type
)
}
else
if
(
Array
.
isArray
(
obj
[
keyCopy
]))
{
obj
[
keyCopy
]
=
obj
[
keyCopy
].
map
((
item
)
=>
{
return
parseObjectKeys
(
item
,
type
)
})
}
}
}
}
return
obj
}
function
snake2camelJson
(
obj
)
{
return
parseObjectKeys
(
obj
,
'
snake2camel
'
)
}
function
camel2snakeJson
(
obj
)
{
return
parseObjectKeys
(
obj
,
'
camel2snake
'
)
}
function
getOffsetDate
(
offset
)
{
return
new
Date
(
Date
.
now
()
+
(
new
Date
().
getTimezoneOffset
()
+
(
offset
||
0
)
*
60
)
*
60000
)
}
function
getDateStr
(
date
,
separator
=
'
-
'
)
{
date
=
date
||
new
Date
()
const
dateArr
=
[]
dateArr
.
push
(
date
.
getFullYear
())
dateArr
.
push
((
'
00
'
+
(
date
.
getMonth
()
+
1
)).
substr
(
-
2
))
dateArr
.
push
((
'
00
'
+
date
.
getDate
()).
substr
(
-
2
))
return
dateArr
.
join
(
separator
)
}
function
getTimeStr
(
date
,
separator
=
'
:
'
)
{
date
=
date
||
new
Date
()
const
timeArr
=
[]
timeArr
.
push
((
'
00
'
+
date
.
getHours
()).
substr
(
-
2
))
timeArr
.
push
((
'
00
'
+
date
.
getMinutes
()).
substr
(
-
2
))
timeArr
.
push
((
'
00
'
+
date
.
getSeconds
()).
substr
(
-
2
))
return
timeArr
.
join
(
separator
)
}
function
getFullTimeStr
(
date
)
{
date
=
date
||
new
Date
()
return
getDateStr
(
date
)
+
'
'
+
getTimeStr
(
date
)
}
function
getDistinctArray
(
arr
)
{
return
Array
.
from
(
new
Set
(
arr
))
}
/**
* 拼接url
* @param {string} base 基础路径
* @param {string} path 在基础路径上拼接的路径
* @returns
*/
function
resolveUrl
(
base
,
path
)
{
if
(
/^https
?
:/
.
test
(
path
))
{
return
path
}
return
base
+
path
}
function
getVerifyCode
(
len
=
6
)
{
let
code
=
''
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
code
+=
Math
.
floor
(
Math
.
random
()
*
10
)
}
return
code
}
function
coverMobile
(
mobile
)
{
if
(
typeof
mobile
!==
'
string
'
)
{
return
mobile
}
return
mobile
.
slice
(
0
,
3
)
+
'
****
'
+
mobile
.
slice
(
7
)
}
function
getNonceStr
(
length
=
16
)
{
let
str
=
''
while
(
str
.
length
<
length
)
{
str
+=
Math
.
random
().
toString
(
32
).
substring
(
2
)
}
return
str
.
substring
(
0
,
length
)
}
try
{
require
(
'
lodash.merge
'
)
}
catch
(
error
)
{
console
.
error
(
'
uni-id-co缺少依赖,请在uniCloud/cloudfunctions/uni-id-co目录执行 npm install 安装依赖
'
)
throw
error
}
function
isMatchUserApp
(
userAppList
,
matchAppList
)
{
if
(
userAppList
===
undefined
||
userAppList
===
null
)
{
return
true
}
if
(
getType
(
userAppList
)
!==
'
array
'
)
{
return
false
}
if
(
userAppList
.
includes
(
'
*
'
))
{
return
true
}
if
(
getType
(
matchAppList
)
===
'
string
'
)
{
matchAppList
=
[
matchAppList
]
}
return
userAppList
.
some
(
item
=>
matchAppList
.
includes
(
item
))
}
module
.
exports
=
{
getType
,
isValidString
,
batchFindObjctValue
,
isPlainObject
,
isFn
,
getDistinctArray
,
getFullTimeStr
,
resolveUrl
,
getOffsetDate
,
camel2snakeJson
,
snake2camelJson
,
getExtension
,
getVerifyCode
,
coverMobile
,
getNonceStr
,
isMatchUserApp
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/validator.js
浏览文件 @
c16e922e
...
...
@@ -366,7 +366,7 @@ class Validator {
schemaKey
}
}
else
{
delete
value
[
schemaKey
]
//
delete value[schemaKey]
continue
}
}
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/index.obj.js
浏览文件 @
c16e922e
此差异已折叠。
点击以展开。
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js
浏览文件 @
c16e922e
const
{
db
,
dbCmd
,
userCollection
}
=
require
(
'
../../common/constants
'
)
const
{
USER_IDENTIFIER
}
=
require
(
'
../../common/constants
'
)
const
{
batchFindObjctValue
,
getType
,
isMatchUserApp
}
=
require
(
'
../../common/utils
'
)
/**
* 查询满足条件的用户
* @param {Object} params
* @param {Object} params.userQuery 用户唯一标识组成的查询条件
* @param {Object} params.authorizedApp 用户允许登录的应用
* @returns userMatched 满足条件的用户列表
*/
async
function
findUser
(
params
=
{})
{
const
{
userQuery
,
authorizedApp
=
[]
}
=
params
const
condition
=
getUserQueryCondition
(
userQuery
)
if
(
condition
.
length
===
0
)
{
throw
new
Error
(
'
Invalid user query
'
)
}
const
authorizedAppType
=
getType
(
authorizedApp
)
if
(
authorizedAppType
!==
'
string
'
&&
authorizedAppType
!==
'
array
'
)
{
throw
new
Error
(
'
Invalid authorized app
'
)
}
let
finalQuery
if
(
condition
.
length
===
1
)
{
finalQuery
=
condition
[
0
]
}
else
{
finalQuery
=
dbCmd
.
or
(
condition
)
}
const
userQueryRes
=
await
userCollection
.
where
(
finalQuery
).
get
()
return
{
total
:
userQueryRes
.
data
.
length
,
userMatched
:
userQueryRes
.
data
.
filter
(
item
=>
{
return
isMatchUserApp
(
item
.
dcloud_appid
,
authorizedApp
)
})
}
}
function
getUserIdentifier
(
userRecord
=
{})
{
const
keys
=
Object
.
keys
(
USER_IDENTIFIER
)
return
batchFindObjctValue
(
userRecord
,
keys
)
}
function
getUserQueryCondition
(
userRecord
=
{})
{
const
userIdentifier
=
getUserIdentifier
(
userRecord
)
const
condition
=
[]
for
(
const
key
in
userIdentifier
)
{
const
value
=
userIdentifier
[
key
]
if
(
!
value
)
{
// 过滤所有value为假值的条件,在查询用户时没有意义
continue
}
const
queryItem
=
{
[
key
]:
value
}
// 为兼容用户老数据用户名及邮箱需要同时查小写及原始大小写数据
if
(
key
===
'
mobile
'
)
{
queryItem
.
mobile_confirmed
=
1
}
else
if
(
key
===
'
email
'
)
{
queryItem
.
email_confirmed
=
1
const
email
=
userIdentifier
.
email
if
(
email
.
toLowerCase
()
!==
email
)
{
condition
.
push
({
email
:
email
.
toLowerCase
(),
email_confirmed
:
1
})
}
}
else
if
(
key
===
'
username
'
)
{
const
username
=
userIdentifier
.
username
if
(
username
.
toLowerCase
()
!==
username
)
{
condition
.
push
({
username
:
username
.
toLowerCase
()
})
}
}
condition
.
push
(
queryItem
)
}
return
condition
}
module
.
exports
=
{
findUser
,
getUserIdentifier
}
const
{
db
,
dbCmd
,
userCollection
}
=
require
(
'
../../common/constants
'
)
const
{
USER_IDENTIFIER
}
=
require
(
'
../../common/constants
'
)
const
{
batchFindObjctValue
,
getType
,
isMatchUserApp
}
=
require
(
'
../../common/utils
'
)
/**
* 查询满足条件的用户
* @param {Object} params
* @param {Object} params.userQuery 用户唯一标识组成的查询条件
* @param {Object} params.authorizedApp 用户允许登录的应用
* @returns userMatched 满足条件的用户列表
*/
async
function
findUser
(
params
=
{})
{
const
{
userQuery
,
authorizedApp
=
[]
}
=
params
const
condition
=
getUserQueryCondition
(
userQuery
)
if
(
condition
.
length
===
0
)
{
throw
new
Error
(
'
Invalid user query
'
)
}
const
authorizedAppType
=
getType
(
authorizedApp
)
if
(
authorizedAppType
!==
'
string
'
&&
authorizedAppType
!==
'
array
'
)
{
throw
new
Error
(
'
Invalid authorized app
'
)
}
let
finalQuery
if
(
condition
.
length
===
1
)
{
finalQuery
=
condition
[
0
]
}
else
{
finalQuery
=
dbCmd
.
or
(
condition
)
}
const
userQueryRes
=
await
userCollection
.
where
(
finalQuery
).
get
()
return
{
total
:
userQueryRes
.
data
.
length
,
userMatched
:
userQueryRes
.
data
.
filter
(
item
=>
{
return
isMatchUserApp
(
item
.
dcloud_appid
,
authorizedApp
)
})
}
}
function
getUserIdentifier
(
userRecord
=
{})
{
const
keys
=
Object
.
keys
(
USER_IDENTIFIER
)
return
batchFindObjctValue
(
userRecord
,
keys
)
}
function
getUserQueryCondition
(
userRecord
=
{})
{
const
userIdentifier
=
getUserIdentifier
(
userRecord
)
const
condition
=
[]
for
(
const
key
in
userIdentifier
)
{
const
value
=
userIdentifier
[
key
]
if
(
!
value
)
{
// 过滤所有value为假值的条件,在查询用户时没有意义
continue
}
const
queryItem
=
{
[
key
]:
value
}
// 为兼容用户老数据用户名及邮箱需要同时查小写及原始大小写数据
if
(
key
===
'
mobile
'
)
{
queryItem
.
mobile_confirmed
=
1
}
else
if
(
key
===
'
email
'
)
{
queryItem
.
email_confirmed
=
1
const
email
=
userIdentifier
.
email
if
(
email
.
toLowerCase
()
!==
email
)
{
condition
.
push
({
email
:
email
.
toLowerCase
(),
email_confirmed
:
1
})
}
}
else
if
(
key
===
'
username
'
)
{
const
username
=
userIdentifier
.
username
if
(
username
.
toLowerCase
()
!==
username
)
{
condition
.
push
({
username
:
username
.
toLowerCase
()
})
}
}
condition
.
push
(
queryItem
)
}
return
condition
}
module
.
exports
=
{
findUser
,
getUserIdentifier
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/login.js
浏览文件 @
c16e922e
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
{
mobileComfirmd
:
user
.
mobile_comfirmd
,
emailComfirmd
:
user
.
email_comfirmd
}
}
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
{
token
,
tokenExpired
}
=
await
this
.
uniIdCommon
.
createToken
({
uid
})
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
}
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
{
mobileComfirmd
:
user
.
mobile_comfirmd
,
emailComfirmd
:
user
.
email_comfirmd
}
}
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
{
token
,
tokenExpired
}
=
await
this
.
uniIdCommon
.
createToken
({
uid
})
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
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/logout.js
浏览文件 @
c16e922e
const
{
dbCmd
,
LOG_TYPE
,
deviceCollection
,
userCollection
}
=
require
(
'
../../common/constants
'
)
async
function
logout
()
{
const
{
deviceId
}
=
this
.
getUniversalClientInfo
()
const
uniIdToken
=
this
.
getUniversalUniIdToken
()
const
payload
=
await
this
.
uniIdCommon
.
checkToken
(
uniIdToken
,
{
autoRefresh
:
false
}
)
if
(
payload
.
errCode
)
{
throw
payload
}
const
uid
=
payload
.
uid
// 删除token
await
userCollection
.
doc
(
uid
).
update
({
token
:
dbCmd
.
pull
(
uniIdToken
)
})
// 仅当device表的device_id和user_id均对应时才进行更新
await
deviceCollection
.
where
({
device_id
:
deviceId
,
user_id
:
uid
}).
update
({
token_expired
:
0
})
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
LOG_TYPE
.
LOGOUT
})
return
{
errCode
:
0
}
}
module
.
exports
=
{
logout
}
const
{
dbCmd
,
LOG_TYPE
,
deviceCollection
,
userCollection
}
=
require
(
'
../../common/constants
'
)
async
function
logout
()
{
const
{
deviceId
}
=
this
.
getUniversalClientInfo
()
const
uniIdToken
=
this
.
getUniversalUniIdToken
()
const
payload
=
await
this
.
uniIdCommon
.
checkToken
(
uniIdToken
,
{
autoRefresh
:
false
}
)
if
(
payload
.
errCode
)
{
throw
payload
}
const
uid
=
payload
.
uid
// 删除token
await
userCollection
.
doc
(
uid
).
update
({
token
:
dbCmd
.
pull
(
uniIdToken
)
})
// 仅当device表的device_id和user_id均对应时才进行更新
await
deviceCollection
.
where
({
device_id
:
deviceId
,
user_id
:
uid
}).
update
({
token_expired
:
0
})
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
LOG_TYPE
.
LOGOUT
})
return
{
errCode
:
0
}
}
module
.
exports
=
{
logout
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js
浏览文件 @
c16e922e
const
{
findUser
}
=
require
(
'
./account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
userCollection
,
dbCmd
,
USER_IDENTIFIER
}
=
require
(
'
../../common/constants
'
)
const
{
getUserIdentifier
}
=
require
(
'
../../lib/utils/account
'
)
const
{
batchFindObjctValue
}
=
require
(
'
../../common/utils
'
)
const
merge
=
require
(
'
lodash.merge
'
)
/**
*
* @param {object} param
* @param {string} param.uid 用户id
* @param {string} param.bindAccount 要绑定的三方账户、手机号或邮箱
*/
async
function
preBind
({
uid
,
bindAccount
,
logType
}
=
{})
{
const
{
userMatched
}
=
await
findUser
({
userQuery
:
bindAccount
,
authorizedApp
:
this
.
getUniversalClientInfo
().
appId
})
if
(
userMatched
.
length
>
0
)
{
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
logType
,
success
:
false
})
throw
{
errCode
:
ERROR
.
BIND_CONFLICT
}
}
}
async
function
postBind
({
uid
,
extraData
=
{},
bindAccount
,
logType
}
=
{})
{
await
userCollection
.
doc
(
uid
).
update
(
merge
(
bindAccount
,
extraData
))
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
logType
})
return
{
errCode
:
0
}
}
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
=
{
preBind
,
postBind
,
preUnBind
,
postUnBind
}
const
{
findUser
}
=
require
(
'
./account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
userCollection
,
dbCmd
,
USER_IDENTIFIER
}
=
require
(
'
../../common/constants
'
)
const
{
getUserIdentifier
}
=
require
(
'
../../lib/utils/account
'
)
const
{
batchFindObjctValue
}
=
require
(
'
../../common/utils
'
)
const
merge
=
require
(
'
lodash.merge
'
)
/**
*
* @param {object} param
* @param {string} param.uid 用户id
* @param {string} param.bindAccount 要绑定的三方账户、手机号或邮箱
*/
async
function
preBind
({
uid
,
bindAccount
,
logType
}
=
{})
{
const
{
userMatched
}
=
await
findUser
({
userQuery
:
bindAccount
,
authorizedApp
:
this
.
getUniversalClientInfo
().
appId
})
if
(
userMatched
.
length
>
0
)
{
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
logType
,
success
:
false
})
throw
{
errCode
:
ERROR
.
BIND_CONFLICT
}
}
}
async
function
postBind
({
uid
,
extraData
=
{},
bindAccount
,
logType
}
=
{})
{
await
userCollection
.
doc
(
uid
).
update
(
merge
(
bindAccount
,
extraData
))
await
this
.
middleware
.
uniIdLog
({
data
:
{
user_id
:
uid
},
type
:
logType
})
return
{
errCode
:
0
}
}
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
=
{
preBind
,
postBind
,
preUnBind
,
postUnBind
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/unified-login.js
浏览文件 @
c16e922e
const
{
checkLoginUserRecord
,
postLogin
}
=
require
(
'
./login
'
)
const
{
postRegister
}
=
require
(
'
./register
'
)
const
{
findUser
}
=
require
(
'
./account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
async
function
realPreUnifiedLogin
(
params
=
{})
{
const
{
user
,
type
}
=
params
const
appId
=
this
.
getUniversalClientInfo
().
appId
const
{
total
,
userMatched
}
=
await
findUser
({
userQuery
:
user
,
authorizedApp
:
appId
})
if
(
userMatched
.
length
===
0
)
{
if
(
type
===
'
login
'
)
{
if
(
total
>
0
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS_IN_CURRENT_APP
}
}
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS
}
}
return
{
type
:
'
register
'
,
user
}
}
if
(
userMatched
.
length
===
1
)
{
if
(
type
===
'
register
'
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_EXISTS
}
}
const
userRecord
=
userMatched
[
0
]
checkLoginUserRecord
(
userRecord
)
return
{
type
:
'
login
'
,
user
:
userRecord
}
}
else
if
(
userMatched
.
length
>
1
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_CONFLICT
}
}
}
async
function
preUnifiedLogin
(
params
=
{})
{
try
{
const
result
=
await
realPreUnifiedLogin
.
call
(
this
,
params
)
return
result
}
catch
(
error
)
{
await
this
.
middleware
.
uniIdLog
({
success
:
false
})
throw
error
}
}
async
function
postUnifiedLogin
(
params
=
{})
{
const
{
user
,
extraData
=
{},
isThirdParty
=
false
,
type
,
inviteCode
}
=
params
let
result
if
(
type
===
'
login
'
)
{
result
=
await
postLogin
.
call
(
this
,
{
user
,
extraData
,
isThirdParty
})
}
else
if
(
type
===
'
register
'
)
{
result
=
await
postRegister
.
call
(
this
,
{
user
,
extraData
,
isThirdParty
,
inviteCode
})
}
return
{
...
result
,
type
}
}
module
.
exports
=
{
preUnifiedLogin
,
postUnifiedLogin
}
const
{
checkLoginUserRecord
,
postLogin
}
=
require
(
'
./login
'
)
const
{
postRegister
}
=
require
(
'
./register
'
)
const
{
findUser
}
=
require
(
'
./account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
async
function
realPreUnifiedLogin
(
params
=
{})
{
const
{
user
,
type
}
=
params
const
appId
=
this
.
getUniversalClientInfo
().
appId
const
{
total
,
userMatched
}
=
await
findUser
({
userQuery
:
user
,
authorizedApp
:
appId
})
if
(
userMatched
.
length
===
0
)
{
if
(
type
===
'
login
'
)
{
if
(
total
>
0
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS_IN_CURRENT_APP
}
}
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS
}
}
return
{
type
:
'
register
'
,
user
}
}
if
(
userMatched
.
length
===
1
)
{
if
(
type
===
'
register
'
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_EXISTS
}
}
const
userRecord
=
userMatched
[
0
]
checkLoginUserRecord
(
userRecord
)
return
{
type
:
'
login
'
,
user
:
userRecord
}
}
else
if
(
userMatched
.
length
>
1
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_CONFLICT
}
}
}
async
function
preUnifiedLogin
(
params
=
{})
{
try
{
const
result
=
await
realPreUnifiedLogin
.
call
(
this
,
params
)
return
result
}
catch
(
error
)
{
await
this
.
middleware
.
uniIdLog
({
success
:
false
})
throw
error
}
}
async
function
postUnifiedLogin
(
params
=
{})
{
const
{
user
,
extraData
=
{},
isThirdParty
=
false
,
type
,
inviteCode
}
=
params
let
result
if
(
type
===
'
login
'
)
{
result
=
await
postLogin
.
call
(
this
,
{
user
,
extraData
,
isThirdParty
})
}
else
if
(
type
===
'
register
'
)
{
result
=
await
postRegister
.
call
(
this
,
{
user
,
extraData
,
isThirdParty
,
inviteCode
})
}
return
{
...
result
,
type
}
}
module
.
exports
=
{
preUnifiedLogin
,
postUnifiedLogin
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-email.js
浏览文件 @
c16e922e
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
getNeedCaptcha
,
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
verifyEmailCode
}
=
require
(
'
../../lib/utils/verify-code
'
)
const
{
userCollection
,
EMAIL_SCENE
,
CAPTCHA_SCENE
,
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 通过邮箱验证码重置密码
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#reset-pwd-by-email
* @param {object} params
* @param {string} params.email 邮箱
* @param {string} params.code 邮箱验证码
* @param {string} params.password 密码
* @param {string} params.captcha 图形验证码
* @returns {object}
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
email
:
'
email
'
,
code
:
'
string
'
,
password
:
'
password
'
,
captcha
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
email
,
code
,
password
,
captcha
}
=
params
const
needCaptcha
=
await
getNeedCaptcha
.
call
(
this
,
{
email
,
type
:
LOG_TYPE
.
RESET_PWD_BY_EMAIL
})
if
(
needCaptcha
)
{
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
RESET_PWD_BY_EMAIL
})
}
try
{
// 验证手机号验证码,验证不通过时写入失败日志
await
verifyEmailCode
({
email
,
code
,
scene
:
EMAIL_SCENE
.
RESET_PWD_BY_EMAIL
})
}
catch
(
error
)
{
await
this
.
middleware
.
uniIdLog
({
data
:
{
email
},
type
:
LOG_TYPE
.
RESET_PWD_BY_EMAIL
,
success
:
false
})
throw
error
}
// 根据手机号查找匹配的用户
const
{
total
,
userMatched
}
=
await
findUser
.
call
(
this
,
{
userQuery
:
{
email
},
authorizedApp
:
[
this
.
getUniversalClientInfo
().
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
{
_id
:
uid
}
=
userMatched
[
0
]
const
{
passwordHash
,
version
}
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
}).
generatePasswordHash
({
password
})
// 更新用户密码
await
userCollection
.
doc
(
uid
).
update
({
password
:
passwordHash
,
password_secret_version
:
version
,
valid_token_date
:
Date
.
now
()
})
// 写入成功日志
await
this
.
middleware
.
uniIdLog
({
data
:
{
email
},
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
})
return
{
errCode
:
0
}
}
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
getNeedCaptcha
,
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
verifyEmailCode
}
=
require
(
'
../../lib/utils/verify-code
'
)
const
{
userCollection
,
EMAIL_SCENE
,
CAPTCHA_SCENE
,
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 通过邮箱验证码重置密码
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#reset-pwd-by-email
* @param {object} params
* @param {string} params.email 邮箱
* @param {string} params.code 邮箱验证码
* @param {string} params.password 密码
* @param {string} params.captcha 图形验证码
* @returns {object}
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
email
:
'
email
'
,
code
:
'
string
'
,
password
:
'
password
'
,
captcha
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
email
,
code
,
password
,
captcha
}
=
params
const
needCaptcha
=
await
getNeedCaptcha
.
call
(
this
,
{
email
,
type
:
LOG_TYPE
.
RESET_PWD_BY_EMAIL
})
if
(
needCaptcha
)
{
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
RESET_PWD_BY_EMAIL
})
}
try
{
// 验证手机号验证码,验证不通过时写入失败日志
await
verifyEmailCode
({
email
,
code
,
scene
:
EMAIL_SCENE
.
RESET_PWD_BY_EMAIL
})
}
catch
(
error
)
{
await
this
.
middleware
.
uniIdLog
({
data
:
{
email
},
type
:
LOG_TYPE
.
RESET_PWD_BY_EMAIL
,
success
:
false
})
throw
error
}
// 根据手机号查找匹配的用户
const
{
total
,
userMatched
}
=
await
findUser
.
call
(
this
,
{
userQuery
:
{
email
},
authorizedApp
:
[
this
.
getUniversalClientInfo
().
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
{
_id
:
uid
}
=
userMatched
[
0
]
const
{
passwordHash
,
version
}
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
}).
generatePasswordHash
({
password
})
// 更新用户密码
await
userCollection
.
doc
(
uid
).
update
({
password
:
passwordHash
,
password_secret_version
:
version
,
valid_token_date
:
Date
.
now
()
})
// 写入成功日志
await
this
.
middleware
.
uniIdLog
({
data
:
{
email
},
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
})
return
{
errCode
:
0
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/reset-pwd-by-sms.js
浏览文件 @
c16e922e
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
getNeedCaptcha
,
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
verifyMobileCode
}
=
require
(
'
../../lib/utils/verify-code
'
)
const
{
userCollection
,
SMS_SCENE
,
CAPTCHA_SCENE
,
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 通过短信验证码重置密码
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#reset-pwd-by-sms
* @param {object} params
* @param {string} params.mobile 手机号
* @param {string} params.mobile 短信验证码
* @param {string} params.password 密码
* @param {string} params.captcha 图形验证码
* @returns {object}
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
mobile
:
'
mobile
'
,
code
:
'
string
'
,
password
:
'
password
'
,
captcha
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
mobile
,
code
,
password
,
captcha
}
=
params
const
needCaptcha
=
await
getNeedCaptcha
.
call
(
this
,
{
mobile
,
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
})
if
(
needCaptcha
)
{
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
RESET_PWD_BY_SMS
})
}
try
{
// 验证手机号验证码,验证不通过时写入失败日志
await
verifyMobileCode
({
mobile
,
code
,
scene
:
SMS_SCENE
.
RESET_PWD_BY_SMS
})
}
catch
(
error
)
{
await
this
.
middleware
.
uniIdLog
({
data
:
{
mobile
},
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
,
success
:
false
})
throw
error
}
// 根据手机号查找匹配的用户
const
{
total
,
userMatched
}
=
await
findUser
.
call
(
this
,
{
userQuery
:
{
mobile
},
authorizedApp
:
[
this
.
getUniversalClientInfo
().
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
{
_id
:
uid
}
=
userMatched
[
0
]
const
{
passwordHash
,
version
}
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
}).
generatePasswordHash
({
password
})
// 更新用户密码
await
userCollection
.
doc
(
uid
).
update
({
password
:
passwordHash
,
password_secret_version
:
version
,
valid_token_date
:
Date
.
now
()
})
// 写入成功日志
await
this
.
middleware
.
uniIdLog
({
data
:
{
mobile
},
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
})
return
{
errCode
:
0
}
}
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
getNeedCaptcha
,
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
verifyMobileCode
}
=
require
(
'
../../lib/utils/verify-code
'
)
const
{
userCollection
,
SMS_SCENE
,
CAPTCHA_SCENE
,
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 通过短信验证码重置密码
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#reset-pwd-by-sms
* @param {object} params
* @param {string} params.mobile 手机号
* @param {string} params.mobile 短信验证码
* @param {string} params.password 密码
* @param {string} params.captcha 图形验证码
* @returns {object}
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
mobile
:
'
mobile
'
,
code
:
'
string
'
,
password
:
'
password
'
,
captcha
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
mobile
,
code
,
password
,
captcha
}
=
params
const
needCaptcha
=
await
getNeedCaptcha
.
call
(
this
,
{
mobile
,
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
})
if
(
needCaptcha
)
{
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
RESET_PWD_BY_SMS
})
}
try
{
// 验证手机号验证码,验证不通过时写入失败日志
await
verifyMobileCode
({
mobile
,
code
,
scene
:
SMS_SCENE
.
RESET_PWD_BY_SMS
})
}
catch
(
error
)
{
await
this
.
middleware
.
uniIdLog
({
data
:
{
mobile
},
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
,
success
:
false
})
throw
error
}
// 根据手机号查找匹配的用户
const
{
total
,
userMatched
}
=
await
findUser
.
call
(
this
,
{
userQuery
:
{
mobile
},
authorizedApp
:
[
this
.
getUniversalClientInfo
().
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
{
_id
:
uid
}
=
userMatched
[
0
]
const
{
passwordHash
,
version
}
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
}).
generatePasswordHash
({
password
})
// 更新用户密码
await
userCollection
.
doc
(
uid
).
update
({
password
:
passwordHash
,
password_secret_version
:
version
,
valid_token_date
:
Date
.
now
()
})
// 写入成功日志
await
this
.
middleware
.
uniIdLog
({
data
:
{
mobile
},
type
:
LOG_TYPE
.
RESET_PWD_BY_SMS
})
return
{
errCode
:
0
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/account/update-pwd.js
浏览文件 @
c16e922e
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 更新密码
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-pwd
* @param {object} params
* @param {string} params.oldPassword 旧密码
* @param {string} params.newPassword 新密码
* @returns {object}
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
oldPassword
:
'
string
'
,
// 防止密码规则调整导致旧密码无法更新
newPassword
:
'
password
'
}
this
.
middleware
.
validate
(
params
,
schema
)
const
uid
=
this
.
authInfo
.
uid
const
getUserRes
=
await
userCollection
.
doc
(
uid
).
get
()
const
userRecord
=
getUserRes
.
data
[
0
]
if
(
!
userRecord
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS
}
}
const
{
oldPassword
,
newPassword
}
=
params
const
passwordUtils
=
new
PasswordUtils
({
userRecord
,
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
})
const
{
success
:
checkPasswordSuccess
}
=
passwordUtils
.
checkUserPassword
({
password
:
oldPassword
,
autoRefresh
:
false
})
if
(
!
checkPasswordSuccess
)
{
throw
{
errCode
:
ERROR
.
PASSWORD_ERROR
}
}
const
{
passwordHash
,
version
}
=
passwordUtils
.
generatePasswordHash
({
password
:
newPassword
})
await
userCollection
.
doc
(
uid
).
update
({
password
:
passwordHash
,
password_secret_version
:
version
,
valid_token_date
:
Date
.
now
()
// refreshToken时会校验,如果创建token时间在此时间点之前,则拒绝下发新token,返回token失效错误码
})
// 执行更新密码操作后客户端应将用户退出重新登录
return
{
errCode
:
0
}
}
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 更新密码
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-pwd
* @param {object} params
* @param {string} params.oldPassword 旧密码
* @param {string} params.newPassword 新密码
* @returns {object}
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
oldPassword
:
'
string
'
,
// 防止密码规则调整导致旧密码无法更新
newPassword
:
'
password
'
}
this
.
middleware
.
validate
(
params
,
schema
)
const
uid
=
this
.
authInfo
.
uid
const
getUserRes
=
await
userCollection
.
doc
(
uid
).
get
()
const
userRecord
=
getUserRes
.
data
[
0
]
if
(
!
userRecord
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS
}
}
const
{
oldPassword
,
newPassword
}
=
params
const
passwordUtils
=
new
PasswordUtils
({
userRecord
,
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
})
const
{
success
:
checkPasswordSuccess
}
=
passwordUtils
.
checkUserPassword
({
password
:
oldPassword
,
autoRefresh
:
false
})
if
(
!
checkPasswordSuccess
)
{
throw
{
errCode
:
ERROR
.
PASSWORD_ERROR
}
}
const
{
passwordHash
,
version
}
=
passwordUtils
.
generatePasswordHash
({
password
:
newPassword
})
await
userCollection
.
doc
(
uid
).
update
({
password
:
passwordHash
,
password_secret_version
:
version
,
valid_token_date
:
Date
.
now
()
// refreshToken时会校验,如果创建token时间在此时间点之前,则拒绝下发新token,返回token失效错误码
})
// 执行更新密码操作后客户端应将用户退出重新登录
return
{
errCode
:
0
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js
浏览文件 @
c16e922e
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 新增用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#add-user
* @param {Object} params
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.nickname 昵称
* @param {Array} params.authorizedApp 允许登录的AppID列表
* @param {Array} params.role 用户角色列表
* @param {String} params.mobile 手机号
* @param {String} params.email 邮箱
* @param {Array} params.tags 用户标签
* @param {Number} params.status 用户状态
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
username
:
'
username
'
,
password
:
'
password
'
,
authorizedApp
:
{
required
:
false
,
type
:
'
array<string>
'
},
// 指定允许登录的app,传空数组或不传时表示可以不可以在任何端登录
nickname
:
{
required
:
false
,
type
:
'
nickname
'
},
role
:
{
require
:
false
,
type
:
'
array<string>
'
},
mobile
:
{
required
:
false
,
type
:
'
mobile
'
},
email
:
{
required
:
false
,
type
:
'
email
'
},
tags
:
{
required
:
false
,
type
:
'
array<string>
'
},
status
:
{
required
:
false
,
type
:
'
number
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
username
,
password
,
authorizedApp
,
nickname
,
role
,
mobile
,
email
,
tags
,
status
}
=
params
const
{
userMatched
}
=
await
findUser
({
userQuery
:
{
username
,
mobile
,
email
},
authorizedApp
})
if
(
userMatched
.
length
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_EXISTS
}
}
const
passwordUtils
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
})
const
{
passwordHash
,
version
}
=
passwordUtils
.
generatePasswordHash
({
password
})
const
data
=
{
username
,
password
:
passwordHash
,
password_secret_version
:
version
,
dcloud_appid
:
authorizedApp
||
[],
nickname
,
role
:
role
||
[],
mobile
,
email
,
tags
:
tags
||
[],
status
}
if
(
email
)
{
data
.
email_confirmed
=
1
}
if
(
mobile
)
{
data
.
mobile_confirmed
=
1
}
await
userCollection
.
add
(
data
)
return
{
errCode
:
0
,
errMsg
:
''
}
}
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 新增用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#add-user
* @param {Object} params
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.nickname 昵称
* @param {Array} params.authorizedApp 允许登录的AppID列表
* @param {Array} params.role 用户角色列表
* @param {String} params.mobile 手机号
* @param {String} params.email 邮箱
* @param {Array} params.tags 用户标签
* @param {Number} params.status 用户状态
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
username
:
'
username
'
,
password
:
'
password
'
,
authorizedApp
:
{
required
:
false
,
type
:
'
array<string>
'
},
// 指定允许登录的app,传空数组或不传时表示可以不可以在任何端登录
nickname
:
{
required
:
false
,
type
:
'
nickname
'
},
role
:
{
require
:
false
,
type
:
'
array<string>
'
},
mobile
:
{
required
:
false
,
type
:
'
mobile
'
},
email
:
{
required
:
false
,
type
:
'
email
'
},
tags
:
{
required
:
false
,
type
:
'
array<string>
'
},
status
:
{
required
:
false
,
type
:
'
number
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
username
,
password
,
authorizedApp
,
nickname
,
role
,
mobile
,
email
,
tags
,
status
}
=
params
const
{
userMatched
}
=
await
findUser
({
userQuery
:
{
username
,
mobile
,
email
},
authorizedApp
})
if
(
userMatched
.
length
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_EXISTS
}
}
const
passwordUtils
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
})
const
{
passwordHash
,
version
}
=
passwordUtils
.
generatePasswordHash
({
password
})
const
data
=
{
username
,
password
:
passwordHash
,
password_secret_version
:
version
,
dcloud_appid
:
authorizedApp
||
[],
nickname
,
role
:
role
||
[],
mobile
,
email
,
tags
:
tags
||
[],
status
}
if
(
email
)
{
data
.
email_confirmed
=
1
}
if
(
mobile
)
{
data
.
mobile_confirmed
=
1
}
await
userCollection
.
add
(
data
)
return
{
errCode
:
0
,
errMsg
:
''
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/update-user.js
浏览文件 @
c16e922e
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 修改用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user
* @param {Object} params
* @param {String} params.uid 要更新的用户id
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.nickname 昵称
* @param {Array} params.authorizedApp 允许登录的AppID列表
* @param {Array} params.role 用户角色列表
* @param {String} params.mobile 手机号
* @param {String} params.email 邮箱
* @param {Array} params.tags 用户标签
* @param {Number} params.status 用户状态
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
uid
:
'
string
'
,
username
:
'
username
'
,
password
:
{
required
:
false
,
type
:
'
password
'
},
authorizedApp
:
{
required
:
false
,
type
:
'
array<string>
'
},
// 指定允许登录的app,传空数组或不传时表示可以不可以在任何端登录
nickname
:
{
required
:
false
,
type
:
'
nickname
'
},
role
:
{
require
:
false
,
type
:
'
array<string>
'
},
mobile
:
{
required
:
false
,
type
:
'
mobile
'
},
email
:
{
required
:
false
,
type
:
'
email
'
},
tags
:
{
required
:
false
,
type
:
'
array<string>
'
},
status
:
{
required
:
false
,
type
:
'
number
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
uid
,
username
,
password
,
authorizedApp
,
nickname
,
role
,
mobile
,
email
,
tags
,
status
}
=
params
// 更新的用户数据字段
const
data
=
{
username
,
dcloud_appid
:
authorizedApp
,
nickname
,
role
:
role
,
mobile
,
email
,
tags
:
tags
,
status
}
const
realData
=
Object
.
keys
(
data
).
reduce
((
res
,
key
)
=>
{
const
item
=
data
[
key
]
if
(
item
)
{
res
[
key
]
=
item
}
return
res
},
{})
// 更新用户名时验证用户名是否重新
if
(
username
)
{
const
{
userMatched
}
=
await
findUser
({
userQuery
:
{
username
},
authorizedApp
})
if
(
userMatched
.
filter
(
user
=>
user
.
_id
!==
uid
).
length
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_EXISTS
}
}
}
if
(
password
)
{
const
passwordUtils
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
})
const
{
passwordHash
,
version
}
=
passwordUtils
.
generatePasswordHash
({
password
})
data
.
password
=
passwordHash
data
.
password_secret_version
=
version
}
await
userCollection
.
doc
(
uid
).
update
(
realData
)
return
{
errCode
:
0
}
}
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
PasswordUtils
=
require
(
'
../../lib/utils/password
'
)
/**
* 修改用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#update-user
* @param {Object} params
* @param {String} params.uid 要更新的用户id
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.nickname 昵称
* @param {Array} params.authorizedApp 允许登录的AppID列表
* @param {Array} params.role 用户角色列表
* @param {String} params.mobile 手机号
* @param {String} params.email 邮箱
* @param {Array} params.tags 用户标签
* @param {Number} params.status 用户状态
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
uid
:
'
string
'
,
username
:
'
username
'
,
password
:
{
required
:
false
,
type
:
'
password
'
},
authorizedApp
:
{
required
:
false
,
type
:
'
array<string>
'
},
// 指定允许登录的app,传空数组或不传时表示可以不可以在任何端登录
nickname
:
{
required
:
false
,
type
:
'
nickname
'
},
role
:
{
require
:
false
,
type
:
'
array<string>
'
},
mobile
:
{
required
:
false
,
type
:
'
mobile
'
},
email
:
{
required
:
false
,
type
:
'
email
'
},
tags
:
{
required
:
false
,
type
:
'
array<string>
'
},
status
:
{
required
:
false
,
type
:
'
number
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
uid
,
username
,
password
,
authorizedApp
,
nickname
,
role
,
mobile
,
email
,
tags
,
status
}
=
params
// 更新的用户数据字段
const
data
=
{
username
,
dcloud_appid
:
authorizedApp
,
nickname
,
role
:
role
,
mobile
,
email
,
tags
:
tags
,
status
}
const
realData
=
Object
.
keys
(
data
).
reduce
((
res
,
key
)
=>
{
const
item
=
data
[
key
]
if
(
item
!==
undefined
)
{
res
[
key
]
=
item
}
return
res
},
{})
// 更新用户名时验证用户名是否重新
if
(
username
)
{
const
{
userMatched
}
=
await
findUser
({
userQuery
:
{
username
},
authorizedApp
})
if
(
userMatched
.
filter
(
user
=>
user
.
_id
!==
uid
).
length
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_EXISTS
}
}
}
if
(
password
)
{
const
passwordUtils
=
new
PasswordUtils
({
clientInfo
:
this
.
getUniversalClientInfo
(),
passwordSecret
:
this
.
config
.
passwordSecret
})
const
{
passwordHash
,
version
}
=
passwordUtils
.
generatePasswordHash
({
password
})
realData
.
password
=
passwordHash
realData
.
password_secret_version
=
version
}
await
userCollection
.
doc
(
uid
).
update
(
realData
)
return
{
errCode
:
0
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/login/login-by-sms.js
浏览文件 @
c16e922e
const
{
getNeedCaptcha
,
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
verifyMobileCode
}
=
require
(
'
../../lib/utils/verify-code
'
)
const
{
preUnifiedLogin
,
postUnifiedLogin
}
=
require
(
'
../../lib/utils/unified-login
'
)
const
{
CAPTCHA_SCENE
,
SMS_SCENE
,
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
/**
* 短信验证码登录
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-sms
* @param {Object} params
* @param {String} params.mobile 手机号
* @param {String} params.code 短信验证码
* @param {String} params.captcha 图形验证码
* @param {String} params.inviteCode 邀请码
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
mobile
:
'
mobile
'
,
code
:
'
string
'
,
captcha
:
{
required
:
false
,
type
:
'
string
'
},
inviteCode
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
mobile
,
code
,
captcha
,
inviteCode
}
=
params
const
needCaptcha
=
await
getNeedCaptcha
.
call
(
this
,
{
mobile
})
if
(
needCaptcha
)
{
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
LOGIN_BY_SMS
})
}
try
{
await
verifyMobileCode
({
mobile
,
code
,
scene
:
SMS_SCENE
.
LOGIN_BY_SMS
})
}
catch
(
error
)
{
console
.
log
(
error
,
{
mobile
,
code
,
type
:
SMS_SCENE
.
LOGIN_BY_SMS
})
await
this
.
middleware
.
uniIdLog
({
success
:
false
,
data
:
{
mobile
},
type
:
LOG_TYPE
.
LOGIN
})
throw
error
}
const
{
type
,
user
}
=
await
preUnifiedLogin
.
call
(
this
,
{
user
:
{
mobile
}
})
return
postUnifiedLogin
.
call
(
this
,
{
user
,
extraData
:
{
mobile_confirmed
:
1
},
isThirdParty
:
false
,
type
,
inviteCode
})
}
const
{
getNeedCaptcha
,
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
verifyMobileCode
}
=
require
(
'
../../lib/utils/verify-code
'
)
const
{
preUnifiedLogin
,
postUnifiedLogin
}
=
require
(
'
../../lib/utils/unified-login
'
)
const
{
CAPTCHA_SCENE
,
SMS_SCENE
,
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
/**
* 短信验证码登录
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#login-by-sms
* @param {Object} params
* @param {String} params.mobile 手机号
* @param {String} params.code 短信验证码
* @param {String} params.captcha 图形验证码
* @param {String} params.inviteCode 邀请码
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
mobile
:
'
mobile
'
,
code
:
'
string
'
,
captcha
:
{
required
:
false
,
type
:
'
string
'
},
inviteCode
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
mobile
,
code
,
captcha
,
inviteCode
}
=
params
const
needCaptcha
=
await
getNeedCaptcha
.
call
(
this
,
{
mobile
})
if
(
needCaptcha
)
{
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
LOGIN_BY_SMS
})
}
try
{
await
verifyMobileCode
({
mobile
,
code
,
scene
:
SMS_SCENE
.
LOGIN_BY_SMS
})
}
catch
(
error
)
{
console
.
log
(
error
,
{
mobile
,
code
,
type
:
SMS_SCENE
.
LOGIN_BY_SMS
})
await
this
.
middleware
.
uniIdLog
({
success
:
false
,
data
:
{
mobile
},
type
:
LOG_TYPE
.
LOGIN
})
throw
error
}
const
{
type
,
user
}
=
await
preUnifiedLogin
.
call
(
this
,
{
user
:
{
mobile
}
})
return
postUnifiedLogin
.
call
(
this
,
{
user
,
extraData
:
{
mobile_confirmed
:
1
},
isThirdParty
:
false
,
type
,
inviteCode
})
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js
浏览文件 @
c16e922e
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
async
function
isAuthorizeApproved
({
uid
,
appIdList
}
=
{})
{
const
getUserRes
=
await
userCollection
.
doc
(
uid
).
get
()
const
userRecord
=
getUserRes
.
data
[
0
]
if
(
!
userRecord
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS
}
}
const
{
userMatched
}
=
await
findUser
({
userQuery
:
userRecord
,
authorizedApp
:
appIdList
})
if
(
userMatched
.
some
(
item
=>
item
.
_id
!==
uid
))
{
throw
{
errCode
:
ERROR
.
ACCOUNT_CONFLICT
}
}
}
module
.
exports
=
{
isAuthorizeApproved
}
const
{
userCollection
}
=
require
(
'
../../common/constants
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
const
{
findUser
}
=
require
(
'
../../lib/utils/account
'
)
async
function
isAuthorizeApproved
({
uid
,
appIdList
}
=
{})
{
const
getUserRes
=
await
userCollection
.
doc
(
uid
).
get
()
const
userRecord
=
getUserRes
.
data
[
0
]
if
(
!
userRecord
)
{
throw
{
errCode
:
ERROR
.
ACCOUNT_NOT_EXISTS
}
}
const
{
userMatched
}
=
await
findUser
({
userQuery
:
userRecord
,
authorizedApp
:
appIdList
})
if
(
userMatched
.
some
(
item
=>
item
.
_id
!==
uid
))
{
throw
{
errCode
:
ERROR
.
ACCOUNT_CONFLICT
}
}
}
module
.
exports
=
{
isAuthorizeApproved
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/register/register-user.js
浏览文件 @
c16e922e
const
{
postRegister
,
preRegisterWithPassword
}
=
require
(
'
../../lib/utils/register
'
)
const
{
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
CAPTCHA_SCENE
}
=
require
(
'
../../common/constants
'
)
/**
* 注册普通用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#register-user
* @param {Object} params
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.captcha 图形验证码
* @param {String} params.nickname 昵称
* @param {String} params.inviteCode 邀请码
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
username
:
'
username
'
,
password
:
'
password
'
,
captcha
:
'
string
'
,
nickname
:
{
required
:
false
,
type
:
'
nickname
'
},
inviteCode
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
username
,
password
,
nickname
,
captcha
,
inviteCode
}
=
params
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
REGISTER
})
const
{
user
,
extraData
}
=
await
preRegisterWithPassword
.
call
(
this
,
{
user
:
{
username
},
password
})
return
postRegister
.
call
(
this
,
{
user
,
extraData
:
{
...
extraData
,
nickname
},
inviteCode
})
}
const
{
postRegister
,
preRegisterWithPassword
}
=
require
(
'
../../lib/utils/register
'
)
const
{
verifyCaptcha
}
=
require
(
'
../../lib/utils/captcha
'
)
const
{
CAPTCHA_SCENE
}
=
require
(
'
../../common/constants
'
)
/**
* 注册普通用户
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#register-user
* @param {Object} params
* @param {String} params.username 用户名
* @param {String} params.password 密码
* @param {String} params.captcha 图形验证码
* @param {String} params.nickname 昵称
* @param {String} params.inviteCode 邀请码
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
const
schema
=
{
username
:
'
username
'
,
password
:
'
password
'
,
captcha
:
'
string
'
,
nickname
:
{
required
:
false
,
type
:
'
nickname
'
},
inviteCode
:
{
required
:
false
,
type
:
'
string
'
}
}
this
.
middleware
.
validate
(
params
,
schema
)
const
{
username
,
password
,
nickname
,
captcha
,
inviteCode
}
=
params
await
verifyCaptcha
.
call
(
this
,
{
captcha
,
scene
:
CAPTCHA_SCENE
.
REGISTER
})
const
{
user
,
extraData
}
=
await
preRegisterWithPassword
.
call
(
this
,
{
user
:
{
username
},
password
})
return
postRegister
.
call
(
this
,
{
user
,
extraData
:
{
...
extraData
,
nickname
},
inviteCode
})
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-mp-weixin.js
浏览文件 @
c16e922e
const
{
preBind
,
postBind
}
=
require
(
'
../../lib/utils/relate
'
)
const
{
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
const
{
decryptWeixinData
,
getWeixinCache
,
getWeixinAccessToken
}
=
require
(
'
../../lib/utils/weixin
'
)
const
{
initWeixin
}
=
require
(
'
../../lib/third-party
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
/**
* 通过微信绑定手机号
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-mp-weixin
* @param {Object} params
* @param {String} params.encryptedData 微信获取手机号返回的加密信息
* @param {String} params.iv 微信获取手机号返回的初始向量
* @param {String} params.code 微信获取手机号返回的code
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
/**
* 微信小程序的规则是客户端应先使用checkSession接口检测上次获取的sessionKey是否仍有效
* 如果有效则直接使用上次存储的sessionKey即可
* 如果无效应重新调用login接口再次刷新sessionKey
* 因此此接口不应直接使用客户端login获取的code,只能使用缓存的sessionKey
*/
const
schema
=
{
encryptedData
:
{
required
:
false
,
type
:
'
string
'
},
iv
:
{
required
:
false
,
type
:
'
string
'
},
code
:
{
required
:
false
,
type
:
'
string
'
}
}
const
{
encryptedData
,
iv
,
code
}
=
params
this
.
middleware
.
validate
(
params
,
schema
)
if
((
!
encryptedData
&&
!
iv
)
&&
!
code
)
{
return
{
errCode
:
ERROR
.
INVALID_PARAM
}
}
const
uid
=
this
.
authInfo
.
uid
let
mobile
if
(
code
)
{
// 区分客户端类型 小程序还是App
const
accessToken
=
await
getWeixinAccessToken
.
call
(
this
)
const
weixinApi
=
initWeixin
.
call
(
this
)
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
bindAccount
=
{
mobile
}
await
preBind
.
call
(
this
,
{
uid
,
bindAccount
,
logType
:
LOG_TYPE
.
BIND_MOBILE
})
await
postBind
.
call
(
this
,
{
uid
,
bindAccount
,
extraData
:
{
mobile_confirmed
:
1
},
logType
:
LOG_TYPE
.
BIND_MOBILE
})
return
{
errCode
:
0
}
}
const
{
preBind
,
postBind
}
=
require
(
'
../../lib/utils/relate
'
)
const
{
LOG_TYPE
}
=
require
(
'
../../common/constants
'
)
const
{
decryptWeixinData
,
getWeixinCache
,
getWeixinAccessToken
}
=
require
(
'
../../lib/utils/weixin
'
)
const
{
initWeixin
}
=
require
(
'
../../lib/third-party
'
)
const
{
ERROR
}
=
require
(
'
../../common/error
'
)
/**
* 通过微信绑定手机号
* @tutorial https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#bind-mobile-by-mp-weixin
* @param {Object} params
* @param {String} params.encryptedData 微信获取手机号返回的加密信息
* @param {String} params.iv 微信获取手机号返回的初始向量
* @param {String} params.code 微信获取手机号返回的code
* @returns
*/
module
.
exports
=
async
function
(
params
=
{})
{
/**
* 微信小程序的规则是客户端应先使用checkSession接口检测上次获取的sessionKey是否仍有效
* 如果有效则直接使用上次存储的sessionKey即可
* 如果无效应重新调用login接口再次刷新sessionKey
* 因此此接口不应直接使用客户端login获取的code,只能使用缓存的sessionKey
*/
const
schema
=
{
encryptedData
:
{
required
:
false
,
type
:
'
string
'
},
iv
:
{
required
:
false
,
type
:
'
string
'
},
code
:
{
required
:
false
,
type
:
'
string
'
}
}
const
{
encryptedData
,
iv
,
code
}
=
params
this
.
middleware
.
validate
(
params
,
schema
)
if
((
!
encryptedData
&&
!
iv
)
&&
!
code
)
{
return
{
errCode
:
ERROR
.
INVALID_PARAM
}
}
const
uid
=
this
.
authInfo
.
uid
let
mobile
if
(
code
)
{
// 区分客户端类型 小程序还是App
const
accessToken
=
await
getWeixinAccessToken
.
call
(
this
)
const
weixinApi
=
initWeixin
.
call
(
this
)
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
bindAccount
=
{
mobile
}
await
preBind
.
call
(
this
,
{
uid
,
bindAccount
,
logType
:
LOG_TYPE
.
BIND_MOBILE
})
await
postBind
.
call
(
this
,
{
uid
,
bindAccount
,
extraData
:
{
mobile_confirmed
:
1
},
logType
:
LOG_TYPE
.
BIND_MOBILE
})
return
{
errCode
:
0
}
}
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/relate/bind-mobile-by-sms.js
浏览文件 @
c16e922e
此差异已折叠。
点击以展开。
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/utils/set-push-cid.js
浏览文件 @
c16e922e
...
...
@@ -95,7 +95,7 @@ module.exports = async function (params = {}) {
const
getDeviceRes
=
await
deviceCollection
.
where
({
device_id
:
deviceId
}).
get
()
console
.
log
(
getDeviceRes
)
//
console.log(getDeviceRes)
if
(
getDeviceRes
.
data
.
length
>
1
)
{
return
{
errCode
:
ERROR
.
SYSTEM_ERROR
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package-lock.json
浏览文件 @
c16e922e
此差异已折叠。
点击以展开。
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/package.json
浏览文件 @
c16e922e
{
"name"
:
"uni-id-co"
,
"version"
:
"1.0.3
9
"
,
"version"
:
"1.0.3
8
"
,
"description"
:
""
,
"main"
:
"index.js"
,
"keywords"
:
[],
"author"
:
"DCloud"
,
"dependencies"
:
{
"jsonwebtoken"
:
"8.5.1"
,
"lodash.merge"
:
"
^
4.6.2"
,
"lodash.merge"
:
"4.6.2"
,
"uni-captcha"
:
"file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
,
"uni-config-center"
:
"file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
,
"uni-id-common"
:
"file:../../../../uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
,
...
...
@@ -19,12 +19,5 @@
},
"cloudfunction-config"
:
{
"keepRunningAfterReturn"
:
false
},
"devDependencies"
:
{
"eslint"
:
"^8.18.0"
,
"eslint-config-standard"
:
"^17.0.0"
,
"eslint-plugin-import"
:
"^2.26.0"
,
"eslint-plugin-n"
:
"^15.2.3"
,
"eslint-plugin-promise"
:
"^6.0.0"
}
}
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/index.js
浏览文件 @
c16e922e
...
...
@@ -124,8 +124,10 @@ class Ticket extends Storage {
const
responseData
=
await
WeixinServer
.
GetH5TicketData
(
accessToken
)
const
duration
=
responseData
.
expires_in
const
duration
=
responseData
.
expires_in
||
(
60
*
60
*
2
)
delete
responseData
.
expires_in
delete
responseData
.
errcode
delete
responseData
.
errmsg
return
{
value
:
responseData
,
...
...
uni_modules/uni-open-bridge-common/uniCloud/cloudfunctions/common/uni-open-bridge-common/weixin-server.js
浏览文件 @
c16e922e
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录