Commit a9f7fc8b authored by ml's avatar ml

管理后台 权限 角色 登陆 谷歌 相关功能

parent abd07b9b
// 配置文件暂时和 js 的导出方式保持一致,涉及到线上环境变量的替换等
module.exports = {};
\ No newline at end of file
module.exports = {
BASE_URL: "/backend/v1/"
};
\ No newline at end of file
// 配置文件暂时和 js 的导出方式保持一致,涉及到线上环境变量的替换等
module.exports = {
BASE_URL: "/backend/v1/"
}
\ No newline at end of file
......@@ -15,5 +15,12 @@ export default _.merge(
{
port: 8080, //服务端口
contractData: {}
}
},
{
LOGIN_ERROR_LIMIT: 10,
LOGIN_EXPIRED: 16 * 60 * 60,
LOGIN_IP_LIMIT: 40,
MIN_RATIO_LIMIT: 0, // 由0.01 =>变为0
MAX_RATIO_LIMIT: 1,
},
);
\ No newline at end of file
......@@ -2,15 +2,15 @@ let express = require('express');
let errorHandler = require('errorhandler');
let logger = require("@madex/ex-js-public").logger;
import configSetting from "./config"
import { apiRouterV1 } from "./src/functional/router/v1/index"
/* ======================================================================
* Config
* ====================================================================== */
let app = express();
logger.use(app);
const tfUrl = "/api/v1/tf";
// express 全局设定
require('@madex/ex-js-common').expressSetting(app);
// Request frequency limit
......@@ -22,7 +22,10 @@ const limitList = [
require("@madex/ex-js-common").frequencyLimiting.cookieLimitForCmd(app, limitList);
require("@madex/ex-js-common").apiExceedAlertUtils.check(app, { projectNO: 20, expireTime: 1000 }) // 检查
import configSetting from "./config"
require("./src/setting/access-limit").filter(app);
require("./src/setting/login-filter").filter(app);
if (configSetting.node_env == "development") {
app.use(errorHandler());
......@@ -34,29 +37,9 @@ else {
});
}
/* ======================================================================
* internal Router
* ====================================================================== */
// require('./setting/access-limit')(app);
// require('./setting/apikey-filter')(app);
// require('./setting/need-login')(app);
// require('./setting/need-newotc')(app);
// if (configSetting.node_env === 'development') {
// require("./setting/swagger-setting")(app);
// app.listen(3020, () => logger.info("South Gate to Heaven swagger started!! suffix : 3020/southHeaven"));
// }
import { apiRouterV1 } from "./src/functional/router/v1/index"
app.use('/demo/v1', apiRouterV1);
app.use(apiRouterV1);
//启动Server
// app.listen(configSetting.port, function () {
// // logger.info("Wallet Gateway-(bibox_b020_southgatetoheaven) server listening on %d, in %s mode", configSetting.port, app.get("env"));
// // wxUtils.serviceStartSend('bibox_b020_southgatetoheaven');
// });
// 输出进程错误
process.on('uncaughtException', (error) => {
......@@ -74,7 +57,7 @@ process.on('unhandledRejection', (error, promise) => {
// console.log(configSetting)
app.listen(configSetting.port, '0.0.0.0', () => {
logger.info(
'demo',
'backend',
configSetting.port,
app.get('env'),
);
......
......@@ -11,7 +11,7 @@
"dependencies": {
"@madex/ex-js-common": "git+ssh://git@bitbucket.org:biiigle/ex-js-common.git#master",
"@madex/ex-js-public": "git+ssh://git@bitbucket.org:biiigle/ex-js-public.git#master",
"@madex/ex-ts-dao": "0.0.8",
"@madex/ex-ts-dao": "0.0.9",
"@types/errorhandler": "^1.5.3",
"@types/express": "^4.17.21",
"@types/morgan": "^1.9.9",
......@@ -934,7 +934,8 @@
},
"node_modules/@madex/ex-js-public": {
"version": "1.0.0",
"resolved": "git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#bea44e9b9a086499655a638c5761e0df29c3a6d3",
"resolved": "git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#a328aeba78ae3f4860368a6c790ef434f7dd53be",
"license": "ISC",
"dependencies": {
"axios": "^0.18.0",
"bignumber": "^1.1.0",
......@@ -1079,9 +1080,9 @@
}
},
"node_modules/@madex/ex-ts-dao": {
"version": "0.0.8",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.8.tgz",
"integrity": "sha512-ctDm83WdlNLFP1Phfcqn0ptXVpg067w4xX9gIk62ZASOM8Sr5BtUYOJx8/h17qG05SC3b4LLBvb09wiZ/uAn4g==",
"version": "0.0.9",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.9.tgz",
"integrity": "sha512-Zrn7CAV0zNoOiZQFA016Il5igqNByB2v6JjmGS4U/i7zsw/U+svuOA52owFZGHkggk409qNfWl3bA+gTpAgOhA==",
"license": "ISC",
"dependencies": {
"@madex/ex-js-public": "git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#master",
......
......@@ -39,7 +39,7 @@
"dependencies": {
"@madex/ex-js-common": "git+ssh://git@bitbucket.org:biiigle/ex-js-common.git#master",
"@madex/ex-js-public": "git+ssh://git@bitbucket.org:biiigle/ex-js-public.git#master",
"@madex/ex-ts-dao": "0.0.8",
"@madex/ex-ts-dao": "0.0.9",
"@types/errorhandler": "^1.5.3",
"@types/express": "^4.17.21",
"@types/morgan": "^1.9.9",
......
export const AuthConfigConst = {
IS_LOCKED: {
FALSE: 0,
TRUE: 1,
},
FORCE: {
FALSE: 0,
TRUE: 1
}
}
export const AclUserInfoConst = {
USER_STATUS: {
NORMAL: 0,
LOCK: 1,
DEL: 2,
},
PWD_STATUS: {
DEFAULT: 0,//默认密码
NORMAL: 1,//用户修改后的正常密码
},
USER_TYPE: {
ADMIN: 1,
SUPPORT: 2,
},
}
export const ErrorCode = {
PARAM_MISS:'30000',//请求参数错误
DATA_NOT_EXIST:'30001',//数据不存在
DATA_EXIST:'30002',//数据已存在
NOT_LOGIN: '30003',//账号未登录
NO_PERMISSION: '30004',//账号没有权限
USER_EXIST: '30005',//用户已存在
USER_NOT_EXIST: '30006',//用户不存在
PARENT_MENU_NOT_EXIST: '30007',//父菜单不存在
AUTH_EXIST: '30008',//权限已存在
AUTH_NOT_EXIST: '30009',//权限不存在
EXIST_SUB_AUTH: '30010',//存在下级权限,无法删除
ROLE_NOT_EXIST: '30011',//角色不存在
ROLE_USE: '30012',//角色有用户使用,不允许删除
AUTH_EXIST_ILLEGAL: '30013',//权限ID列表中存在非法的权限ID
ROLE_EXIST_ILLEGAL: '30014',//角色ID列表中存在非法的角色ID
ACCOUNT_LOCK: '30015',//账户已锁定
ACCOUNT_STOP: '30016',//账户已停用
ACCOUNT_OR_PWD_ERR: '30017',//电话号码没有注册或密码错误
TOTP_UNBOUND_LOCKED: '30018',//未绑定二次验证,账号已被锁定
UNBOUND_TOTP: '30019',//未绑定二次验证,账号已被锁定
TOTP_CODE_USED: '30020',//该Google验证码已经被使用过
GOOGLE_HAS_BIND: '30021',//Google认证已被绑定,不可重复绑定
TOTP_KEY_OVERSTAYED: '30022',//密钥已失效,请重新获取
USER_TYPE_ILLEGAL: '30023',//用户类型不合法
NEED_INPUT_GOOGLE_CODE: '30024',//请输入Google验证码
}
/**
* redis中常用值
*/
const RedisValInner = Object.freeze({
LOGIN_ERROR_TIMES_SUFFIX: ".PARTNER_LOGIN_ERROR_COUNT",
SESSION_ID_LIST_SUFFIX: ".PARTNER_SESSION_ID_LIST",
})
export const RedisVal = {
loginErrTimesKey: (userId: any) => `${userId}${RedisValInner.LOGIN_ERROR_TIMES_SUFFIX}`,
sessionListKey: (userId: any) => `${userId}${RedisValInner.SESSION_ID_LIST_SUFFIX}`,
}
\ No newline at end of file
import * as aclRoleAuthService from "../service/aclRoleAuth.service";
import { AclAuthVO, AclAuthPageVO, AclRolePageVO, AclRoleVO } from "../service/aclRoleAuth.service";
import { getCurrentUserId, isAdminUserBySessionId } 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 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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 权限树
* @param req
* @param infoVO
*/
export const getAuthTree = async (req: any, aclAuthPageVO: AclAuthPageVO) => {
let func_name = "aclRoleAuthCtrl.getAuthTree";
let cmd = req.path;
try {
let res = await aclRoleAuthService.getAuthTree();
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 查询权限
* @param req
* @param infoVO
*/
export const getAuthByUser = async (req: any, aclAuthPageVO: AclAuthPageVO) => {
let func_name = "aclRoleAuthCtrl.getAuthByUser";
let cmd = req.path;
try {
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await aclRoleAuthService.getAuthByUser(currentUserId);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 查询权限
* @param req
* @param infoVO
*/
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);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 保存权限信息
* @param req
* @param infoVO
*/
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 删除权限信息
* @param req
* @param infoVO
*/
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 分页查询角色列表
* @param req
* @param infoVO
*/
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);
aclRolePageVO.creator = currentUserId;
let res = await aclRoleAuthService.roleList(aclRolePageVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 查询角色列表
* @param req
* @param infoVO
*/
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);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 查询角色
* @param req
* @param infoVO
*/
export const getRoleByUser = async (req: any, aclRolePageVO: AclRolePageVO) => {
let func_name = "aclRoleAuthCtrl.getRoleByUser";
let cmd = req.path;
try {
let userId = aclRolePageVO.user_id;
let res = await aclRoleAuthService.getRoleByUser(userId);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 保存角色
* @param req
* @param infoVO
*/
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;
let res = await aclRoleAuthService.saveRole(aclRoleVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 删除角色
* @param req
* @param infoVO
*/
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 修改角色权限
* @param req
* @param infoVO
*/
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 修改用户角色
* @param req
* @param infoVO
*/
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 校验
* @param infoVO
*/
async function preCheckAuth(aclAuthVO: AclAuthVO) {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclAuthVO.pid);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclAuthVO.name);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclAuthVO.url);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclAuthVO.type);
}
/**
* 校验
* @param infoVO
*/
async function preCheckRole(aclRoleVO: AclRoleVO) {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclRoleVO.name);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclRoleVO.remark);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclRoleVO.type);
}
import * as aclUserService from "../service/aclUser.service";
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";
/**
* 分页查询用户列表
* @param req
* @param infoVO
*/
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 添加用户信息
* @param req
* @param infoVO
*/
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 修改用户信息
* @param req
* @param infoVO
*/
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);
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, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "aclUserCtrl.updateStatus";
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 重置密码
* @param req
* @param infoVO
*/
export const resetPwd = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "aclUserCtrl.resetPwd";
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 校验
* @param infoVO
*/
async function preCheck(aclUserInfoVO: AclUserInfoVO) {
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.account);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.user_type);
ApiAssert.notNull(ErrorCode.PARAM_MISS, aclUserInfoVO.remark);
}
import * as i18nService from "../service/i18n.service";
import { I18nInfoVO, I18nInfoPageVO } from "../service/i18n.service";
import { ErrorCode } from "../../../constant/errorCode";
let { logger, ResponseUtils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
/**
* 分页查询列表
......@@ -13,17 +14,17 @@ export const list = async (req: any, infoPageVO: I18nInfoPageVO) => {
let cmd = req.path;
try {
infoPageVO.page = Optional.opt(infoPageVO, 'page', 1);
infoPageVO.size = Optional.opt(infoPageVO, 'size', 50);
infoPageVO.size = Optional.opt(infoPageVO, 'size', 20);
infoPageVO.platform = Optional.opt(infoPageVO, 'platform', 1);
infoPageVO.module = Optional.opt(infoPageVO, 'module', 1);
infoPageVO.lang = Optional.opt(infoPageVO, 'lang', 'en');
let res = await i18nService.list(infoPageVO);
return ResponseUtils.success(cmd, res);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return ResponseUtils.error(func_name, cmd, e);
return Res3Utils.getErrorResult(e);
}
};
/**
......@@ -37,11 +38,11 @@ export const add = async (req: any, infoVO: I18nInfoVO) => {
try {
await preCheck(infoVO);
let res = await i18nService.add(infoVO);
return ResponseUtils.success(cmd, res);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return ResponseUtils.error(func_name, cmd, e);
return Res3Utils.getErrorResult(e);
}
};
/**
......@@ -53,13 +54,13 @@ export const update = async (req: any, infoVO: I18nInfoVO) => {
let func_name = "i18nCtrl.update";
let cmd = req.path;
try {
ApiAssert.notNull('3000', infoVO.id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, infoVO.id);
let res = await i18nService.update(infoVO);
return ResponseUtils.success(cmd, res);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return ResponseUtils.error(func_name, cmd, e);
return Res3Utils.getErrorResult(e);
}
};
/**
......@@ -71,13 +72,13 @@ export const del = async (req: any, infoVO: I18nInfoVO) => {
let func_name = "i18nCtrl.del";
let cmd = req.path;
try {
ApiAssert.notNull('3000', infoVO.id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, infoVO.id);
let res = await i18nService.del(infoVO);
return ResponseUtils.success(cmd, res);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return ResponseUtils.error(func_name, cmd, e);
return Res3Utils.getErrorResult(e);
}
};
......@@ -88,10 +89,10 @@ export const del = async (req: any, infoVO: I18nInfoVO) => {
*/
async function preCheck(infoVO: I18nInfoVO) {
if (![1, 2, 3, 4, 5].includes(infoVO.platform)) {
throw '3000';
throw ErrorCode.PARAM_MISS;
}
ApiAssert.notNull('3000', infoVO.module);
ApiAssert.notNull('3000', infoVO.code);
ApiAssert.notNull('3000', infoVO.lang);
ApiAssert.notNull('3000', infoVO.content);
ApiAssert.notNull(ErrorCode.PARAM_MISS, infoVO.module);
ApiAssert.notNull(ErrorCode.PARAM_MISS, infoVO.code);
ApiAssert.notNull(ErrorCode.PARAM_MISS, infoVO.lang);
ApiAssert.notNull(ErrorCode.PARAM_MISS, infoVO.content);
}
\ No newline at end of file
import * as i18nLogService from "../service/i18nlog.service";
import { I18nInfoLogVO } from "../service/i18nlog.service";
import { ErrorCode } from "../../../constant/errorCode";
let { logger, ResponseUtils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
/**
* 国际化信息修改日志列表
......@@ -13,16 +14,16 @@ export const list = async (req: any, i18nInfoLogVO: I18nInfoLogVO) => {
let cmd = req.path;
try {
i18nInfoLogVO.page = Optional.opt(i18nInfoLogVO, 'page', 1);
i18nInfoLogVO.size = Optional.opt(i18nInfoLogVO, 'size', 50);
i18nInfoLogVO.size = Optional.opt(i18nInfoLogVO, 'size', 20);
i18nInfoLogVO.platform = Optional.opt(i18nInfoLogVO, 'platform', 1);
i18nInfoLogVO.module = Optional.opt(i18nInfoLogVO, 'module', 1);
i18nInfoLogVO.lang = Optional.opt(i18nInfoLogVO, 'lang', 'en');
let res = await i18nLogService.list(i18nInfoLogVO);
return ResponseUtils.success(cmd, res);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return ResponseUtils.error(func_name, cmd, e);
return Res3Utils.getErrorResult(e);
}
};
/**
......@@ -34,13 +35,13 @@ export const revert = async (req: any, i18nInfoLogVO: I18nInfoLogVO) => {
let func_name = "i18nLogCtrl.revert";
let cmd = req.path;
try {
ApiAssert.notNull('3000', i18nInfoLogVO.id);
ApiAssert.notNull('3000', i18nInfoLogVO.info_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, i18nInfoLogVO.id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, i18nInfoLogVO.info_id);
let res = await i18nLogService.revert(i18nInfoLogVO);
return ResponseUtils.success(cmd, res);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return ResponseUtils.error(func_name, cmd, e);
return Res3Utils.getErrorResult(e);
}
};
import * as userAuthConfigService from "../service/userAuthConfig.service";
import { AuthConfigVO, AuthConfigPageVO } from "../service/userAuthConfig.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUserId, isAdminUserBySessionId } 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);
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);
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, 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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
\ No newline at end of file
import * as userOptService from "../service/userOpt.service";
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";
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);
}
};
/**
* 登陆
* @param req
* @param infoVO
*/
export const login = async (req: any, aclUserInfoVO: AclUserInfoVO, res: any) => {
let func_name = "userOptCtrl.login";
let cmd = req.path;
let result: any;
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
ApiAssert.isNotEmpty(ErrorCode.PARAM_MISS, aclUserInfoVO.account);
ApiAssert.isNotEmpty(ErrorCode.PARAM_MISS, aclUserInfoVO.pwd);
ApiAssert.isFalse(ErrorCode.ACCOUNT_OR_PWD_ERR, aclUserInfoVO.pwd.length < 8);
ApiAssert.isFalse(ErrorCode.ACCOUNT_OR_PWD_ERR, aclUserInfoVO.pwd.length > 30);
result = await userOptService.login(aclUserInfoVO.account, aclUserInfoVO.pwd, ip || "");
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
if (result.result && result.sessionId) {
if (req.headers.origin){
let iSecure = req.headers.origin.startsWith("https");
let options = {
expires: new Date(new Date().getTime() + 1000 * 60 * 60 * 8), // 15 days
httpOnly: true,
secure: iSecure
};
res.cookie('session_id', result.sessionId, options);
delete result.sessionId;
}
}
return Res3Utils.result(result);
};
/**
* 登出
* @param req
* @param aclUserInfoVO
* @param res
*/
export const logout = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "userOptCtrl.logout";
let cmd = req.path;
try {
if (req.cookies.session_id) {
let currentUser = await getCurrentUser(req.cookies.session_id);
if (currentUser) {
await userOptService.deleteAllSessionByUserId(currentUser.userId);
}
}
return Res3Utils.result('ok');
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 登录-二次验证
* @param req
* @param aclUserInfoVO
* @param res
*/
export const loginConfirm = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "userOptCtrl.loginConfirm";
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 修改密码
* @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);
}
};
/**
* 绑定谷歌-生成新的密钥
* @param req
* @param aclUserInfoVO
* @param res
*/
export const bindTotpAsk = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "userOptCtrl.bindTotpAsk";
let cmd = req.path;
try {
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await userOptService.bindTotpAsk(req.cookies.session_id, currentUserId);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 绑定谷歌-验证新密钥
* @param req
* @param aclUserInfoVO
* @param res
*/
export const bindTotpConfirm = async (req: any, aclUserInfoVO: AclUserInfoVO) => {
let func_name = "userOptCtrl.bindTotpConfirm";
let cmd = req.path;
try {
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);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
This diff is collapsed.
// @madex/ex-ts-dao 是 ts 的 dao, 代码在 bitbucket/ex-js-dao 的 ts 分支上
import { madAdminOrmDB, aclUserInfo } 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";
let { logger } = require('@madex/ex-js-public');
export interface AclUserInfoVO {
user_id?: number;
account?: string | any;
phone?: string | any;
email?: string | any;
remark?: string | any;
user_type?: number;
pwd?: string | any;
pwd_salt?: string;
pwd_status?: number;
user_status?: number;
createdAt?: Date | any;
updatedAt?: Date | any;
totpCode?: any,
originPwd?: any,
newPwd?: any,
}
export interface AclUserInfoPageVO extends AclUserInfoVO {
page?: number,
size?: number
}
export const list = async (aclUserInfoPageVO: AclUserInfoPageVO) => {
if (aclUserInfoPageVO.account) {
aclUserInfoPageVO.account = { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.account}%` };
}
if (aclUserInfoPageVO.phone) {
aclUserInfoPageVO.phone = { [madAdminOrmDB.Op.like]: `${aclUserInfoPageVO.phone}%` };
}
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() };
}
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({
where: where,
limit: size,
offset: (page - 1) * size,
order: [["user_id", "asc"]],
raw: true
});
return resList;
};
export const add = async (aclUserInfoVO: AclUserInfoVO) => {
if (!aclUserInfoVO.createdAt) {
aclUserInfoVO.createdAt = new Date();
}
if (!aclUserInfoVO.updatedAt) {
aclUserInfoVO.updatedAt = new Date();
}
let dbInfo = await aclUserInfo.prototype.findOne({
where: {
account: aclUserInfoVO.account,
},
raw: true
});
if (dbInfo) {
throw ErrorCode.USER_EXIST;
}
aclUserInfoVO.pwd = CryptUtils.defPwd();
aclUserInfoVO.pwd_salt = CryptUtils.salt();
await aclUserInfo.prototype.create(aclUserInfoVO);
//TODO:写日志
return 'ok';
};
export const update = async (aclUserInfoVO: AclUserInfoVO) => {
let userId = Number(aclUserInfoVO.user_id);
await getOneAclUserByUid(userId);
let updateInfo = Object.create(null);
updateInfo.remark = aclUserInfoVO.remark;
updateInfo.updatedAt = new Date();
if (aclUserInfoVO.phone) {
updateInfo.phone = aclUserInfoVO.phone
}
if (aclUserInfoVO.email) {
updateInfo.email = aclUserInfoVO.email
}
await aclUserInfo.prototype.update(updateInfo, {
where: {
user_id: userId
}
});
//TODO:写日志
return 'ok';
};
export const updateStatus = async (aclUserInfoVO: AclUserInfoVO) => {
let userId = Number(aclUserInfoVO.user_id);
await getOneAclUserByUid(userId);
let updateInfo = Object.create(null);
updateInfo.status = aclUserInfoVO.user_status;
updateInfo.updatedAt = new Date();
await aclUserInfo.prototype.update(updateInfo, {
where: {
user_id: userId
}
});
//TODO:写日志
return 'ok';
};
export const resetPwd = async (aclUserInfoVO: AclUserInfoVO) => {
let userId = Number(aclUserInfoVO.user_id);
await getOneAclUserByUid(userId);
let updateInfo = Object.create(null);
updateInfo.pwd = CryptUtils.defPwd();
updateInfo.pwd_status = AclUserInfoConst.PWD_STATUS.DEFAULT;
updateInfo.user_status = AclUserInfoConst.USER_STATUS.NORMAL;
updateInfo.updatedAt = new Date();
await aclUserInfo.prototype.update(updateInfo, {
where: {
user_id: userId
}
});
//TODO:写日志
return 'ok';
};
export async function updateUserStatus(userId: any, userStatus: number) {
try {
await aclUserInfo.prototype.update({
user_status: userStatus
}, {
where: {
user_id: userId,
}
});
}
catch (e) {
logger.error('aclUserService.updateUserStatus.error:' + e)
throw e;
}
}
export async function findAllForPage(page: number, size: number, userId?: number,
typeArr?: any, statusArr?: any,
fromTime?: any, toTime?: any, remark?: any) {
try {
let where = Object.create(null);
if (userId) {
where.user_id = userId
}
if (typeArr) {
where.user_type = { [madAdminOrmDB.Op.in]: typeArr };
}
if (statusArr) {
where.user_status = { [madAdminOrmDB.Op.in]: statusArr };
}
if (fromTime && toTime) {
where.createdAt = { [madAdminOrmDB.Op.between]: [fromTime, toTime] };
}
if (remark) {
where.remark = { [madAdminOrmDB.Op.like]: `${remark}%` };
}
let resList = await aclUserInfo.prototype.findAndCount({
where: where,
limit: size,
offset: (page - 1) * size,
order: [["user_id", "asc"]],
raw: true
});
return resList;
}
catch (e) {
logger.error('aclUserService.findAllForPage.error:' + e)
throw e;
}
}
// @madex/ex-ts-dao 是 ts 的 dao, 代码在 bitbucket/ex-js-dao 的 ts 分支上
import { i18nInfo, i18nInfoLog, ormDB } from "@madex/ex-ts-dao";
import * as i18nLogService from "../service/i18nlog.service";
import { ErrorCode } from "../../../constant/errorCode";
let { logger } = require('@madex/ex-js-public');
......@@ -78,7 +79,7 @@ export const add = async (infoVO: I18nInfoVO) => {
raw: true
});
if (dbInfo){
throw '25511';
throw ErrorCode.DATA_EXIST;
}
await i18nInfo.prototype.create(infoVO);
return 'ok';
......@@ -94,7 +95,7 @@ export const update = async (infoVO: I18nInfoVO) => {
}
});
if (!dbOneI18nInfo) {
throw '3246';
throw ErrorCode.DATA_NOT_EXIST;
}
delete infoVO.id;
let i18nInfoLogOne = await buildOneI18nInfoLog(dbOneI18nInfo, infoVO);
......@@ -132,7 +133,7 @@ export const del = async (infoVO: I18nInfoVO) => {
}
});
if (!dbOneI18nInfo) {
throw '3246';
throw ErrorCode.DATA_NOT_EXIST;
}
delete infoVO.id;
let i18nInfoLogOne = await buildOneI18nInfoLog(dbOneI18nInfo, infoVO);
......
......@@ -2,6 +2,7 @@
import { i18nInfo, i18nInfoLog, ormDB } from "@madex/ex-ts-dao";
import * as i18nService from "./i18n.service";
import { I18nInfoPageVO, I18nInfoVO } from "./i18n.service";
import { ErrorCode } from "../../../constant/errorCode";
export interface I18nInfoLogVO extends I18nInfoPageVO {
info_id?: number;
......@@ -58,7 +59,7 @@ export async function revert(i18nInfoLogVO: I18nInfoLogVO) {
}
});
if (!dbOneI18nInfoLog) {
throw '3246';
throw ErrorCode.DATA_NOT_EXIST;
}
let infoId = dbOneI18nInfoLog.info_id;
......
// @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";
let { apiAssertUtils: ApiAssert, datetimeUtils: DatetimeUtils } = require('@madex/ex-js-public');
let { authCommon: AuthCommon, redisUtilsCommon: RedisClient, BigNumberUtils } = require('@madex/ex-js-common');
let _ = require('lodash');
let { logger } = require('@madex/ex-js-public');
//默认的有效期时间,3天
const LockedDeadlineDay = 3
export interface AuthConfigVO {
id?: number;
user_id?: number;
totp_encrypt?: string | any;
is_locked?: number | any;
locked_time?: Date | any;
force?: number | any;
deadline?: Date | any;
createdAt?: Date | any;
updatedAt?: Date | any;
user_type?: number | any;
}
export interface AuthConfigPageVO extends AuthConfigVO {
page?: number,
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
}
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
}
export async function changeForceStatus(userId: number, forceStatus: 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)
}
return 'success'
}
export async function changeLockedStatus(userId: number | undefined) {
//查询是否已有配置记录
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 } })
return "success"
}
export async function resetTotp(userId: number | undefined) {
//查询是否已有配置记录
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));
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) {
//获取该账户使用过的所有sessionId
let sessionListKey = RedisVal.sessionListKey(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)
})
}
This diff is collapsed.
import Express from "express"
const {
Res3Utils,
logger,
} = require("@madex/ex-js-public");
const router = Express.Router();
import * as userController from "../../mvc/control/user.control";
import * as i18nCtrl from "../../mvc/control/i18n.control";
import * as i18nLogCtrl from "../../mvc/control/i18nlog.control";
import * as aclUserCtrl from "../../mvc/control/aclUser.control";
import * as aclRoleAuthCtrl from "../../mvc/control/aclRoleAuth.control";
import * as userOptCtrl from "../../mvc/control/userOpt.control";
import * as userAuthConfigCtrl from "../../mvc/control/userAuthConfig.control";
import * as ReqUtils from "../../../utils/req-utils";
const getFunc = {
'user/info': userController.getUserInfo,
......@@ -19,40 +28,69 @@ const postFunc = {
'i18n/info/log/list': i18nLogCtrl.list,
'i18n/info/log/revert': i18nLogCtrl.revert,
};
'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,
'acl/auth/list': aclRoleAuthCtrl.authList,
'acl/auth/tree': aclRoleAuthCtrl.getAuthTree,
'acl/auth/getByUser': aclRoleAuthCtrl.getAuthByUser,
'acl/auth/getByRole': aclRoleAuthCtrl.getAuthByRole,
'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/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,
let getErrorMessage = (code: number, message?: string) => {
return {
code: code,
msg: message,
data: [],
};
};
// TODO 这里先和 nodejs 的注册路由方式保持一样,后面在调整。
router.get('/*', (req, res, next) => {
let path = req.path ? req.path.slice(1) : '';
let path = ReqUtils.parsePath(req.originalUrl);
if (!path) {
return res.json(getErrorMessage(3000));
return Res3Utils.responseError('4003', res);
}
if (!getFunc[path]) {
return res.json(getErrorMessage(3000));
return Res3Utils.responseError('4003', res);
}
doJob(req, res, next, req.query, getFunc[path]);
});
router.post('/*', (req, res, next) => {
const path = req.path ? req.path.slice(1) : '';
let path = ReqUtils.parsePath(req.originalUrl);
if (!path) {
return res.json(getErrorMessage(3000));
return Res3Utils.responseError('4003', res);
}
if (!postFunc[path]) {
return res.json(getErrorMessage(3000));
return Res3Utils.responseError('4003', res);
}
doJob(req, res, next, req.body, postFunc[path]);
......@@ -63,18 +101,11 @@ const doJob = (req, res, next, param, func) => {
let _func_name_ = 'router.doJob';
func(req, param).then(data => {
func(req, param, res).then(data => {
res.json(data);
}).catch(err => { // 可以抛出错误码
console.error(_func_name_, err);
// if (isValidResponseData(err)) {
// res.json(err);
// return;
// }
// if (!err || !errorCodeDefine[err]) {
// err = errCode.CODE_INTERNAL;
// }
return res.json(getErrorMessage(3000));
logger.error(_func_name_, err);
return Res3Utils.responseError(err, res);
});
};
......
'use strict';
import * as ReqUtils from "../utils/req-utils";
const {
Res3Utils,
logger: Logger,
} = require("@madex/ex-js-public");
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,
'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,
'acl/role/list': 1,
'acl/role/getByUser': 1,
'acl/role/getAll': 1,
'acl/role/save': 1,
'acl/role/del': 1,
'acl/changeRoleAuth': 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,
};
let filter = function (app: any) {
app.use(function (req, res, next) {
let path = ReqUtils.parsePath(req.originalUrl);
try {
//如果是非登录接口,可以直接跳过
if (!cmdWhiteList[path]) {
throw '3000'
}
next();
}
catch (e) {
Logger.error(`access-limit filter error!! - ${e}`);
return res.json(Res3Utils.getErrorResult(e));
}
});
};
module.exports = {
filter: filter,
};
\ No newline at end of file
/**
* 登录过滤
*/
const {
Res3Utils,
logger: Logger,
} = require("@madex/ex-js-public");
import * as ReqUtils from "../utils/req-utils"
const CLASS_NAME = "login-filter";
const ExcludeApi = {
"user/login": 1,
"user/logout": 1,
"user/login/confirm": 1,
};
//管理员需要强制绑定,该位置做特殊处理
const AdminExcludeApi = {
"user/bind/totp/ask": 1,
"user/bind/totp/confirm": 1,
}
let filter = function (app: any) {
app.use(function (req, res, next) {
let path = ReqUtils.parsePath(req.originalUrl);
try {
//如果是非登录接口,可以直接跳过
if (ExcludeApi[path] || path.indexOf("bastard") > 0) {
next();
}
else {
let cookies = req.cookies
ReqUtils
.checkCookie(cookies, AdminExcludeApi[path], path, req)
.then(() => next())
.catch(e => res.json(Res3Utils.getErrorResult(e)))
}
}
catch (e) {
Logger.error(`${CLASS_NAME} filter error!! - ${e}`);
return res.json(Res3Utils.getErrorResult(e));
}
});
};
module.exports = {
filter: filter,
};
import * as ReqUtils from "./req-utils";
import { ErrorCode } from "../constant/errorCode";
import { aclUserInfo } from "@madex/ex-ts-dao";
let { logger } = require("@madex/ex-js-public");
import { AclUserInfoConst } from "../constant/aclUserConstant";
/**
* 获取当前登陆用户信息
* @param sessionId
*/
export const getCurrentUser = async function (sessionId: string) {
let currentUser = await ReqUtils.getCookie(sessionId);
return currentUser;
}
/**
* 获取当前登陆用户userId
* @param sessionId
*/
export const getCurrentUserId = async function (sessionId: string) {
let currentUser = await ReqUtils.getCookie(sessionId);
return currentUser.userId;
}
/**
* 判断是否是超管 通过 UID
* @param user_id
*/
export const isAdminUserByUid = async function (user_id: number) {
let dbInfo = await getOneAclUserByUid(user_id);
if (dbInfo.user_type != AclUserInfoConst.USER_TYPE.ADMIN) {
throw ErrorCode.NO_PERMISSION
}
}
/**
* 判断是否是超管 通过 session_id
* @param sessionId
*/
export const isAdminUserBySessionId = async function (sessionId: string) {
let currentUserId = await getCurrentUserId(sessionId);
let dbInfo = await getOneAclUserByUid(currentUserId);
if (dbInfo.user_type != AclUserInfoConst.USER_TYPE.ADMIN) {
throw ErrorCode.NO_PERMISSION
}
}
/**
* 通过 user_id 查询用户
* @param user_id
*/
export const getOneAclUserByUid = async function (user_id: number) {
if (!user_id) {
logger.error('aclUserUtils.getOneAclUserByUid.error:' + 'user_id is null');
throw ErrorCode.PARAM_MISS
}
let dbInfo = await aclUserInfo.prototype.findOne({
where: {
user_id: user_id,
},
raw: true
});
if (!dbInfo) {
logger.error('aclUserUtils.getOneAclUserByUid.error:' + 'dbInfo is null');
throw ErrorCode.USER_NOT_EXIST
}
return dbInfo;
}
/**
* 通过 account 查询用户
* @param account
*/
export const getOneAclUserByAccount = async function (account: string) {
if (!account) {
logger.error('aclUserUtils.getOneAclUserByAccount.error:' + 'account is null');
throw ErrorCode.PARAM_MISS
}
let dbInfo = await aclUserInfo.prototype.findOne({
where: {
account: account,
},
raw: true
});
if (!dbInfo) {
logger.error('aclUserUtils.getOneAclUserByAccount.error:' + 'dbInfo is null');
throw ErrorCode.USER_NOT_EXIST
}
return dbInfo;
}
\ No newline at end of file
/**
* 加密工具类
*/
import Sha1 from 'crypto-js/sha1';
import Cryptiles from "cryptiles";
export const CryptUtils = {
salt: (digit = 9) => Cryptiles.randomDigits(digit),
sessionId: (userId: any) => Sha1(userId + Cryptiles.randomString(32)).toString(),
defPwd: () => Cryptiles.randomDigits(8),
};
import Config from "../../config";
let { redisUtilsCommon: RedisUtils } = require('@madex/ex-js-common')
let { logger, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public')
import { ErrorCode } from "../constant/errorCode";
import * as aclRoleAuthService from "../functional/mvc/service/aclRoleAuth.service";
import { AclUserInfoConst } from "../constant/aclUserConstant";
const aclPass = [
'user/getInfo',
'acl/auth/tree',
'acl/role/getAll',
'user/bind/totp/ask',
'user/bind/totp/confirm',
'user/updatePwd',
'acl/user/add'
]
export const getCookie = async function (sessionId: string) {
let func_name = 'reqUtils.getCookie';
try {
let cookieData = await RedisUtils.getSync(sessionId);
if (!cookieData || !cookieData.userId) {
throw ErrorCode.NOT_LOGIN;
}
return cookieData;
}
catch (e) {
logger.error(`${func_name}.error:` + e);
throw e;
}
}
export const checkCookie = async (cookies: any, isAdminExclude: any, path: any, req: any) => {
ApiAssert.isNotEmpty(ErrorCode.NOT_LOGIN, cookies);
ApiAssert.isNotEmpty(ErrorCode.NOT_LOGIN, cookies.session_id);
let sessionId = cookies.session_id;
let cookieData = await RedisUtils.getSync(sessionId);
ApiAssert.isNotEmpty(ErrorCode.NOT_LOGIN, cookieData);
if (!cookieData.authSet && cookieData.userId) {
// 自动注入acl于缓存
let { roleSet, authSet } = await aclRoleAuthService.getUserAcl(cookieData.userId);
cookieData.roleSet = roleSet;
cookieData.authSet = authSet;
await RedisUtils.writeSync(sessionId, cookieData, Config.LOGIN_EXPIRED);
}
//管理员需要强制绑定谷歌
if (Number(cookieData.userType) === AclUserInfoConst.USER_TYPE.ADMIN && isAdminExclude) {
return cookieData
}
ApiAssert.isTrue(ErrorCode.NEED_INPUT_GOOGLE_CODE, Number(cookieData.needConfirm) === 0)
await aclCheck(cookieData, path, req)
return cookieData;
}
async function aclCheck(cookieData: any, path: any, req: any) {
path = toHump(path); //先转驼峰
if (aclPass.includes(path)) {
return;
}
if (!cookieData.authSet.includes(path)) {
throw ErrorCode.NO_PERMISSION;
}
}
export const parsePath = function (url: any) {
if (!url) return url;
if (!url.includes(Config.BASE_URL)) return url;
let r = url.replace(Config.BASE_URL, "");
r = r.split("?")[0];
return r;
}
function toHump(name: any) {
if (name.includes("_")) {
return name.replace(/\_(\w)/g, function (all, letter) {
return letter.toUpperCase();
});
}
return name;
}
\ No newline at end of file
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