Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
T
ts-api-demo
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wmvm
ts-api-demo
Commits
c6a45512
Commit
c6a45512
authored
Dec 07, 2024
by
ml
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
资产管理后台-账户管理、登陆、谷歌等(未测试)
parent
cb257484
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
453 additions
and
95 deletions
+453
-95
errorCode.ts
src/constant/errorCode.ts
+1
-1
abkUserInfo.control.ts
src/functional/mvc/control/v2/abkUserInfo.control.ts
+109
-92
abkUserInfo.service.ts
src/functional/mvc/service/v2/abkUserInfo.service.ts
+260
-0
index.ts
src/functional/router/v2/index.ts
+7
-1
abkUserUtils.ts
src/utils/abkUserUtils.ts
+75
-0
req-utils.ts
src/utils/req-utils.ts
+1
-1
No files found.
src/constant/errorCode.ts
View file @
c6a45512
...
...
@@ -82,5 +82,5 @@ export const ErrorCode = {
PAIR_IS_NOT_ACTIVE
:
'30078'
,
//交易对已是未激活状态
PAIR_IS_HIDE
:
'30079'
,
//交易对已是隐藏状态
PAIR_IS_NOT_HIDE
:
'30080'
,
//交易对已是未隐藏状态
PWD_FORMAT_ERR
:
'3008
1
'
,
//密码格式错误
PWD_FORMAT_ERR
:
'3008
3
'
,
//密码格式错误
}
src/functional/mvc/control/
abkctrl
/abkUserInfo.control.ts
→
src/functional/mvc/control/
v2
/abkUserInfo.control.ts
View file @
c6a45512
import
*
as
abkUserService
from
"../../service/
abkservice
/abkUserInfo.service"
;
import
{
AbkUserInfoVO
,
AbkUserInfoPageVO
}
from
"../../service/abkservice
/abkUserInfo.service"
;
import
*
as
abkUserService
from
"../../service/
v2
/abkUserInfo.service"
;
import
{
AbkUserInfoVO
,
AbkUserInfoPageVO
,
resetAbkTotp
}
from
"../../service/v2
/abkUserInfo.service"
;
let
{
logger
,
Res3Utils
,
optionalUtils
:
Optional
,
apiAssertUtils
:
ApiAssert
}
=
require
(
'@madex/ex-js-public'
);
import
{
ErrorCode
}
from
"../../../../constant/errorCode"
;
import
{
getCurrentUser
,
getCurrentUserId
,
}
from
"../../../utils/aclUserUtils"
;
import
{
getCurrentUser
,
getCurrentUserId
,
}
from
"../../../../utils/aclUserUtils"
;
import
{
isSuperUser
}
from
"../../../../utils/abkUserUtils"
;
let
isIp
=
require
(
'is-ip'
);
/**
* 获取当前登陆的用户信息
* @param req
* @param infoVO
*/
export
const
getInfo
=
async
(
req
:
any
,
aclUserInfoVO
:
AclUserInfoVO
)
=>
{
let
func_name
=
"userOptCtrl.getInfo"
;
let
cmd
=
req
.
path
;
try
{
let
currentUserId
=
await
getCurrentUserId
(
req
.
cookies
.
session_id
);
let
res
=
await
userOptService
.
getInfo
(
currentUserId
,
req
.
cookies
.
session_id
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
/**
* 获取用户信息根据uid
* @param req
* @param infoVO
*/
export
const
getInfoByUserId
=
async
(
req
:
any
,
aclUserInfoVO
:
AclUserInfoVO
)
=>
{
let
func_name
=
"userOptCtrl.getInfoByUserId"
;
let
cmd
=
req
.
path
;
try
{
if
(
!
aclUserInfoVO
.
user_id
)
{
throw
ErrorCode
.
PARAM_MISS
}
let
res
=
await
userOptService
.
getInfoByUserId
(
aclUserInfoVO
.
user_id
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
/**
* 获取用户信息详情(这里主要包含密码、google等敏感信息)根据uid
* @param req
* @param infoVO
*/
export
const
getInfoDetailByUserId
=
async
(
req
:
any
,
aclUserInfoVO
:
AclUserInfoVO
)
=>
{
let
func_name
=
"userOptCtrl.getInfoDetailByUserId"
;
let
cmd
=
req
.
path
;
try
{
if
(
!
aclUserInfoVO
.
user_id
)
{
throw
ErrorCode
.
PARAM_MISS
}
let
res
=
await
userOptService
.
getInfoDetailByUserId
(
aclUserInfoVO
.
user_id
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
/**
* 登陆
* @param req
* @param infoVO
*/
export
const
login
=
async
(
req
:
any
,
abkUserInfoVO
:
AbkUserInfoVO
,
res
:
any
)
=>
{
let
func_name
=
"
userOptCtr
l.login"
;
let
func_name
=
"
abkUserInfo.contro
l.login"
;
let
cmd
=
req
.
path
;
let
result
:
any
;
try
{
...
...
@@ -116,14 +55,14 @@ export const login = async (req: any, abkUserInfoVO: AbkUserInfoVO, res: any) =>
* @param aclUserInfoVO
* @param res
*/
export
const
logout
=
async
(
req
:
any
,
a
clUserInfoVO
:
Acl
UserInfoVO
)
=>
{
let
func_name
=
"
userOptCtr
l.logout"
;
export
const
logout
=
async
(
req
:
any
,
a
bkUserInfoVO
:
Abk
UserInfoVO
)
=>
{
let
func_name
=
"
abkUserInfo.contro
l.logout"
;
let
cmd
=
req
.
path
;
try
{
if
(
req
.
cookies
.
session_id
)
{
let
currentUser
=
await
getCurrentUser
(
req
.
cookies
.
session_id
);
if
(
currentUser
)
{
await
userOptService
.
deleteAll
SessionByUserId
(
currentUser
.
userId
);
await
abkUserService
.
deleteAllAbk
SessionByUserId
(
currentUser
.
userId
);
}
}
return
Res3Utils
.
result
(
'ok'
);
...
...
@@ -134,74 +73,124 @@ export const logout = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
}
};
/**
*
登录-二次验证
*
获取当前登陆的用户信息
* @param req
* @param aclUserInfoVO
* @param res
* @param infoVO
*/
export
const
loginConfirm
=
async
(
req
:
any
,
aclUserInfoVO
:
Acl
UserInfoVO
)
=>
{
let
func_name
=
"
userOptCtrl.loginConfirm
"
;
export
const
getInfo
=
async
(
req
:
any
,
abkUserInfoVO
:
Abk
UserInfoVO
)
=>
{
let
func_name
=
"
abkUserInfo.control.getInfo
"
;
let
cmd
=
req
.
path
;
try
{
ApiAssert
.
notNull
(
ErrorCode
.
PARAM_MISS
,
aclUserInfoVO
.
totpCode
);
let
currentUserId
=
await
getCurrentUserId
(
req
.
cookies
.
session_id
);
let
res
=
await
userOptService
.
loginConfirm
(
req
.
cookies
.
session_id
,
currentUserId
,
aclUserInfoVO
.
totpCode
);
let
res
=
await
abkUserService
.
getInfo
(
currentUserId
,
req
.
cookies
.
session_id
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
/**
*
绑定谷歌-生成新的密钥
*
获取用户信息详情(这里主要包含密码、google等敏感信息)根据uid
* @param req
* @param aclUserInfoVO
* @param res
* @param infoVO
*/
export
const
bindTotpAsk
=
async
(
req
:
any
,
aclUserInfoVO
:
Acl
UserInfoVO
)
=>
{
let
func_name
=
"
userOptCtrl.bindTotpAsk
"
;
export
const
getInfoDetailByUserId
=
async
(
req
:
any
,
abkUserInfoVO
:
Abk
UserInfoVO
)
=>
{
let
func_name
=
"
abkUserInfo.control.getInfoDetailByUserId
"
;
let
cmd
=
req
.
path
;
try
{
if
(
!
abkUserInfoVO
.
user_id
)
{
throw
ErrorCode
.
PARAM_MISS
}
if
(
!
abkUserInfoVO
.
totp_code
)
{
throw
ErrorCode
.
PARAM_MISS
}
let
currentUserId
=
await
getCurrentUserId
(
req
.
cookies
.
session_id
);
let
res
=
await
userOptService
.
bindTotpAsk
(
req
.
cookies
.
session_id
,
currentUserId
);
await
isSuperUser
(
currentUserId
);
let
res
=
await
abkUserService
.
getInfoDetailByUserId
(
abkUserInfoVO
.
user_id
,
abkUserInfoVO
.
totp_code
,
currentUserId
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
/**
* 重置谷歌-生成一个新的密钥返回,保存时重新绑定谷歌
* @param req
* @param authConfigVO
*/
export
const
resetTotp
=
async
(
req
:
any
,
abkUserInfoVO
:
AbkUserInfoVO
)
=>
{
let
func_name
=
"abkUserInfo.control.resetTotp"
;
let
cmd
=
req
.
path
;
try
{
let
currentUserId
=
await
getCurrentUserId
(
req
.
cookies
.
session_id
);
await
isSuperUser
(
currentUserId
)
let
res
=
await
abkUserService
.
resetAbkTotp
(
abkUserInfoVO
.
user_id
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
/**
*
绑定谷歌-验证新密钥
*
获取用户列表
* @param req
* @param aclUserInfoVO
* @param res
* @param infoVO
*/
export
const
bindTotpConfirm
=
async
(
req
:
any
,
aclUserInfoVO
:
AclUserInfo
VO
)
=>
{
let
func_name
=
"
userOptCtrl.bindTotpConfirm
"
;
export
const
userList
=
async
(
req
:
any
,
abkUserInfoPageVO
:
AbkUserInfoPage
VO
)
=>
{
let
func_name
=
"
abkUserInfo.control.userList
"
;
let
cmd
=
req
.
path
;
try
{
abkUserInfoPageVO
.
page
=
Optional
.
opt
(
abkUserInfoPageVO
,
'page'
,
1
);
abkUserInfoPageVO
.
size
=
Optional
.
opt
(
abkUserInfoPageVO
,
'size'
,
20
);
let
currentUserId
=
await
getCurrentUserId
(
req
.
cookies
.
session_id
);
ApiAssert
.
notNull
(
ErrorCode
.
PARAM_MISS
,
aclUserInfoVO
.
totpCode
);
let
res
=
await
userOptService
.
bindTotpConfirm
(
req
.
cookies
.
session_id
,
currentUserId
,
aclUserInfoVO
.
totpCode
);
await
isSuperUser
(
currentUserId
)
let
res
=
await
abkUserService
.
userList
(
abkUserInfoPageVO
,
currentUserId
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
/**
* 修改用户状态
* @param req
* @param infoVO
*/
export
const
updateStatus
=
async
(
req
:
any
,
abkUserInfoPageVO
:
AbkUserInfoPageVO
)
=>
{
let
func_name
=
"abkUserInfo.control.updateStatus"
;
let
cmd
=
req
.
path
;
try
{
if
(
!
abkUserInfoPageVO
.
user_id
)
{
throw
ErrorCode
.
PARAM_MISS
}
if
(
!
abkUserInfoPageVO
.
user_status
)
{
throw
ErrorCode
.
PARAM_MISS
}
let
currentUserId
=
await
getCurrentUserId
(
req
.
cookies
.
session_id
);
await
isSuperUser
(
currentUserId
)
let
res
=
await
abkUserService
.
updateStatus
(
abkUserInfoPageVO
.
user_id
,
abkUserInfoPageVO
.
user_status
,
currentUserId
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
function
checkPwd
(
pwd
:
string
)
{
let
reg
=
/^
(?=
.
[
0-9
])(?=
.
[
A-Z
])(?=
.
[
a-z
])(?=
.
[
!@#%^&*?
])
.
{8,12}
$/
;
if
(
!
reg
.
test
(
pwd
))
{
...
...
@@ -210,3 +199,31 @@ function checkPwd(pwd: string) {
}
/**
* 新增用户信息
* @param req
* @param infoVO
*/
export
const
addAbkUser
=
async
(
req
:
any
,
abkUserInfoVO
:
AbkUserInfoVO
)
=>
{
let
func_name
=
"abkUserInfo.control.getInfo"
;
let
cmd
=
req
.
path
;
try
{
let
currentUserId
=
await
getCurrentUserId
(
req
.
cookies
.
session_id
);
await
isSuperUser
(
currentUserId
);
addCheck
(
abkUserInfoVO
);
let
res
=
await
abkUserService
.
addAbkUser
(
abkUserInfoVO
);
return
Res3Utils
.
result
(
res
);
}
catch
(
e
)
{
logger
.
error
(
`
${
func_name
}
error:
${
e
}
`
);
return
Res3Utils
.
getErrorResult
(
e
);
}
};
function
addCheck
(
abkUserInfoVO
:
AbkUserInfoVO
)
{
if
(
!
abkUserInfoVO
.
account
||
!
abkUserInfoVO
.
pwd
||
!
abkUserInfoVO
.
totp_encrypt
)
{
throw
ErrorCode
.
PARAM_MISS
;
}
checkPwd
(
abkUserInfoVO
.
pwd
);
}
src/functional/mvc/service/
abkservice
/abkUserInfo.service.ts
→
src/functional/mvc/service/
v2
/abkUserInfo.service.ts
View file @
c6a45512
import
{
madAdminOrmDB
,
abkUserInfo
,
aclUserInfo
}
from
"@madex/ex-ts-dao"
;
import
{
getOneA
clUserByAccount
,
getOneAclUserByUid
}
from
"../../../../utils/acl
UserUtils"
;
import
{
madAdminOrmDB
,
abkUserInfo
}
from
"@madex/ex-ts-dao"
;
import
{
getOneA
bkUserByAccount
,
getOneAbkUserByUid
,
checkAbkTotp
}
from
"../../../../utils/abk
UserUtils"
;
import
{
ErrorCode
}
from
"../../../../constant/errorCode"
;
import
{
AbkUserInfoConst
}
from
"../../../../constant/abkUserConstant"
;
import
{
CryptUtils
}
from
"../../../../utils/crypt-utils"
;
import
{
RedisVal
}
from
"../../../../constant/redis-val"
;
import
*
as
aclRoleAuthService
from
"../aclRoleAuth.service"
;
import
Config
from
"../../../../../config"
;
import
{
addOptLog
}
from
"../userOptLog.service"
;
import
*
as
aclUserService
from
"../aclUser.service"
;
const
Otplib
=
require
(
'otplib'
)
;
let
{
logger
,
apiAssertUtils
:
ApiAssert
,
BigNumberUtils
}
=
require
(
'@madex/ex-js-public'
);
let
{
authCommon
:
AuthCommon
,
redisUtilsCommon
:
RedisClient
,
}
=
require
(
'@madex/ex-js-common'
);
...
...
@@ -55,17 +54,17 @@ export async function login(account: any, pwd: any, totp_code: any, ip: string)
ApiAssert
.
isFalse
(
ErrorCode
.
ACCOUNT_STOP
,
userInfo
.
user_status
===
AbkUserInfoConst
.
USER_STATUS
.
STOP
);
ApiAssert
.
isFalse
(
ErrorCode
.
USER_IS_DEL
,
userInfo
.
user_status
===
AbkUserInfoConst
.
USER_STATUS
.
DEL
);
//校验谷歌
await
checkAbkTotp
(
userInfo
.
user_id
,
totp_code
);
await
_checkPwd
(
userInfo
,
pwd
);
let
sessionId
=
CryptUtils
.
sessionId
(
userInfo
.
user_id
);
RedisClient
.
rpush
(
RedisVal
.
s
essionListKey
(
userInfo
.
user_id
),
sessionId
);
RedisClient
.
rpush
(
RedisVal
.
abkS
essionListKey
(
userInfo
.
user_id
),
sessionId
);
let
cookies
=
{
account
:
userInfo
.
account
,
userId
:
userInfo
.
user_id
,
//是否需要进行二次验证。0:不需要或者已通过验证;1:需要;
needConfirm
:
0
,
is_abk_user
:
1
,
allow_ips
:
userInfo
.
allow_ips
,
//ip白名单
totp_encrypt
:
''
...
...
@@ -75,7 +74,6 @@ export async function login(account: any, pwd: any, totp_code: any, ip: string)
//如果绑定了谷歌则必须校验, 增加属性 needConfirm = 1
let
totp_encrypt
=
userInfo
.
totp_encrypt
;
if
(
totp_encrypt
)
{
cookies
.
needConfirm
=
1
;
cookies
.
totp_encrypt
=
totp_encrypt
;
hasTotp
=
1
;
}
...
...
@@ -83,8 +81,10 @@ export async function login(account: any, pwd: any, totp_code: any, ip: string)
await
RedisClient
.
writeSync
(
sessionId
,
cookies
,
Config
.
LOGIN_EXPIRED
);
await
_unlockPwd
(
userInfo
.
user_id
);
//第一次登陆状态改为在用
if
(
!
userInfo
.
user_status
)
{
updateAbkUserStatus
(
userInfo
.
user_id
,
1
);
}
return
{
result
:
"success"
,
sessionId
:
sessionId
,
...
...
@@ -94,40 +94,6 @@ export async function login(account: any, pwd: any, totp_code: any, ip: string)
};
}
/**
* 根据account 查询 资产管理后台用户
* @param account
*/
export
async
function
getOneAbkUserByAccount
(
account
:
string
)
{
let
dbOne
=
await
abkUserInfo
.
prototype
.
findOne
({
where
:
{
account
},
raw
:
true
});
if
(
!
dbOne
)
{
throw
ErrorCode
.
USER_NOT_EXIST
;
}
return
dbOne
;
}
/**
* 根据user_id 查询 资产管理后台用户
* @param account
*/
export
async
function
getOneAbkUserByUserId
(
user_id
:
number
)
{
let
dbOne
=
await
abkUserInfo
.
prototype
.
findOne
({
where
:
{
user_id
},
raw
:
true
});
if
(
!
dbOne
)
{
throw
ErrorCode
.
USER_NOT_EXIST
;
}
return
dbOne
;
}
/**
* 校验密码
...
...
@@ -178,42 +144,117 @@ export async function updateAbkUserStatus(user_id: number, user_status: number)
}
}
export
async
function
loginConfirm
(
sessionId
:
any
,
userId
:
any
,
totpCode
:
any
)
{
export
async
function
deleteAllAbkSessionByUserId
(
userId
:
number
)
{
//获取该账户使用过的所有sessionId
let
sessionListKey
=
RedisVal
.
abkSessionListKey
(
userId
)
RedisClient
.
lrange
(
sessionListKey
,
0
,
-
1
,
async
(
err
,
reply
)
=>
{
//删除所有sessionId
if
(
!
err
&&
reply
&&
reply
.
length
>=
1
)
{
await
RedisClient
.
delSync
(...
reply
)
}
//删除sessionList
await
RedisClient
.
delSync
(
sessionListKey
)
});
}
//判断是否在登录锁定中
let
cookies
=
await
RedisClient
.
getSync
(
sessionId
)
ApiAssert
.
isTrue
(
ErrorCode
.
PARAM_MISS
,
Number
(
cookies
.
needConfirm
)
===
1
);
let
totp_encrypt
=
cookies
.
totp_encrypt
;
//谷歌密钥验证
ApiAssert
.
isTrue
(
ErrorCode
.
UNBOUND_TOTP
,
totp_encrypt
!==
''
);
await
AuthCommon
.
totpCheckSync
(
totpCode
,
totp_encrypt
)
export
const
getInfo
=
async
(
currentUserId
:
number
|
any
,
sessionId
:
string
)
=>
{
let
dbUserInfo
=
await
getOneAbkUserByUid
(
currentUserId
);
//判断是否已经使用过
let
latestVerifiedKey
=
"bastard.totp.used.user."
+
userId
let
latestUsed
=
RedisClient
.
getSync
(
latestVerifiedKey
)
ApiAssert
.
isFalse
(
ErrorCode
.
TOTP_CODE_USED
,
totpCode
===
latestUsed
)
await
RedisClient
.
writeSync
(
latestVerifiedKey
,
totpCode
,
60
*
60
)
ApiAssert
.
isNotEmpty
(
ErrorCode
.
USER_NOT_EXIST
,
dbUserInfo
);
ApiAssert
.
isFalse
(
ErrorCode
.
ACCOUNT_STOP
,
dbUserInfo
.
user_status
===
AbkUserInfoConst
.
USER_STATUS
.
STOP
);
ApiAssert
.
isFalse
(
ErrorCode
.
USER_IS_DEL
,
dbUserInfo
.
user_status
===
AbkUserInfoConst
.
USER_STATUS
.
DEL
);
//解除缓存中的锁定标识
cookies
.
needConfirm
=
0
await
RedisClient
.
writeSync
(
sessionId
,
cookies
,
Config
.
LOGIN_EXPIRED
)
return
"success"
;
}
let
data
=
{
userId
:
dbUserInfo
.
user_id
,
account
:
dbUserInfo
.
account
,
remark
:
dbUserInfo
.
remark
,
allow_ips
:
dbUserInfo
.
allow_ips
,
user_status
:
dbUserInfo
.
user_status
,
user_type
:
dbUserInfo
.
user_type
,
sessionId
:
sessionId
,
hasTotp
:
dbUserInfo
&&
dbUserInfo
.
totp_encrypt
?
1
:
0
,
}
return
data
};
export
const
getInfoDetailByUserId
=
async
(
user_id
:
any
,
totp_code
:
any
,
currentUserId
:
any
)
=>
{
let
dbUserInfo
=
await
getOneAbkUserByUid
(
user_id
);
await
checkAbkTotp
(
currentUserId
,
totp_code
);
ApiAssert
.
isNotEmpty
(
ErrorCode
.
USER_NOT_EXIST
,
dbUserInfo
);
let
data
=
{
userId
:
dbUserInfo
.
user_id
,
account
:
dbUserInfo
.
account
,
remark
:
dbUserInfo
.
remark
,
allow_ips
:
dbUserInfo
.
allow_ips
,
user_status
:
dbUserInfo
.
user_status
,
user_type
:
dbUserInfo
.
user_type
,
hasTotp
:
dbUserInfo
&&
dbUserInfo
.
totp_encrypt
?
1
:
0
,
pwd
:
dbUserInfo
.
pwd
,
pwd_salt
:
dbUserInfo
.
pwd_salt
,
totp_encrypt
:
dbUserInfo
?
dbUserInfo
.
totp_encrypt
:
""
,
}
return
data
};
export
async
function
resetAbkTotp
(
userId
:
number
|
undefined
)
{
if
(
userId
)
{
let
userInfo
=
await
getOneAbkUserByUid
(
Number
(
userId
));
ApiAssert
.
isNotEmpty
(
ErrorCode
.
USER_NOT_EXIST
,
userInfo
);
}
//生成新的密钥
let
totpEncrypt
=
Otplib
.
authenticator
.
generateSecret
();
let
email
=
userId
?
userId
:
0
+
'-'
+
totpEncrypt
.
slice
(
0
,
3
)
let
uri
=
'otpauth://totp/'
+
email
+
'?secret='
+
totpEncrypt
+
'&issuer=team888'
;
return
{
uri
:
uri
,
totpEncrypt
:
totpEncrypt
};
}
export
const
checkAbkTotp
=
async
function
(
user_id
:
number
,
totp_code
:
string
)
{
export
async
function
userList
(
abkUserInfoPageVO
:
AbkUserInfoPageVO
,
currentUserId
:
any
)
{
let
page
=
Number
(
abkUserInfoPageVO
.
page
);
let
size
=
Number
(
abkUserInfoPageVO
.
size
);
//获取谷歌密钥并验证
let
dbUserInfo
=
await
getOneAbkUserByUserId
(
user_id
);
ApiAssert
.
isTrue
(
ErrorCode
.
UNBOUND_TOTP
,
dbUserInfo
&&
dbUserInfo
.
totp_encrypt
!==
''
);
await
AuthCommon
.
totpCheckSync
(
totp_code
,
dbUserInfo
.
totp_encrypt
)
let
res
=
await
abkUserInfo
.
prototype
.
findAndCount
({
where
:
{},
limit
:
size
,
offset
:
(
page
-
1
)
*
size
,
order
:
[[
"user_id"
,
"asc"
]],
raw
:
true
});
for
(
let
item
of
res
.
rows
)
{
delete
item
.
pwd
;
delete
item
.
pwd_salt
;
delete
item
.
totp_encrypt
;
item
.
del_time
=
item
.
user_status
==
AbkUserInfoConst
.
USER_STATUS
.
DEL
?
item
.
updatedAt
:
""
}
return
res
;
}
//判断是否已经使用过
let
latestVerifiedKey
=
"abk.totp.used.user."
+
user_id
let
latestUsed
=
RedisClient
.
getSync
(
latestVerifiedKey
)
ApiAssert
.
isFalse
(
ErrorCode
.
TOTP_CODE_USED
,
totp_code
===
latestUsed
)
await
RedisClient
.
writeSync
(
latestVerifiedKey
,
totp_code
,
60
*
60
)
export
async
function
updateStatus
(
user_id
:
number
,
user_status
:
number
,
currentUserId
:
any
)
{
await
getOneAbkUserByUid
(
user_id
)
await
updateAbkUserStatus
(
user_id
,
user_status
);
return
'success'
;
}
export
async
function
addAbkUser
(
abkUserInfoVO
:
AbkUserInfoVO
)
{
let
insertData
=
{
account
:
abkUserInfoVO
.
account
,
pwd
:
abkUserInfoVO
.
pwd
,
user_status
:
0
,
user_type
:
0
,
remark
:
abkUserInfoVO
.
remark
?
abkUserInfoVO
.
remark
:
""
,
totp_encrypt
:
abkUserInfoVO
.
totp_encrypt
,
allow_ips
:
abkUserInfoVO
.
allow_ips
?
abkUserInfoVO
.
allow_ips
:
""
,
}
await
abkUserInfo
.
prototype
.
create
(
insertData
);
return
'success'
;
}
src/functional/router/v2/index.ts
View file @
c6a45512
...
...
@@ -10,7 +10,7 @@ const {
const
router
=
Express
.
Router
();
import
*
as
abkUserCtrl
from
"../../mvc/control/
abkctrl
/abkUserInfo.control"
;
import
*
as
abkUserCtrl
from
"../../mvc/control/
v2
/abkUserInfo.control"
;
import
*
as
userAuthConfigCtrl
from
"../../mvc/control/userAuthConfig.control"
;
import
Config
from
"../../../../config"
;
...
...
@@ -18,6 +18,12 @@ import Config from "../../../../config";
const
postFunc
=
{
'abkUser/login'
:
abkUserCtrl
.
login
,
'abkUser/logout'
:
abkUserCtrl
.
logout
,
'abkUser/getInfo'
:
abkUserCtrl
.
getInfo
,
'abkUser/getInfoDetailByUserId'
:
abkUserCtrl
.
getInfoDetailByUserId
,
'abkUser/reset/totp'
:
abkUserCtrl
.
resetTotp
,
'abkUser/list'
:
abkUserCtrl
.
userList
,
'abkUser/updateStatus'
:
abkUserCtrl
.
updateStatus
,
'abkUser/addUser'
:
abkUserCtrl
.
addAbkUser
,
/*
'user/login/confirm': userOptCtrl.loginConfirm,
'user/bind/totp/ask': userOptCtrl.bindTotpAsk,
...
...
src/utils/abkUserUtils.ts
0 → 100644
View file @
c6a45512
import
*
as
ReqUtils
from
"./req-utils"
;
import
{
ErrorCode
}
from
"../constant/errorCode"
;
import
{
abkUserInfo
,
aclUserDepartmentPosition
,
madAdminOrmDB
}
from
"@madex/ex-ts-dao"
;
let
{
logger
}
=
require
(
"@madex/ex-js-public"
);
let
{
apiAssertUtils
:
ApiAssert
,
BigNumberUtils
}
=
require
(
'@madex/ex-js-public'
);
let
{
authCommon
:
AuthCommon
,
redisUtilsCommon
:
RedisClient
,
}
=
require
(
'@madex/ex-js-common'
);
/**
* 通过 user_id 查询用户
* @param user_id
*/
export
const
getOneAbkUserByUid
=
async
function
(
user_id
:
number
)
{
if
(
!
user_id
)
{
logger
.
error
(
'abkUserUtils.getOneAbkUserByUid.error:'
+
'user_id is null'
);
throw
ErrorCode
.
PARAM_MISS
}
let
dbInfo
=
await
abkUserInfo
.
prototype
.
findOne
({
where
:
{
user_id
:
user_id
,
},
raw
:
true
});
if
(
!
dbInfo
)
{
logger
.
error
(
'abkUserUtils.getOneAbkUserByUid.error:'
+
'dbInfo is null'
);
throw
ErrorCode
.
USER_NOT_EXIST
}
return
dbInfo
;
}
/**
* 通过 account 查询用户
* @param account
*/
export
const
getOneAbkUserByAccount
=
async
function
(
account
:
string
)
{
if
(
!
account
)
{
logger
.
error
(
'abkUserUtils.getOneAbkUserByAccount.error:'
+
'account is null'
);
throw
ErrorCode
.
PARAM_MISS
}
let
dbInfo
=
await
abkUserInfo
.
prototype
.
findOne
({
where
:
{
account
:
account
,
},
raw
:
true
});
if
(
!
dbInfo
)
{
logger
.
error
(
'abkUserUtils.getOneAbkUserByAccount.error:'
+
'dbInfo is null'
);
throw
ErrorCode
.
USER_NOT_EXIST
}
return
dbInfo
;
}
export
const
checkAbkTotp
=
async
function
(
user_id
:
number
,
totp_code
:
string
)
{
//获取谷歌密钥并验证
let
dbUserInfo
=
await
getOneAbkUserByUid
(
user_id
);
ApiAssert
.
isTrue
(
ErrorCode
.
UNBOUND_TOTP
,
dbUserInfo
&&
dbUserInfo
.
totp_encrypt
!==
''
);
await
AuthCommon
.
totpCheckSync
(
totp_code
,
dbUserInfo
.
totp_encrypt
)
//判断是否已经使用过
let
latestVerifiedKey
=
"abk.totp.used.user."
+
user_id
let
latestUsed
=
RedisClient
.
getSync
(
latestVerifiedKey
)
ApiAssert
.
isFalse
(
ErrorCode
.
TOTP_CODE_USED
,
totp_code
===
latestUsed
)
await
RedisClient
.
writeSync
(
latestVerifiedKey
,
totp_code
,
60
*
60
)
return
'success'
;
}
export
const
isSuperUser
=
async
function
(
user_id
:
any
)
{
let
dbUser
=
await
getOneAbkUserByUid
(
user_id
);
if
(
!
dbUser
.
user_type
)
{
throw
ErrorCode
.
NO_PERMISSION
;
}
}
src/utils/req-utils.ts
View file @
c6a45512
...
...
@@ -73,7 +73,7 @@ export const checkAbkCookie = async (cookies: any, req: any) => {
let
cookieData
=
await
RedisUtils
.
getSync
(
sessionId
);
ApiAssert
.
isNotEmpty
(
ErrorCode
.
NOT_LOGIN
,
cookieData
);
ApiAssert
.
isNotEmpty
(
ErrorCode
.
NO_PERMISSION
,
cookieData
.
is_abk_user
);
ApiAssert
.
isTrue
(
ErrorCode
.
NEED_INPUT_GOOGLE_CODE
,
Number
(
cookieData
.
needConfirm
)
===
0
)
//
ApiAssert.isTrue(ErrorCode.NEED_INPUT_GOOGLE_CODE, Number(cookieData.needConfirm) === 0)
if
(
cookieData
.
allow_ips
)
{
let
ips
=
cookieData
.
allow_ips
.
split
(
","
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment