doomiwork 4.1.5 → 4.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/controller.js +1 -1
- package/package.json +1 -1
- package/utilities/requestparser.js +37 -15
package/core/controller.js
CHANGED
|
@@ -182,7 +182,7 @@ class controller {
|
|
|
182
182
|
*/
|
|
183
183
|
async getListData(req, dataKey, configFile = 0) {
|
|
184
184
|
if (this.logger) this.logger.trace("准备获取dataconfig文件中对应的 %s list数据",dataKey)
|
|
185
|
-
const listinfo = getListInfo(req, dataKey, configFile, this._daoModel
|
|
185
|
+
const listinfo = getListInfo(req, dataKey, configFile, this._daoModel); //, ignorefilter==1
|
|
186
186
|
if (!listinfo) return { successed: false, errcode: -10, errmsg:`缺失${dataKey}对应的查询语句`};
|
|
187
187
|
|
|
188
188
|
////直接操作数据库之前,可由子类再次Handler
|
package/package.json
CHANGED
|
@@ -60,9 +60,7 @@ module.exports.parseTagInSql = (req, sql, allowNull = true) => {
|
|
|
60
60
|
if (notdo && notdo.length > 0) return;
|
|
61
61
|
|
|
62
62
|
let noQuoteProtect = matchValue[0] == '!';
|
|
63
|
-
if (noQuoteProtect)
|
|
64
|
-
matchValue = matchValue.substring(1);
|
|
65
|
-
}
|
|
63
|
+
if (noQuoteProtect) matchValue = matchValue.substring(1);
|
|
66
64
|
///是否有格式要求
|
|
67
65
|
let validformat = matchValue.split('|');
|
|
68
66
|
matchValue = validformat[0];
|
|
@@ -138,17 +136,39 @@ module.exports.parseTagForParameterize = (req, filterSetting={}) => {
|
|
|
138
136
|
}
|
|
139
137
|
return {sql,params};
|
|
140
138
|
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* 检查排序字段是否合法
|
|
142
|
+
* @param {*} sortField
|
|
143
|
+
* @returns
|
|
144
|
+
*/
|
|
145
|
+
function sortFieldIsLegal(sortField,allowedFields = []){
|
|
146
|
+
/// 没有传递排序字段,则不用检查
|
|
147
|
+
if (!sortField) return sortField;
|
|
148
|
+
/// 检查排序字段是否在允许的字段列表中,如果存在allowedFields,则只允许在allowedFields中排序
|
|
149
|
+
if (allowedFields && allowedFields.length) {
|
|
150
|
+
if(allowedFields.map(item => item.toLowerCase()).includes(sortField.toLowerCase())) return sortField;
|
|
151
|
+
/// 如果不在allowedFields中,则不允许使用传入的字段名进行排序,防止sql注入
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
/// 如果allowedFields为空,则检查排序的字段是否合法,防止sql注入
|
|
155
|
+
if (sortField.indexOf(' ') >= 0 || sortField.indexOf('(') >= 0 || sortField.indexOf(')') >= 0) return null;
|
|
156
|
+
return checkSqlInjection(sortField);
|
|
157
|
+
}
|
|
158
|
+
|
|
141
159
|
/*
|
|
142
160
|
* 列表请求上下文中获取需要的信息
|
|
143
161
|
* 如Page ,PageSize , Sort 等等
|
|
144
162
|
*/
|
|
145
163
|
module.exports.getListInfo = (req, dataKey, cfgType = 0, dao) => {
|
|
146
164
|
if (!dataKey) return null;
|
|
165
|
+
const dataConfig = dataconfig.getConfig(dataKey, cfgType);
|
|
166
|
+
if (!dataConfig?.list) return null;
|
|
147
167
|
///确认是否是需要导出Excel
|
|
148
168
|
const export2Excel = (req.query.exportexcel + "").toLowerCase() === "true";
|
|
149
169
|
let { page = 1, rows: pageSize = 100, sort, order, clientFilter: filter } = req.query
|
|
150
170
|
///防止sortSql 注入在排序的参数中
|
|
151
|
-
if (sort) sort = checkSqlInjection(sort);
|
|
171
|
+
if (sort) sort = sortFieldIsLegal(sort, dataConfig.list.allow_sort_fields) //checkSqlInjection(sort);
|
|
152
172
|
// 防止页面数据传入非数字
|
|
153
173
|
if (isNaN(pageSize)) pageSize = 30;
|
|
154
174
|
// 防止页面数据传入非数字
|
|
@@ -158,7 +178,7 @@ module.exports.getListInfo = (req, dataKey, cfgType = 0, dao) => {
|
|
|
158
178
|
///拼接排序的语句
|
|
159
179
|
if (order && sort && ORDER_STRING.includes(order.toLowerCase())) sort = sort + ' ' + order
|
|
160
180
|
//req.order =req.sort? utility.ifNull((req.body.order || req.query.order), ""):'';
|
|
161
|
-
|
|
181
|
+
|
|
162
182
|
if (dataConfig && dataConfig.list) {
|
|
163
183
|
req.dataConfig = dataConfig
|
|
164
184
|
let { sql, listsql, countsql, sqltype = 'sql', field, footer, search, sort: constsort } = dataConfig.list
|
|
@@ -167,7 +187,8 @@ module.exports.getListInfo = (req, dataKey, cfgType = 0, dao) => {
|
|
|
167
187
|
/**排序方式 *///
|
|
168
188
|
sort = sort || constsort;
|
|
169
189
|
/**来自req请求参数中的过滤条件 */
|
|
170
|
-
|
|
190
|
+
const clientfilter = null;// 不再支持可以通过客户端传递过滤条件,防止sql注入 //checkSqlInjection(this.parseTagInSql(req, filter, false));
|
|
191
|
+
let SqlParameters = [];
|
|
171
192
|
//如果配置文件中不是直接的sql语句,则从DAO对象中的指定方法来获取sql
|
|
172
193
|
if (sqltype !== 'sql' && listsql && typeof (dao[listsql]) === 'function') {
|
|
173
194
|
sql = dao[sql](req, { page, rows: pageSize, sort, filter: searchCondition.filter, client: clientfilter });
|
|
@@ -177,20 +198,21 @@ module.exports.getListInfo = (req, dataKey, cfgType = 0, dao) => {
|
|
|
177
198
|
|
|
178
199
|
/**根据过滤条件、排序条件、分页获取的方式,和原始sql拼接成最终获取数据的sql */
|
|
179
200
|
if (sqltype==='sql'){
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
/////在Sql中再放入获取总记录数的语句
|
|
185
|
-
';SELECT FOUND_ROWS() AS total;';
|
|
201
|
+
const mainParameterlizedSql = this.parseTagForParameterize(req, {pattern:sql});
|
|
202
|
+
if (!mainParameterlizedSql.sql) return null;
|
|
203
|
+
sql = `${mainParameterlizedSql.sql} ${searchCondition.filter} ${sort ? (' order by ' + sort) : ''} ${export2Excel ? '' : ' limit ' + Number(pageSize) + ' OFFSET ' + (Math.max(Number(page), 1) - 1) * Number(pageSize)};SELECT FOUND_ROWS() AS total`;
|
|
204
|
+
SqlParameters = SqlParameters.concat(mainParameterlizedSql.params || [], searchCondition.params);
|
|
186
205
|
/*** 如果存在汇总列的sql,则把SQL放置在最末尾 */
|
|
187
206
|
if (countsql) {
|
|
188
|
-
|
|
207
|
+
const countParameterlizedSql = this.parseTagForParameterize(req, { pattern: countsql });
|
|
208
|
+
if (!countParameterlizedSql.sql) return null;
|
|
209
|
+
sql += appendSearchCondition2Count(countParameterlizedSql.sql, searchCondition.filter)
|
|
210
|
+
SqlParameters = SqlParameters.concat(countParameterlizedSql.params || [], searchCondition.params);
|
|
189
211
|
}
|
|
190
212
|
}
|
|
191
213
|
///如果存在统计的SQL,则参数需要Double一次
|
|
192
|
-
const sqlParams = countsql ? [].concat(searchCondition.params, searchCondition.params):searchCondition.params;
|
|
193
|
-
return { sql, fields: field, params:
|
|
214
|
+
// const sqlParams = countsql ? [].concat(searchCondition.params, searchCondition.params):searchCondition.params;
|
|
215
|
+
return { sql, fields: field, params: SqlParameters, footers: footer, page, hascounter: countsql?true:false };
|
|
194
216
|
}
|
|
195
217
|
}
|
|
196
218
|
/*
|