Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello_uni-id-pages
提交
61350c19
H
hello_uni-id-pages
项目概览
DCloud
/
hello_uni-id-pages
通知
1051
Star
31
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
61350c19
编写于
11月 29, 2022
作者:
雪洛
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: tips for account not exists in current app
上级
68bf8359
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
1126 addition
and
1097 deletion
+1126
-1097
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/error.js
...d-pages/uniCloud/cloudfunctions/uni-id-co/common/error.js
+1
-0
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js
...d-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js
+214
-197
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/en.js
...uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/en.js
+1
-0
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/zh-hans.js
...d-pages/uniCloud/cloudfunctions/uni-id-co/lang/zh-hans.js
+1
-0
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
-130
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
-232
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js
...s/uniCloud/cloudfunctions/uni-id-co/lib/utils/register.js
+3
-1
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
-162
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
-98
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
-120
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
+9
-1
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
-119
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
+3
-1
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
-36
未找到文件。
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/error.js
浏览文件 @
61350c19
const
ERROR
=
{
ACCOUNT_EXISTS
:
'
uni-id-account-exists
'
,
ACCOUNT_NOT_EXISTS
:
'
uni-id-account-not-exists
'
,
ACCOUNT_NOT_EXISTS_IN_CURRENT_APP
:
'
uni-id-account-not-exists-in-current-app
'
,
ACCOUNT_CONFLICT
:
'
uni-id-account-conflict
'
,
ACCOUNT_BANNED
:
'
uni-id-account-banned
'
,
ACCOUNT_AUDITING
:
'
uni-id-account-auditing
'
,
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/common/utils.js
浏览文件 @
61350c19
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/common/uni-id-co目录执行 npm install 安装依赖
'
)
throw
error
}
module
.
exports
=
{
getType
,
isValidString
,
batchFindObjctValue
,
isPlainObject
,
isFn
,
getDistinctArray
,
getFullTimeStr
,
resolveUrl
,
getOffsetDate
,
camel2snakeJson
,
snake2camelJson
,
getExtension
,
getVerifyCode
,
coverMobile
,
getNonceStr
}
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/common/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/lang/en.js
浏览文件 @
61350c19
...
...
@@ -6,6 +6,7 @@ const word = {
const
sentence
=
{
'
uni-id-account-exists
'
:
'
Account exists
'
,
'
uni-id-account-not-exists
'
:
'
Account does not exists
'
,
'
uni-id-account-not-exists-in-current-app
'
:
'
Account does not exists in current app
'
,
'
uni-id-account-conflict
'
:
'
User account conflict
'
,
'
uni-id-account-banned
'
:
'
Account has been banned
'
,
'
uni-id-account-auditing
'
:
'
Account audit in progress
'
,
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lang/zh-hans.js
浏览文件 @
61350c19
...
...
@@ -6,6 +6,7 @@ const word = {
const
sentence
=
{
'
uni-id-account-exists
'
:
'
此账号已注册
'
,
'
uni-id-account-not-exists
'
:
'
此账号未注册
'
,
'
uni-id-account-not-exists-in-current-app
'
:
'
此账号未在该应用注册
'
,
'
uni-id-account-conflict
'
:
'
用户账号冲突
'
,
'
uni-id-account-banned
'
:
'
此账号已封禁
'
,
'
uni-id-account-auditing
'
:
'
此账号正在审核中
'
,
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/account.js
浏览文件 @
61350c19
const
{
db
,
dbCmd
,
userCollection
}
=
require
(
'
../../common/constants
'
)
const
{
USER_IDENTIFIER
}
=
require
(
'
../../common/constants
'
)
const
{
batchFindObjctValue
,
getType
}
=
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
)
let
appQuery
=
null
if
(
authorizedAppType
===
'
string
'
)
{
// 传入authorizedApp为单个appId时
appQuery
=
dbCmd
.
or
(
{
dcloud_appid
:
authorizedApp
},
{
dcloud_appid
:
dbCmd
.
exists
(
false
)
}
)
}
else
if
(
authorizedAppType
===
'
array
'
)
{
if
(
authorizedApp
.
length
===
0
)
{
// 传入空数组表示希望获取不能登录任一客户端的用户
appQuery
=
{
dcloud_appid
:
[]
}
}
else
if
(
authorizedApp
.
length
===
1
)
{
appQuery
=
dbCmd
.
or
(
{
dcloud_appid
:
authorizedApp
[
0
]
},
{
dcloud_appid
:
dbCmd
.
exists
(
false
)
}
)
}
else
{
appQuery
=
dbCmd
.
or
(
{
dcloud_appid
:
db
.
command
.
in
(
authorizedApp
)
},
{
dcloud_appid
:
dbCmd
.
exists
(
false
)
}
)
}
}
else
{
throw
new
Error
(
'
Invalid authorized app
'
)
}
let
finalQuery
if
(
condition
.
length
===
1
)
{
finalQuery
=
dbCmd
.
and
(
condition
[
0
],
appQuery
)
}
else
{
finalQuery
=
dbCmd
.
and
(
dbCmd
.
or
(
condition
),
appQuery
)
}
const
userQueryRes
=
await
userCollection
.
where
(
finalQuery
).
get
()
return
userQueryRes
.
data
}
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
浏览文件 @
61350c19
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
userMatched
=
await
findUser
({
userQuery
:
user
,
authorizedApp
:
appId
})
if
(
userMatched
.
length
===
0
)
{
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/register.js
浏览文件 @
61350c19
...
...
@@ -22,7 +22,9 @@ async function realPreRegister (params = {}) {
const
{
user
}
=
params
const
userMatched
=
await
findUser
({
const
{
userMatched
}
=
await
findUser
({
userQuery
:
user
,
authorizedApp
:
this
.
getUniversalClientInfo
().
appId
})
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/lib/utils/relate.js
浏览文件 @
61350c19
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
浏览文件 @
61350c19
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
userMatched
=
await
findUser
({
userQuery
:
user
,
authorizedApp
:
appId
})
if
(
userMatched
.
length
===
0
)
{
if
(
type
===
'
login
'
)
{
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
浏览文件 @
61350c19
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
userMatched
=
await
findUser
.
call
(
this
,
{
userQuery
:
{
email
},
authorizedApp
:
[
this
.
getUniversalClientInfo
().
appId
]
})
if
(
userMatched
.
length
===
0
)
{
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
浏览文件 @
61350c19
...
...
@@ -75,13 +75,21 @@ module.exports = async function (params = {}) {
throw
error
}
// 根据手机号查找匹配的用户
const
userMatched
=
await
findUser
.
call
(
this
,
{
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
}
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/admin/add-user.js
浏览文件 @
61350c19
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
浏览文件 @
61350c19
...
...
@@ -92,7 +92,9 @@ module.exports = async function (params = {}) {
// 更新用户名时验证用户名是否重新
if
(
username
)
{
const
userMatched
=
await
findUser
({
const
{
userMatched
}
=
await
findUser
({
userQuery
:
{
username
},
...
...
uni_modules/uni-id-pages/uniCloud/cloudfunctions/uni-id-co/module/multi-end/utils.js
浏览文件 @
61350c19
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
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录