abler-api 0.1.71 → 0.1.73
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/dist/cjs/pp-util.js +509 -762
- package/package.json +1 -1
package/dist/cjs/pp-util.js
CHANGED
|
@@ -1,102 +1,328 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var require$$0 = require('
|
|
4
|
-
var require$$1 = require('
|
|
3
|
+
var require$$0 = require('fs');
|
|
4
|
+
var require$$1$1 = require('crypto');
|
|
5
|
+
var require$$2$1 = require('basic-auth');
|
|
5
6
|
var require$$2 = require('abler-util');
|
|
6
7
|
var require$$3 = require('abler-db');
|
|
7
|
-
var require$$
|
|
8
|
-
var require$$
|
|
9
|
-
var require$$1$1 = require('path');
|
|
8
|
+
var require$$5 = require('abler-net');
|
|
9
|
+
var require$$1 = require('path');
|
|
10
10
|
var require$$1$2 = require('abler-messenger');
|
|
11
11
|
var require$$0$1 = require('node-cron');
|
|
12
12
|
|
|
13
13
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
14
|
|
|
15
15
|
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
|
|
16
|
-
var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
|
|
16
|
+
var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
|
|
17
|
+
var require$$2__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$2$1);
|
|
17
18
|
var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);
|
|
18
19
|
var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
|
|
19
|
-
var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4);
|
|
20
20
|
var require$$5__default = /*#__PURE__*/_interopDefaultLegacy(require$$5);
|
|
21
|
-
var require$$1__default
|
|
21
|
+
var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
|
|
22
22
|
var require$$1__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$1$2);
|
|
23
23
|
var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
|
|
24
24
|
|
|
25
|
-
const
|
|
26
|
-
const
|
|
25
|
+
const fs$1 = require$$0__default["default"];
|
|
26
|
+
const path = require$$1__default["default"];
|
|
27
27
|
const ppUtil$4 = require$$2__default["default"].ppUtil;
|
|
28
28
|
const {
|
|
29
29
|
dbUtil: dbUtil$1,
|
|
30
|
-
|
|
30
|
+
ppRedis,
|
|
31
|
+
kvStorage: kvStorage$1,
|
|
32
|
+
redisSimulator
|
|
33
|
+
} = require$$3__default["default"];
|
|
34
|
+
let conf$3, err$2;
|
|
35
|
+
// const dbCheck = require('../dbupdate/dd-version');
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* API服务启动时前置条件检查
|
|
39
|
+
* ok = await preconditions
|
|
40
|
+
* .setAppName(conf.thisApp)
|
|
41
|
+
* .addCheckPromise(preconditions.checkExEnvSetting())
|
|
42
|
+
* .addCheckPromise(preconditions.checkRedis())
|
|
43
|
+
* .addCheckPromise(checkDatabase())
|
|
44
|
+
* .addChecker(myChecker, args)
|
|
45
|
+
* .checkAll()
|
|
46
|
+
*/
|
|
47
|
+
class preconditions$2 {
|
|
48
|
+
static appName;
|
|
49
|
+
static checkFunctions = [];
|
|
50
|
+
static checkPromises = [];
|
|
51
|
+
static setAppName(aName) {
|
|
52
|
+
ppUtil$4.configNeeded();
|
|
53
|
+
conf$3 = ppUtil$4.appConfig;
|
|
54
|
+
err$2 = ppUtil$4.appErrCfg;
|
|
55
|
+
preconditions$2.appName = aName || conf$3.thisApp;
|
|
56
|
+
return preconditions$2;
|
|
57
|
+
}
|
|
58
|
+
static addCheckPromise(p) {
|
|
59
|
+
preconditions$2.checkPromises.push(p);
|
|
60
|
+
return preconditions$2;
|
|
61
|
+
}
|
|
62
|
+
static addChecker(checkFunc, args, blocked) {
|
|
63
|
+
preconditions$2.checkFunctions.push({
|
|
64
|
+
check: checkFunc,
|
|
65
|
+
args: args,
|
|
66
|
+
blocked: blocked
|
|
67
|
+
});
|
|
68
|
+
return preconditions$2;
|
|
69
|
+
}
|
|
70
|
+
static pushMessage(msg) {
|
|
71
|
+
if (msg) {
|
|
72
|
+
if (!preconditions$2.messages) {
|
|
73
|
+
preconditions$2.messages = [];
|
|
74
|
+
}
|
|
75
|
+
preconditions$2.messages.push(`${preconditions$2.messages.length + 1}. ${msg}`);
|
|
76
|
+
}
|
|
77
|
+
return msg;
|
|
78
|
+
}
|
|
79
|
+
static async checkAll() {
|
|
80
|
+
try {
|
|
81
|
+
// for (let i = 0; i < preconditions.checkFunctions.length; i++) {
|
|
82
|
+
// const f = preconditions.checkFunctions[i];
|
|
83
|
+
// // preconditions.addCheckPromise(f.check(f.args));
|
|
84
|
+
// preconditions.pushMessage(await f.check(f.args));
|
|
85
|
+
// }
|
|
86
|
+
while (preconditions$2.checkFunctions.length > 0) {
|
|
87
|
+
const f = preconditions$2.checkFunctions.shift();
|
|
88
|
+
if (preconditions$2.pushMessage(await f.check(f.args)) && f.blocked) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// for (let i = 0; i < preconditions.checkPromises.length; i++) {
|
|
94
|
+
// preconditions.pushMessage(await preconditions.checkPromises[i]);
|
|
95
|
+
// }
|
|
96
|
+
while (preconditions$2.checkPromises.length > 0) {
|
|
97
|
+
const p = preconditions$2.checkPromises.shift();
|
|
98
|
+
preconditions$2.pushMessage(await p);
|
|
99
|
+
}
|
|
100
|
+
} catch (e) {
|
|
101
|
+
preconditions$2.pushMessage(e.message);
|
|
102
|
+
}
|
|
103
|
+
let text = "";
|
|
104
|
+
if (preconditions$2.messages) {
|
|
105
|
+
text = `*** 由于以下原因,${preconditions$2.appName} 尚不能正常提供服务:\n\n` + preconditions$2.messages.join("\n\n") + "\n\n*** 请检查以上各项条件,修复后重新启动服务";
|
|
106
|
+
console.log("\n" + text);
|
|
107
|
+
// for (let i = 0; i < preconditions.messages.length; i++) {
|
|
108
|
+
// console.log(preconditions.messages[i]);
|
|
109
|
+
// }
|
|
110
|
+
}
|
|
111
|
+
if (!(await fs$1.async_exists("../log"))) {
|
|
112
|
+
await fs$1.async_mkdir("../log");
|
|
113
|
+
}
|
|
114
|
+
await fs$1.async_writeFile(`../log/preconditions`, text);
|
|
115
|
+
return !text;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 检查器
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 检查本机外部配置文件版本
|
|
122
|
+
*/
|
|
123
|
+
static async checkExEnvSetting(loadjs) {
|
|
124
|
+
return await checkExEnvSetting(loadjs);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* redis 可用性检查
|
|
129
|
+
*/
|
|
130
|
+
static async checkRedis() {
|
|
131
|
+
return await checkRedis();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 初始化数据库连接
|
|
136
|
+
*/
|
|
137
|
+
static async initDb() {
|
|
138
|
+
return await initDb();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 初始化键值对存储器
|
|
143
|
+
*/
|
|
144
|
+
static async initKvStorage(dbSql) {
|
|
145
|
+
return await initKvStorage(dbSql);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// /**
|
|
149
|
+
// * 数据库可用性及业务数据版本版本检查
|
|
150
|
+
// */
|
|
151
|
+
// static async checkDatabase() {
|
|
152
|
+
// return await checkDatabase();
|
|
153
|
+
// }
|
|
154
|
+
}
|
|
155
|
+
async function createEnvSettingFile(fileName, lastEnvSettingEx) {
|
|
156
|
+
try {
|
|
157
|
+
const cfgText = await ppUtil$4.doCreateEnvSettingFile(fileName, lastEnvSettingEx);
|
|
158
|
+
if (cfgText.indexOf(`cfgVersion: "${conf$3._envSetting.cfgVersion}"`) > 0) {
|
|
159
|
+
console.log(`\n*** 已創建新的本機環境配置文件\n${fileName}\n请檢查各項內容是否正确(此项更新服务可正常运行)\n\n`);
|
|
160
|
+
return "";
|
|
161
|
+
}
|
|
162
|
+
return `已創建新的本機環境配置文件\n${fileName}\n请檢查並正確設置各項內容,然後將配置版本號修改為${conf$3._envSettings.default.cfgVersion}`;
|
|
163
|
+
} catch (e) {
|
|
164
|
+
return `創建本機環境配置文件失敗\n《${fileName}》\n${err$2.ERROR(e).message}`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function checkExEnvSetting(loadjs) {
|
|
168
|
+
if (conf$3._envSetting.localSettingImported) return "";
|
|
169
|
+
try {
|
|
170
|
+
let fileName = conf$3.getEnvSettingFileName();
|
|
171
|
+
if (!fs$1.existsSync(fileName)) {
|
|
172
|
+
return await createEnvSettingFile(fileName);
|
|
173
|
+
}
|
|
174
|
+
let envSettingEx = loadjs(fileName);
|
|
175
|
+
if (envSettingEx.cfgVersion !== conf$3._envSettings.default.cfgVersion) {
|
|
176
|
+
if (envSettingEx.cfgVersion !== "0.0") {
|
|
177
|
+
let fp = path.parse(fileName);
|
|
178
|
+
let lastVerFileName = path.join(fp.dir, fp.name + envSettingEx.cfgVersion + fp.ext);
|
|
179
|
+
if (!fs$1.existsSync(lastVerFileName)) {
|
|
180
|
+
fs$1.renameSync(fileName, lastVerFileName);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
let msg = await createEnvSettingFile(fileName, envSettingEx);
|
|
184
|
+
if (msg) {
|
|
185
|
+
return msg;
|
|
186
|
+
}
|
|
187
|
+
delete require.cache[fileName];
|
|
188
|
+
}
|
|
189
|
+
ppUtil$4.importExEnvSetting(conf$3._envSetting, fileName, loadjs);
|
|
190
|
+
} catch (e) {
|
|
191
|
+
return `导入本机环境配置失败\n${e.stack}`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// async function checkDatabase() {
|
|
196
|
+
// return dbCheck.check().then(info => info.updateMessage);
|
|
197
|
+
// }
|
|
198
|
+
|
|
199
|
+
async function checkRedis() {
|
|
200
|
+
if (!conf$3.redis.enabled) return "";
|
|
201
|
+
const redis = ppRedis.newClient("kv");
|
|
202
|
+
// console.log(`checkRedis begin:`);
|
|
203
|
+
await ppUtil$4.wait(15 * 1000, param => {
|
|
204
|
+
if (redis.ready && redis.connected || redis.error) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
}).catch(e => {
|
|
208
|
+
redis.error = e;
|
|
209
|
+
});
|
|
210
|
+
if (redis.error) {
|
|
211
|
+
console.log(`未能成功連接 redis: ${redis.error},請檢查相關設置`);
|
|
212
|
+
return `未能成功連接 redis: ${redis.error},請檢查相關設置`;
|
|
213
|
+
}
|
|
214
|
+
// console.log(`checkRedis done:`);
|
|
215
|
+
// console.log(redis);
|
|
216
|
+
}
|
|
217
|
+
async function initDb() {
|
|
218
|
+
try {
|
|
219
|
+
dbUtil$1.config(conf$3, err$2);
|
|
220
|
+
} catch (e) {
|
|
221
|
+
if (e.reason === 'bad decrypt') {
|
|
222
|
+
e = new Error(`解密数据库密码(${conf$3.dbconn.dbpwd})失败`);
|
|
223
|
+
}
|
|
224
|
+
// if (e.reason === 'bad decrypt') {
|
|
225
|
+
// e = new Error(`解密Redis密码(${conf.redis.password})失败`);
|
|
226
|
+
// }
|
|
227
|
+
return `初始化数据库连接失败(${e.message})`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
async function initKvStorage(dbSql) {
|
|
231
|
+
try {
|
|
232
|
+
kvStorage$1.config(conf$3, err$2);
|
|
233
|
+
if (conf$3.redis.enabled) {
|
|
234
|
+
kvStorage$1.setRedis(ppRedis.newClient("kv"));
|
|
235
|
+
} else {
|
|
236
|
+
kvStorage$1.setRedis(new redisSimulator(dbSql));
|
|
237
|
+
}
|
|
238
|
+
} catch (e) {
|
|
239
|
+
// if (e.reason === 'bad decrypt') {
|
|
240
|
+
// e = new Error(`解密Redis密码(${conf.redis.password})失败`);
|
|
241
|
+
// }
|
|
242
|
+
return `初始化键值对存储器失败(${e.message})`;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
var ppPrecond = preconditions$2;
|
|
246
|
+
|
|
247
|
+
const fs = require$$0__default["default"];
|
|
248
|
+
const crypto = require$$1__default$1["default"];
|
|
249
|
+
const getBasicAuthorization = require$$2__default$1["default"];
|
|
250
|
+
const ppUtil$3 = require$$2__default["default"].ppUtil;
|
|
251
|
+
const {
|
|
252
|
+
dbUtil,
|
|
253
|
+
kvStorage
|
|
31
254
|
} = require$$3__default["default"];
|
|
32
255
|
const {
|
|
33
256
|
netUtil: netUtil$1
|
|
34
|
-
} = require$$
|
|
35
|
-
const
|
|
36
|
-
let conf$
|
|
257
|
+
} = require$$5__default["default"];
|
|
258
|
+
const preconditions$1 = ppPrecond;
|
|
259
|
+
let conf$2, appSetting, err$1, dbSql;
|
|
37
260
|
const pnToken = "access_token",
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
pnApiSecret = "apiSecret",
|
|
43
|
-
|
|
44
|
-
const MD5 = ppUtil$
|
|
45
|
-
|
|
46
|
-
|
|
261
|
+
hnToken = pnToken,
|
|
262
|
+
pnApiKey = "apiKey",
|
|
263
|
+
hnApiKey = pnApiKey.toLowerCase(),
|
|
264
|
+
// 我们接收到的 headers 中的字段名总是全小写的
|
|
265
|
+
pnApiSecret = "apiSecret",
|
|
266
|
+
hnApiSecret = pnApiSecret.toLowerCase();
|
|
267
|
+
const MD5 = ppUtil$3.MD5,
|
|
268
|
+
moveProperty = ppUtil$3.moveProperty;
|
|
47
269
|
class apiUtil$2 {
|
|
48
|
-
static debugFlag = ppUtil$
|
|
49
|
-
|
|
50
|
-
static testFlag = ppUtil$4.newGuid();
|
|
270
|
+
static debugFlag = ppUtil$3.newGuid(); //应用必须设置,否则谁也不知道是啥
|
|
271
|
+
static testFlag = ppUtil$3.newGuid();
|
|
51
272
|
static envId_dev = "?";
|
|
52
273
|
static _validateBasicAuth = function (userName, password) {
|
|
53
274
|
throw {
|
|
54
275
|
status: 500,
|
|
55
276
|
message: 'no basic auth validator'
|
|
56
277
|
};
|
|
57
|
-
};
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// static apiCallRecSaver;
|
|
58
281
|
|
|
59
282
|
static config(appConfig, appErrCfg, appDbSql) {
|
|
60
|
-
conf$
|
|
61
|
-
appSetting
|
|
62
|
-
err$
|
|
283
|
+
conf$2 = appConfig;
|
|
284
|
+
appSetting = conf$2?.appSetting;
|
|
285
|
+
err$1 = appErrCfg;
|
|
63
286
|
dbSql = appDbSql;
|
|
64
|
-
ppUtil$
|
|
65
|
-
kvStorage
|
|
66
|
-
apiUtil$2.debugFlag = appSetting
|
|
67
|
-
apiUtil$2.testFlag = appSetting
|
|
68
|
-
|
|
287
|
+
ppUtil$3.config(appConfig, appErrCfg);
|
|
288
|
+
kvStorage.config(appConfig, appErrCfg);
|
|
289
|
+
apiUtil$2.debugFlag = appSetting?.debugFlag || apiUtil$2.debugFlag;
|
|
290
|
+
apiUtil$2.testFlag = appSetting?.testFlag || apiUtil$2.testFlag;
|
|
291
|
+
// apiUtil.apiCallRecSaver = apiCallRecSaver;
|
|
292
|
+
preconditions$1.setAppName();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
//#region ===== 需要应用系统重写的方法
|
|
69
296
|
|
|
70
297
|
/**
|
|
71
298
|
* 根据机构标识获取机构的 ApiSecret
|
|
72
299
|
* @param companyId
|
|
73
300
|
* @returns {*}
|
|
74
301
|
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
302
|
static _getApiSecret(companyId) {
|
|
78
|
-
return ppUtil$
|
|
303
|
+
return ppUtil$3.newGuid();
|
|
79
304
|
}
|
|
305
|
+
|
|
80
306
|
/**
|
|
81
307
|
* 保存 API 调用记录,应用系统必须重写此方法
|
|
82
308
|
* @param rec
|
|
83
309
|
* @param responseData
|
|
84
310
|
* @returns {Promise<unknown>}
|
|
85
311
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
88
312
|
static async _saveApiCallRec(rec, responseData) {
|
|
89
313
|
return false;
|
|
90
314
|
}
|
|
315
|
+
|
|
91
316
|
/**
|
|
92
317
|
* 检查API调用签名是否已经完成了验证
|
|
93
318
|
* @param req
|
|
94
319
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
320
|
static signatureVerified(req) {
|
|
98
321
|
return req?.signatureVerified;
|
|
99
|
-
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
//#endregion
|
|
325
|
+
|
|
100
326
|
//#region ===== API服务相关工具
|
|
101
327
|
|
|
102
328
|
/**
|
|
@@ -104,16 +330,12 @@ class apiUtil$2 {
|
|
|
104
330
|
* @param req
|
|
105
331
|
* @returns {*}
|
|
106
332
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
333
|
static extractParams(req) {
|
|
110
334
|
if (!req._requestParams) {
|
|
111
335
|
if (req.method === "POST" || req.method === "PUT") {
|
|
112
336
|
let contentType = req.headers["content-type"] || "application/json";
|
|
113
|
-
|
|
114
337
|
if (contentType.startsWith("multipart/form-data")) {
|
|
115
338
|
req._requestParams = new Object();
|
|
116
|
-
|
|
117
339
|
for (let k in req.body) {
|
|
118
340
|
req._requestParams[k] = req.body[k];
|
|
119
341
|
}
|
|
@@ -123,14 +345,11 @@ class apiUtil$2 {
|
|
|
123
345
|
} else {
|
|
124
346
|
req._requestParams = req.query;
|
|
125
347
|
}
|
|
126
|
-
|
|
127
348
|
if (req.headers["content-type"] !== "application/json") {
|
|
128
349
|
const obj = req._requestParams;
|
|
129
|
-
|
|
130
350
|
for (let key in obj) {
|
|
131
351
|
if (!obj.hasOwnProperty(key)) continue;
|
|
132
352
|
let value = obj[key];
|
|
133
|
-
|
|
134
353
|
if (typeof value === "string" && value.length > 0) {
|
|
135
354
|
if (value[0] === "{" || value[0] === "[") {
|
|
136
355
|
try {
|
|
@@ -138,31 +357,24 @@ class apiUtil$2 {
|
|
|
138
357
|
continue;
|
|
139
358
|
} catch (e) {}
|
|
140
359
|
}
|
|
141
|
-
|
|
142
360
|
let x = JSON.hbDateConv(key, value);
|
|
143
|
-
|
|
144
361
|
if (x !== value) {
|
|
145
362
|
obj[key] = x;
|
|
146
363
|
}
|
|
147
364
|
}
|
|
148
365
|
}
|
|
149
366
|
}
|
|
150
|
-
|
|
151
367
|
if (req.params) {
|
|
152
368
|
req._requestParams = Object.assign(req.params, req._requestParams);
|
|
153
369
|
}
|
|
154
|
-
|
|
155
370
|
apiUtil$2.setParamsFunctions(req._requestParams);
|
|
156
371
|
}
|
|
157
|
-
|
|
158
372
|
return req._requestParams;
|
|
159
373
|
}
|
|
160
|
-
|
|
161
374
|
static extractTokenData(req) {
|
|
162
375
|
if (req.tokenData) {
|
|
163
376
|
return req.tokenData;
|
|
164
377
|
}
|
|
165
|
-
|
|
166
378
|
let params = apiUtil$2.extractParams(req);
|
|
167
379
|
let tokenData = {
|
|
168
380
|
apiKey: req.headers[hnApiKey] || params[pnApiKey],
|
|
@@ -171,38 +383,34 @@ class apiUtil$2 {
|
|
|
171
383
|
};
|
|
172
384
|
return tokenData;
|
|
173
385
|
}
|
|
386
|
+
|
|
174
387
|
/**
|
|
175
388
|
* 为从传入请求中解出的参数对象设置一些函数属性,包括 asNumber, asBool
|
|
176
389
|
* @param params
|
|
177
390
|
*/
|
|
178
|
-
|
|
179
|
-
|
|
180
391
|
static setParamsFunctions(params) {
|
|
181
|
-
ppUtil$
|
|
392
|
+
ppUtil$3.defUnenumProp(params, "asNumber", function (name, minValue, maxValue, defaultValue) {
|
|
182
393
|
// if (!this.hasOwnProperty(name)) // {} 定义的对象没有 hasOwnProperty 函数
|
|
183
394
|
if (this[name] === undefined) return defaultValue;
|
|
184
395
|
let result = +this[name];
|
|
185
|
-
|
|
186
396
|
if (typeof result !== "number" || result < minValue || result > maxValue) {
|
|
187
|
-
throw [err$
|
|
397
|
+
throw [err$1.INVALID_PARAM, `参数 ${name} 必须是 ${minValue} ~ ${maxValue} 之间的数字`];
|
|
188
398
|
}
|
|
189
|
-
|
|
190
399
|
return result;
|
|
191
400
|
});
|
|
192
|
-
ppUtil$
|
|
401
|
+
ppUtil$3.defUnenumProp(params, "asBool", function (name, defaultValue) {
|
|
193
402
|
if (this[name] === undefined) return defaultValue;
|
|
194
403
|
let result = JSON.parse(this[name]);
|
|
195
404
|
return !!result;
|
|
196
405
|
});
|
|
197
406
|
}
|
|
407
|
+
|
|
198
408
|
/**
|
|
199
409
|
* 将返回结果转向到指定地址或者通过response发送返回结果
|
|
200
410
|
* @param res
|
|
201
411
|
* @param redirectUrl
|
|
202
412
|
* @param data
|
|
203
413
|
*/
|
|
204
|
-
|
|
205
|
-
|
|
206
414
|
static sendOrRedirect(res, redirectUrl, data) {
|
|
207
415
|
if (redirectUrl) {
|
|
208
416
|
redirectUrl = netUtil$1.urlAppendParams(redirectUrl, data, true);
|
|
@@ -211,14 +419,13 @@ class apiUtil$2 {
|
|
|
211
419
|
res.send(data);
|
|
212
420
|
}
|
|
213
421
|
}
|
|
422
|
+
|
|
214
423
|
/**
|
|
215
424
|
* 生成 API 成功返回结果
|
|
216
425
|
* @param data
|
|
217
426
|
* @param req
|
|
218
427
|
* @returns {{datetime: Date, success: boolean, stateCode: number, message: string}}
|
|
219
428
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
429
|
static apiSuccess(data, req, spOrderNum) {
|
|
223
430
|
let response = {
|
|
224
431
|
success: true,
|
|
@@ -226,86 +433,73 @@ class apiUtil$2 {
|
|
|
226
433
|
message: '',
|
|
227
434
|
datetime: new Date()
|
|
228
435
|
};
|
|
229
|
-
|
|
230
436
|
if (spOrderNum) {
|
|
231
437
|
response.spOrderNum = spOrderNum;
|
|
232
438
|
}
|
|
233
|
-
|
|
234
439
|
if (req && req.headers) {
|
|
235
440
|
let userAgent = req.headers["user-agent"];
|
|
236
|
-
|
|
237
441
|
if (userAgent && userAgent.startsWith("Postman")) {
|
|
238
442
|
response._elapse = (new Date().valueOf() - req.headers.timestamp) / 1000;
|
|
239
443
|
}
|
|
240
444
|
}
|
|
241
|
-
|
|
242
445
|
if (data && data._message_) {
|
|
243
446
|
response.message = data._message_;
|
|
244
447
|
delete data._message_;
|
|
245
448
|
}
|
|
246
|
-
|
|
247
449
|
response.data = data;
|
|
248
450
|
if (Array.isArray(data) && typeof data.recordCount != 'undefined') response.recordCount = data.recordCount;
|
|
249
451
|
return response;
|
|
250
452
|
}
|
|
453
|
+
|
|
251
454
|
/**
|
|
252
455
|
* 生成 API 失败返回结果
|
|
253
456
|
* @param error
|
|
254
457
|
* @param req
|
|
255
458
|
* @returns {*}
|
|
256
459
|
*/
|
|
257
|
-
|
|
258
|
-
|
|
259
460
|
static apiFail(error, req, spOrderNum) {
|
|
260
461
|
configNeeded();
|
|
261
|
-
let response = err$
|
|
462
|
+
let response = err$1.ERROR(error, err$1.errorLangParamFlag + ppUtil$3.getMsgLang(req));
|
|
262
463
|
response.datetime = new Date();
|
|
263
|
-
|
|
264
464
|
if (spOrderNum) {
|
|
265
465
|
response.spOrderNum = spOrderNum;
|
|
266
466
|
}
|
|
267
|
-
|
|
268
467
|
if (req && req.headers) {
|
|
269
468
|
let userAgent = req.headers["user-agent"];
|
|
270
|
-
|
|
271
469
|
if (userAgent && userAgent.startsWith("Postman")) {
|
|
272
470
|
response._elapse = (new Date().valueOf() - req.headers.timestamp) / 1000;
|
|
273
471
|
}
|
|
274
472
|
}
|
|
275
|
-
|
|
276
473
|
return response;
|
|
277
474
|
}
|
|
475
|
+
|
|
278
476
|
/**
|
|
279
477
|
* 生成面向服务商的API成功返回结果
|
|
280
478
|
* @param data
|
|
281
479
|
* @param req
|
|
282
480
|
* @returns {*}
|
|
283
481
|
*/
|
|
284
|
-
|
|
285
|
-
|
|
286
482
|
static spoApiSucc(data, req) {
|
|
287
483
|
let params = apiUtil$2.extractParams(req);
|
|
288
484
|
return apiUtil$2.apiSuccess(data, req, params.spOrderNum);
|
|
289
485
|
}
|
|
486
|
+
|
|
290
487
|
/**
|
|
291
488
|
* 生成面向服务商的API失败返回结果
|
|
292
489
|
* @param error
|
|
293
490
|
* @param req
|
|
294
491
|
* @returns {*}
|
|
295
492
|
*/
|
|
296
|
-
|
|
297
|
-
|
|
298
493
|
static spoApiFail(error, req) {
|
|
299
494
|
let params = apiUtil$2.extractParams(req);
|
|
300
495
|
return apiUtil$2.apiFail(error, req, params.spOrderNum);
|
|
301
496
|
}
|
|
497
|
+
|
|
302
498
|
/**
|
|
303
499
|
* API 服务结束,发送响应
|
|
304
500
|
* @param response
|
|
305
501
|
* @param promise
|
|
306
502
|
*/
|
|
307
|
-
|
|
308
|
-
|
|
309
503
|
static sendResponse(response, promise) {
|
|
310
504
|
promise.then(function (data) {
|
|
311
505
|
if (!response.finished) {
|
|
@@ -323,13 +517,12 @@ class apiUtil$2 {
|
|
|
323
517
|
}
|
|
324
518
|
});
|
|
325
519
|
}
|
|
520
|
+
|
|
326
521
|
/**
|
|
327
522
|
* API 服务结束,包装数据并发送响应
|
|
328
523
|
* @param response
|
|
329
524
|
* @param promise
|
|
330
525
|
*/
|
|
331
|
-
|
|
332
|
-
|
|
333
526
|
static async responseOf(response, promise) {
|
|
334
527
|
promise.then(function (data) {
|
|
335
528
|
// console.log('RES:', apiSuccess(data));
|
|
@@ -339,64 +532,58 @@ class apiUtil$2 {
|
|
|
339
532
|
if (!response.finished) response.send(apiUtil$2.apiFail(error, response.req));
|
|
340
533
|
});
|
|
341
534
|
}
|
|
535
|
+
|
|
342
536
|
/**
|
|
343
537
|
* 面向服务商的API结束,发送响应
|
|
344
538
|
* @param response
|
|
345
539
|
* @param promise
|
|
346
540
|
*/
|
|
347
|
-
|
|
348
|
-
|
|
349
541
|
static async spoApiResponse(response, promise) {
|
|
350
542
|
promise.then(function (result) {
|
|
351
543
|
let responseData = apiUtil$2.spoApiSucc(result, response.req);
|
|
352
|
-
|
|
353
544
|
apiUtil$2._saveApiCallRec(response.req.apiCallRec, responseData);
|
|
354
|
-
|
|
355
545
|
if (!response.finished) response.send(responseData);
|
|
356
546
|
}, function (error) {
|
|
357
547
|
// console.log('ERROR:', error);
|
|
358
548
|
let responseData = apiUtil$2.spoApiFail(error, response.req);
|
|
359
|
-
|
|
360
549
|
apiUtil$2._saveApiCallRec(response.req.apiCallRec, responseData);
|
|
361
|
-
|
|
362
550
|
if (!response.finished) response.send(responseData);
|
|
363
551
|
});
|
|
364
552
|
}
|
|
553
|
+
|
|
365
554
|
/**
|
|
366
555
|
* 从请求参数中获取查询参数
|
|
367
556
|
* @param req
|
|
368
557
|
* @param res
|
|
369
558
|
* @returns {*}
|
|
370
559
|
*/
|
|
371
|
-
|
|
372
|
-
|
|
373
560
|
static getQueryOptions(req, res) {
|
|
374
|
-
req.headers.timestamp = new Date().valueOf();
|
|
375
|
-
|
|
561
|
+
req.headers.timestamp = new Date().valueOf();
|
|
562
|
+
// let options = {replacements: {}};
|
|
376
563
|
let options = {};
|
|
377
564
|
let parameters = apiUtil$2.extractParams(req);
|
|
378
|
-
|
|
379
565
|
for (let qryParam in parameters) {
|
|
380
566
|
if (qryParam !== 'token') {
|
|
381
567
|
if (['start', 'limit', 'orderby', 'orderBy'].indexOf(qryParam) >= 0) {
|
|
382
568
|
options[qryParam] = parameters[qryParam];
|
|
383
569
|
delete parameters[qryParam];
|
|
384
|
-
}
|
|
570
|
+
}
|
|
571
|
+
// else
|
|
385
572
|
// options.replacements[qryParam] = parameters[qryParam];
|
|
386
|
-
|
|
387
573
|
}
|
|
388
574
|
}
|
|
389
|
-
|
|
390
575
|
if (options.limit && !options.start) {
|
|
391
576
|
options.start = 0;
|
|
392
577
|
}
|
|
393
|
-
|
|
394
578
|
if (options.orderby) {
|
|
395
579
|
options.orderBy = options.orderby;
|
|
396
|
-
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// options.__debug__ = req.headers['__debug__'] && req.headers['__debug__'] == "true";
|
|
397
583
|
|
|
584
|
+
options.replacements = parameters;
|
|
398
585
|
|
|
399
|
-
|
|
586
|
+
// if (arguments.length > 1) //其后的每个参数是要求必须存在的参数名称
|
|
400
587
|
// {
|
|
401
588
|
// for(i=1; i<arguments.length; i++){
|
|
402
589
|
// var paramName = arguments[i];
|
|
@@ -408,14 +595,13 @@ class apiUtil$2 {
|
|
|
408
595
|
options.userInfo = req.userInfo;
|
|
409
596
|
return apiUtil$2.setOptionsPropFuncions(options, res);
|
|
410
597
|
}
|
|
598
|
+
|
|
411
599
|
/**
|
|
412
600
|
* 为API请求 options 设置属性
|
|
413
601
|
* @param options
|
|
414
602
|
* @param res
|
|
415
603
|
* @returns {{identifyLimit}|*}
|
|
416
604
|
*/
|
|
417
|
-
|
|
418
|
-
|
|
419
605
|
static setOptionsPropFuncions(options, res) {
|
|
420
606
|
// if (!options.identifyLimit) {
|
|
421
607
|
// // 根据企业标识获取身份认证限制相关设置,如果没有传递企业标识,
|
|
@@ -451,9 +637,9 @@ class apiUtil$2 {
|
|
|
451
637
|
enumerable: false
|
|
452
638
|
});
|
|
453
639
|
}
|
|
454
|
-
|
|
455
640
|
return options;
|
|
456
641
|
}
|
|
642
|
+
|
|
457
643
|
/**
|
|
458
644
|
* 从请求头获取token
|
|
459
645
|
* @param req
|
|
@@ -461,64 +647,53 @@ class apiUtil$2 {
|
|
|
461
647
|
* @param noErr
|
|
462
648
|
* @returns {Promise<*>}
|
|
463
649
|
*/
|
|
464
|
-
|
|
465
|
-
|
|
466
650
|
static extractToken(req, res, noErr) {
|
|
467
651
|
configNeeded();
|
|
468
|
-
|
|
469
652
|
if (!req.accessToken) {
|
|
470
653
|
let token = req.header('Authorization');
|
|
471
|
-
|
|
472
654
|
if (token && token.startsWith('Bearer ')) {
|
|
473
655
|
token = token.substring(7);
|
|
474
656
|
} else {
|
|
475
657
|
//检查post的信息或者url查询参数或者头信息
|
|
476
658
|
token = req.headers[hnToken] || req.headers['x-access-token']; //向后兼容
|
|
477
659
|
}
|
|
478
|
-
|
|
479
660
|
if (!token) {
|
|
480
661
|
let params = apiUtil$2.extractParams(req);
|
|
481
662
|
token = params[pnToken];
|
|
482
|
-
|
|
483
663
|
if (token) {
|
|
484
664
|
delete params[pnToken];
|
|
485
665
|
} else if (params.token) {
|
|
486
666
|
token = params.token; //向后兼容
|
|
487
|
-
|
|
488
667
|
delete params.token;
|
|
489
668
|
} else {
|
|
490
669
|
// 如果没有token,则返回错误
|
|
491
|
-
console.log(err$
|
|
492
|
-
|
|
670
|
+
console.log(err$1.TOKEN_NEEDED);
|
|
493
671
|
if (res) {
|
|
494
|
-
res.send(err$
|
|
672
|
+
res.send(err$1.ERROR(err$1.TOKEN_NEEDED));
|
|
495
673
|
} else if (!noErr) {
|
|
496
|
-
throw err$
|
|
674
|
+
throw err$1.TOKEN_NEEDED;
|
|
497
675
|
}
|
|
498
676
|
}
|
|
499
677
|
}
|
|
500
|
-
|
|
501
678
|
req.accessToken = token;
|
|
502
679
|
}
|
|
503
|
-
|
|
504
680
|
return req.accessToken;
|
|
505
681
|
}
|
|
682
|
+
|
|
506
683
|
/**
|
|
507
684
|
* 检查是不是内部调用,应用系统可替换此函数实施更隐秘的检查
|
|
508
685
|
* @param req
|
|
509
686
|
* @returns {Promise<boolean|undefined>}
|
|
510
687
|
*/
|
|
511
|
-
|
|
512
|
-
|
|
513
688
|
static async checkInternalToken(req) {
|
|
514
689
|
// return await checkInternalToken(req);
|
|
515
690
|
const params = apiUtil$2.extractParams(req);
|
|
516
691
|
req.accessToken = req.accessToken || apiUtil$2.extractToken(req);
|
|
517
|
-
|
|
518
|
-
if (req.accessToken === MD5(ppUtil$4.commonHashDisturbing)) {
|
|
692
|
+
if (req.accessToken === MD5(ppUtil$3.commonHashDisturbing)) {
|
|
519
693
|
//todo: 检查IP
|
|
520
694
|
params.__internal__ = true;
|
|
521
|
-
req.ignoreToken = true;
|
|
695
|
+
req.ignoreToken = true;
|
|
696
|
+
// if (params.idNum || params.personId) {
|
|
522
697
|
// return queryPersonUser(params.idNum, params.personId)
|
|
523
698
|
// .then(async userInfo => {
|
|
524
699
|
// if (!userInfo) {
|
|
@@ -532,20 +707,18 @@ class apiUtil$2 {
|
|
|
532
707
|
// } else {
|
|
533
708
|
// return true
|
|
534
709
|
// }
|
|
535
|
-
|
|
536
710
|
return true;
|
|
537
711
|
} else {
|
|
538
712
|
// console.log('token error.', req.accessToken);
|
|
539
|
-
throw err$
|
|
713
|
+
throw err$1.TOKEN_INVALID;
|
|
540
714
|
}
|
|
541
715
|
}
|
|
716
|
+
|
|
542
717
|
/**
|
|
543
718
|
* 检查请求是否存在合法的token,若不存在则抛出异常
|
|
544
719
|
* @param req
|
|
545
720
|
* @returns {Promise<void>}
|
|
546
721
|
*/
|
|
547
|
-
|
|
548
|
-
|
|
549
722
|
static async checkRequestToken(req) {
|
|
550
723
|
req.accessToken = req.accessToken || apiUtil$2.extractToken(req);
|
|
551
724
|
const tokenKey = apiUtil$2.userTokenStoreKey(req.accessToken);
|
|
@@ -559,39 +732,35 @@ class apiUtil$2 {
|
|
|
559
732
|
return await apiUtil$2.checkInternalToken(req);
|
|
560
733
|
});
|
|
561
734
|
}
|
|
735
|
+
|
|
562
736
|
/**
|
|
563
737
|
* 检查是不是调试模式
|
|
564
738
|
* @param req
|
|
565
739
|
* @returns {*|boolean|boolean}
|
|
566
740
|
*/
|
|
567
|
-
|
|
568
|
-
|
|
569
741
|
static isDebugMode(req) {
|
|
570
742
|
if (req.__debug__ === undefined) {
|
|
571
743
|
let dbgToken = req.headers['__debug__'] || req.headers[apiUtil$2.debugFlag];
|
|
572
|
-
|
|
573
744
|
if (dbgToken) {
|
|
574
745
|
let envId = process.env.ECS_DEPLOY_ID;
|
|
575
|
-
req.__debug__ = dbgToken && dbgToken === MD5(req.headers.timestamp, ppUtil$
|
|
746
|
+
req.__debug__ = dbgToken && dbgToken === MD5(req.headers.timestamp, ppUtil$3.commonHashDisturbing) && (envId === "florist_longdan" || envId === "shuzi");
|
|
576
747
|
} else {
|
|
577
748
|
req.__debug__ = false;
|
|
578
|
-
}
|
|
579
|
-
|
|
749
|
+
}
|
|
750
|
+
// console.log("__debug__:", req.__debug__, "dbgToken:", dbgToken);
|
|
580
751
|
}
|
|
581
|
-
|
|
582
|
-
|
|
752
|
+
return req.__debug__;
|
|
753
|
+
// return req.headers["postman-token"] || req.headers['__debug__'] && req.headers['__debug__'] == "true";
|
|
583
754
|
}
|
|
755
|
+
|
|
584
756
|
/**
|
|
585
757
|
* 检查是不是测试模式
|
|
586
758
|
* @param req
|
|
587
759
|
* @returns {*|boolean}
|
|
588
760
|
*/
|
|
589
|
-
|
|
590
|
-
|
|
591
761
|
static isTestMode(req) {
|
|
592
762
|
if (req.__postman__ === undefined) {
|
|
593
763
|
let dbgToken = req.headers["__postman__"] || req.headers[apiUtil$2.testFlag];
|
|
594
|
-
|
|
595
764
|
if (dbgToken) {
|
|
596
765
|
let envId = process.env.ECS_DEPLOY_ID;
|
|
597
766
|
let testToken = MD5(req.headers.timestamp, apiUtil$2.extractToken(req, null, true) || req.headers.apikey);
|
|
@@ -600,65 +769,59 @@ class apiUtil$2 {
|
|
|
600
769
|
req.__postman__ = false;
|
|
601
770
|
}
|
|
602
771
|
}
|
|
603
|
-
|
|
604
772
|
return req.__postman__;
|
|
605
773
|
}
|
|
774
|
+
|
|
606
775
|
/**
|
|
607
776
|
* 获取令牌过期时长
|
|
608
777
|
* @param req
|
|
609
778
|
* @returns {any}
|
|
610
779
|
*/
|
|
611
|
-
|
|
612
|
-
|
|
613
780
|
static tokenExpireTime(req) {
|
|
614
|
-
return apiUtil$2.isDebugMode(req) ? 30 * 24 * 60 * 60 : apiUtil$2.isTestMode(req) ? 4 * 60 * 60 : appSetting
|
|
781
|
+
return apiUtil$2.isDebugMode(req) ? 30 * 24 * 60 * 60 : apiUtil$2.isTestMode(req) ? 4 * 60 * 60 : appSetting.tokenExpireTime;
|
|
615
782
|
}
|
|
783
|
+
|
|
616
784
|
/**
|
|
617
785
|
* 获取用户令牌保存键
|
|
618
786
|
* @param token
|
|
619
787
|
* @returns {string}
|
|
620
788
|
*/
|
|
621
|
-
|
|
622
|
-
|
|
623
789
|
static userTokenStoreKey(token) {
|
|
624
790
|
return "ut_" + token;
|
|
625
791
|
}
|
|
792
|
+
|
|
626
793
|
/**
|
|
627
794
|
* 获取机构令牌保存键
|
|
628
795
|
* @param token
|
|
629
796
|
* @returns {string}
|
|
630
797
|
*/
|
|
631
|
-
|
|
632
|
-
|
|
633
798
|
static apiTokenStoreKey(token) {
|
|
634
799
|
return "api_" + token;
|
|
635
800
|
}
|
|
801
|
+
|
|
636
802
|
/**
|
|
637
803
|
* 判断是不是香港身份证
|
|
638
804
|
* @param idNum
|
|
639
805
|
* @returns {boolean}
|
|
640
806
|
*/
|
|
641
|
-
|
|
642
|
-
|
|
643
807
|
static checkIsHKIC(idNum) {
|
|
644
808
|
return idNum.length === 8;
|
|
645
809
|
}
|
|
810
|
+
|
|
646
811
|
/**
|
|
647
812
|
* 将身份证号码暂存到用户信息中
|
|
648
813
|
* @param userInfo
|
|
649
814
|
* @param idNum
|
|
650
815
|
* @returns {*}
|
|
651
816
|
*/
|
|
652
|
-
|
|
653
|
-
|
|
654
817
|
static setUserIdNo(userInfo, idNum) {
|
|
655
818
|
if (userInfo && idNum) {
|
|
656
819
|
userInfo._idNo = idNum;
|
|
657
820
|
userInfo.isHKIC = apiUtil$2.checkIsHKIC(idNum);
|
|
658
821
|
}
|
|
659
|
-
|
|
660
822
|
return userInfo;
|
|
661
823
|
}
|
|
824
|
+
|
|
662
825
|
/**
|
|
663
826
|
* 暂存令牌
|
|
664
827
|
* @param token
|
|
@@ -667,53 +830,46 @@ class apiUtil$2 {
|
|
|
667
830
|
* @param req
|
|
668
831
|
* @returns {Promise<void>}
|
|
669
832
|
*/
|
|
670
|
-
|
|
671
|
-
|
|
672
833
|
static async storeToken(token, tokenData, dataId, req) {
|
|
673
834
|
// let timeout = tokenData.clientIp.substring(0, 8) == "192.168." ? 90 * 24 : 1;
|
|
674
835
|
let timeout = apiUtil$2.tokenExpireTime(req);
|
|
675
|
-
|
|
676
836
|
if (req.certPublicKey) {
|
|
677
837
|
tokenData.certPublicKey = req.certPublicKey;
|
|
678
838
|
}
|
|
679
|
-
|
|
680
|
-
await kvStorage$1.storeObj(token, tokenData, timeout);
|
|
681
|
-
|
|
839
|
+
await kvStorage.storeObj(token, tokenData, timeout);
|
|
682
840
|
if (dataId) {
|
|
683
|
-
await kvStorage
|
|
841
|
+
await kvStorage.restoreValue("token_" + dataId).then(async oldToken => {
|
|
684
842
|
if (oldToken !== token) {
|
|
685
|
-
await kvStorage
|
|
843
|
+
await kvStorage.unstoreValue(oldToken);
|
|
686
844
|
} else {
|
|
687
845
|
dataId = "";
|
|
688
846
|
}
|
|
689
847
|
}, function (e) {}).then(async () => {
|
|
690
|
-
if (dataId !== "") await kvStorage
|
|
848
|
+
if (dataId !== "") await kvStorage.storeValue("token_" + dataId, token, timeout);
|
|
691
849
|
});
|
|
692
850
|
}
|
|
693
851
|
}
|
|
852
|
+
|
|
694
853
|
/**
|
|
695
854
|
* 恢复令牌数据
|
|
696
855
|
* @param accessToken
|
|
697
856
|
* @param expireTime
|
|
698
857
|
* @returns {Promise<any>}
|
|
699
858
|
*/
|
|
700
|
-
|
|
701
|
-
|
|
702
859
|
static async restoreTokenData(accessToken, expireTime) {
|
|
703
|
-
return await kvStorage
|
|
860
|
+
return await kvStorage.restoreObj(accessToken, expireTime);
|
|
704
861
|
}
|
|
862
|
+
|
|
705
863
|
/**
|
|
706
864
|
* 创建 API 调用记录
|
|
707
865
|
* @param tokenData
|
|
708
866
|
* @param req
|
|
709
867
|
* @returns {any}
|
|
710
868
|
*/
|
|
711
|
-
|
|
712
|
-
|
|
713
869
|
static createApiCallRec(tokenData, req) {
|
|
714
870
|
if (!req.apiCallRec) {
|
|
715
871
|
if (req.apiCallRecId) {
|
|
716
|
-
return dbUtil
|
|
872
|
+
return dbUtil.dbQueryOne(dbSql.loadApiUsage, {
|
|
717
873
|
replacements: {
|
|
718
874
|
id: req.apiCallRecId
|
|
719
875
|
}
|
|
@@ -722,10 +878,10 @@ class apiUtil$2 {
|
|
|
722
878
|
return req.apiCallRec;
|
|
723
879
|
});
|
|
724
880
|
} else {
|
|
725
|
-
let params = apiUtil$2.extractParams(req);
|
|
726
|
-
|
|
881
|
+
let params = apiUtil$2.extractParams(req);
|
|
882
|
+
// let contentLength = parseInt(req.headers["content-length"]) || 0;
|
|
727
883
|
let rec = {
|
|
728
|
-
id: ppUtil$
|
|
884
|
+
id: ppUtil$3.newGuid(),
|
|
729
885
|
companyId: tokenData.apiKey || '',
|
|
730
886
|
orderId: params.orderId || '',
|
|
731
887
|
signerId: params.signerId || '',
|
|
@@ -750,54 +906,44 @@ class apiUtil$2 {
|
|
|
750
906
|
resultInfo: params.resultInfo || '',
|
|
751
907
|
resultData: params.resultData || ''
|
|
752
908
|
};
|
|
753
|
-
|
|
754
909
|
if (rec.secret !== "") {
|
|
755
|
-
rec.secret = ppUtil$
|
|
910
|
+
rec.secret = ppUtil$3.getEncAse192(rec.secret);
|
|
756
911
|
}
|
|
757
|
-
|
|
758
912
|
req.apiCallRec = rec;
|
|
759
913
|
}
|
|
760
914
|
}
|
|
761
|
-
|
|
762
915
|
return req.apiCallRec;
|
|
763
|
-
|
|
764
916
|
function _getBodyLogStr(req) {
|
|
765
917
|
let contentLength = parseInt(req.headers["content-length"]) || 0;
|
|
766
918
|
if (contentLength < 500) return req.rawBody || '';
|
|
767
919
|
let tempBody = {};
|
|
768
|
-
|
|
769
920
|
for (let key in req.body) {
|
|
770
921
|
let value = req.body[key];
|
|
771
|
-
|
|
772
922
|
if (typeof value == 'string' && value.length > 500) {
|
|
773
923
|
value = value.substring(0, 31) + '...(' + value.length + ')';
|
|
774
924
|
}
|
|
775
|
-
|
|
776
925
|
tempBody[key] = value;
|
|
777
926
|
}
|
|
778
|
-
|
|
779
927
|
return JSON.stringify(tempBody);
|
|
780
928
|
}
|
|
781
929
|
}
|
|
930
|
+
|
|
782
931
|
/**
|
|
783
932
|
* 查询机构信息
|
|
784
933
|
* @param companyId
|
|
785
934
|
* @param nullable
|
|
786
935
|
* @returns {Promise<null|*>}
|
|
787
936
|
*/
|
|
788
|
-
|
|
789
|
-
|
|
790
937
|
static async queryCompanyInfo(companyId, nullable) {
|
|
791
|
-
return await dbUtil
|
|
938
|
+
return await dbUtil.dbQueryOne(dbSql.queryCompanyInfo, {
|
|
792
939
|
companyId
|
|
793
940
|
}, nullable);
|
|
794
941
|
}
|
|
942
|
+
|
|
795
943
|
/**
|
|
796
944
|
* 获取企业有效证书
|
|
797
945
|
* @param companyId: 企业标识
|
|
798
946
|
*/
|
|
799
|
-
|
|
800
|
-
|
|
801
947
|
static async getCompanyCertificate(companyId) {
|
|
802
948
|
let certInfo = {
|
|
803
949
|
// 正式启用的证书
|
|
@@ -807,26 +953,26 @@ class apiUtil$2 {
|
|
|
807
953
|
certSpare: null,
|
|
808
954
|
certSpareId: ''
|
|
809
955
|
};
|
|
810
|
-
return await dbUtil
|
|
956
|
+
return await dbUtil.dbQueryOne(dbSql.queryCertDataByOwner, {
|
|
811
957
|
ownerId: companyId,
|
|
812
958
|
applyId: "company"
|
|
813
959
|
}, false).then(certRec => {
|
|
814
960
|
// console.log('当前证书:\n', certRec);
|
|
815
961
|
// checkCertStatus(certRec);
|
|
816
962
|
let certData = JSON.parse(certRec.certBody);
|
|
817
|
-
let pubKeyData = Buffer.from(certData.cert, "base64").toString();
|
|
818
|
-
|
|
963
|
+
let pubKeyData = Buffer.from(certData.cert, "base64").toString();
|
|
964
|
+
// 公司正式证书
|
|
819
965
|
certInfo.certLiving = pubKeyData;
|
|
820
966
|
certInfo.certLivingId = certRec.id;
|
|
821
|
-
return dbUtil
|
|
967
|
+
return dbUtil.dbQueryOne(dbSql.queryCertDataByOwner, {
|
|
822
968
|
ownerId: companyId,
|
|
823
969
|
applyId: "company_spare"
|
|
824
970
|
}, false).then(certRec1 => {
|
|
825
971
|
// console.log('备用证书:\n', certRec1);
|
|
826
972
|
// checkCertStatus(certRec1);
|
|
827
973
|
let certData1 = JSON.parse(certRec1.certBody);
|
|
828
|
-
let pubKeyData1 = Buffer.from(certData1.cert, "base64").toString();
|
|
829
|
-
|
|
974
|
+
let pubKeyData1 = Buffer.from(certData1.cert, "base64").toString();
|
|
975
|
+
// 公司备用证书
|
|
830
976
|
certInfo.certSpare = pubKeyData1;
|
|
831
977
|
certInfo.certSpareId = certRec1.id;
|
|
832
978
|
}).catch(e => {
|
|
@@ -837,55 +983,45 @@ class apiUtil$2 {
|
|
|
837
983
|
return certInfo;
|
|
838
984
|
}).catch(e => {
|
|
839
985
|
console.log('获取企业证书失败:\n', e);
|
|
840
|
-
throw [err$
|
|
986
|
+
throw [err$1.ACCESS_REFUSED, `获取企业证书失败:${err$1.ERROR(e).message}`];
|
|
841
987
|
});
|
|
842
988
|
}
|
|
989
|
+
|
|
843
990
|
/**
|
|
844
991
|
* 验证API调用签名
|
|
845
992
|
* @param tokenData
|
|
846
993
|
* @param req
|
|
847
994
|
* @returns {Promise<*|boolean>}
|
|
848
995
|
*/
|
|
849
|
-
|
|
850
|
-
|
|
851
996
|
static async verifyApiSignature(tokenData, req) {
|
|
852
997
|
try {
|
|
853
998
|
if (!req.headers.timestamp) {
|
|
854
|
-
throw [err$
|
|
999
|
+
throw [err$1.ACCESS_REFUSED, `必须在请求头中设置时戳`];
|
|
855
1000
|
}
|
|
856
|
-
|
|
857
1001
|
let timestamp = parseInt(req.headers.timestamp);
|
|
858
1002
|
let currentTime = new Date().valueOf();
|
|
859
1003
|
let maxTimeDiff = apiUtil$2.isDebugMode(req) ? 7 * 24 * 3600 : apiUtil$2.isTestMode(req) ? 4 * 3600 : 100; // 100
|
|
860
|
-
|
|
861
1004
|
if (timestamp.toString() == "NaN" || currentTime < timestamp - 5000 || currentTime - timestamp > maxTimeDiff * 1000) {
|
|
862
|
-
throw [err$
|
|
1005
|
+
throw [err$1.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
|
|
863
1006
|
}
|
|
864
|
-
|
|
865
1007
|
let signature = req.headers.signature;
|
|
866
|
-
|
|
867
1008
|
if (!signature) {
|
|
868
|
-
throw [err$
|
|
1009
|
+
throw [err$1.ACCESS_REFUSED, `必须在请求头中提供签名`];
|
|
869
1010
|
}
|
|
870
|
-
|
|
871
1011
|
let signData = apiUtil$2.extractToken(req, null, true) || tokenData.apiKey;
|
|
872
1012
|
signData += timestamp;
|
|
873
|
-
|
|
874
1013
|
if (apiUtil$2.isDebugMode(req) || apiUtil$2.isTestMode(req)) {
|
|
875
1014
|
let publicKey = req.headers.publickey || req.body.publicKey || req.query.publicKey;
|
|
876
|
-
|
|
877
1015
|
if (publicKey) {
|
|
878
1016
|
publicKey = decodeURIComponent(publicKey);
|
|
879
1017
|
tokenData.certPublicKey = publicKey;
|
|
880
1018
|
req.certPublicKey = publicKey;
|
|
881
1019
|
}
|
|
882
1020
|
}
|
|
883
|
-
|
|
884
1021
|
if (tokenData.certPublicKey) {
|
|
885
1022
|
let verifyResult = doVerify(signData, signature, tokenData.certPublicKey);
|
|
886
1023
|
return await verifyResult;
|
|
887
1024
|
}
|
|
888
|
-
|
|
889
1025
|
return apiUtil$2.getCompanyCertificate(tokenData.apiKey).then(info => {
|
|
890
1026
|
tokenData.certPublicKey = info.certLiving;
|
|
891
1027
|
tokenData.certPublicKeySpare = info.certSpare;
|
|
@@ -893,7 +1029,6 @@ class apiUtil$2 {
|
|
|
893
1029
|
tokenData.certSpareId = info.certSpareId;
|
|
894
1030
|
req.certPublicKey = info.certLiving;
|
|
895
1031
|
let token = apiUtil$2.extractToken(req, null, true);
|
|
896
|
-
|
|
897
1032
|
if (token) {
|
|
898
1033
|
apiUtil$2.storeToken(apiUtil$2.apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
|
|
899
1034
|
}
|
|
@@ -904,29 +1039,25 @@ class apiUtil$2 {
|
|
|
904
1039
|
// return Promise.reject(e);
|
|
905
1040
|
throw e;
|
|
906
1041
|
}
|
|
907
|
-
|
|
908
1042
|
function doVerify(signData, signature) {
|
|
909
1043
|
let verify = crypto.createVerify('SHA256');
|
|
910
1044
|
verify.write(signData);
|
|
911
1045
|
verify.end();
|
|
912
1046
|
let verifyOK = false;
|
|
913
|
-
|
|
914
1047
|
try {
|
|
915
1048
|
// 先用正式证书验证
|
|
916
1049
|
verifyOK = verify.verify(tokenData.certPublicKey, signature, 'base64');
|
|
917
1050
|
} catch (e) {
|
|
918
1051
|
console.log("SPO服务签名验证异常(正式证书), ", e);
|
|
919
1052
|
verifyOK = false;
|
|
920
|
-
|
|
921
1053
|
if (!tokenData.certPublicKeySpare) {
|
|
922
1054
|
throw {
|
|
923
|
-
eo: err$
|
|
1055
|
+
eo: err$1.ACCESS_REFUSED,
|
|
924
1056
|
msgArgv: "签名验证异常",
|
|
925
1057
|
data: e
|
|
926
1058
|
};
|
|
927
1059
|
}
|
|
928
1060
|
}
|
|
929
|
-
|
|
930
1061
|
if (!verifyOK && tokenData.certPublicKeySpare) {
|
|
931
1062
|
try {
|
|
932
1063
|
// 再用备用证书验证
|
|
@@ -934,18 +1065,17 @@ class apiUtil$2 {
|
|
|
934
1065
|
verifySpare.write(signData);
|
|
935
1066
|
verifySpare.end();
|
|
936
1067
|
verifyOK = verifySpare.verify(tokenData.certPublicKeySpare, signature, 'base64');
|
|
937
|
-
|
|
938
1068
|
if (verifyOK) {
|
|
939
1069
|
// 备用证书验证成功了,则将备用证书替换为正式证书
|
|
940
1070
|
console.log(`公司(${tokenData.apiKey})备用证书验签成功,正式启用...`);
|
|
941
|
-
return dbUtil
|
|
942
|
-
let p1 = dbUtil
|
|
1071
|
+
return dbUtil.dbTrans(trans => {
|
|
1072
|
+
let p1 = dbUtil.dbExec(dbSql.deleteCertRecById, {
|
|
943
1073
|
replacements: {
|
|
944
1074
|
id: tokenData.certLivingId
|
|
945
1075
|
},
|
|
946
1076
|
transaction: trans
|
|
947
1077
|
});
|
|
948
|
-
let p2 = dbUtil
|
|
1078
|
+
let p2 = dbUtil.dbExec(dbSql.spareCertToLiving, {
|
|
949
1079
|
replacements: {
|
|
950
1080
|
id: tokenData.certSpareId
|
|
951
1081
|
},
|
|
@@ -958,59 +1088,51 @@ class apiUtil$2 {
|
|
|
958
1088
|
delete tokenData.certSpareId;
|
|
959
1089
|
delete tokenData.certPublicKeySpare;
|
|
960
1090
|
let token = apiUtil$2.extractToken(req);
|
|
961
|
-
|
|
962
1091
|
if (token) {
|
|
963
1092
|
apiUtil$2.storeToken(apiUtil$2.apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
|
|
964
1093
|
}
|
|
965
|
-
|
|
966
1094
|
console.log(`公司(${tokenData.apiKey})备用证书成功转换为正式证书`);
|
|
967
1095
|
});
|
|
968
1096
|
}
|
|
969
1097
|
} catch (e) {
|
|
970
1098
|
console.log("SPO服务签名验证异常(备用证书), ", e);
|
|
971
1099
|
throw {
|
|
972
|
-
eo: err$
|
|
1100
|
+
eo: err$1.ACCESS_REFUSED,
|
|
973
1101
|
msgArgv: "签名验证异常(spare)",
|
|
974
1102
|
data: e
|
|
975
1103
|
};
|
|
976
1104
|
}
|
|
977
1105
|
}
|
|
978
|
-
|
|
979
1106
|
if (!verifyOK) {
|
|
980
1107
|
console.log("SPO服务签名验证失败, tokenData: ", tokenData);
|
|
981
|
-
throw [err$
|
|
1108
|
+
throw [err$1.ACCESS_REFUSED, "签名验证未通过"];
|
|
982
1109
|
}
|
|
983
|
-
|
|
984
1110
|
return verifyOK;
|
|
985
1111
|
}
|
|
986
1112
|
}
|
|
1113
|
+
|
|
987
1114
|
/**
|
|
988
1115
|
* 检查API调用之合法性
|
|
989
1116
|
* @param tokenData
|
|
990
1117
|
* @param req
|
|
991
1118
|
* @returns {Promise<any>}
|
|
992
1119
|
*/
|
|
993
|
-
|
|
994
|
-
|
|
995
1120
|
static async checkApiCallValid(tokenData, req) {
|
|
996
1121
|
if (!tokenData.companyInfo) {
|
|
997
1122
|
tokenData.companyInfo = await apiUtil$2.queryCompanyInfo(tokenData.apiKey, true).catch(e => {
|
|
998
1123
|
console.log("执行企业信息查询发生异常", e);
|
|
999
|
-
throw [err$
|
|
1124
|
+
throw [err$1.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
|
|
1000
1125
|
});
|
|
1001
1126
|
}
|
|
1002
|
-
|
|
1003
1127
|
const companyInfo = tokenData.companyInfo;
|
|
1004
|
-
|
|
1005
1128
|
if (companyInfo != null) {
|
|
1006
1129
|
let secret = apiUtil$2._getApiSecret(tokenData.apiKey);
|
|
1007
|
-
|
|
1008
|
-
|
|
1130
|
+
if (secret !== tokenData.apiSecret) throw err$1.API_SCREPT_INVALID;
|
|
1131
|
+
// 不再检查 IP 白名单,改为验证证书签名
|
|
1009
1132
|
// console.log("fromIp:", tokenData.clientIp, "ipWhiteList:", companyInfo.ipWhiteList);
|
|
1010
1133
|
// let whiteList = companyInfo.ipWhiteList || "";
|
|
1011
1134
|
// // 没有设置ip白名单的就不检查了
|
|
1012
1135
|
// if (whiteList == "" || ipMatched(tokenData.clientIp, whiteList + ",127.0.0.1,1"))
|
|
1013
|
-
|
|
1014
1136
|
if (apiUtil$2.signatureVerified(req)) return companyInfo;
|
|
1015
1137
|
return apiUtil$2.verifyApiSignature(tokenData, req).then(x => {
|
|
1016
1138
|
return companyInfo;
|
|
@@ -1018,30 +1140,26 @@ class apiUtil$2 {
|
|
|
1018
1140
|
throw e;
|
|
1019
1141
|
});
|
|
1020
1142
|
}
|
|
1021
|
-
|
|
1022
|
-
throw [err$2.API_KEY_INVALID, tokenData.apiKey];
|
|
1143
|
+
throw [err$1.API_KEY_INVALID, tokenData.apiKey];
|
|
1023
1144
|
}
|
|
1145
|
+
|
|
1024
1146
|
/**
|
|
1025
1147
|
* 检查令牌数据是否存在
|
|
1026
1148
|
* @param token
|
|
1027
1149
|
* @returns {*}
|
|
1028
1150
|
*/
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
1151
|
static tokenDataExist(token) {
|
|
1032
|
-
return kvStorage
|
|
1152
|
+
return kvStorage.stored(token);
|
|
1033
1153
|
}
|
|
1034
|
-
|
|
1035
1154
|
static parametersOK(params) {
|
|
1036
1155
|
configNeeded();
|
|
1037
1156
|
let paramSufix = params._param_sufix || "";
|
|
1038
|
-
|
|
1039
1157
|
for (let i = 1; i < arguments.length; i++) {
|
|
1040
1158
|
let paramName = arguments[i];
|
|
1041
1159
|
let paramExists = false;
|
|
1042
|
-
|
|
1043
1160
|
if (paramName.includes("/")) {
|
|
1044
|
-
let names = paramName.split("/");
|
|
1161
|
+
let names = paramName.split("/");
|
|
1162
|
+
// if (params[names[0]]) {
|
|
1045
1163
|
// paramExists = true;
|
|
1046
1164
|
// } else {
|
|
1047
1165
|
// if (params[names[1]]) {
|
|
@@ -1050,113 +1168,96 @@ class apiUtil$2 {
|
|
|
1050
1168
|
// delete params[names[1]];
|
|
1051
1169
|
// }
|
|
1052
1170
|
// }
|
|
1053
|
-
|
|
1054
1171
|
for (let ind in names) {
|
|
1055
1172
|
let name = names[ind];
|
|
1056
|
-
|
|
1057
1173
|
if (typeof params[name] != 'undefined') {
|
|
1058
1174
|
paramExists = true;
|
|
1059
1175
|
break;
|
|
1060
1176
|
}
|
|
1061
|
-
|
|
1062
1177
|
if (paramSufix != "" && typeof params[name + paramSufix] != 'undefined') {
|
|
1063
1178
|
paramExists = true;
|
|
1064
1179
|
break;
|
|
1065
1180
|
}
|
|
1066
1181
|
}
|
|
1067
|
-
|
|
1068
1182
|
paramName = `${paramName} 之一`;
|
|
1069
1183
|
} else {
|
|
1070
1184
|
paramExists = typeof params[paramName] != 'undefined' || typeof params[paramName + paramSufix] != 'undefined';
|
|
1071
1185
|
}
|
|
1072
|
-
|
|
1073
|
-
if (!paramExists) return ppUtil$4.errorPormise(err$2.ERROR(err$2.PARAMETER_NEEDED, paramName));
|
|
1186
|
+
if (!paramExists) return ppUtil$3.errorPormise(err$1.ERROR(err$1.PARAMETER_NEEDED, paramName));
|
|
1074
1187
|
}
|
|
1075
|
-
|
|
1076
1188
|
return Promise.resolve(paramSufix);
|
|
1077
1189
|
}
|
|
1190
|
+
|
|
1078
1191
|
/**
|
|
1079
1192
|
* 获取客户端IP地址
|
|
1080
1193
|
* @param req
|
|
1081
1194
|
* @returns {*|string|string}
|
|
1082
1195
|
*/
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
1196
|
static getClientIp(req) {
|
|
1086
1197
|
if (!req.hasOwnProperty("clientIp")) {
|
|
1087
|
-
let ip = req.headers["x-real-ip"] || req.headers["x-true-ip"] || req.headers['x-forwarded-for'] || req.headers['x-forward-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.headers['host'] || "";
|
|
1088
|
-
|
|
1198
|
+
let ip = req.headers["x-real-ip"] || req.headers["x-true-ip"] || req.headers['x-forwarded-for'] || req.headers['x-forward-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.headers['host'] || "";
|
|
1199
|
+
// console.log("Request IP:", ip, "req: ", req);
|
|
1089
1200
|
if (ip.indexOf(",") >= 0) {
|
|
1090
1201
|
ip = ip.split(',')[0];
|
|
1091
1202
|
}
|
|
1092
|
-
|
|
1093
1203
|
if (ip.indexOf(":") >= 0) {
|
|
1094
1204
|
ip = ip.substring(ip.lastIndexOf(':') + 1);
|
|
1095
1205
|
}
|
|
1096
|
-
|
|
1097
1206
|
req.clientIp = ip;
|
|
1098
1207
|
}
|
|
1099
|
-
|
|
1100
1208
|
return req.clientIp;
|
|
1101
1209
|
}
|
|
1210
|
+
|
|
1102
1211
|
/**
|
|
1103
1212
|
* 获取与本机一起提供服务的所有主机
|
|
1104
1213
|
* @param params
|
|
1105
1214
|
* @returns {{port: (number|number), hosts: [string]}}
|
|
1106
1215
|
*/
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
1216
|
static getEnvHosts(params) {
|
|
1110
1217
|
configNeeded();
|
|
1111
1218
|
return {
|
|
1112
|
-
hosts: appSetting
|
|
1113
|
-
port: appSetting
|
|
1219
|
+
hosts: appSetting.serverHosts || ["localhost"],
|
|
1220
|
+
port: appSetting.listenPort || +params.port || 8443
|
|
1114
1221
|
};
|
|
1115
1222
|
}
|
|
1223
|
+
|
|
1116
1224
|
/**
|
|
1117
1225
|
* 检查指定的host和发送请求的ip是不是自己的ip
|
|
1118
1226
|
* @param host
|
|
1119
1227
|
* @param req
|
|
1120
1228
|
* @returns {Promise<*>}
|
|
1121
1229
|
*/
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
1230
|
static async hostIsMySelf(host, req) {
|
|
1125
1231
|
let clientIp = apiUtil$2.getClientIp(req);
|
|
1126
|
-
|
|
1127
1232
|
try {
|
|
1128
|
-
return !!ppUtil$
|
|
1233
|
+
return !!ppUtil$3.getMyIp({
|
|
1129
1234
|
hosts: [host, clientIp]
|
|
1130
1235
|
});
|
|
1131
1236
|
} catch (e) {
|
|
1132
1237
|
return false;
|
|
1133
1238
|
}
|
|
1134
1239
|
}
|
|
1240
|
+
|
|
1135
1241
|
/**
|
|
1136
1242
|
* 检查是否应该把请求转发到其它服务器,若是则转发
|
|
1137
1243
|
* @param options
|
|
1138
1244
|
* @returns {Promise<boolean>}
|
|
1139
1245
|
*/
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
1246
|
static async checkForwardsHost(options) {
|
|
1143
1247
|
configNeeded();
|
|
1144
1248
|
const params = options.replacements;
|
|
1145
1249
|
const myEnvHosts = apiUtil$2.getEnvHosts(params);
|
|
1146
|
-
const myIp = ppUtil$
|
|
1250
|
+
const myIp = ppUtil$3.getMyIp();
|
|
1147
1251
|
const host = params.host || myIp;
|
|
1148
|
-
if (!myEnvHosts.hosts.contains(host)) throw [err$
|
|
1149
|
-
|
|
1252
|
+
if (!myEnvHosts.hosts.contains(host)) throw [err$1.ACCESS_REFUSED, `环境${conf$2.envId}貌似无此主机:${params.host}`];
|
|
1150
1253
|
if (!apiUtil$2.hostIsMySelf(host, options._res.req)) {
|
|
1151
1254
|
let result = await apiUtil$2.forwardsTo(host, myEnvHosts.port, params, options._res.req, myIp);
|
|
1152
|
-
|
|
1153
1255
|
options._res.send(result);
|
|
1154
|
-
|
|
1155
1256
|
return true;
|
|
1156
1257
|
}
|
|
1157
|
-
|
|
1158
1258
|
return false;
|
|
1159
1259
|
}
|
|
1260
|
+
|
|
1160
1261
|
/**
|
|
1161
1262
|
* 将收到的请求转发到另一台主机
|
|
1162
1263
|
* @param anotherIp
|
|
@@ -1166,181 +1267,156 @@ class apiUtil$2 {
|
|
|
1166
1267
|
* @param lanClient
|
|
1167
1268
|
* @returns {Promise<*>}
|
|
1168
1269
|
*/
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
1270
|
static async forwardsTo(anotherIp, port, params, req, lanClient) {
|
|
1172
1271
|
let url = anotherIp.indexOf("://") > 0 ? anotherIp : `${req.headers.scheme}://${anotherIp}:${port}${req.originalUrl}`;
|
|
1173
|
-
|
|
1174
1272
|
if (url.indexOf("?") > 0) {
|
|
1175
1273
|
url = url.substring(0, url.indexOf("?"));
|
|
1176
1274
|
}
|
|
1177
|
-
|
|
1178
1275
|
let reqOptions = {
|
|
1179
1276
|
method: req.method,
|
|
1180
1277
|
url: url,
|
|
1181
1278
|
data: params
|
|
1182
1279
|
};
|
|
1183
1280
|
let result = await netUtil$1.apiRequest(reqOptions);
|
|
1184
|
-
|
|
1185
1281
|
if (result.status !== 200) {
|
|
1186
1282
|
console.log(`访问 ${reqOptions.url} 出错`, result.status, result.res.statusMessage);
|
|
1187
|
-
throw [err$
|
|
1283
|
+
throw [err$1.EXCEPTION, `[${result.status}] - ${result.res.statusMessage}`];
|
|
1188
1284
|
}
|
|
1189
|
-
|
|
1190
1285
|
return result.data;
|
|
1191
1286
|
}
|
|
1287
|
+
|
|
1192
1288
|
/**
|
|
1193
1289
|
* 解析配置项路径
|
|
1194
1290
|
* @param keyPath
|
|
1195
1291
|
* @returns {{parent: null, parentKey: string, value, key: string}}
|
|
1196
1292
|
*/
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
1293
|
static parseCfgPath(keyPath) {
|
|
1200
1294
|
let keys = Array.isArray(keyPath) ? keyPath : keyPath.split(".");
|
|
1201
1295
|
let parentKey = "";
|
|
1202
1296
|
let key = "config";
|
|
1203
|
-
let value = conf$
|
|
1297
|
+
let value = conf$2;
|
|
1204
1298
|
let parent = null;
|
|
1205
|
-
|
|
1206
1299
|
for (let i = 0; i < keys.length; i++) {
|
|
1207
1300
|
parent = value;
|
|
1208
1301
|
parentKey += (parentKey ? "." : "") + key;
|
|
1209
1302
|
key = keys[i];
|
|
1210
1303
|
value = parent[key];
|
|
1211
|
-
|
|
1212
1304
|
if (value === undefined) {
|
|
1213
|
-
throw [err$
|
|
1305
|
+
throw [err$1.INVALID_PARAM, `无此配置项: ${key}`];
|
|
1214
1306
|
}
|
|
1215
1307
|
}
|
|
1216
|
-
|
|
1217
1308
|
return {
|
|
1218
1309
|
parent,
|
|
1219
1310
|
parentKey,
|
|
1220
1311
|
key,
|
|
1221
1312
|
value
|
|
1222
1313
|
};
|
|
1223
|
-
}
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
//#endregion
|
|
1317
|
+
|
|
1224
1318
|
//region ====中间件
|
|
1225
1319
|
|
|
1226
1320
|
/**
|
|
1227
1321
|
* 检查令牌,若存在则将其的用户信息置入req,否则返回错误信息
|
|
1228
1322
|
*/
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
1323
|
static async $checkToken(req, res, next) {
|
|
1232
1324
|
try {
|
|
1233
1325
|
await apiUtil$2.checkRequestToken(req);
|
|
1234
1326
|
next();
|
|
1235
1327
|
} catch (e) {
|
|
1236
|
-
res.send(err$
|
|
1328
|
+
res.send(err$1.ERROR(e));
|
|
1237
1329
|
}
|
|
1238
|
-
|
|
1239
1330
|
return false;
|
|
1240
1331
|
}
|
|
1332
|
+
|
|
1241
1333
|
/**
|
|
1242
1334
|
* 检查令牌,若存在则将其用户信息置入req
|
|
1243
1335
|
*/
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
1336
|
static async $getToken(req, res, next) {
|
|
1247
1337
|
function extractToken(req, res) {
|
|
1248
1338
|
if (!req.accessToken) {
|
|
1249
1339
|
//检查post的信息或者url查询参数或者头信息
|
|
1250
1340
|
let token = req.headers["access_token"] || req.headers['x-access-token']; //向后兼容
|
|
1251
|
-
|
|
1252
1341
|
if (!token) {
|
|
1253
1342
|
let params = apiUtil$2.extractParams(req);
|
|
1254
1343
|
token = params["access_token"];
|
|
1255
|
-
|
|
1256
1344
|
if (token) {
|
|
1257
1345
|
delete params["access_token"];
|
|
1258
1346
|
} else if (params.token) {
|
|
1259
1347
|
token = params.token; //向后兼容
|
|
1260
|
-
|
|
1261
|
-
|
|
1348
|
+
delete params.token;
|
|
1349
|
+
// } else if (res) {
|
|
1262
1350
|
// // 如果没有token,则返回错误
|
|
1263
1351
|
// console.log(err.TOKEN_NEEDED);
|
|
1264
1352
|
// res.send(err.ERROR(err.TOKEN_NEEDED));
|
|
1265
1353
|
}
|
|
1266
1354
|
}
|
|
1267
|
-
|
|
1268
1355
|
req.accessToken = token;
|
|
1269
1356
|
}
|
|
1270
|
-
|
|
1271
1357
|
return req.accessToken;
|
|
1272
1358
|
}
|
|
1273
|
-
|
|
1274
1359
|
try {
|
|
1275
1360
|
if (extractToken(req, res)) {
|
|
1276
1361
|
await apiUtil$2.restoreTokenData(apiUtil$2.userTokenStoreKey(req.accessToken), apiUtil$2.tokenExpireTime(req)).then(function (data) {
|
|
1277
1362
|
req.userInfo = apiUtil$2.setUserIdNo(data, data._idNo);
|
|
1278
|
-
}, function (e) {
|
|
1363
|
+
}, function (e) {
|
|
1364
|
+
//no token
|
|
1279
1365
|
});
|
|
1280
1366
|
}
|
|
1281
|
-
|
|
1282
1367
|
return true;
|
|
1283
1368
|
} catch (e) {
|
|
1284
|
-
res.send(err$
|
|
1369
|
+
res.send(err$1.ERROR(e));
|
|
1285
1370
|
return false;
|
|
1286
1371
|
}
|
|
1287
1372
|
}
|
|
1373
|
+
|
|
1288
1374
|
/**
|
|
1289
1375
|
* 标识此请求已经完成了签名验证或者无需进行签名验证
|
|
1290
1376
|
*/
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
1377
|
static $signatureVerified(req, res, next) {
|
|
1294
1378
|
req.signatureVerified = true;
|
|
1295
1379
|
next();
|
|
1296
1380
|
}
|
|
1381
|
+
|
|
1297
1382
|
/**
|
|
1298
1383
|
* 标识此请求是从前端发过来的,比如移动端、PC浏览器等,区别于SPO一般的服务端后台请求。
|
|
1299
1384
|
* 如果在请求参数中包含有签名参数,则将其移到请求头中
|
|
1300
1385
|
*/
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
1386
|
static $isMobile(req, res, next) {
|
|
1304
1387
|
req.isMobile = true;
|
|
1305
|
-
|
|
1306
1388
|
if (!apiUtil$2.signatureVerified(req)) {
|
|
1307
1389
|
let params = apiUtil$2.extractParams(req);
|
|
1308
1390
|
moveProperty(params, req.headers, "access_token");
|
|
1309
1391
|
moveProperty(params, req.headers, "timestamp");
|
|
1310
|
-
|
|
1311
1392
|
if (moveProperty(params, req.headers, "signature")) {
|
|
1312
1393
|
req.headers.signature = decodeURIComponent(req.headers.signature);
|
|
1313
1394
|
}
|
|
1314
1395
|
}
|
|
1315
|
-
|
|
1316
1396
|
next();
|
|
1317
1397
|
}
|
|
1398
|
+
|
|
1318
1399
|
/**
|
|
1319
1400
|
* 检查企业 API 调用合法性 (apiKey, apiSecret)
|
|
1320
1401
|
* @param req
|
|
1321
1402
|
* @param res
|
|
1322
1403
|
* @param next
|
|
1323
1404
|
*/
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
1405
|
static $checkApiKeyOld(req, res, next) {
|
|
1327
1406
|
//检查post的信息或者url查询参数或者头信息
|
|
1328
1407
|
const tokenData = apiUtil$2.extractTokenData(req);
|
|
1329
1408
|
const params = apiUtil$2.extractParams(req);
|
|
1330
1409
|
apiUtil$2.createApiCallRec(tokenData, req);
|
|
1331
1410
|
let errResponse = null;
|
|
1332
|
-
|
|
1333
1411
|
if (!tokenData.clientIp) {
|
|
1334
|
-
errResponse = apiUtil$2.spoApiFail(err$
|
|
1412
|
+
errResponse = apiUtil$2.spoApiFail(err$1.GET_CLIENTIP_FAIL, req);
|
|
1335
1413
|
} else if (!tokenData.apiKey) {
|
|
1336
|
-
errResponse = apiUtil$2.spoApiFail([err$
|
|
1414
|
+
errResponse = apiUtil$2.spoApiFail([err$1.PARAMETER_NEEDED, "apiKey"], req);
|
|
1337
1415
|
} else if (!tokenData.apiSecret) {
|
|
1338
|
-
errResponse = apiUtil$2.spoApiFail([err$
|
|
1416
|
+
errResponse = apiUtil$2.spoApiFail([err$1.PARAMETER_NEEDED, "apiSecret"], req);
|
|
1339
1417
|
}
|
|
1340
|
-
|
|
1341
1418
|
if (errResponse != null) {
|
|
1342
1419
|
apiUtil$2._saveApiCallRec(req.apiCallRec, errResponse);
|
|
1343
|
-
|
|
1344
1420
|
apiUtil$2.sendOrRedirect(res, params.redirectUrl || params.callbackUrl, errResponse);
|
|
1345
1421
|
} else {
|
|
1346
1422
|
apiUtil$2.checkApiCallValid(tokenData, req).then(companyInfo => {
|
|
@@ -1350,32 +1426,26 @@ class apiUtil$2 {
|
|
|
1350
1426
|
}, e => {
|
|
1351
1427
|
console.log('apiCallInvalid:', e);
|
|
1352
1428
|
let errResponse = apiUtil$2.spoApiFail(e, req);
|
|
1353
|
-
|
|
1354
1429
|
apiUtil$2._saveApiCallRec(req.apiCallRec, errResponse);
|
|
1355
|
-
|
|
1356
1430
|
apiUtil$2.sendOrRedirect(res, params.redirectUrl || params.callbackUrl, errResponse);
|
|
1357
1431
|
});
|
|
1358
1432
|
}
|
|
1359
1433
|
}
|
|
1434
|
+
|
|
1360
1435
|
/**
|
|
1361
1436
|
* 检查机构令牌
|
|
1362
1437
|
*/
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
1438
|
static $checkApiKey(req, res, next) {
|
|
1366
1439
|
if (req.ignoreToken) {
|
|
1367
1440
|
next();
|
|
1368
1441
|
return;
|
|
1369
1442
|
}
|
|
1370
|
-
|
|
1371
1443
|
let accessToken = apiUtil$2.extractToken(req);
|
|
1372
|
-
|
|
1373
1444
|
if (!accessToken) {
|
|
1374
|
-
res.send(apiUtil$2.spoApiFail(err$
|
|
1375
|
-
|
|
1445
|
+
res.send(apiUtil$2.spoApiFail(err$1.TOKEN_NEEDED, req));
|
|
1446
|
+
// apiUtil.sendOrRedirect(req, res, spoApiFail(err.TOKEN_NEEDED, req));
|
|
1376
1447
|
return;
|
|
1377
1448
|
}
|
|
1378
|
-
|
|
1379
1449
|
apiUtil$2.restoreTokenData(apiUtil$2.apiTokenStoreKey(accessToken)).then(p => {
|
|
1380
1450
|
// req.headers[hnApiKey] = p.apiKey || '';
|
|
1381
1451
|
// req.headers[hnApiSecret] = p.apiSecret || '';
|
|
@@ -1387,15 +1457,15 @@ class apiUtil$2 {
|
|
|
1387
1457
|
} else {
|
|
1388
1458
|
p.clientIp = apiUtil$2.getClientIp(req);
|
|
1389
1459
|
}
|
|
1390
|
-
|
|
1391
1460
|
req.isApiCall = true;
|
|
1392
1461
|
req.tokenData = p;
|
|
1393
1462
|
return apiUtil$2.$checkApiKeyOld(req, res, next);
|
|
1394
1463
|
}).catch(e => {
|
|
1395
1464
|
const params = apiUtil$2.extractParams(req);
|
|
1396
|
-
apiUtil$2.sendOrRedirect(res, params.redirectUrl || params.callbackUrl, apiUtil$2.spoApiFail(err$
|
|
1465
|
+
apiUtil$2.sendOrRedirect(res, params.redirectUrl || params.callbackUrl, apiUtil$2.spoApiFail(err$1.TOKEN_INVALID, req));
|
|
1397
1466
|
});
|
|
1398
1467
|
}
|
|
1468
|
+
|
|
1399
1469
|
/**
|
|
1400
1470
|
* 检查请求令牌,允许个人用户令牌和机构令牌,若不存在或不合法,则返回错误信息
|
|
1401
1471
|
* @param req
|
|
@@ -1403,31 +1473,25 @@ class apiUtil$2 {
|
|
|
1403
1473
|
* @param next
|
|
1404
1474
|
* @returns {Promise<void|boolean|boolean|undefined>}
|
|
1405
1475
|
*/
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
1476
|
static async $checkTokenOrApiKey(req, res, next) {
|
|
1409
1477
|
let accessToken = apiUtil$2.extractToken(req, res);
|
|
1410
|
-
|
|
1411
1478
|
if (accessToken) {
|
|
1412
1479
|
let tokenExist = await apiUtil$2.tokenDataExist(apiUtil$2.userTokenStoreKey(accessToken));
|
|
1413
|
-
|
|
1414
1480
|
if (tokenExist) {
|
|
1415
1481
|
return await apiUtil$2.$checkToken(req, res, next);
|
|
1416
1482
|
}
|
|
1417
|
-
|
|
1418
1483
|
tokenExist = await apiUtil$2.tokenDataExist(apiUtil$2.apiTokenStoreKey(accessToken));
|
|
1419
|
-
|
|
1420
1484
|
if (tokenExist) {
|
|
1421
1485
|
return apiUtil$2.$checkApiKey(req, res, next);
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
|
|
1486
|
+
}
|
|
1487
|
+
// 如果给定的token不存在,看看是不是平台内部调用
|
|
1425
1488
|
return await apiUtil$2.checkInternalToken(req).catch(e => {
|
|
1426
1489
|
res.send(apiUtil$2.apiFail(e, req));
|
|
1427
1490
|
return false;
|
|
1428
1491
|
});
|
|
1429
1492
|
}
|
|
1430
1493
|
}
|
|
1494
|
+
|
|
1431
1495
|
/**
|
|
1432
1496
|
* 基本验证,应用系统应该预先设置验证函数 _validateBasicAuth(userName, password)
|
|
1433
1497
|
* @param req
|
|
@@ -1435,12 +1499,9 @@ class apiUtil$2 {
|
|
|
1435
1499
|
* @param next
|
|
1436
1500
|
* @returns {Promise<*>}
|
|
1437
1501
|
*/
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
1502
|
static async $basicAuth(req, res, next) {
|
|
1441
1503
|
try {
|
|
1442
1504
|
const authorization = getBasicAuthorization(req);
|
|
1443
|
-
|
|
1444
1505
|
if (!authorization) {
|
|
1445
1506
|
throw {
|
|
1446
1507
|
status: 401,
|
|
@@ -1451,7 +1512,6 @@ class apiUtil$2 {
|
|
|
1451
1512
|
}
|
|
1452
1513
|
};
|
|
1453
1514
|
}
|
|
1454
|
-
|
|
1455
1515
|
if (!(await apiUtil$2._validateBasicAuth(authorization.name, authorization.pass, req, res, next))) {
|
|
1456
1516
|
throw {
|
|
1457
1517
|
status: 401,
|
|
@@ -1468,373 +1528,113 @@ class apiUtil$2 {
|
|
|
1468
1528
|
res.set('WWW-Authenticate', `Basic realm=${e.message}`);
|
|
1469
1529
|
return res.status(401).send(e.message);
|
|
1470
1530
|
} catch {}
|
|
1471
|
-
res.set('WWW-Authenticate', `Basic realm=validate fail`);
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
return res.status(e.status || 500).send(e.error || e);
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
next();
|
|
1478
|
-
} //#endregion
|
|
1479
|
-
//region ====一些通用服务功能
|
|
1480
|
-
|
|
1481
|
-
/**
|
|
1482
|
-
* 获取配置数据
|
|
1483
|
-
* @param options
|
|
1484
|
-
* @returns {Promise<boolean|*>}
|
|
1485
|
-
*/
|
|
1486
|
-
// api/config/appSetting.ossEnabled
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
static async getConfigValue(options) {
|
|
1490
|
-
configNeeded();
|
|
1491
|
-
const params = options.replacements;
|
|
1492
|
-
let cfgItem = params._cfgItem;
|
|
1493
|
-
delete params._cfgItem;
|
|
1494
|
-
if (await apiUtil$2.checkForwardsHost(options)) return true;
|
|
1495
|
-
let c = apiUtil$2.parseCfgPath(cfgItem);
|
|
1496
|
-
delete c.parent;
|
|
1497
|
-
c.host = ppUtil$4.getMyIp();
|
|
1498
|
-
return c;
|
|
1499
|
-
}
|
|
1500
|
-
/**
|
|
1501
|
-
* 设置配置数据
|
|
1502
|
-
* @param options
|
|
1503
|
-
* @returns {Promise<*>}
|
|
1504
|
-
*/
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
static async setConfigValue(options) {
|
|
1508
|
-
configNeeded();
|
|
1509
|
-
const params = options.replacements;
|
|
1510
|
-
let cfgItem = params._cfgItem;
|
|
1511
|
-
delete params._cfgItem; // if (await checkForwardsHost(options))
|
|
1512
|
-
// return true;
|
|
1513
|
-
|
|
1514
|
-
await apiUtil$2.parametersOK(params, "value");
|
|
1515
|
-
let c = apiUtil$2.parseCfgPath(cfgItem);
|
|
1516
|
-
|
|
1517
|
-
if (typeof c.value === "object") {
|
|
1518
|
-
throw [err$2.ACCESS_REFUSED, `暂不支持修改复杂配置`];
|
|
1519
|
-
} // c.oldValue = c.value;
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
c.newValue = params.value;
|
|
1523
|
-
c.parent[c.key] = c.newValue;
|
|
1524
|
-
delete c.parent;
|
|
1525
|
-
c.host = ppUtil$4.getMyIp();
|
|
1526
|
-
return c; // 应用层自行处理多机同步
|
|
1527
|
-
}
|
|
1528
|
-
/**
|
|
1529
|
-
* 修改重启标志文件
|
|
1530
|
-
* 前提,PM2监视 restart,please.flag 文件,此文件若被修改则重启服务进程
|
|
1531
|
-
* 此服务假设 restart,please.flag 文件最后一行是一个整数,此整数+1后保存
|
|
1532
|
-
* @param options
|
|
1533
|
-
* @returns {Promise<number>}
|
|
1534
|
-
*/
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
static async updateRestartFlag(options) {
|
|
1538
|
-
const fileName = `restart,please.flag`;
|
|
1539
|
-
let text = await fs$1.async_readFile(fileName, 'utf8');
|
|
1540
|
-
const lines = text.split('\r\n');
|
|
1541
|
-
const n = +lines[lines.length - 1] + 1;
|
|
1542
|
-
lines[lines.length - 1] = ' '.repeat(50) + n.toString();
|
|
1543
|
-
text = lines.join('\r\n');
|
|
1544
|
-
await fs$1.async_writeFile(fileName, text);
|
|
1545
|
-
return n;
|
|
1546
|
-
}
|
|
1547
|
-
/**
|
|
1548
|
-
* 创建验证码对象
|
|
1549
|
-
* npm i svg-captcha
|
|
1550
|
-
* npm i svg2png
|
|
1551
|
-
*/
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
static createSvgCaptcha(options) {
|
|
1555
|
-
const captcha = svgCaptcha.create({
|
|
1556
|
-
inverse: options.hasOwnProperty('inverse') ? options.inverse : false,
|
|
1557
|
-
fontSize: options.fontSize || 48,
|
|
1558
|
-
noise: options.noise || 2,
|
|
1559
|
-
width: options.width || 150,
|
|
1560
|
-
height: options.height || 75,
|
|
1561
|
-
size: options.size || 4,
|
|
1562
|
-
charPreset: options.charPreset || '0123456789',
|
|
1563
|
-
ignoreChars: options.ignoreChars || '0oli',
|
|
1564
|
-
color: options.hasOwnProperty('color') ? options.color : true,
|
|
1565
|
-
background: options.background || '#cc9966'
|
|
1566
|
-
});
|
|
1567
|
-
return captcha;
|
|
1568
|
-
} //#endregion
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
|
-
function configNeeded() {
|
|
1574
|
-
if (!conf$3 || !err$2) {
|
|
1575
|
-
ppUtil$4.configNeeded();
|
|
1576
|
-
conf$3 = ppUtil$4.appConfig;
|
|
1577
|
-
appSetting$1 = conf$3.appSetting;
|
|
1578
|
-
err$2 = ppUtil$4.appErrCfg;
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
var ppUtilApi = apiUtil$2;
|
|
1583
|
-
|
|
1584
|
-
const fs = require$$5__default["default"];
|
|
1585
|
-
const path = require$$1__default$1["default"];
|
|
1586
|
-
const ppUtil$3 = require$$2__default["default"].ppUtil;
|
|
1587
|
-
const {
|
|
1588
|
-
dbUtil,
|
|
1589
|
-
ppRedis,
|
|
1590
|
-
kvStorage,
|
|
1591
|
-
redisSimulator
|
|
1592
|
-
} = require$$3__default["default"];
|
|
1593
|
-
let conf$2, err$1; // const dbCheck = require('../dbupdate/dd-version');
|
|
1594
|
-
|
|
1595
|
-
/**
|
|
1596
|
-
* API服务启动时前置条件检查
|
|
1597
|
-
* ok = await preconditions
|
|
1598
|
-
* .setAppName(conf.thisApp)
|
|
1599
|
-
* .addCheckPromise(preconditions.checkExEnvSetting())
|
|
1600
|
-
* .addCheckPromise(preconditions.checkRedis())
|
|
1601
|
-
* .addCheckPromise(checkDatabase())
|
|
1602
|
-
* .addChecker(myChecker, args)
|
|
1603
|
-
* .checkAll()
|
|
1604
|
-
*/
|
|
1605
|
-
|
|
1606
|
-
class preconditions$1 {
|
|
1607
|
-
static appName;
|
|
1608
|
-
static checkFunctions = [];
|
|
1609
|
-
static checkPromises = [];
|
|
1610
|
-
|
|
1611
|
-
static setAppName(aName) {
|
|
1612
|
-
ppUtil$3.configNeeded();
|
|
1613
|
-
conf$2 = ppUtil$3.appConfig;
|
|
1614
|
-
err$1 = ppUtil$3.appErrCfg;
|
|
1615
|
-
preconditions$1.appName = aName || conf$2.thisApp;
|
|
1616
|
-
return preconditions$1;
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
|
-
static addCheckPromise(p) {
|
|
1620
|
-
preconditions$1.checkPromises.push(p);
|
|
1621
|
-
return preconditions$1;
|
|
1622
|
-
}
|
|
1623
|
-
|
|
1624
|
-
static addChecker(checkFunc, args, blocked) {
|
|
1625
|
-
preconditions$1.checkFunctions.push({
|
|
1626
|
-
check: checkFunc,
|
|
1627
|
-
args: args,
|
|
1628
|
-
blocked: blocked
|
|
1629
|
-
});
|
|
1630
|
-
return preconditions$1;
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
static pushMessage(msg) {
|
|
1634
|
-
if (msg) {
|
|
1635
|
-
if (!preconditions$1.messages) {
|
|
1636
|
-
preconditions$1.messages = [];
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
preconditions$1.messages.push(`${preconditions$1.messages.length + 1}. ${msg}`);
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
return msg;
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
static async checkAll() {
|
|
1646
|
-
try {
|
|
1647
|
-
// for (let i = 0; i < preconditions.checkFunctions.length; i++) {
|
|
1648
|
-
// const f = preconditions.checkFunctions[i];
|
|
1649
|
-
// // preconditions.addCheckPromise(f.check(f.args));
|
|
1650
|
-
// preconditions.pushMessage(await f.check(f.args));
|
|
1651
|
-
// }
|
|
1652
|
-
while (preconditions$1.checkFunctions.length > 0) {
|
|
1653
|
-
const f = preconditions$1.checkFunctions.shift();
|
|
1654
|
-
|
|
1655
|
-
if (preconditions$1.pushMessage(await f.check(f.args)) && f.blocked) {
|
|
1656
|
-
break;
|
|
1657
|
-
}
|
|
1658
|
-
} // for (let i = 0; i < preconditions.checkPromises.length; i++) {
|
|
1659
|
-
// preconditions.pushMessage(await preconditions.checkPromises[i]);
|
|
1660
|
-
// }
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
while (preconditions$1.checkPromises.length > 0) {
|
|
1664
|
-
const p = preconditions$1.checkPromises.shift();
|
|
1665
|
-
preconditions$1.pushMessage(await p);
|
|
1666
|
-
}
|
|
1667
|
-
} catch (e) {
|
|
1668
|
-
preconditions$1.pushMessage(e.message);
|
|
1669
|
-
}
|
|
1670
|
-
|
|
1671
|
-
let text = "";
|
|
1672
|
-
|
|
1673
|
-
if (preconditions$1.messages) {
|
|
1674
|
-
text = `*** 由于以下原因,${preconditions$1.appName} 尚不能正常提供服务:\n\n` + preconditions$1.messages.join("\n\n") + "\n\n*** 请检查以上各项条件,修复后重新启动服务";
|
|
1675
|
-
console.log("\n" + text); // for (let i = 0; i < preconditions.messages.length; i++) {
|
|
1676
|
-
// console.log(preconditions.messages[i]);
|
|
1677
|
-
// }
|
|
1531
|
+
res.set('WWW-Authenticate', `Basic realm=validate fail`);
|
|
1532
|
+
}
|
|
1533
|
+
return res.status(e.status || 500).send(e.error || e);
|
|
1678
1534
|
}
|
|
1535
|
+
next();
|
|
1536
|
+
}
|
|
1679
1537
|
|
|
1680
|
-
|
|
1681
|
-
await fs.async_mkdir("../log");
|
|
1682
|
-
}
|
|
1538
|
+
//#endregion
|
|
1683
1539
|
|
|
1684
|
-
|
|
1685
|
-
return !text;
|
|
1686
|
-
} // 检查器
|
|
1540
|
+
//region ====一些通用服务功能
|
|
1687
1541
|
|
|
1688
1542
|
/**
|
|
1689
|
-
*
|
|
1543
|
+
* 获取配置数据
|
|
1544
|
+
* @param options
|
|
1545
|
+
* @returns {Promise<boolean|*>}
|
|
1690
1546
|
*/
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1547
|
+
// api/config/appSetting.ossEnabled
|
|
1548
|
+
static async getConfigValue(options) {
|
|
1549
|
+
configNeeded();
|
|
1550
|
+
const params = options.replacements;
|
|
1551
|
+
let cfgItem = params._cfgItem;
|
|
1552
|
+
delete params._cfgItem;
|
|
1553
|
+
if (await apiUtil$2.checkForwardsHost(options)) return true;
|
|
1554
|
+
let c = apiUtil$2.parseCfgPath(cfgItem);
|
|
1555
|
+
delete c.parent;
|
|
1556
|
+
c.host = ppUtil$3.getMyIp();
|
|
1557
|
+
return c;
|
|
1695
1558
|
}
|
|
1696
|
-
/**
|
|
1697
|
-
* redis 可用性检查
|
|
1698
|
-
*/
|
|
1699
|
-
|
|
1700
1559
|
|
|
1701
|
-
static async checkRedis() {
|
|
1702
|
-
return await checkRedis();
|
|
1703
|
-
}
|
|
1704
1560
|
/**
|
|
1705
|
-
*
|
|
1561
|
+
* 设置配置数据
|
|
1562
|
+
* @param options
|
|
1563
|
+
* @returns {Promise<*>}
|
|
1706
1564
|
*/
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1565
|
+
static async setConfigValue(options) {
|
|
1566
|
+
configNeeded();
|
|
1567
|
+
const params = options.replacements;
|
|
1568
|
+
let cfgItem = params._cfgItem;
|
|
1569
|
+
delete params._cfgItem;
|
|
1570
|
+
// if (await checkForwardsHost(options))
|
|
1571
|
+
// return true;
|
|
1572
|
+
await apiUtil$2.parametersOK(params, "value");
|
|
1573
|
+
let c = apiUtil$2.parseCfgPath(cfgItem);
|
|
1574
|
+
if (typeof c.value === "object") {
|
|
1575
|
+
throw [err$1.ACCESS_REFUSED, `暂不支持修改复杂配置`];
|
|
1576
|
+
}
|
|
1577
|
+
// c.oldValue = c.value;
|
|
1578
|
+
c.newValue = params.value;
|
|
1579
|
+
c.parent[c.key] = c.newValue;
|
|
1580
|
+
delete c.parent;
|
|
1581
|
+
c.host = ppUtil$3.getMyIp();
|
|
1582
|
+
return c;
|
|
1583
|
+
// 应用层自行处理多机同步
|
|
1711
1584
|
}
|
|
1585
|
+
|
|
1712
1586
|
/**
|
|
1713
|
-
*
|
|
1587
|
+
* 修改重启标志文件
|
|
1588
|
+
* 前提,PM2监视 restart,please.flag 文件,此文件若被修改则重启服务进程
|
|
1589
|
+
* 此服务假设 restart,please.flag 文件最后一行是一个整数,此整数+1后保存
|
|
1590
|
+
* @param options
|
|
1591
|
+
* @returns {Promise<number>}
|
|
1714
1592
|
*/
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
// }
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
|
-
async function createEnvSettingFile(fileName, lastEnvSettingEx) {
|
|
1730
|
-
try {
|
|
1731
|
-
const cfgText = await ppUtil$3.doCreateEnvSettingFile(fileName, lastEnvSettingEx);
|
|
1732
|
-
|
|
1733
|
-
if (cfgText.indexOf(`cfgVersion: "${conf$2._envSetting.cfgVersion}"`) > 0) {
|
|
1734
|
-
console.log(`\n*** 已創建新的本機環境配置文件\n${fileName}\n请檢查各項內容是否正确(此项更新服务可正常运行)\n\n`);
|
|
1735
|
-
return "";
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
return `已創建新的本機環境配置文件\n${fileName}\n请檢查並正確設置各項內容,然後將配置版本號修改為${conf$2._envSettings.default.cfgVersion}`;
|
|
1739
|
-
} catch (e) {
|
|
1740
|
-
return `創建本機環境配置文件失敗\n《${fileName}》\n${err$1.ERROR(e).message}`;
|
|
1593
|
+
static async updateRestartFlag(options) {
|
|
1594
|
+
const fileName = `restart,please.flag`;
|
|
1595
|
+
let text = await fs.async_readFile(fileName, 'utf8');
|
|
1596
|
+
const lines = text.split('\r\n');
|
|
1597
|
+
const n = +lines[lines.length - 1] + 1;
|
|
1598
|
+
lines[lines.length - 1] = ' '.repeat(50) + n.toString();
|
|
1599
|
+
text = lines.join('\r\n');
|
|
1600
|
+
await fs.async_writeFile(fileName, text);
|
|
1601
|
+
return n;
|
|
1741
1602
|
}
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
async function checkExEnvSetting(loadjs) {
|
|
1745
|
-
if (conf$2._envSetting.localSettingImported) return "";
|
|
1746
|
-
|
|
1747
|
-
try {
|
|
1748
|
-
let fileName = conf$2.getEnvSettingFileName();
|
|
1749
|
-
|
|
1750
|
-
if (!fs.existsSync(fileName)) {
|
|
1751
|
-
return await createEnvSettingFile(fileName);
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
let envSettingEx = loadjs(fileName);
|
|
1755
|
-
|
|
1756
|
-
if (envSettingEx.cfgVersion !== conf$2._envSettings.default.cfgVersion) {
|
|
1757
|
-
if (envSettingEx.cfgVersion !== "0.0") {
|
|
1758
|
-
let fp = path.parse(fileName);
|
|
1759
|
-
let lastVerFileName = path.join(fp.dir, fp.name + envSettingEx.cfgVersion + fp.ext);
|
|
1760
|
-
|
|
1761
|
-
if (!fs.existsSync(lastVerFileName)) {
|
|
1762
|
-
fs.renameSync(fileName, lastVerFileName);
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
let msg = await createEnvSettingFile(fileName, envSettingEx);
|
|
1767
|
-
|
|
1768
|
-
if (msg) {
|
|
1769
|
-
return msg;
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
delete require.cache[fileName];
|
|
1773
|
-
}
|
|
1774
1603
|
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1604
|
+
/**
|
|
1605
|
+
* 创建验证码对象
|
|
1606
|
+
* npm i svg-captcha
|
|
1607
|
+
* npm i svg2png
|
|
1608
|
+
*/
|
|
1609
|
+
static createSvgCaptcha(options) {
|
|
1610
|
+
const captcha = svgCaptcha.create({
|
|
1611
|
+
inverse: options.hasOwnProperty('inverse') ? options.inverse : false,
|
|
1612
|
+
fontSize: options.fontSize || 48,
|
|
1613
|
+
noise: options.noise || 2,
|
|
1614
|
+
width: options.width || 150,
|
|
1615
|
+
height: options.height || 75,
|
|
1616
|
+
size: options.size || 4,
|
|
1617
|
+
charPreset: options.charPreset || '0123456789',
|
|
1618
|
+
ignoreChars: options.ignoreChars || '0oli',
|
|
1619
|
+
color: options.hasOwnProperty('color') ? options.color : true,
|
|
1620
|
+
background: options.background || '#cc9966'
|
|
1621
|
+
});
|
|
1622
|
+
return captcha;
|
|
1778
1623
|
}
|
|
1779
|
-
} // async function checkDatabase() {
|
|
1780
|
-
// return dbCheck.check().then(info => info.updateMessage);
|
|
1781
|
-
// }
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
async function checkRedis() {
|
|
1785
|
-
if (!conf$2.redis.enabled) return "";
|
|
1786
|
-
const redis = ppRedis.newClient("kv"); // console.log(`checkRedis begin:`);
|
|
1787
|
-
|
|
1788
|
-
await ppUtil$3.wait(15 * 1000, param => {
|
|
1789
|
-
if (redis.ready && redis.connected || redis.error) {
|
|
1790
|
-
return true;
|
|
1791
|
-
}
|
|
1792
|
-
}).catch(e => {
|
|
1793
|
-
redis.error = e;
|
|
1794
|
-
});
|
|
1795
|
-
|
|
1796
|
-
if (redis.error) {
|
|
1797
|
-
console.log(`未能成功連接 redis: ${redis.error},請檢查相關設置`);
|
|
1798
|
-
return `未能成功連接 redis: ${redis.error},請檢查相關設置`;
|
|
1799
|
-
} // console.log(`checkRedis done:`);
|
|
1800
|
-
// console.log(redis);
|
|
1801
|
-
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1804
|
-
async function initDb() {
|
|
1805
|
-
try {
|
|
1806
|
-
dbUtil.config(conf$2, err$1);
|
|
1807
|
-
} catch (e) {
|
|
1808
|
-
if (e.reason === 'bad decrypt') {
|
|
1809
|
-
e = new Error(`解密数据库密码(${conf$2.dbconn.dbpwd})失败`);
|
|
1810
|
-
} // if (e.reason === 'bad decrypt') {
|
|
1811
|
-
// e = new Error(`解密Redis密码(${conf.redis.password})失败`);
|
|
1812
|
-
// }
|
|
1813
|
-
|
|
1814
1624
|
|
|
1815
|
-
|
|
1816
|
-
}
|
|
1625
|
+
//#endregion
|
|
1817
1626
|
}
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
kvStorage.setRedis(ppRedis.newClient("kv"));
|
|
1825
|
-
} else {
|
|
1826
|
-
kvStorage.setRedis(new redisSimulator(dbSql));
|
|
1827
|
-
}
|
|
1828
|
-
} catch (e) {
|
|
1829
|
-
// if (e.reason === 'bad decrypt') {
|
|
1830
|
-
// e = new Error(`解密Redis密码(${conf.redis.password})失败`);
|
|
1831
|
-
// }
|
|
1832
|
-
return `初始化键值对存储器失败(${e.message})`;
|
|
1627
|
+
function configNeeded() {
|
|
1628
|
+
if (!conf$2 || !err$1) {
|
|
1629
|
+
ppUtil$3.configNeeded();
|
|
1630
|
+
conf$2 = ppUtil$3.appConfig;
|
|
1631
|
+
appSetting = conf$2.appSetting;
|
|
1632
|
+
err$1 = ppUtil$3.appErrCfg;
|
|
1833
1633
|
}
|
|
1834
1634
|
}
|
|
1635
|
+
var ppUtilApi = apiUtil$2;
|
|
1835
1636
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1637
|
+
// 普通消息系统
|
|
1838
1638
|
// 若 redis 可用,则使用基于 redis 的消息订阅发布系统
|
|
1839
1639
|
// 若 redis 不可用,则将消息转发到其它主机
|
|
1840
1640
|
|
|
@@ -1844,49 +1644,39 @@ const {
|
|
|
1844
1644
|
const RedisMessenger = require$$1__default$2["default"];
|
|
1845
1645
|
const {
|
|
1846
1646
|
netUtil
|
|
1847
|
-
} = require$$
|
|
1647
|
+
} = require$$5__default["default"];
|
|
1848
1648
|
let conf$1;
|
|
1849
|
-
|
|
1850
1649
|
class commonMessenger$2 {
|
|
1851
1650
|
static myMsgAddr = "";
|
|
1852
1651
|
static redisMessenger = null;
|
|
1853
1652
|
static onMessage = [];
|
|
1854
|
-
|
|
1855
1653
|
static initMessenger(appConfig, appErrCfg, msgChannel) {
|
|
1856
1654
|
conf$1 = appConfig;
|
|
1857
1655
|
commonMessenger$2.redisMessenger = conf$1.redis.enabled ? new RedisMessenger(appConfig, appErrCfg, msgChannel).subscribe(msgChannel) : null;
|
|
1858
1656
|
commonMessenger$2.myMsgAddr = commonMessenger$2.getMyMsgAddr();
|
|
1859
1657
|
}
|
|
1860
|
-
|
|
1861
1658
|
static getMyMsgAddr() {
|
|
1862
1659
|
if (!conf$1.myMsgAddr) {
|
|
1863
1660
|
conf$1.pm_id = process.env.pm_id || "0";
|
|
1864
1661
|
let myIp = ppUtil$2.getMyIp();
|
|
1865
|
-
|
|
1866
1662
|
if (commonMessenger$2.redisMessenger) {
|
|
1867
1663
|
myIp = `${conf$1.pm_id}@${myIp}`;
|
|
1868
1664
|
}
|
|
1869
|
-
|
|
1870
1665
|
conf$1.myMsgAddr = myIp;
|
|
1871
1666
|
console.log(`myMsgAddr: `, conf$1.myMsgAddr);
|
|
1872
1667
|
}
|
|
1873
|
-
|
|
1874
1668
|
return conf$1.myMsgAddr;
|
|
1875
1669
|
}
|
|
1876
|
-
|
|
1877
|
-
static setMessageHandle(messageHandle) {
|
|
1670
|
+
static setMessageHandle(messageHandle, msgChannel) {
|
|
1878
1671
|
if (commonMessenger$2.redisMessenger) {
|
|
1879
1672
|
return commonMessenger$2.redisMessenger.setMessageHandle(messageHandle, msgChannel);
|
|
1880
1673
|
}
|
|
1881
|
-
|
|
1882
1674
|
if (commonMessenger$2.onMessage.indexOf(messageHandle) < 0) {
|
|
1883
1675
|
commonMessenger$2.onMessage.push(messageHandle);
|
|
1884
1676
|
}
|
|
1885
|
-
|
|
1886
1677
|
return commonMessenger$2;
|
|
1887
1678
|
}
|
|
1888
|
-
|
|
1889
|
-
static async publishMessage(message) {
|
|
1679
|
+
static async publishMessage(message, msgChannel) {
|
|
1890
1680
|
if (commonMessenger$2.redisMessenger) {
|
|
1891
1681
|
return commonMessenger$2.redisMessenger.publish(message, msgChannel);
|
|
1892
1682
|
} else {
|
|
@@ -1896,7 +1686,6 @@ class commonMessenger$2 {
|
|
|
1896
1686
|
} else {
|
|
1897
1687
|
for (let i = 0; i < conf$1.appSetting.serverHosts.length; i++) {
|
|
1898
1688
|
message.destAddr = conf$1.appSetting.serverHosts[i];
|
|
1899
|
-
|
|
1900
1689
|
if (message.destAddr !== conf$1.myMsgAddr) {
|
|
1901
1690
|
await forwardMessage(message);
|
|
1902
1691
|
}
|
|
@@ -1904,13 +1693,10 @@ class commonMessenger$2 {
|
|
|
1904
1693
|
}
|
|
1905
1694
|
}
|
|
1906
1695
|
}
|
|
1907
|
-
|
|
1908
1696
|
static async handleInternalMessage(options) {
|
|
1909
1697
|
const message = options.replacements;
|
|
1910
|
-
|
|
1911
1698
|
for (let i = 0; i < commonMessenger$2.onMessage.length; i++) {
|
|
1912
1699
|
const appMsgHandle = commonMessenger$2.onMessage[i];
|
|
1913
|
-
|
|
1914
1700
|
try {
|
|
1915
1701
|
await appMsgHandle(message);
|
|
1916
1702
|
} catch (e) {
|
|
@@ -1918,12 +1704,10 @@ class commonMessenger$2 {
|
|
|
1918
1704
|
}
|
|
1919
1705
|
}
|
|
1920
1706
|
}
|
|
1921
|
-
|
|
1922
1707
|
}
|
|
1923
|
-
|
|
1924
1708
|
async function forwardMessage(message) {
|
|
1925
1709
|
let reqOptions = {
|
|
1926
|
-
url: `https://${message.destAddr}:${appSetting.listenPort}/api/message`,
|
|
1710
|
+
url: `https://${message.destAddr}:${conf$1.appSetting.listenPort}/api/message`,
|
|
1927
1711
|
method: "POST",
|
|
1928
1712
|
data: message
|
|
1929
1713
|
};
|
|
@@ -1933,7 +1717,6 @@ async function forwardMessage(message) {
|
|
|
1933
1717
|
});
|
|
1934
1718
|
return res.data;
|
|
1935
1719
|
}
|
|
1936
|
-
|
|
1937
1720
|
var ppMessengerEx = commonMessenger$2;
|
|
1938
1721
|
|
|
1939
1722
|
/**
|
|
@@ -1947,11 +1730,11 @@ const {
|
|
|
1947
1730
|
const apiUtil$1 = ppUtilApi;
|
|
1948
1731
|
const commonMessenger$1 = ppMessengerEx;
|
|
1949
1732
|
const MT_SCHEDULE_STATE = 'schedule-state',
|
|
1950
|
-
|
|
1733
|
+
MT_SCHEDULE_STATE_REPLY = 'schedule-state-reply';
|
|
1951
1734
|
let conf, err;
|
|
1952
|
-
|
|
1953
1735
|
class schedule$1 {
|
|
1954
1736
|
static tasks = {};
|
|
1737
|
+
|
|
1955
1738
|
/**
|
|
1956
1739
|
* 注册一个计划任务
|
|
1957
1740
|
* @param taskName
|
|
@@ -1961,18 +1744,15 @@ class schedule$1 {
|
|
|
1961
1744
|
* @param autoStart
|
|
1962
1745
|
* @returns {Promise<{}|{}|{cron: *, _message_: string}|any>}
|
|
1963
1746
|
*/
|
|
1964
|
-
|
|
1965
1747
|
static async registerTask(taskName, taskCaption, cronExp, taskFunc, autoStart) {
|
|
1966
1748
|
if (!this.envAllowed()) return {};
|
|
1967
1749
|
let task = this.findTask(taskName);
|
|
1968
|
-
|
|
1969
1750
|
if (task) {
|
|
1970
1751
|
if (task.cronExp !== cronExp || task.taskFunc !== taskFunc) {
|
|
1971
1752
|
this.stop(taskName);
|
|
1972
1753
|
task = null;
|
|
1973
1754
|
}
|
|
1974
1755
|
}
|
|
1975
|
-
|
|
1976
1756
|
if (!task) {
|
|
1977
1757
|
task = {
|
|
1978
1758
|
name: taskName,
|
|
@@ -1989,17 +1769,13 @@ class schedule$1 {
|
|
|
1989
1769
|
}
|
|
1990
1770
|
};
|
|
1991
1771
|
this.tasks[taskName] = task;
|
|
1992
|
-
|
|
1993
1772
|
if (autoStart) {
|
|
1994
1773
|
return await this.start(task);
|
|
1995
1774
|
}
|
|
1996
|
-
|
|
1997
1775
|
return this.getTaskInfo(task, "任务已注册。");
|
|
1998
1776
|
}
|
|
1999
|
-
|
|
2000
1777
|
return this.getTaskInfo(task, "任务已存在。");
|
|
2001
1778
|
}
|
|
2002
|
-
|
|
2003
1779
|
static getTaskInfo(task, msg) {
|
|
2004
1780
|
// return Object.assign({_message_: msg}, task);
|
|
2005
1781
|
return {
|
|
@@ -2010,75 +1786,62 @@ class schedule$1 {
|
|
|
2010
1786
|
_message_: msg
|
|
2011
1787
|
};
|
|
2012
1788
|
}
|
|
1789
|
+
|
|
2013
1790
|
/**
|
|
2014
1791
|
* 启动任务
|
|
2015
1792
|
* @param taskOrName
|
|
2016
1793
|
* @param cronExp
|
|
2017
1794
|
* @returns {Promise<{}|{cron: *, _message_: string}>}
|
|
2018
1795
|
*/
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
1796
|
static async start(taskOrName, cronExp) {
|
|
2022
1797
|
if (!this.envAllowed()) return {};
|
|
2023
1798
|
let task = taskOrName;
|
|
2024
|
-
|
|
2025
1799
|
if (typeof task === "string") {
|
|
2026
1800
|
task = this.findTask(taskOrName);
|
|
2027
1801
|
}
|
|
2028
|
-
|
|
2029
1802
|
if (!task) throw [err.INVALID_PARAM, `任务${taskOrName}不存在`];
|
|
2030
1803
|
cronExp = cronExp || task.cronExp;
|
|
2031
|
-
|
|
2032
1804
|
if (task.cronExp !== cronExp) {
|
|
2033
1805
|
this.stop(task);
|
|
2034
1806
|
task.cronExp = cronExp;
|
|
2035
1807
|
}
|
|
2036
|
-
|
|
2037
1808
|
if (task.schedule) {
|
|
2038
1809
|
return this.getTaskInfo(task, "任务已启动,无需重复启动。");
|
|
2039
1810
|
}
|
|
2040
|
-
|
|
2041
1811
|
task.schedule = CRON.schedule(cronExp, task.doScheduleTask);
|
|
2042
1812
|
task.schedule._task._pp_task = task;
|
|
2043
1813
|
return this.getTaskInfo(task, "任务已启动。");
|
|
2044
1814
|
}
|
|
1815
|
+
|
|
2045
1816
|
/**
|
|
2046
1817
|
* 停止任务
|
|
2047
1818
|
* @param taskOrName
|
|
2048
1819
|
* @returns {Promise<{}|{cron: *, _message_: string}|{_message_: string}>}
|
|
2049
1820
|
*/
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
1821
|
static async stop(taskOrName) {
|
|
2053
1822
|
if (!this.envAllowed()) return {};
|
|
2054
1823
|
let task = taskOrName;
|
|
2055
|
-
|
|
2056
1824
|
if (typeof task === "string") {
|
|
2057
1825
|
task = this.findTask(taskOrName);
|
|
2058
1826
|
}
|
|
2059
|
-
|
|
2060
1827
|
if (!task) throw [err.INVALID_PARAM, `任务${taskOrName}不存在`];
|
|
2061
|
-
|
|
2062
1828
|
if (task.schedule) {
|
|
2063
1829
|
task.schedule.stop();
|
|
2064
1830
|
task.schedule = null;
|
|
2065
1831
|
return this.getTaskInfo(task, "任务已停止。");
|
|
2066
1832
|
}
|
|
2067
|
-
|
|
2068
1833
|
return this.getTaskInfo(task, "任务未启动,无需停止。");
|
|
2069
1834
|
}
|
|
1835
|
+
|
|
2070
1836
|
/**
|
|
2071
1837
|
* 获取或设置当前状态(来自远程的API调用)
|
|
2072
1838
|
* @param options
|
|
2073
1839
|
* @returns {Promise<unknown>}
|
|
2074
1840
|
*/
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
1841
|
static async state(options) {
|
|
2078
|
-
const params = options.replacements;
|
|
2079
|
-
|
|
1842
|
+
const params = options.replacements;
|
|
1843
|
+
// await commonMessenger.parametersOK(params, "taskName");
|
|
2080
1844
|
const req = options._res.req;
|
|
2081
|
-
|
|
2082
1845
|
if (req) {
|
|
2083
1846
|
if (req.method === 'GET') {
|
|
2084
1847
|
delete params.state;
|
|
@@ -2086,16 +1849,15 @@ class schedule$1 {
|
|
|
2086
1849
|
await apiUtil$1.parametersOK(params, 'taskName', "state");
|
|
2087
1850
|
}
|
|
2088
1851
|
}
|
|
2089
|
-
|
|
2090
1852
|
if (this.envAllowed()) {
|
|
2091
1853
|
return this._state(params);
|
|
2092
|
-
}
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
// 环境变量启用计划任务,但当前环境不能执行,
|
|
2093
1857
|
// 说明收到此API请求的进程不是第一个进程,或者此前服务器不是第一台服务器,
|
|
2094
1858
|
// 这种情况下,将此请求作为消息发布出去,
|
|
2095
1859
|
// 第一台服务器的第一个进程收到消息后进行处理,再将结果作为消息发布,
|
|
2096
1860
|
// 本进程收到处理结果后果作为响应发送回客户端
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
1861
|
if (process.env.SCHEDULE_ENABLED) {
|
|
2100
1862
|
let replyId = ppUtil$1.newGuid();
|
|
2101
1863
|
return await new Promise((resolve, reject) => {
|
|
@@ -2105,7 +1867,6 @@ class schedule$1 {
|
|
|
2105
1867
|
resolve(message.result);
|
|
2106
1868
|
return;
|
|
2107
1869
|
}
|
|
2108
|
-
|
|
2109
1870
|
if (message._type === MT_SCHEDULE_STATE) {
|
|
2110
1871
|
if (schedule$1.enabled()) {
|
|
2111
1872
|
message.result = schedule$1._state(message.params);
|
|
@@ -2131,21 +1892,17 @@ class schedule$1 {
|
|
|
2131
1892
|
}, 2 * 60 * 1000);
|
|
2132
1893
|
});
|
|
2133
1894
|
}
|
|
2134
|
-
|
|
2135
1895
|
return {
|
|
2136
1896
|
_message_: "此环境无自动任务"
|
|
2137
1897
|
};
|
|
2138
1898
|
}
|
|
2139
|
-
|
|
2140
1899
|
static async _state(params) {
|
|
2141
1900
|
let apiResult = {};
|
|
2142
1901
|
let task;
|
|
2143
|
-
|
|
2144
1902
|
if (params.taskName) {
|
|
2145
1903
|
task = this.findTask(params.taskName);
|
|
2146
1904
|
if (!task) throw [err.INVALID_PARAM, `任务${params.taskName}不存在`];
|
|
2147
1905
|
}
|
|
2148
|
-
|
|
2149
1906
|
if (params.state) {
|
|
2150
1907
|
if ("started" === params.state) {
|
|
2151
1908
|
apiResult = await this.start(task, params.cron);
|
|
@@ -2154,62 +1911,52 @@ class schedule$1 {
|
|
|
2154
1911
|
} else {
|
|
2155
1912
|
throw [err.INVALID_PARAM, `(${params.state}), 只能是 started/stopped`];
|
|
2156
1913
|
}
|
|
2157
|
-
|
|
2158
1914
|
if (params.runOnce) {
|
|
2159
1915
|
task = this.findTask(params.taskName);
|
|
2160
|
-
apiResult._message_ += "\n正在手动执行任务";
|
|
2161
|
-
|
|
1916
|
+
apiResult._message_ += "\n正在手动执行任务";
|
|
1917
|
+
// await
|
|
2162
1918
|
task.doScheduleTask();
|
|
2163
1919
|
}
|
|
2164
|
-
|
|
2165
1920
|
return this.getTaskInfo(task, apiResult._message_);
|
|
2166
1921
|
}
|
|
2167
|
-
|
|
2168
1922
|
if (task) {
|
|
2169
1923
|
return this.getTaskInfo(task);
|
|
2170
1924
|
}
|
|
2171
|
-
|
|
2172
1925
|
const result = [];
|
|
2173
|
-
|
|
2174
1926
|
for (let k in this.tasks) {
|
|
2175
1927
|
result.push(this.getTaskInfo(this.tasks[k]));
|
|
2176
1928
|
}
|
|
2177
|
-
|
|
2178
1929
|
return result;
|
|
2179
1930
|
}
|
|
2180
|
-
|
|
2181
1931
|
static deleteTask(taskName) {
|
|
2182
1932
|
delete this.tasks[taskName];
|
|
2183
1933
|
}
|
|
2184
|
-
|
|
2185
1934
|
static findTask(taskName) {
|
|
2186
1935
|
return this.tasks[taskName];
|
|
2187
1936
|
}
|
|
1937
|
+
|
|
2188
1938
|
/**
|
|
2189
1939
|
* 确定当前进程环境是否启用自动任务
|
|
2190
1940
|
*/
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
1941
|
static envAllowed() {
|
|
2194
1942
|
if (!conf) {
|
|
2195
1943
|
ppUtil$1.configNeeded();
|
|
2196
1944
|
conf = ppUtil$1.appConfig;
|
|
2197
1945
|
err = ppUtil$1.appErrCfg;
|
|
2198
1946
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
!!process.env.SCHEDULE_ENABLED
|
|
2202
|
-
|
|
1947
|
+
let enabled =
|
|
1948
|
+
// PM2配置中指定了环境变量 SCHEDULE_ENABLED
|
|
1949
|
+
!!process.env.SCHEDULE_ENABLED
|
|
1950
|
+
// 如果PM2启动了多个进程,则只在第一个进程执行
|
|
1951
|
+
&& process.env.NODE_APP_INSTANCE === '0';
|
|
1952
|
+
// // 如果有多台服务器,则只在第一台执行
|
|
2203
1953
|
// if (enabled && conf.appSetting.serverHosts && (conf.appSetting.serverHosts.length > 1)) {
|
|
2204
1954
|
// enabled = conf.myMsgAddr.indexOf(conf.appSetting.serverHosts[0]) === 0;
|
|
2205
1955
|
// }
|
|
2206
1956
|
// todo: 暂时取消此限制,要通过配置设定
|
|
2207
|
-
|
|
2208
1957
|
return enabled;
|
|
2209
1958
|
}
|
|
2210
|
-
|
|
2211
1959
|
}
|
|
2212
|
-
|
|
2213
1960
|
var ppSchedule = schedule$1;
|
|
2214
1961
|
|
|
2215
1962
|
const apiUtil = ppUtilApi;
|