Commit 7752480f authored by ml's avatar ml

逻辑调整 增加功能

parent 95678d2c
......@@ -875,7 +875,7 @@
},
"node_modules/@madex/ex-js-common": {
"version": "1.0.0",
"resolved": "git+ssh://git@bitbucket.org/biiigle/ex-js-common.git#8731a80a995567cd1c6e9ecdb256ea9df1e0ff31",
"resolved": "git+ssh://git@bitbucket.org/biiigle/ex-js-common.git#91fc84edac31b5b04e37dfeaab51cbb7cb3fd98b",
"license": "ISC",
"dependencies": {
"@madex/ex-js-dao": "git+ssh://git@bitbucket.org/biiigle/ex-js-dao.git#master",
......@@ -1069,9 +1069,9 @@
}
},
"node_modules/@madex/ex-ts-dao": {
"version": "0.0.22",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.22.tgz",
"integrity": "sha512-BUr/YIK2FHnjmVMXVegkVYhFihbv3nVBxrLN1ngcTVuWaABWpsPxufyvPYOm+Wvpn5ndUdHOAPtqUMZr++PppA==",
"version": "0.0.27",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.27.tgz",
"integrity": "sha512-+wt6GSr/Gs+KBjNL1U7xsSUaYGhWNiPhIAjXvlb/Klmx7lzf/95MDbKmD2+bC1ydbTknsiG1XyNE/0Iu/tDS4Q==",
"license": "ISC",
"dependencies": {
"@madex/ex-js-public": "git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#master",
......@@ -1084,9 +1084,9 @@
}
},
"node_modules/@mongodb-js/saslprep": {
"version": "1.1.8",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz",
"integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==",
"version": "1.1.9",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
"integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -1617,9 +1617,9 @@
}
},
"node_modules/@types/node": {
"version": "20.16.3",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/node/-/node-20.16.3.tgz",
"integrity": "sha512-/wdGiWRkMOm53gAsSyFMXFZHbVg7C6CbkrzHNpaHoYfsUWPg7m6ZRKtvQjgvQ9i8WT540a3ydRlRQbxjY30XxQ==",
"version": "20.16.4",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/node/-/node-20.16.4.tgz",
"integrity": "sha512-ioyQ1zK9aGEomJ45zz8S8IdzElyxhvP1RVWnPrXDf6wFaUb+kk1tEcVVJkF7RPGM0VWI7cp5U57oCPIn5iN1qg==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"
......@@ -5016,9 +5016,9 @@
}
},
"node_modules/eslint-module-utils": {
"version": "2.8.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/eslint-module-utils/-/eslint-module-utils-2.8.2.tgz",
"integrity": "sha512-3XnC5fDyc8M4J2E8pt8pmSVRX2M+5yWMCfI/kDZwauQeFgzQOuhcRBFKjTeJagqgk4sFKxe1mvNVnaWwImx/Tg==",
"version": "2.9.0",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/eslint-module-utils/-/eslint-module-utils-2.9.0.tgz",
"integrity": "sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -5765,9 +5765,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"version": "1.15.8",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/follow-redirects/-/follow-redirects-1.15.8.tgz",
"integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==",
"funding": [
{
"type": "individual",
......@@ -11114,9 +11114,9 @@
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.0.1",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/picocolors/-/picocolors-1.0.1.tgz",
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
"version": "1.1.0",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/picocolors/-/picocolors-1.1.0.tgz",
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
"dev": true,
"license": "ISC"
},
......
export const AclUserInfoConst = {
USER_STATUS: {
NORMAL: 0,
LOCK: 1,
DEL: 2,
NORMAL: 0,//正常状态-在职
LOCK: 1,//锁定状态
STOP: 2,//停用状态-离职
},
PWD_STATUS: {
......@@ -11,8 +11,17 @@ export const AclUserInfoConst = {
},
USER_TYPE: {
ADMIN: 1,
SUPPORT: 2,
SUPER_ADMIN: 1,//超管
ADMIN: 2,//管理员
CONTENT_ADMIN: 3,//内容管理员
USER_ADMIN: 4,//用户管理员
ONLY_READ: 5,//只读用户
NORMAL: 6,//普通
},
DEL_FLAG: {
FALSE: 0,//未删除
TRUE: 1,//逻辑删除
},
}
......@@ -51,4 +51,8 @@ export const ErrorCode = {
DEL_UN_SUBMIT_ACTIVE:'30047',//只能删除未提交或未生效的记录
FEE_USED_NOT_DEL:'30048',//费率已生效,不能删除
ONLY_UN_SUBMIT_CAN_SUBMIT:'30049',//只有未提交的记录才能提交
USER_IS_DEL:'30050',//用户已被逻辑删除
IP_ADDR_LIMIT:'30051',//ip地址受限或不在您配置的IP白名单中
DEPARTMENT_HAS_USER:'30052',//当前部门下有用户存在,不允许修改或删除
PWD_ILLEGAL:'30053',//密码过短或过长
}
import * as aclDepartmentService from "../service/aclDepartment.service";
import { AclDepartmentVO, AclDepartmentPageVO } from "../service/aclDepartment.service";
import { getCurrentUserId, } from "../../../utils/aclUserUtils";
import { ErrorCode } from "../../../constant/errorCode";
let isIp = require('is-ip');
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
/**
* 分页查询部门列表
* @param req
* @param infoVO
*/
export const pageList = async (req: any, aclDepartmentPageVO: AclDepartmentPageVO) => {
let func_name = "aclDepartmentCtrl.pageList";
try {
aclDepartmentPageVO.page = Optional.opt(aclDepartmentPageVO, 'page', 1);
aclDepartmentPageVO.size = Optional.opt(aclDepartmentPageVO, 'size', 20);
let res = await aclDepartmentService.pageList(aclDepartmentPageVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 查询所有部门列表
* @param req
* @param infoVO
*/
export const allList = async (req: any, aclDepartmentPageVO: AclDepartmentPageVO) => {
let func_name = "aclDepartmentCtrl.allList";
try {
let res = await aclDepartmentService.allList();
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 部门树
* @param req
* @param infoVO
*/
export const getDepartmentTree = async (req: any, aclDepartmentPageVO: AclDepartmentPageVO) => {
let func_name = "aclDepartmentCtrl.getDepartmentTree";
let cmd = req.path;
try {
let res = await aclDepartmentService.getDepartmentTree();
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 添加部门
* @param req
* @param aclDepartmentVO
*/
export const add = async (req: any, aclDepartmentVO: AclDepartmentVO) => {
let func_name = "aclDepartmentCtrl.add";
let cmd = req.path;
try {
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let res = await aclDepartmentService.add(aclDepartmentVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 修改部门
* @param req
* @param aclDepartmentVO
*/
export const update = async (req: any, aclDepartmentVO: AclDepartmentVO) => {
let func_name = "aclDepartmentCtrl.update";
let cmd = req.path;
try {
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let res = await aclDepartmentService.update(aclDepartmentVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 删除部门
* @param req
* @param aclDepartmentVO
*/
export const del = async (req: any, aclDepartmentVO: AclDepartmentVO) => {
let func_name = "aclDepartmentCtrl.del";
let cmd = req.path;
try {
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let res = await aclDepartmentService.del(Number(aclDepartmentVO.id), currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 根据部门IDS 或者user_id/邮箱/用户名 查询用户
* @param req
* @param infoVO
*/
export const getUserList = async (req: any, aclDepartmentPageVO: AclDepartmentPageVO) => {
let func_name = "aclDepartmentCtrl.getUserList";
try {
aclDepartmentPageVO.page = Optional.opt(aclDepartmentPageVO, 'page', 1);
aclDepartmentPageVO.size = Optional.opt(aclDepartmentPageVO, 'size', 20);
let res = await aclDepartmentService.getUserList(aclDepartmentPageVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
import * as aclPositionService from "../service/aclPosition.service";
import { AclAuthVO, AclAuthPageVO, AclRolePageVO, AclRoleVO } from "../service/aclRoleAuth.service";
import { getCurrentUserId, } from "../../../utils/aclUserUtils";
import { ErrorCode } from "../../../constant/errorCode";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
/**
* 列表
* @param req
* @param infoVO
*/
export const allList = async (req: any, aclAuthPageVO: AclAuthPageVO) => {
let func_name = "aclPositionCtrl.allList";
try {
let res = await aclPositionService.getAllPosition();
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
import * as aclRoleAuthService from "../service/aclRoleAuth.service";
import { AclAuthVO, AclAuthPageVO, AclRolePageVO, AclRoleVO } from "../service/aclRoleAuth.service";
import { getCurrentUserId, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import { getCurrentUserId, } from "../../../utils/aclUserUtils";
import { ErrorCode } from "../../../constant/errorCode";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
......@@ -13,7 +13,6 @@ let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } =
export const authList = async (req: any, aclAuthPageVO: AclAuthPageVO) => {
let func_name = "aclRoleAuthCtrl.authList";
try {
await isAdminUserBySessionId(req.cookies.session_id);
aclAuthPageVO.page = Optional.opt(aclAuthPageVO, 'page', 1);
aclAuthPageVO.size = Optional.opt(aclAuthPageVO, 'size', 20);
let res = await aclRoleAuthService.authList(aclAuthPageVO);
......@@ -71,7 +70,6 @@ export const getAuthByRole = async (req: any, aclAuthVO: AclAuthVO) => {
let func_name = "aclRoleAuthCtrl.getAuthByRole";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
let res = await aclRoleAuthService.getAuthByRole(aclAuthVO.id);
return Res3Utils.result(res);
}
......@@ -89,7 +87,6 @@ export const saveAuth = async (req: any, aclAuthVO: AclAuthVO) => {
let func_name = "aclUserCtrl.saveAuth";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
await preCheckAuth(aclAuthVO);
let res = await aclRoleAuthService.saveAuth(aclAuthVO, req.cookies.session_id);
return Res3Utils.result(res);
......@@ -109,7 +106,6 @@ export const delAuth = async (req: any, aclAuthVO: AclAuthVO) => {
let func_name = "aclUserCtrl.delAuth";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclAuthVO.id);
let res = await aclRoleAuthService.delAuth(aclAuthVO.id, req.cookies.session_id);
return Res3Utils.result(res);
......@@ -129,7 +125,6 @@ export const roleList = async (req: any, aclRolePageVO: AclRolePageVO) => {
let func_name = "aclRoleAuthCtrl.roleList";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
aclRolePageVO.page = Optional.opt(aclRolePageVO, 'page', 1);
aclRolePageVO.size = Optional.opt(aclRolePageVO, 'size', 20);
let currentUserId = await getCurrentUserId(req.cookies.session_id);
......@@ -151,7 +146,6 @@ export const getAllRole = async (req: any, aclRolePageVO: AclRolePageVO) => {
let func_name = "aclRoleAuthCtrl.getAllRole";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
let res = await aclRoleAuthService.getAllRole();
return Res3Utils.result(res);
}
......@@ -189,7 +183,6 @@ export const saveRole = async (req: any, aclRoleVO: AclRoleVO) => {
let func_name = "aclRoleAuthCtrl.saveRole";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
await preCheckRole(aclRoleVO);
let currentUserId = await getCurrentUserId(req.cookies.session_id);
aclRoleVO.creator = currentUserId;
......@@ -211,7 +204,6 @@ export const delRole = async (req: any, aclRoleVO: AclRoleVO) => {
let func_name = "aclRoleAuthCtrl.delRole";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclRoleVO.id);
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await aclRoleAuthService.delRole(aclRoleVO.id, currentUserId);
......@@ -233,7 +225,6 @@ export const changeRoleAuth = async (req: any, aclAuthVO: AclAuthVO) => {
let func_name = "aclRoleAuthCtrl.changeRoleAuth";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclAuthVO.id);
let res = await aclRoleAuthService.changeRoleAuth(aclAuthVO.id, aclAuthVO.authIds, req.cookies.session_id);
return Res3Utils.result(res);
......@@ -253,7 +244,6 @@ export const changeUserRole = async (req: any, aclRoleVO: AclRoleVO) => {
let func_name = "aclRoleAuthCtrl.changeUserRole";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclRoleVO.user_id);
let res = await aclRoleAuthService.changeUserRole(aclRoleVO.user_id, aclRoleVO.roleIds, req.cookies.session_id);
return Res3Utils.result(res);
......
......@@ -3,7 +3,7 @@ import { AclUserInfoVO, AclUserInfoPageVO } from "../service/aclUser.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUserId, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import { checkTotp, getCurrentUserId, } from "../../../utils/aclUserUtils";
/**
* 分页查询用户列表
......@@ -14,7 +14,6 @@ export const list = async (req: any, aclUserInfoPageVO: AclUserInfoPageVO) => {
let func_name = "aclUserCtrl.list";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
aclUserInfoPageVO.page = Optional.opt(aclUserInfoPageVO, 'page', 1);
aclUserInfoPageVO.size = Optional.opt(aclUserInfoPageVO, 'size', 20);
let res = await aclUserService.list(aclUserInfoPageVO);
......@@ -34,9 +33,8 @@ export const add = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "aclUserCtrl.add";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
await preCheck(aclUserInfoVO);
let res = await aclUserService.add(aclUserInfoVO,req.cookies.session_id);
let res = await aclUserService.add(aclUserInfoVO, req.cookies.session_id);
return Res3Utils.result(res);
}
catch (e) {
......@@ -53,9 +51,8 @@ export const update = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "aclUserCtrl.update";
let cmd = req.path;
try {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.user_id);
await isAdminUserBySessionId(req.cookies.session_id);
let res = await aclUserService.update(aclUserInfoVO,req.cookies.session_id);
await updatePreCheck(aclUserInfoVO);
let res = await aclUserService.update(aclUserInfoVO, req.cookies.session_id);
return Res3Utils.result(res);
}
catch (e) {
......@@ -74,8 +71,7 @@ export const updateStatus = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let cmd = req.path;
try {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.user_id);
await isAdminUserBySessionId(req.cookies.session_id);
let res = await aclUserService.updateStatus(aclUserInfoVO,req.cookies.session_id);
let res = await aclUserService.updateStatus(aclUserInfoVO, req.cookies.session_id);
return Res3Utils.result(res);
}
catch (e) {
......@@ -94,8 +90,27 @@ export const resetPwd = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let cmd = req.path;
try {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.user_id);
await isAdminUserBySessionId(req.cookies.session_id);
let res = await aclUserService.resetPwd(aclUserInfoVO,req.cookies.session_id);
let res = await aclUserService.resetPwd(aclUserInfoVO, req.cookies.session_id);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 校验谷歌验证码
* @param req
* @param infoVO
*/
export const checkTotpCode = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "aclUserCtrl.checkTotpCode";
let cmd = req.path;
try {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.totpCode);
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await checkTotp(currentUserId, aclUserInfoVO.totpCode);
return Res3Utils.result(res);
}
catch (e) {
......@@ -109,8 +124,26 @@ export const resetPwd = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
* @param infoVO
*/
async function preCheck(aclUserInfoVO: AclUserInfoVO) {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.remark);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.account);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.user_type);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.department_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.position_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.role_ids);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.totp_encrypt);
if (aclUserInfoVO.pwd && (aclUserInfoVO.pwd.length < 8 || aclUserInfoVO.pwd.length > 30)) {
throw ErrorCode.PWD_ILLEGAL;
}
}
async function updatePreCheck(aclUserInfoVO: AclUserInfoVO) {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.user_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.remark);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.department_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.position_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.role_ids);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.totp_encrypt);
if (aclUserInfoVO.pwd && (aclUserInfoVO.pwd.length < 8 || aclUserInfoVO.pwd.length > 30)) {
throw ErrorCode.PWD_ILLEGAL;
}
}
......@@ -3,7 +3,7 @@ import { QueryVO } from "../service/mUserManage.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUserId, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import { getCurrentUserId, } from "../../../utils/aclUserUtils";
import * as IsEmail from "isemail";
import { isLimitUserId } from "../../../utils/mUserCommonUtils";
......@@ -60,8 +60,7 @@ export const updateUserEmail = async (req: any, queryVO: QueryVO) => {
if (!queryVO.user_id || !queryVO.email || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限修改
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
......@@ -92,8 +91,7 @@ export const lockAccount = async (req: any, queryVO: QueryVO) => {
if (!queryVO.user_id || !queryVO.lock_type || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
......@@ -122,8 +120,7 @@ export const unlockAccount = async (req: any, queryVO: QueryVO) => {
if (!queryVO.user_id || !queryVO.lock_type || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
......@@ -150,8 +147,7 @@ export const clearLoginLimit = async (req: any, queryVO: QueryVO) => {
if (!queryVO.user_id || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
......@@ -179,8 +175,7 @@ export const clear24WithdrawLimit = async (req: any, queryVO: QueryVO) => {
if (!queryVO.user_id || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
......
......@@ -3,7 +3,7 @@ import { QueryVO } from "../service/mUserRealName.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUserId, getOneAclUserByUid, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import { getCurrentUserId, getOneAclUserByUid, } from "../../../utils/aclUserUtils";
import { isLimitUserId } from "../../../utils/mUserCommonUtils";
import { AclUserInfoConst } from "../../../constant/aclUserConstant";
......@@ -43,8 +43,6 @@ export const oneDetail = async (req: any, queryVO: QueryVO) => {
if (!queryVO.id) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限修改
await isAdminUserBySessionId(req.cookies.session_id);
let res = await mUserRealNameService.oneDetail(queryVO.id);
return Res3Utils.result(res);
......@@ -65,8 +63,6 @@ export const audit = async (req: any, queryVO: QueryVO) => {
if (!queryVO.id) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限修改
await isAdminUserBySessionId(req.cookies.session_id);
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let res = await mUserRealNameService.audit(queryVO, currentUserId, ip);
......
......@@ -3,73 +3,10 @@ import { AuthConfigVO, AuthConfigPageVO } from "../service/userAuthConfig.servic
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUserId, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import { getCurrentUserId, } from "../../../utils/aclUserUtils";
/**
* 分页查询用户安全项配置列表
* @param req
* @param infoVO
*/
export const authConfigList = async (req: any, authConfigPageVO: AuthConfigPageVO) => {
let func_name = "userAuthConfigCtrl.queryConfigList";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
authConfigPageVO.page = Optional.opt(authConfigPageVO, 'page', 1);
authConfigPageVO.size = Optional.opt(authConfigPageVO, 'size', 20);
let res = await userAuthConfigService.queryConfigList(authConfigPageVO.user_id, authConfigPageVO.user_type,
authConfigPageVO.page, authConfigPageVO.size);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 开启、关闭指定账户的"强制绑定谷歌"属性
* @param req
* @param infoVO
*/
export const changeForceStatus = async (req: any, authConfigVO: AuthConfigVO) => {
let func_name = "userAuthConfigCtrl.changeForceStatus";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, authConfigVO.user_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, authConfigVO.force);
let res = await userAuthConfigService.changeForceStatus(Number(authConfigVO.user_id), authConfigVO.force,req.cookies.session_id);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 解锁指定账户
* @param req
* @param infoVO
*/
export const changeLockedStatus = async (req: any, authConfigVO: AuthConfigVO) => {
let func_name = "userAuthConfigCtrl.changeLockedStatus";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, authConfigVO.user_id);
//暂时只支持解锁
let res = await userAuthConfigService.changeLockedStatus(authConfigVO.user_id,req.cookies.session_id);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 清除谷歌验证
* 重置谷歌-生成一个新的密钥返回,保存时重新绑定谷歌
* @param req
* @param authConfigVO
*/
......@@ -77,9 +14,8 @@ export const resetTotp = async (req: any, authConfigVO: AuthConfigVO) => {
let func_name = "userAuthConfigCtrl.resetTotp";
let cmd = req.path;
try {
await isAdminUserBySessionId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, authConfigVO.user_id);
let res = await userAuthConfigService.resetTotp(authConfigVO.user_id,req.cookies.session_id);
let res = await userAuthConfigService.resetTotp(authConfigVO.user_id);
return Res3Utils.result(res);
}
catch (e) {
......
......@@ -3,12 +3,12 @@ import { AclUserInfoVO, AclUserInfoPageVO } from "../service/aclUser.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUser, getCurrentUserId, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import { getCurrentUser, getCurrentUserId, } from "../../../utils/aclUserUtils";
let isIp = require('is-ip');
/**
* 获取用户信息
* 获取当前登陆的用户信息
* @param req
* @param infoVO
*/
......@@ -26,6 +26,48 @@ export const getInfo = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
}
};
/**
* 获取用户信息根据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);
}
};
/**
* 登陆
......@@ -116,37 +158,7 @@ export const loginConfirm = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
};
/**
* 修改密码
* @param req
* @param aclUserInfoVO
* @param res
*/
export const updatePwd = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "userOptCtrl.updatePwd";
let cmd = req.path;
try {
let originPwd = aclUserInfoVO.originPwd;
let newPwd = aclUserInfoVO.newPwd;
let currentUserId = await getCurrentUserId(req.cookies.session_id);
ApiAssert.isNotEmpty(ErrorCode.PARAM_MISS, originPwd);
ApiAssert.isFalse(ErrorCode.PARAM_MISS, originPwd.length < 8);
ApiAssert.isFalse(ErrorCode.PARAM_MISS, originPwd.length > 30);
ApiAssert.isNotEmpty(ErrorCode.PARAM_MISS, newPwd);
ApiAssert.isFalse(ErrorCode.PARAM_MISS, newPwd.length < 8);
ApiAssert.isFalse(ErrorCode.PARAM_MISS, newPwd.length > 30);
let res = await userOptService.updatePwd(currentUserId, originPwd, newPwd);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 绑定谷歌-生成新的密钥
......
// @madex/ex-ts-dao 是 ts 的 dao, 代码在 bitbucket/ex-js-dao 的 ts 分支上
import { madAdminOrmDB, aclDepartment, aclUserDepartmentPosition, aclPosition, aclUserInfo } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { getOneAclUserByUid } from "../../../utils/aclUserUtils";
import * as userOptLogService from "./userOptLog.service";
import { addOptLog, LogType } from "./userOptLog.service";
let _ = require("lodash");
let { logger } = require('@madex/ex-js-public');
export interface AclDepartmentVO {
id?: number;
pid?: number;
name?: string | any;
level?: number | any;
remark?: string | any;
createdAt?: Date | any;
updatedAt?: Date | any;
}
export interface AclDepartmentPageVO extends AclDepartmentVO {
page?: number,
size?: number
account?: string | any
dIds?: string | any
}
export const getAllDepartment = async function () {
let res = await aclDepartment.prototype.findAll({
raw: true,
});
return res
}
export const pageList = async function (aclDepartmentPageVO: AclDepartmentPageVO) {
let where = {};
if (aclDepartmentPageVO.name) {
where["name"] = { [madAdminOrmDB.Op.like]: `${aclDepartmentPageVO.name}%` }
}
if (aclDepartmentPageVO.level) {
where["level"] = aclDepartmentPageVO.level
}
let size = Number(aclDepartmentPageVO.size);
let page = Number(aclDepartmentPageVO.page);
let resList = await aclDepartment.prototype.findAndCount({
where: where,
limit: size,
offset: (page - 1) * size,
order: [["level", "asc"]],
raw: true
});
return resList;
}
export const allList = async function () {
let resList = await aclDepartment.prototype.findAll({
order: [["level", "asc"]],
raw: true
});
return resList;
}
export const getDepartmentTree = async function () {
let departmentMap = {};
let resList: any = [];
let departmentList = await aclDepartment.prototype.findAll({
attributes: ['id', 'pid', 'name', 'level'],
order: [["pid"], ["level"]],
raw: true
});
let departmentUserMap = await getAllUserDepartmentPositionMap();
for (let oneDepartment of departmentList) {
departmentMap[oneDepartment.id] = oneDepartment;
let pid = oneDepartment.pid;
if (Number(pid) === -1) {
let departmentIds: number[] = [oneDepartment.id];
oneDepartment.department_ids = departmentIds;
resList.push(oneDepartment);
oneDepartment.userList = departmentUserMap[departmentIds.toString()] ? departmentUserMap[departmentIds.toString()] : []
}
else {
let pDepartment = departmentMap[pid];
if (!pDepartment) {
logger.warn("上级部门被删除或者不存在");
continue
}
else {
let departmentIds = pDepartment.department_ids;
let tmp: number[] = [];
tmp.push(...departmentIds, oneDepartment.id);
oneDepartment.department_ids = tmp;
oneDepartment.userList = departmentUserMap[tmp.toString()] ? departmentUserMap[tmp.toString()] : []
}
if (!pDepartment['nextList']) {
pDepartment['nextList'] = [];
}
pDepartment['nextList'].push(oneDepartment);
}
}
return resList;
}
export const add = async function (aclDepartmentVO: AclDepartmentVO, currentUserId: any, ip: string | undefined) {
if (!aclDepartmentVO.name || !aclDepartmentVO.level) {
throw ErrorCode.PARAM_MISS
}
await aclDepartment.prototype.create({
pid: aclDepartmentVO.pid ? aclDepartmentVO.pid : -1,
name: aclDepartmentVO.name,
level: aclDepartmentVO.level,
createdAt: new Date(),
updatedAt: new Date(),
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},新增部门:${JSON.stringify(aclDepartmentVO)}`, LogType.ADD);
return 'success'
}
export const update = async function (aclDepartmentVO: AclDepartmentVO, currentUserId: any, ip: string | undefined) {
if (!aclDepartmentVO.id) {
throw ErrorCode.PARAM_MISS
}
let dbInfo = await aclDepartment.prototype.findOne({
where: { id: aclDepartmentVO.id },
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST;
}
let dbPid = dbInfo.pid;
//要修改部门的上级,需要确定当前部门下没有用户
if (aclDepartmentVO.pid && aclDepartmentVO.pid != dbPid) {
let udpInfo = await aclUserDepartmentPosition.prototype.findOne({
where: {
department_id: { [madAdminOrmDB.Op.like]: `%${aclDepartmentVO.id}%` }
},
raw: true
});
if (udpInfo) {
throw ErrorCode.DEPARTMENT_HAS_USER
}
}
let updateInfo = {
updatedAt: new Date(),
};
if (aclDepartmentVO.name) {
updateInfo["name"] = aclDepartmentVO.name
}
if (aclDepartmentVO.pid) {
updateInfo["pid"] = aclDepartmentVO.pid
}
if (aclDepartmentVO.level) {
updateInfo["level"] = aclDepartmentVO.level
}
await aclDepartment.prototype.update(updateInfo, {
where: {
id: aclDepartmentVO.id
}
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},修改部门:${JSON.stringify(aclDepartmentVO)}`, LogType.UPDATE);
return 'success'
}
export const del = async function (id: number, currentUserId: any, ip: string | undefined) {
if (!id) {
throw ErrorCode.PARAM_MISS
}
let dbInfo = await aclDepartment.prototype.findOne({
where: { id: id },
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST;
}
//要删除部门,需要确定当前部门下没有用户
let udpInfo = await aclUserDepartmentPosition.prototype.findOne({
where: {
department_id: { [madAdminOrmDB.Op.like]: `%${id}%` }
},
raw: true
});
if (udpInfo) {
throw ErrorCode.DEPARTMENT_HAS_USER
}
await aclDepartment.prototype.destroy({
where: {
id: id
}
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},删除部门:${JSON.stringify(dbInfo)}`, LogType.DEL);
return 'success'
}
export const getUserList = async function (aclDepartmentPageVO: AclDepartmentPageVO) {
let page = Number(aclDepartmentPageVO.page);
let size = Number(aclDepartmentPageVO.size);
let account = aclDepartmentPageVO.account;
let dIds = aclDepartmentPageVO.dIds;
let pageData: any;
if (account) {
pageData = await getAclUserPageData(account, page, size);
if (pageData.rows && pageData.rows.length) {
let uids = pageData.rows.map(item => item.user_id);
let udpList = await aclUserDepartmentPosition.prototype.findAll({
where: {
user_id: { [madAdminOrmDB.Op.in]: uids }
},
raw: true
});
let udpMap = {}
for (let item of udpList) {
udpMap[item.user_id] = item;
}
for (let oneItem of pageData.rows) {
oneItem.department_id = udpMap[oneItem.user_id] ? udpMap[oneItem.user_id].department_id : "";
oneItem.position_id = udpMap[oneItem.user_id] ? udpMap[oneItem.user_id].position_id : "";
}
}
}
else {
pageData = await getDpUserPageData(dIds, page, size);
if (pageData.rows && pageData.rows.length) {
let uids = pageData.rows.map(item => item.user_id);
let udpList = await aclUserInfo.prototype.findAll({
where: {
user_id: { [madAdminOrmDB.Op.in]: uids }
},
raw: true
});
let userMap = {}
for (let item of udpList) {
userMap[item.user_id] = item;
}
for (let oneItem of pageData.rows) {
oneItem.account = userMap[oneItem.user_id] ? userMap[oneItem.user_id].account : "";
oneItem.phone = userMap[oneItem.user_id] ? userMap[oneItem.user_id].phone : "";
oneItem.email = userMap[oneItem.user_id] ? userMap[oneItem.user_id].email : "";
oneItem.user_status = userMap[oneItem.user_id] ? userMap[oneItem.user_id].user_status : "";
}
}
}
return pageData;
}
async function getDpUserPageData(dIds: string, page: number, size: number) {
let where = {};
if (dIds) {
where['department_id'] = dIds;
}
let resList = await aclUserDepartmentPosition.prototype.findAndCount({
where: where,
limit: size,
offset: (page - 1) * size,
order: [["id", "asc"]],
raw: true
});
return resList;
}
async function getAclUserPageData(account: string, page: number, size: number) {
let where = {}
if (!isNaN(Number(account))) {
where = {
[madAdminOrmDB.Op.or]: {
user_id: Number(account),
account: { [madAdminOrmDB.Op.like]: `${account}%` },
email: { [madAdminOrmDB.Op.like]: `${account}%` },
}
}
}
else {
where = {
[madAdminOrmDB.Op.or]: {
account: { [madAdminOrmDB.Op.like]: `${account}%` },
email: { [madAdminOrmDB.Op.like]: `${account}%` },
}
}
}
let resList = await aclUserInfo.prototype.findAndCount({
attributes: ['user_id', 'account', 'phone', 'email', 'user_status'],
where: where,
limit: size,
offset: (page - 1) * size,
order: [["user_id", "asc"]],
raw: true
});
return resList;
}
async function getAllUserDepartmentPositionMap() {
let udpList = await aclUserDepartmentPosition.prototype.findAll({
attributes: ['user_id', 'department_id', 'position_id'],
raw: true
});
let positionList = await aclPosition.prototype.findAll({
raw: true
});
let positionMap = {};
for (let item of positionList) {
positionMap[item.id] = item.name;
}
let userList = await aclUserInfo.prototype.findAll({
raw: true
});
let userMap = {};
for (let item of userList) {
userMap[item.user_id] = item.account;
}
for (let item of udpList) {
let positionId = item.position_id;
let ids = positionId.split(",");
let positionNameList: any = [];
if (ids.length) {
for (let positionId of ids) {
positionNameList.push(positionMap[positionId]);
}
}
let position_name = positionNameList.join(",");
let user_name = userMap[item.user_id];
item.user_position = user_name + " | " + position_name;
}
let departmentUserMap = _.groupBy(udpList, 'department_id');
return departmentUserMap;
}
// @madex/ex-ts-dao 是 ts 的 dao, 代码在 bitbucket/ex-js-dao 的 ts 分支上
import { madAdminOrmDB, aclPosition } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { getOneAclUserByUid } from "../../../utils/aclUserUtils";
import * as userOptLogService from "./userOptLog.service";
let { logger } = require('@madex/ex-js-public');
export const getAllPosition = async function () {
let res = await aclPosition.prototype.findAll({
raw: true,
});
return res
}
......@@ -18,6 +18,8 @@ export interface AclAuthVO {
type?: number | any;
opt_type?: number | any;
idx_number?: number | any;
remark?: string | any;
......@@ -525,6 +527,85 @@ export const changeUserRole = async (userId: number | any, roleIds: any, session
};
export const changeUserRoleWithTx = async (userId: number | any, roleIds: any, tx: any) => {
if (!tx) {
throw ErrorCode.PARAM_MISS;
}
let sp = roleIds.split(",");
let roleIDArr: any[] = [];
for (let i of sp) {
if (!isNaN(i)) {
roleIDArr.push(i);
}
}
if (!roleIDArr.length) {
// 没有指定权限的,直接删除角色对应的所有权限。
await aclUserRole.prototype.destroy({
where: {
user_id: userId
},
transaction: tx
})
}
else {
// 检查权限是不是都存在
let roleArr = await getRole(roleIDArr);
if (roleArr.length !== roleIDArr.length) {
throw ErrorCode.ROLE_EXIST_ILLEGAL
}
// 找出重叠的部分
let oldData = await aclUserRole.prototype.findAll({
where: {
user_id: userId,
},
raw: true,
transaction: tx
});
let oldIDArr = oldData.map(item => item.role_id);
// 找出删除的数据的authID
let deleteIDArr: any[] = [];
for (let i of oldIDArr) {
if (!roleIDArr.includes(i)) {
deleteIDArr.push(i)
}
}
// 找出需要新增的数据
let now = new Date()
let addData: any[] = [];
for (let i of roleIDArr) {
if (!oldIDArr.includes(i)) {
let item = {
role_id: i,
user_id: userId,
createdAt: now,
updatedAt: now,
}
addData.push(item)
}
}
if (deleteIDArr.length) {
await aclUserRole.prototype.destroy({
where: {
user_id: userId,
role_id: { [madAdminOrmDB.Op.in]: deleteIDArr }
},
transaction: tx
})
}
if (addData.length) {
await aclUserRole.prototype.bulkCreate(addData, {
transaction: tx
})
}
}
}
/**
* 获取用户权限
* @param userId
......@@ -662,4 +743,15 @@ async function _isSuper(userId: number) {
return false;
}
export const getUserRoleListByUids = async function (uids: number[]) {
let dbInfoList = await aclUserRole.prototype.findAll({
where: {
user_id: { [madAdminOrmDB.Op.in]: uids }
},
raw: true
});
return dbInfoList;
}
// @madex/ex-ts-dao 是 ts 的 dao, 代码在 bitbucket/ex-js-dao 的 ts 分支上
import { madAdminOrmDB, aclUserInfo } from "@madex/ex-ts-dao";
import { madAdminOrmDB, aclUserInfo, ormDB, aclUserDepartmentPosition, aclUserRole } from "@madex/ex-ts-dao";
import { AclUserInfoConst } from "../../../constant/aclUserConstant";
import { CryptUtils } from "../../../utils/crypt-utils";
import { ErrorCode } from "../../../constant/errorCode";
import { getOneAclUserByAccount, getOneAclUserByUid } from "../../../utils/aclUserUtils";
import { getDepartmentPositionByUids, getOneAclUserByAccount, getOneAclUserByUid } from "../../../utils/aclUserUtils";
import * as userOptLogService from "./userOptLog.service";
import { changeUserRoleWithTx, getUserRoleListByUids } from "./aclRoleAuth.service";
import { _deleteAllSessionByUserId } from "./userAuthConfig.service";
let { logger } = require('@madex/ex-js-public');
let { authCommon: AuthCommon, redisUtilsCommon: RedisClient, } = require('@madex/ex-js-common');
let _ = require('lodash');
export interface AclUserInfoVO {
user_id?: number;
......@@ -18,18 +22,26 @@ export interface AclUserInfoVO {
email?: string | any;
remark?: string | any;
user_type?: number;
remark?: string | any;//姓名
pwd?: string | any;
pwd_salt?: string;
pwd_status?: number;
user_status?: number;
del_flag?: number;
totp_encrypt?: string;
allow_ips?: string;
department_id?: string;
position_id?: string;
role_ids?: string;
createdAt?: Date | any;
updatedAt?: Date | any;
......@@ -50,45 +62,43 @@ export interface AclUserInfoPageVO extends AclUserInfoVO {
}
export const list = async (aclUserInfoPageVO: AclUserInfoPageVO) => {
if (aclUserInfoPageVO.account) {
aclUserInfoPageVO.account = { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.account}%` };
let where = {}
if (!aclUserInfoPageVO.account) {
where = {};
}
if (aclUserInfoPageVO.phone) {
aclUserInfoPageVO.phone = { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.phone}%` };
else if (!isNaN(Number(aclUserInfoPageVO.account))) {
where = {
[madAdminOrmDB.Op.or]: {
user_id: Number(aclUserInfoPageVO.account),
account: { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.account}%` },
email: { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.account}%` },
}
if (aclUserInfoPageVO.email) {
aclUserInfoPageVO.email = { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.email}%` };
}
if (aclUserInfoPageVO.remark) {
aclUserInfoPageVO.remark = { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.remark}%` };
}
if (aclUserInfoPageVO.updatedAt) {
aclUserInfoPageVO.updatedAt = { [madAdminOrmDB.Op.gte]: new Date(madAdminOrmDB.updatedAt).getTime() };
else {
where = {
[madAdminOrmDB.Op.or]: {
account: { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.account}%` },
email: { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.account}%` },
}
}
}
let page = Number(aclUserInfoPageVO.page);
let size = Number(aclUserInfoPageVO.size);
let where = Object.assign(aclUserInfoPageVO);
delete aclUserInfoPageVO.page;
delete aclUserInfoPageVO.size;
let resList = await aclUserInfo.prototype.findAndCount({
let res = await aclUserInfo.prototype.findAndCount({
where: where,
limit: size,
offset: (page - 1) * size,
order: [["user_id", "asc"]],
raw: true
});
return resList;
await dealReturnData(res.rows);
return res;
};
export const add = async (aclUserInfoVO: AclUserInfoVO, session_id: any) => {
if (!aclUserInfoVO.createdAt) {
aclUserInfoVO.createdAt = new Date();
}
if (!aclUserInfoVO.updatedAt) {
aclUserInfoVO.updatedAt = new Date();
}
let dbInfo = await aclUserInfo.prototype.findOne({
where: {
account: aclUserInfoVO.account,
......@@ -99,35 +109,155 @@ export const add = async (aclUserInfoVO: AclUserInfoVO, session_id: any) => {
if (dbInfo) {
throw ErrorCode.USER_EXIST;
}
aclUserInfoVO.pwd = CryptUtils.defPwd();
aclUserInfoVO.pwd_salt = CryptUtils.salt();
let insertInfo = {
remark: aclUserInfoVO.remark,
account: aclUserInfoVO.account,
user_status: aclUserInfoVO.user_status ? aclUserInfoVO.user_status : 0,
pwd_salt: CryptUtils.salt(),
totp_encrypt: aclUserInfoVO.totp_encrypt,
createdAt: new Date(),
updatedAt: new Date(),
};
if (aclUserInfoVO.email) {
insertInfo['email'] = aclUserInfoVO.email
}
if (aclUserInfoVO.phone) {
insertInfo['phone'] = aclUserInfoVO.phone
}
if (aclUserInfoVO.allow_ips) {
insertInfo['allow_ips'] = aclUserInfoVO.allow_ips
}
if (aclUserInfoVO.pwd) {
insertInfo['pwd'] = aclUserInfoVO.pwd
}
else {
insertInfo['pwd'] = CryptUtils.defPwd();
}
await aclUserInfo.prototype.create(aclUserInfoVO);
let tx;
try {
tx = await madAdminOrmDB.transaction();
//创建用户
let insertUser = await aclUserInfo.prototype.create(insertInfo, {
transaction: tx
});
//保存部门和职位
await aclUserDepartmentPosition.prototype.create({
user_id: insertUser.user_id,
department_id: aclUserInfoVO.department_id,
position_id: aclUserInfoVO.position_id,
createdAt: new Date(),
updatedAt: new Date(),
}, {
transaction: tx
});
let userRoleList: any = [];
let roleIds = String(aclUserInfoVO.role_ids).split(',');
for (let roleId of roleIds) {
let item = {
role_id: roleId,
user_id: insertUser.user_id,
createdAt: new Date(),
updatedAt: new Date(),
}
userRoleList.push(item);
}
//保存用户角色
await aclUserRole.prototype.bulkCreate(userRoleList, {
transaction: tx
});
await tx.commit();
}
catch (e) {
logger.error('add user error:' + e);
if (tx) {
await tx.rollback();
}
throw e;
}
userOptLogService.addOptLog(null, `add user : ${JSON.stringify(aclUserInfoVO)}`, userOptLogService.LogType.ADD, '', session_id);
return 'ok';
};
export const update = async (aclUserInfoVO: AclUserInfoVO, session_id: any) => {
let userId = Number(aclUserInfoVO.user_id);
await getOneAclUserByUid(userId);
let updateInfo = Object.create(null);
updateInfo.remark = aclUserInfoVO.remark;
updateInfo.updatedAt = new Date();
let dbInfo = await aclUserInfo.prototype.findOne({
where: {
user_id: aclUserInfoVO.user_id,
},
raw: true
});
if (aclUserInfoVO.phone) {
updateInfo.phone = aclUserInfoVO.phone
if (!dbInfo) {
throw ErrorCode.USER_NOT_EXIST;
}
if (aclUserInfoVO.email) {
updateInfo.email = aclUserInfoVO.email
let updateInfo = {
updatedAt: new Date(),
};
if (aclUserInfoVO.remark != dbInfo.remark) {
updateInfo['remark'] = aclUserInfoVO.remark
}
if (aclUserInfoVO.email != dbInfo.email) {
updateInfo['email'] = aclUserInfoVO.email
}
if (aclUserInfoVO.phone != dbInfo.phone) {
updateInfo['phone'] = aclUserInfoVO.phone
}
if (aclUserInfoVO.allow_ips != dbInfo.allow_ips) {
updateInfo['allow_ips'] = aclUserInfoVO.allow_ips
}
if (aclUserInfoVO.pwd != dbInfo.pwd) {
let encrypted = await AuthCommon.getPasswordEncrypt(aclUserInfoVO.pwd, dbInfo.pwd_salt);
updateInfo['pwd'] = encrypted;
updateInfo['pwd_status'] = 1;
}
if (aclUserInfoVO.user_status != dbInfo.user_status) {
updateInfo['user_status'] = aclUserInfoVO.user_status
}
if (aclUserInfoVO.totp_encrypt != dbInfo.totp_encrypt) {
updateInfo['totp_encrypt'] = aclUserInfoVO.totp_encrypt
}
let tx;
try {
tx = await madAdminOrmDB.transaction();
//修改用户
await aclUserInfo.prototype.update(updateInfo, {
where: {
user_id: userId
}
user_id: Number(aclUserInfoVO.user_id),
},
transaction: tx
});
//保存部门和职位
await aclUserDepartmentPosition.prototype.update({
department_id: aclUserInfoVO.department_id,
position_id: aclUserInfoVO.position_id,
updatedAt: new Date(),
}, {
where: {
user_id: Number(aclUserInfoVO.user_id),
},
transaction: tx
});
//修改用户角色
await changeUserRoleWithTx(aclUserInfoVO.user_id, aclUserInfoVO.role_ids, tx);
await tx.commit();
}
catch (e) {
logger.error('update user error:' + e);
if (tx) {
await tx.rollback();
}
throw e;
}
//修改了谷歌 需要踢出登陆
if (aclUserInfoVO.totp_encrypt != dbInfo.totp_encrypt) {
_deleteAllSessionByUserId(Number(aclUserInfoVO.user_id));
}
userOptLogService.addOptLog(null, `update user : ${JSON.stringify(aclUserInfoVO)}`, userOptLogService.LogType.UPDATE, '', session_id);
return 'ok';
......@@ -227,5 +357,28 @@ export async function findAllForPage(page: number, size: number, userId?: number
}
async function dealReturnData(rows: any) {
if (!rows.length) {
return
}
let uids = rows.map(item => item.user_id);
let [userRoleList, dpMap] = await Promise.all([getUserRoleListByUids(uids), getDepartmentPositionByUids(uids)]);
let userRoleMap = _.groupBy(userRoleList, 'user_id');
for (let oneItem of rows) {
delete oneItem.pwd;
delete oneItem.pwd_salt;
let userId = oneItem.user_id;
let roleList = userRoleMap[userId];
let dbOne = dpMap[userId];
oneItem.role_ids = roleList && roleList.length ? roleList.map(item => item.role_id).join(",") : ""
oneItem.department_id = dbOne ? dbOne.department_id : ""
oneItem.position_id = dbOne ? dbOne.position_id : ""
}
}
......@@ -198,7 +198,7 @@ export async function audit(queryVO: QueryVO, currentUserId: any, ip: string | u
if (dbOne.status == KYC_STATUS.STATUS_AUDIT_DENY) {
throw ErrorCode.DATA_STATUS_CHANGED
}
await auditDeny(dbOne.id, dbUserInfo.user_id, settingFlag, queryVO.audit_deny, currentUserId, queryVO.comment ? queryVO.audit_deny : "")
await auditDeny(dbOne.id, dbUserInfo.user_id, settingFlag, queryVO.audit_deny, currentUserId, queryVO.comment ? queryVO.comment : "")
}
//发邮件
......
// @madex/ex-ts-dao 是 ts 的 dao, 代码在 bitbucket/ex-js-dao 的 ts 分支上
import { madAdminOrmDB, aclUserInfo, aclUserAuthConfig } from "@madex/ex-ts-dao";
import { AclUserInfoConst } from "../../../constant/aclUserConstant";
import { CryptUtils } from "../../../utils/crypt-utils";
import { ErrorCode } from "../../../constant/errorCode";
import * as aclRoleAuthService from "../service/aclRoleAuth.service";
import * as aclUserService from "../service/aclUser.service";
import { getOneAclUserByAccount, getOneAclUserByUid } from "../../../utils/aclUserUtils";
import { RedisVal } from "../../../constant/redis-val";
import Config from "../../../../config";
import { AuthConfigConst } from "../../../constant/aclUserAuthConfigConstant";
import * as userOptLogService from "./userOptLog.service";
let { apiAssertUtils: ApiAssert, datetimeUtils: DatetimeUtils } = require('@madex/ex-js-public');
......@@ -18,8 +10,8 @@ let { authCommon: AuthCommon, redisUtilsCommon: RedisClient, BigNumberUtils } =
let _ = require('lodash');
let { logger } = require('@madex/ex-js-public');
//默认的有效期时间,3天
const LockedDeadlineDay = 3
const Otplib = require('otplib');
export interface AuthConfigVO {
id?: number;
......@@ -42,6 +34,8 @@ export interface AuthConfigVO {
user_type?: number | any;
totp_code?: any
}
export interface AuthConfigPageVO extends AuthConfigVO {
......@@ -50,210 +44,20 @@ export interface AuthConfigPageVO extends AuthConfigVO {
size?: number
}
export async function findByUserId(userId: number) {
try {
if (!userId) {
throw ErrorCode.PARAM_MISS
}
let configInfo = await aclUserAuthConfig.prototype.findOne({
where: {
user_id: userId
},
raw: true
});
return configInfo;
}
catch (e) {
logger.error('aclUserService.findByUserId.error:' + e)
throw e;
}
}
async function findByUserIdList(userIdList: number[]) {
try {
if (!userIdList || userIdList.length < 1) {
throw ErrorCode.PARAM_MISS
}
let configInfoList = await aclUserAuthConfig.prototype.findAll({
where: {
user_id: { [madAdminOrmDB.Op.in]: userIdList }
},
raw: true
});
return configInfoList;
}
catch (e) {
logger.error('aclUserService.findByUserIdList.error:' + e)
throw e;
}
}
export async function queryConfigList(userId: number | undefined, userType: any, page: number | undefined, size: number | undefined) {
//查询账户信息
let typeArr = [AclUserInfoConst.USER_TYPE.SUPPORT]
if (userType && (await _checkUserType(userType))) {
typeArr = [Number(userType)]
}
let pageList = await aclUserService.findAllForPage(Number(page), Number(size), userId, typeArr,
[AclUserInfoConst.USER_STATUS.NORMAL, AclUserInfoConst.USER_STATUS.LOCK], null, null, null);
if (pageList.rows.length < 1) {
return pageList;
}
//查询安全项配置
let configMap = {}
let configList = await findByUserIdList(pageList.rows.map(item => item.user_id))
if (configList && configList.length >= 1) {
configMap = _.keyBy(configList, item => item.user_id)
}
let resultList: any[] = []
for (let infoItem of pageList.rows) {
let force = 0, isLocked = 0, hasTotp = 0, deadline = '', lockedTime = ''
let configItem = configMap[infoItem.user_id]
if (configItem) {
force = configItem.force
isLocked = configItem.is_locked
hasTotp = configItem.totp_encrypt === '' ? 0 : 1
deadline = configItem.deadline
lockedTime = configItem.locked_time
}
export async function resetTotp(userId: number | undefined) {
let userInfo = await getOneAclUserByUid(Number(userId));
ApiAssert.isNotEmpty(ErrorCode.USER_NOT_EXIST, userInfo);
let item = {
userId: infoItem.user_id,
account: infoItem.account,
force: force,
deadline: deadline,
hasTotp: hasTotp,
isLocked: isLocked,
lockedTime: lockedTime,
}
resultList.push(item)
}
pageList.rows = resultList
return pageList
//生成新的密钥
let totpEncrypt = Otplib.authenticator.generateSecret();
let email = userId + '-' + totpEncrypt.slice(0, 3)
let uri = 'otpauth://totp/' + email + '?secret=' + totpEncrypt + '&issuer=team888';
return { uri: uri, totpEncrypt: totpEncrypt };
}
export async function changeForceStatus(userId: number, forceStatus: any, session_id: any) {
let arr = [AuthConfigConst.FORCE.FALSE, AuthConfigConst.FORCE.TRUE];
if (!arr.includes(forceStatus)) {
throw ErrorCode.PARAM_MISS
}
//已当前时间点顺延
let deadline = DatetimeUtils.add(new Date(), LockedDeadlineDay * DatetimeUtils.DAY)
//查询是否已有配置记录
let configExist = await _checkAndGetAuthConfig(userId)
if (configExist) {
if (Number(configExist.force) === Number(forceStatus)) {
return 'success'
}
if (Number(forceStatus) === AuthConfigConst.FORCE.FALSE) {
deadline = configExist.deadline
}
let data2Update = {
force: forceStatus,
deadline: deadline,
updatedAt: new Date()
}
await aclUserAuthConfig.prototype.update(data2Update, { where: { id: configExist.id } })
}
else {
await getOneAclUserByUid(userId)
let data2Add = {
user_id: userId,
totp_encrypt: '',
is_locked: AuthConfigConst.IS_LOCKED.FALSE,
force: forceStatus,
deadline: deadline,
createdAt: new Date(),
updatedAt: new Date()
}
await aclUserAuthConfig.prototype.create(data2Add)
}
//如果是开启并且已绑定谷歌,则剔除登录状态
if (Number(forceStatus) === AuthConfigConst.FORCE.TRUE && configExist && configExist.totp_encrypt !== '') {
await _deleteAllSessionByUserId(userId)
}
userOptLogService.addOptLog(null, `change user: ${userId} force status : ${forceStatus}`, userOptLogService.LogType.UPDATE, '', session_id);
return 'success'
}
export async function changeLockedStatus(userId: number | undefined, session_id: any) {
//查询是否已有配置记录
let configExist = await _checkAndGetAuthConfig(userId)
if (!configExist || configExist.is_locked === AuthConfigConst.IS_LOCKED.FALSE) {
return 'success'
}
//若已开启强制绑定,则重新设置有效时间
let deadline = configExist.deadline
if (Number(configExist.force) === AuthConfigConst.FORCE.TRUE) {
deadline = DatetimeUtils.add(new Date(), LockedDeadlineDay * DatetimeUtils.DAY)
}
//解除锁定
let data2Update = {
is_locked: AuthConfigConst.IS_LOCKED.FALSE,
deadline: deadline,
updatedAt: new Date()
}
await aclUserAuthConfig.prototype.update(data2Update, { where: { id: configExist.id } })
userOptLogService.addOptLog(null, `change user:${userId} lock status : ${AuthConfigConst.IS_LOCKED.FALSE}`, userOptLogService.LogType.UPDATE, '', session_id);
return "success"
}
export async function resetTotp(userId: number | undefined, session_id: any) {
//查询是否已有配置记录
let configExist = await _checkAndGetAuthConfig(userId)
if (!configExist || configExist.totp_encrypt === '') {
return 'success'
}
let data2Update = {
totp_encrypt: '',
is_locked: AuthConfigConst.IS_LOCKED.FALSE,
force: AuthConfigConst.FORCE.TRUE,
deadline: DatetimeUtils.add(new Date(), LockedDeadlineDay * DatetimeUtils.DAY),
updatedAt: new Date()
}
await aclUserAuthConfig.prototype.update(data2Update, { where: { id: configExist.id } })
//剔除登录态
await _deleteAllSessionByUserId(Number(userId));
userOptLogService.addOptLog(null, `reset user:${userId} totp`, userOptLogService.LogType.UPDATE, '', session_id);
return 'success'
}
async function _checkUserType(userType: number) {
let arr = [AclUserInfoConst.USER_TYPE.SUPPORT, AclUserInfoConst.USER_TYPE.ADMIN];
if (!arr.includes(userType)) {
throw ErrorCode.USER_TYPE_ILLEGAL
}
return true;
}
async function _checkAndGetAuthConfig(userId: number | any) {
let userExist = await getOneAclUserByUid(userId);
if (userExist) {
throw ErrorCode.USER_NOT_EXIST
}
await _checkUserType(userExist.user_type)
return findByUserId(userId);
}
async function _deleteAllSessionByUserId(userId: number) {
export async function _deleteAllSessionByUserId(userId: number) {
//获取该账户使用过的所有sessionId
let sessionListKey = RedisVal.sessionListKey(userId)
......
// @madex/ex-ts-dao 是 ts 的 dao, 代码在 bitbucket/ex-js-dao 的 ts 分支上
import { madAdminOrmDB, aclUserInfo, aclUserAuthConfig } from "@madex/ex-ts-dao";
import { aclUserInfo } from "@madex/ex-ts-dao";
import { AclUserInfoConst } from "../../../constant/aclUserConstant";
import { AuthConfigConst } from "../../../constant/aclUserAuthConfigConstant";
import { CryptUtils } from "../../../utils/crypt-utils";
import { ErrorCode } from "../../../constant/errorCode";
import * as aclRoleAuthService from "../service/aclRoleAuth.service";
import * as aclUserService from "../service/aclUser.service";
import * as userAuthConfigService from "../service/userAuthConfig.service";
import { getOneAclUserByAccount, getOneAclUserByUid } from "../../../utils/aclUserUtils";
import { getDepartmentPositionByUid, getOneAclUserByAccount, getOneAclUserByUid } from "../../../utils/aclUserUtils";
import { RedisVal } from "../../../constant/redis-val";
import Config from "../../../../config";
import * as userOptLogService from "./userOptLog.service";
import { findByUserId } from "../service/userAuthConfig.service";
import { getRoleByUser } from "../service/aclRoleAuth.service";
const Otplib = require('otplib');
......@@ -28,30 +27,78 @@ export const getInfo = async (currentUserId: number | any, sessionId: string) =>
ApiAssert.isNotEmpty(ErrorCode.USER_NOT_EXIST, dbUserInfo);
ApiAssert.isFalse(ErrorCode.ACCOUNT_LOCK, dbUserInfo.user_status === AclUserInfoConst.USER_STATUS.LOCK);
ApiAssert.isFalse(ErrorCode.ACCOUNT_STOP, dbUserInfo.user_status === AclUserInfoConst.USER_STATUS.DEL);
ApiAssert.isFalse(ErrorCode.ACCOUNT_STOP, dbUserInfo.user_status === AclUserInfoConst.USER_STATUS.STOP);
let { roleSet, authSet } = await aclRoleAuthService.getUserAcl(dbUserInfo.user_id);
//安全项配置
let authConfigDbInfo = await findByUserId(currentUserId);
let data = {
remark: dbUserInfo.remark,
phone: dbUserInfo.phone,
email: dbUserInfo.email,
userId: dbUserInfo.user_id,
allow_ips: dbUserInfo.allow_ips,
user_status: dbUserInfo.user_status,
account: dbUserInfo.account,
userType: dbUserInfo.user_type,
sessionId: sessionId,
roleSet: roleSet,
authSet: authSet,
force: authConfigDbInfo ? authConfigDbInfo.force : 0,
deadline: authConfigDbInfo ? authConfigDbInfo.deadline : null,
hasTotp: authConfigDbInfo && authConfigDbInfo.totp_encrypt ? 1 : 0,
isLocked: authConfigDbInfo ? authConfigDbInfo.is_locked : 0,
lockedTime: authConfigDbInfo ? authConfigDbInfo.locked_time : null,
hasTotp: dbUserInfo && dbUserInfo.totp_encrypt ? 1 : 0,
}
await dealDepartmentAndPosition(data);
return data
};
export const getInfoByUserId = async (user_id: number | any) => {
let dbUserInfo = await getOneAclUserByUid(user_id);
ApiAssert.isNotEmpty(ErrorCode.USER_NOT_EXIST, dbUserInfo);
let { roleSet, authSet } = await aclRoleAuthService.getUserAcl(dbUserInfo.user_id);
let data = {
phone: dbUserInfo.phone,
email: dbUserInfo.email,
userId: dbUserInfo.user_id,
account: dbUserInfo.account,
remark: dbUserInfo.remark,
user_status: dbUserInfo.user_status,
roleSet: roleSet,
authSet: authSet
}
await dealDepartmentAndPosition(data);
return data
};
export const getInfoDetailByUserId = async (user_id: number | any) => {
let dbUserInfo = await getOneAclUserByUid(user_id);
ApiAssert.isNotEmpty(ErrorCode.USER_NOT_EXIST, dbUserInfo);
let { roleSet, authSet } = await aclRoleAuthService.getUserAcl(dbUserInfo.user_id);
let data = {
remark: dbUserInfo.remark,
phone: dbUserInfo.phone,
email: dbUserInfo.email,
userId: dbUserInfo.user_id,
allow_ips: dbUserInfo.allow_ips,
user_status: dbUserInfo.user_status,
account: dbUserInfo.account,
pwd: dbUserInfo.pwd,
roleSet: roleSet,
authSet: authSet,
hasTotp: dbUserInfo && dbUserInfo.totp_encrypt ? 1 : 0,
totp_encrypt: dbUserInfo ? dbUserInfo.totp_encrypt : "",
}
await dealDepartmentAndPosition(data);
return data
};
export async function login(account: any, pwd: any, s: string) {
......@@ -59,8 +106,8 @@ export async function login(account: any, pwd: any, s: string) {
ApiAssert.isNotEmpty(ErrorCode.ACCOUNT_OR_PWD_ERR, userInfo);
ApiAssert.isFalse(ErrorCode.ACCOUNT_LOCK, userInfo.user_status === AclUserInfoConst.USER_STATUS.LOCK);
ApiAssert.isFalse(ErrorCode.ACCOUNT_STOP, userInfo.user_status === AclUserInfoConst.USER_STATUS.DEL);
ApiAssert.isFalse(ErrorCode.ACCOUNT_STOP, userInfo.user_status === 3);
ApiAssert.isFalse(ErrorCode.ACCOUNT_STOP, userInfo.user_status === AclUserInfoConst.USER_STATUS.STOP);
ApiAssert.isFalse(ErrorCode.USER_IS_DEL, userInfo.del_flag == AclUserInfoConst.DEL_FLAG.TRUE);
await _checkPwd(userInfo, pwd);
......@@ -71,37 +118,25 @@ export async function login(account: any, pwd: any, s: string) {
let cookies = {
account: userInfo.account,
userId: userInfo.user_id,
userType: userInfo.user_type,
// acl 相关
roleSet: roleSet,
authSet: authSet,
// 添加逻辑
//是否需要进行二次验证。0:不需要或者已通过验证;1:需要;
needConfirm: 0,
allow_ips: userInfo.allow_ips,//ip白名单
totp_encrypt: ''
};
let needBindTotp = 0
let deadline = ''
let needBindTotp = 1
let hasTotp = 0
//如果是管理员,则必须绑定
if (Number(userInfo.user_type) === AclUserInfoConst.USER_TYPE.ADMIN) {
cookies.needConfirm = 1
needBindTotp = 1
}
//如果绑定了谷歌则必须校验, 增加属性 needConfirm = 1
let authConfig = await userAuthConfigService.findByUserId(userInfo.user_id)
if (authConfig) {
if (Number(authConfig.is_locked) === AuthConfigConst.IS_LOCKED.TRUE) {
throw ErrorCode.TOTP_UNBOUND_LOCKED;
}
if (authConfig.totp_encrypt && authConfig.totp_encrypt !== '' && Number(authConfig.force) === AuthConfigConst.FORCE.TRUE) {
cookies.needConfirm = 1
hasTotp = 1
}
if (Number(authConfig.force) === AuthConfigConst.FORCE.TRUE) {
needBindTotp = 1
deadline = authConfig.deadline
}
let totp_encrypt = userInfo.totp_encrypt;
if (totp_encrypt) {
cookies.needConfirm = 1;
cookies.totp_encrypt = totp_encrypt;
hasTotp = 1;
needBindTotp = 0;
}
await RedisClient.writeSync(sessionId, cookies, Config.LOGIN_EXPIRED);
......@@ -113,12 +148,10 @@ export async function login(account: any, pwd: any, s: string) {
return {
result: "success",
sessionId: sessionId,
userType: Number(userInfo.user_type),
//是否已绑定谷歌。0:未绑定;1:已绑定
hasTotp: hasTotp,
//是否需要进行安全项绑定。0:不需要;1:需要;
needBindTotp: needBindTotp,
deadline: deadline,
};
}
......@@ -143,11 +176,11 @@ export async function loginConfirm(sessionId: any, userId: any, totpCode: any) {
//判断是否在登录锁定中
let cookies = await RedisClient.getSync(sessionId)
ApiAssert.isTrue(ErrorCode.PARAM_MISS, Number(cookies.needConfirm) === 1);
let totp_encrypt = cookies.totp_encrypt;
//获取谷歌密钥并验证
let authInfo = await userAuthConfigService.findByUserId(userId)
ApiAssert.isTrue(ErrorCode.UNBOUND_TOTP, authInfo && authInfo.totp_encrypt !== '');
await AuthCommon.totpCheckSync(totpCode, authInfo.totp_encrypt)
//谷歌密钥验证
ApiAssert.isTrue(ErrorCode.UNBOUND_TOTP, totp_encrypt !== '');
await AuthCommon.totpCheckSync(totpCode, totp_encrypt)
//判断是否已经使用过
let latestVerifiedKey = "bastard.totp.used.user." + userId
......@@ -166,7 +199,7 @@ export async function updatePwd(userId: any, originPwd: any, newPwd: any) {
let userInfo = await getOneAclUserByUid(userId);
ApiAssert.isNotEmpty(ErrorCode.USER_NOT_EXIST, userInfo);
ApiAssert.isFalse(ErrorCode.ACCOUNT_LOCK, userInfo.user_status === AclUserInfoConst.USER_STATUS.LOCK);
ApiAssert.isFalse(ErrorCode.USER_NOT_EXIST, userInfo.user_status === AclUserInfoConst.USER_STATUS.DEL);
ApiAssert.isFalse(ErrorCode.USER_NOT_EXIST, userInfo.user_status === AclUserInfoConst.USER_STATUS.STOP);
await _checkPwd(userInfo, originPwd);
......@@ -190,9 +223,8 @@ export async function bindTotpAsk(sessionId: any, userId: any) {
ApiAssert.isNotEmpty(ErrorCode.USER_NOT_EXIST, userInfo);
//判断是否已完成绑定
let authConfig = await userAuthConfigService.findByUserId(userId)
ApiAssert.isTrue(ErrorCode.GOOGLE_HAS_BIND, !authConfig || authConfig.totp_encrypt === '');
ApiAssert.isTrue(ErrorCode.TOTP_UNBOUND_LOCKED, !authConfig || authConfig.is_locked !== AuthConfigConst.IS_LOCKED.TRUE)
let totp_encrypt = userInfo.totp_encrypt
ApiAssert.isTrue(ErrorCode.GOOGLE_HAS_BIND, !totp_encrypt);
//生成新的密钥
let totpEncrypt = Otplib.authenticator.generateSecret();
......@@ -264,44 +296,50 @@ async function _unlockPwd(userId: any) {
}
async function _updateTotpConfig(userId: number, totpEncrypt: any) {
await aclUserInfo.prototype.update({
totp_encrypt: totpEncrypt
}, {
where: {
user_id: userId
}
});
}
//获取当前配置
let configExist = await userAuthConfigService.findByUserId(userId)
if (configExist) {
let data2Update = {
totp_encrypt: totpEncrypt,
updatedAt: new Date()
async function dealDepartmentAndPosition(data: any) {/*
let [departmentList,positionList,dp] =
await Promise.all([getAllDepartment(),getAllPosition(),getDepartmentPositionByUid(data.user_id)]);
let departmentMap = {};
let positionMap = {};
for (let item of departmentList) {
departmentMap[item.id] = item.name;
}
let condition = {
where: {
id: configExist.id
},
raw: true
for (let item of positionList) {
positionMap[item.id] = item.name;
}
await aclUserAuthConfig.prototype.update(data2Update, condition)
let departmentIds = dp.department_id.split(",");
let positionIds = dp.position_id.split(",");
let departmentNameList:any = [];
let positionNameList:any = [];
if (departmentIds.length){
for (let departmentId of departmentIds) {
departmentNameList.push(departmentMap[departmentId])
}
else {
let now = new Date()
let data2Add = {
user_id: userId,
totp_encrypt: totpEncrypt,
is_locked: AuthConfigConst.IS_LOCKED.FALSE,
force: AuthConfigConst.FORCE.TRUE,
deadline: now,
createdAt: now,
updatedAt: now,
}
await aclUserAuthConfig.prototype.create(data2Add)
if (positionIds.length){
for (let positionId of positionIds) {
positionNameList.push(positionMap[positionId])
}
}
}*/
let [aclRoleList, db] =
await Promise.all([getRoleByUser(data.userId), getDepartmentPositionByUid(data.userId)]);
let role_ids = aclRoleList.map(item => item.role_id);
data.role_ids = role_ids && role_ids.length ? role_ids.join(",") : "";
data.department_id = db.department_id;
data.position_id = db.position_id;
/*
async function test() {
let pwd = CryptUtils.defPwd();
let pwd_salt = CryptUtils.salt();
console.log(pwd)
console.log(pwd_salt)
}
test()*/
......@@ -20,13 +20,14 @@ import * as ReqUtils from "../../../utils/req-utils";
import * as spotPairCtrl from "../../mvc/control/spotPair.control";
import * as coinTypeCtrl from "../../mvc/control/coinType.control";
import * as noticeCtrl from "../../mvc/control/notice.control";
import * as mUserOptLogCtrl from "../../mvc/control/mUserOptLog.control";
import * as mUserManageCtrl from "../../mvc/control/mUserManage.control";
import * as mUserRealNameCtrl from "../../mvc/control/mUserRealName.control";
import * as usefulLinkCtrl from "../../mvc/control/usefulLink.control";
import * as mUserSubscribeCtrl from "../../mvc/control/mUserSubscribe.control";
import * as commonUserFeeSettingCtrl from "../../mvc/control/commonUserFeeSetting.control";
import * as mUserAssetsCtrl from "../../mvc/control/mUserAssets.control";
import * as departmentCtrl from "../../mvc/control/aclDepartment.control";
import * as positionCtrl from "../../mvc/control/aclPosition.control";
const getFunc = {
'user/info': userController.getUserInfo,
};
......@@ -48,12 +49,27 @@ const postFunc = {
'coinType/list': coinTypeCtrl.list,
'coinType/spotPairCtl': coinTypeCtrl.pushToCoreSystem,
//权限管理
'acl/user/add': aclUserCtrl.add,
'acl/user/list': aclUserCtrl.list,
'acl/user/update': aclUserCtrl.update,
'acl/user/updateStatus': aclUserCtrl.updateStatus,
'acl/user/resetPwd': aclUserCtrl.resetPwd,
//权限管理 - 我的权限
'user/getInfo': userOptCtrl.getInfo,
'user/getInfoByUserId': userOptCtrl.getInfoByUserId,
'user/getInfoDetailByUserId': userOptCtrl.getInfoDetailByUserId,
//权限管理 - 组织结构
'department/pageList':departmentCtrl.pageList,
'department/allList':departmentCtrl.allList,
'department/getDepartmentTree':departmentCtrl.getDepartmentTree,
'department/add':departmentCtrl.add,
'department/update':departmentCtrl.update,
'department/del':departmentCtrl.del,
'department/userList/dpIdsOrAccount':departmentCtrl.getUserList,
'position/allList':positionCtrl.allList,
//权限管理 - 后台角色管理
'acl/role/list': aclRoleAuthCtrl.roleList,
'acl/role/getByUser': aclRoleAuthCtrl.getRoleByUser,
'acl/role/getAll': aclRoleAuthCtrl.getAllRole,
'acl/role/save': aclRoleAuthCtrl.saveRole,
'acl/role/del': aclRoleAuthCtrl.delRole,
'acl/changeRoleAuth': aclRoleAuthCtrl.changeRoleAuth,
'acl/auth/list': aclRoleAuthCtrl.authList,
'acl/auth/tree': aclRoleAuthCtrl.getAuthTree,
'acl/auth/getByUser': aclRoleAuthCtrl.getAuthByUser,
......@@ -61,27 +77,18 @@ const postFunc = {
'acl/auth/save': aclRoleAuthCtrl.saveAuth,
'acl/auth/del': aclRoleAuthCtrl.delAuth,
//角色管理
'acl/role/list': aclRoleAuthCtrl.roleList,
'acl/role/getByUser': aclRoleAuthCtrl.getRoleByUser,
//'acl/role/getUserList':aclUserCtrl.list,
'acl/role/getAll': aclRoleAuthCtrl.getAllRole,
'acl/role/save': aclRoleAuthCtrl.saveRole,
'acl/role/del': aclRoleAuthCtrl.delRole,
'acl/changeRoleAuth': aclRoleAuthCtrl.changeRoleAuth,
//权限管理 - 后台用户管理
'acl/user/add': aclUserCtrl.add,
'acl/user/list': aclUserCtrl.list,
'acl/user/update': aclUserCtrl.update,
'acl/user/checkTotpCode': aclUserCtrl.checkTotpCode,
'acl/changeUserRole': aclRoleAuthCtrl.changeUserRole,
//管理后台用户管理
'user/getInfo': userOptCtrl.getInfo,
'user/login': userOptCtrl.login,
'user/logout': userOptCtrl.logout,
'user/login/confirm': userOptCtrl.loginConfirm,
'user/updatePwd': userOptCtrl.updatePwd,
'user/bind/totp/ask': userOptCtrl.bindTotpAsk,
'user/bind/totp/confirm': userOptCtrl.bindTotpConfirm,
'user/auth/config/list': userAuthConfigCtrl.authConfigList,
'user/auth/change/force/status': userAuthConfigCtrl.changeForceStatus,
'user/auth/change/locked/status': userAuthConfigCtrl.changeLockedStatus,
'user/auth/reset/totp': userAuthConfigCtrl.resetTotp,
//热门交易对搜索
......@@ -95,8 +102,7 @@ const postFunc = {
'notice/add': noticeCtrl.add,
'notice/update': noticeCtrl.update,
//日志和审计
'mUser/opt/log/list':mUserOptLogCtrl.list,//Madex 用户操作日志列表
//Madex 用户管理
'mUser/manage/userList': mUserManageCtrl.userList,//Madex 用户管理 ->用户列表
'mUser/manage/oneUserDetail': mUserManageCtrl.oneUserDetail,//Madex 用户管理 ->单个用户详情
......
......@@ -8,53 +8,72 @@ const {
let cmdWhiteList = {
//国际化
'i18n/info/list': 1,
'i18n/info/add': 1,
'i18n/info/update': 1,
'i18n/info/del': 1,
'i18n/info/log/list': 1,
'i18n/info/log/revert': 1,
'spotpair/add': 1,
'spotpair/list': 1,
'spotPair/add': 1,
'spotPair/list': 1,
'spotPair/spotPairCtl': 1,
'coinType/add': 1,
'coinType/list': 1,
'acl/user/add': 1,
'acl/user/list': 1,
'acl/user/update': 1,
'acl/user/updateStatus': 1,
'acl/user/resetPwd': 1,
'acl/auth/list': 1,
'acl/auth/tree': 1,
'acl/auth/getByUser': 1,
'acl/auth/getByRole': 1,
'acl/auth/save': 1,
'acl/auth/del': 1,
'coinType/spotPairCtl': 1,
//权限管理 - 我的权限
'user/getInfo': 1,
'user/getInfoByUserId': 1,
'user/getInfoDetailByUserId': 1,
//权限管理 - 组织结构
'department/pageList':1,
'department/allList':1,
'department/getDepartmentTree':1,
'department/add':1,
'department/update':1,
'department/del':1,
'department/userList/dpIdsOrAccount':1,
'position/allList':1,
//权限管理 - 后台角色管理
'acl/role/list': 1,
'acl/role/getByUser': 1,
'acl/role/getAll': 1,
'acl/role/save': 1,
'acl/role/del': 1,
'acl/changeRoleAuth': 1,
'acl/auth/list': 1,
'acl/auth/tree': 1,
'acl/auth/getByUser': 1,
'acl/auth/getByRole': 1,
'acl/auth/save': 1,
'acl/auth/del': 1,
//权限管理 - 后台用户管理
'acl/user/add': 1,
'acl/user/list': 1,
'acl/user/update': 1,
'acl/user/checkTotpCode': 1,
'acl/changeUserRole': 1,
'user/getInfo': 1,
'user/login': 1,
'user/logout': 1,
'user/login/confirm': 1,
'user/updatePwd': 1,
'user/bind/totp/ask': 1,
'user/bind/totp/confirm': 1,
'user/auth/config/list': 1,
'user/auth/change/force/status': 1,
'user/auth/change/locked/status': 1,
'user/auth/reset/totp': 1,
//热门交易对搜索
'hot/pair/config/list': 1,
'hot/pair/config/add': 1,
'hot/pair/config/update': 1,
'hot/pair/config/del': 1,
//消息通知
'notice/list': 1,
'notice/add': 1,
'notice/update': 1,
'mUser/opt/log/list': 1,
//Madex 用户管理
'mUser/manage/userList': 1,
'mUser/manage/oneUserDetail': 1,
'mUser/manage/updateUserEmail': 1,
......@@ -65,11 +84,16 @@ let cmdWhiteList = {
'mUser/manage/kyc/list': 1,
'mUser/manage/kyc/oneDetail': 1,
'mUser/manage/kyc/audit': 1,
'mUser/manage/walletAsset/detail': 1,
'mUser/manage/asset/distribution': 1,
'mUser/manage/tradeAsset/detail': 1,
//资源位管理
'link/useful/list': 1,
'link/useful/add': 1,
'link/useful/delete': 1,
'link/useful/update': 1,
'link/useful/detail': 1,
//邮件订阅
'mUser/subscribe/list': 1,
'mUser/subscribe/delete': 1,
'mUser/subscribe/count': 1,
......@@ -77,14 +101,13 @@ let cmdWhiteList = {
'mUser/subscribe/mail/send': 1,
'mUser/subscribe/mail/detail': 1,
'mUser/subscribe/mail/send/group': 1,
//普通用户手续费
'mUser/fee/setting/list': 1,
'mUser/fee/setting/add': 1,
'mUser/fee/setting/update': 1,
'mUser/fee/setting/delete': 1,
'mUser/fee/setting/submit': 1,
'mUser/manage/walletAsset/detail': 1,
'mUser/manage/asset/distribution': 1,
'mUser/manage/tradeAsset/detail': 1,
};
......
import * as ReqUtils from "./req-utils";
import { ErrorCode } from "../constant/errorCode";
import { aclUserInfo } from "@madex/ex-ts-dao";
import { aclUserInfo, aclUserDepartmentPosition, madAdminOrmDB } from "@madex/ex-ts-dao";
let { logger } = require("@madex/ex-js-public");
import { AclUserInfoConst } from "../constant/aclUserConstant";
import * as userAuthConfigService from "../../src/functional/mvc/service/userAuthConfig.service";
let { apiAssertUtils: ApiAssert, BigNumberUtils } = require('@madex/ex-js-public');
let { authCommon: AuthCommon, redisUtilsCommon: RedisClient, } = require('@madex/ex-js-common');
......@@ -26,7 +25,7 @@ export const getCurrentUserId = async function (sessionId: string) {
}
/**
* 判断是否是超管 通过 UID
* 判断是否是管理员 通过 UID
* @param user_id
*/
export const isAdminUserByUid = async function (user_id: number) {
......@@ -37,7 +36,18 @@ export const isAdminUserByUid = async function (user_id: number) {
}
/**
* 判断是否是超管 通过 session_id
* 判断是否是超管 通过 UID
* @param user_id
*/
export const isSuperAdminUserByUid = async function (user_id: number) {
let dbInfo = await getOneAclUserByUid(user_id);
if (dbInfo.user_type != AclUserInfoConst.USER_TYPE.SUPER_ADMIN) {
throw ErrorCode.NO_PERMISSION
}
}
/**
* 判断是否是管理员 通过 session_id
* @param sessionId
*/
export const isAdminUserBySessionId = async function (sessionId: string) {
......@@ -47,6 +57,18 @@ export const isAdminUserBySessionId = async function (sessionId: string) {
throw ErrorCode.NO_PERMISSION
}
}
/**
* 判断是否是超管 通过 session_id
* @param sessionId
*/
export const isSuperAdminUserBySessionId = async function (sessionId: string) {
let currentUserId = await getCurrentUserId(sessionId);
let dbInfo = await getOneAclUserByUid(currentUserId);
if (dbInfo.user_type != AclUserInfoConst.USER_TYPE.SUPER_ADMIN) {
throw ErrorCode.NO_PERMISSION
}
}
/**
* 通过 user_id 查询用户
* @param user_id
......@@ -91,14 +113,59 @@ export const getOneAclUserByAccount = async function (account: string) {
}
export const checkTotp = async function (user_id: number, totp_code: string) {
//获取谷歌密钥并验证
let authInfo = await userAuthConfigService.findByUserId(user_id)
ApiAssert.isTrue(ErrorCode.UNBOUND_TOTP, authInfo && authInfo.totp_encrypt !== '');
await AuthCommon.totpCheckSync(totp_code, authInfo.totp_encrypt)
let dbUserInfo = await getOneAclUserByUid(user_id);
ApiAssert.isTrue(ErrorCode.UNBOUND_TOTP, dbUserInfo && dbUserInfo.totp_encrypt !== '');
await AuthCommon.totpCheckSync(totp_code, dbUserInfo.totp_encrypt)
//判断是否已经使用过
let latestVerifiedKey = "bastard.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 getDepartmentPositionByUid = async function (user_id: number) {
if (!user_id) {
logger.error('aclUserUtils.getDepartmentPositionByUid.error:' + 'user_id is null');
throw ErrorCode.PARAM_MISS
}
let dbInfo = await aclUserDepartmentPosition.prototype.findOne({
where: {
user_id: user_id
},
raw: true
});
return {
department_id: dbInfo ? dbInfo.department_id : "",
position_id: dbInfo ? dbInfo.position_id : ""
}
}
export const getDepartmentPositionByUids = async function (user_ids: number[]) {
if (!user_ids || !user_ids.length) {
logger.error('aclUserUtils.getDepartmentPositionByUids.error:' + 'user_ids is null');
throw ErrorCode.PARAM_MISS
}
let resMap = {};
let dbInfoList = await aclUserDepartmentPosition.prototype.findAll({
where: {
user_id: { [madAdminOrmDB.Op.in]: user_ids }
},
raw: true
});
if (dbInfoList.length) {
for (let item of dbInfoList) {
resMap[item.user_id] = {
department_id: item ? item.department_id : "",
position_id: item ? item.position_id : ""
}
}
}
return resMap
}
\ No newline at end of file
......@@ -47,11 +47,16 @@ export const checkCookie = async (cookies: any, isAdminExclude: any, path: any,
await RedisUtils.writeSync(sessionId, cookieData, Config.LOGIN_EXPIRED);
}
//管理员需要强制绑定谷歌
if (Number(cookieData.userType) === AclUserInfoConst.USER_TYPE.ADMIN && isAdminExclude) {
if (!cookieData.totp_encrypt && isAdminExclude) {
return cookieData
}
ApiAssert.isTrue(ErrorCode.NEED_INPUT_GOOGLE_CODE, Number(cookieData.needConfirm) === 0)
if (cookieData.allow_ips) {
let ips = cookieData.allow_ips.split(",");
if (!ips.includes("*.*.*.*") && !ips.includes("0.0.0.0") && !ips.includes(req.ip)) {
throw ErrorCode.IP_ADDR_LIMIT
}
}
await aclCheck(cookieData, path, req)
return cookieData;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment