abler-api 0.1.26 → 0.1.29
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 +459 -238
- package/dist/es/pp-util.js +455 -236
- package/package.json +1 -1
package/dist/es/pp-util.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import require$$0
|
|
1
|
+
import require$$0 from 'crypto';
|
|
2
2
|
import require$$1 from 'abler-util';
|
|
3
3
|
import require$$2 from 'abler-db';
|
|
4
4
|
import require$$3 from 'abler-net';
|
|
5
|
-
import require$$
|
|
5
|
+
import require$$4 from 'fs';
|
|
6
6
|
import require$$1$1 from 'path';
|
|
7
|
+
import require$$1$2 from 'abler-messenger';
|
|
8
|
+
import require$$0$1 from 'node-cron';
|
|
7
9
|
|
|
8
|
-
const crypto = require$$0
|
|
10
|
+
const crypto = require$$0;
|
|
9
11
|
const ppUtil$4 = require$$1.ppUtil;
|
|
10
12
|
const {
|
|
11
13
|
dbUtil,
|
|
12
14
|
kvStorage
|
|
13
15
|
} = require$$2;
|
|
14
16
|
const netUtil$1 = require$$3;
|
|
15
|
-
|
|
17
|
+
const fs$1 = require$$4;
|
|
18
|
+
let conf$3, appSetting$1, err$2, dbSql;
|
|
16
19
|
const pnToken = "access_token",
|
|
17
20
|
hnToken = pnToken,
|
|
18
21
|
pnApiKey = "apiKey",
|
|
@@ -23,7 +26,7 @@ pnApiSecret = "apiSecret",
|
|
|
23
26
|
const MD5 = ppUtil$4.MD5,
|
|
24
27
|
moveProperty = ppUtil$4.moveProperty;
|
|
25
28
|
|
|
26
|
-
class apiUtil$
|
|
29
|
+
class apiUtil$2 {
|
|
27
30
|
static debugFlag = ppUtil$4.newGuid(); //应用必须设置,否则谁也不知道是啥
|
|
28
31
|
|
|
29
32
|
static testFlag = ppUtil$4.newGuid();
|
|
@@ -31,11 +34,11 @@ class apiUtil$1 {
|
|
|
31
34
|
|
|
32
35
|
static config(appConfig, appErrCfg, appDbSql) {
|
|
33
36
|
ppUtil$4.config(appConfig, appErrCfg);
|
|
34
|
-
conf$
|
|
35
|
-
appSetting$1 = conf$
|
|
36
|
-
err$
|
|
37
|
-
apiUtil$
|
|
38
|
-
apiUtil$
|
|
37
|
+
conf$3 = appConfig;
|
|
38
|
+
appSetting$1 = conf$3?.appSetting;
|
|
39
|
+
err$2 = appErrCfg, dbSql = appDbSql;
|
|
40
|
+
apiUtil$2.debugFlag = appSetting$1?.debugFlag || apiUtil$2.debugFlag;
|
|
41
|
+
apiUtil$2.testFlag = appSetting$1?.testFlag || apiUtil$2.testFlag; // apiUtil.apiCallRecSaver = apiCallRecSaver;
|
|
39
42
|
} //#region ===== 需要应用系统重写的方法
|
|
40
43
|
|
|
41
44
|
/**
|
|
@@ -123,7 +126,7 @@ class apiUtil$1 {
|
|
|
123
126
|
req._requestParams = Object.assign(req.params, req._requestParams);
|
|
124
127
|
}
|
|
125
128
|
|
|
126
|
-
apiUtil$
|
|
129
|
+
apiUtil$2.setParamsFunctions(req._requestParams);
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
return req._requestParams;
|
|
@@ -134,11 +137,11 @@ class apiUtil$1 {
|
|
|
134
137
|
return req.tokenData;
|
|
135
138
|
}
|
|
136
139
|
|
|
137
|
-
let params = apiUtil$
|
|
140
|
+
let params = apiUtil$2.extractParams(req);
|
|
138
141
|
let tokenData = {
|
|
139
142
|
apiKey: req.headers[hnApiKey] || params[pnApiKey],
|
|
140
143
|
apiSecret: req.headers[hnApiSecret] || params[pnApiSecret],
|
|
141
|
-
clientIp: apiUtil$
|
|
144
|
+
clientIp: apiUtil$2.getClientIp(req)
|
|
142
145
|
};
|
|
143
146
|
return tokenData;
|
|
144
147
|
}
|
|
@@ -155,7 +158,7 @@ class apiUtil$1 {
|
|
|
155
158
|
let result = +this[name];
|
|
156
159
|
|
|
157
160
|
if (typeof result !== "number" || result < minValue || result > maxValue) {
|
|
158
|
-
throw [err$
|
|
161
|
+
throw [err$2.INVALID_PARAM, `参数 ${name} 必须是 ${minValue} ~ ${maxValue} 之间的数字`];
|
|
159
162
|
}
|
|
160
163
|
|
|
161
164
|
return result;
|
|
@@ -225,7 +228,7 @@ class apiUtil$1 {
|
|
|
225
228
|
|
|
226
229
|
static apiFail(error, req) {
|
|
227
230
|
configNeeded();
|
|
228
|
-
let response = err$
|
|
231
|
+
let response = err$2.ERROR(error, err$2.errorLangParamFlag + ppUtil$4.getMsgLang(req));
|
|
229
232
|
response.datetime = new Date();
|
|
230
233
|
|
|
231
234
|
if (req && req.headers) {
|
|
@@ -247,8 +250,8 @@ class apiUtil$1 {
|
|
|
247
250
|
|
|
248
251
|
|
|
249
252
|
static spoApiSucc(data, req) {
|
|
250
|
-
let params = apiUtil$
|
|
251
|
-
return apiUtil$
|
|
253
|
+
let params = apiUtil$2.extractParams(req);
|
|
254
|
+
return apiUtil$2.apiSuccess(data, req, params.spOrderNum);
|
|
252
255
|
}
|
|
253
256
|
/**
|
|
254
257
|
* 生成面向服务商的API失败返回结果
|
|
@@ -259,8 +262,8 @@ class apiUtil$1 {
|
|
|
259
262
|
|
|
260
263
|
|
|
261
264
|
static spoApiFail(error, req) {
|
|
262
|
-
let params = apiUtil$
|
|
263
|
-
return apiUtil$
|
|
265
|
+
let params = apiUtil$2.extractParams(req);
|
|
266
|
+
return apiUtil$2.apiFail(error, req, params.spOrderNum);
|
|
264
267
|
}
|
|
265
268
|
/**
|
|
266
269
|
* API 服务结束,发送响应
|
|
@@ -297,10 +300,10 @@ class apiUtil$1 {
|
|
|
297
300
|
static async responseOf(response, promise) {
|
|
298
301
|
promise.then(function (data) {
|
|
299
302
|
// console.log('RES:', apiSuccess(data));
|
|
300
|
-
if (!response.finished) response.send(apiUtil$
|
|
303
|
+
if (!response.finished) response.send(apiUtil$2.apiSuccess(data, response.req));
|
|
301
304
|
}, function (error) {
|
|
302
305
|
console.log('ERROR:', error);
|
|
303
|
-
if (!response.finished) response.send(apiUtil$
|
|
306
|
+
if (!response.finished) response.send(apiUtil$2.apiFail(error, response.req));
|
|
304
307
|
});
|
|
305
308
|
}
|
|
306
309
|
/**
|
|
@@ -312,16 +315,16 @@ class apiUtil$1 {
|
|
|
312
315
|
|
|
313
316
|
static async spoApiResponse(response, promise) {
|
|
314
317
|
promise.then(function (result) {
|
|
315
|
-
let responseData = apiUtil$
|
|
318
|
+
let responseData = apiUtil$2.spoApiSucc(result, response.req);
|
|
316
319
|
|
|
317
|
-
apiUtil$
|
|
320
|
+
apiUtil$2._saveApiCallRec(response.req.apiCallRec, responseData);
|
|
318
321
|
|
|
319
322
|
if (!response.finished) response.send(responseData);
|
|
320
323
|
}, function (error) {
|
|
321
324
|
console.log('ERROR:', error);
|
|
322
|
-
let responseData = apiUtil$
|
|
325
|
+
let responseData = apiUtil$2.spoApiFail(error, response.req);
|
|
323
326
|
|
|
324
|
-
apiUtil$
|
|
327
|
+
apiUtil$2._saveApiCallRec(response.req.apiCallRec, responseData);
|
|
325
328
|
|
|
326
329
|
if (!response.finished) response.send(responseData);
|
|
327
330
|
});
|
|
@@ -338,7 +341,7 @@ class apiUtil$1 {
|
|
|
338
341
|
req.headers.timestamp = new Date().valueOf(); // let options = {replacements: {}};
|
|
339
342
|
|
|
340
343
|
let options = {};
|
|
341
|
-
let parameters = apiUtil$
|
|
344
|
+
let parameters = apiUtil$2.extractParams(req);
|
|
342
345
|
|
|
343
346
|
for (let qryParam in parameters) {
|
|
344
347
|
if (qryParam !== 'token') {
|
|
@@ -370,7 +373,7 @@ class apiUtil$1 {
|
|
|
370
373
|
// }
|
|
371
374
|
|
|
372
375
|
options.userInfo = req.userInfo;
|
|
373
|
-
return apiUtil$
|
|
376
|
+
return apiUtil$2.setOptionsPropFuncions(options, res);
|
|
374
377
|
}
|
|
375
378
|
/**
|
|
376
379
|
* 为API请求 options 设置属性
|
|
@@ -435,7 +438,7 @@ class apiUtil$1 {
|
|
|
435
438
|
let token = req.headers[hnToken] || req.headers['x-access-token']; //向后兼容
|
|
436
439
|
|
|
437
440
|
if (!token) {
|
|
438
|
-
let params = apiUtil$
|
|
441
|
+
let params = apiUtil$2.extractParams(req);
|
|
439
442
|
token = params[pnToken];
|
|
440
443
|
|
|
441
444
|
if (token) {
|
|
@@ -446,12 +449,12 @@ class apiUtil$1 {
|
|
|
446
449
|
delete params.token;
|
|
447
450
|
} else {
|
|
448
451
|
// 如果没有token,则返回错误
|
|
449
|
-
console.log(err$
|
|
452
|
+
console.log(err$2.TOKEN_NEEDED);
|
|
450
453
|
|
|
451
454
|
if (res) {
|
|
452
|
-
res.send(err$
|
|
455
|
+
res.send(err$2.ERROR(err$2.TOKEN_NEEDED));
|
|
453
456
|
} else if (!noErr) {
|
|
454
|
-
throw err$
|
|
457
|
+
throw err$2.TOKEN_NEEDED;
|
|
455
458
|
}
|
|
456
459
|
}
|
|
457
460
|
}
|
|
@@ -470,8 +473,8 @@ class apiUtil$1 {
|
|
|
470
473
|
|
|
471
474
|
static async checkInternalToken(req) {
|
|
472
475
|
// return await checkInternalToken(req);
|
|
473
|
-
const params = apiUtil$
|
|
474
|
-
req.accessToken = req.accessToken || apiUtil$
|
|
476
|
+
const params = apiUtil$2.extractParams(req);
|
|
477
|
+
req.accessToken = req.accessToken || apiUtil$2.extractToken(req);
|
|
475
478
|
|
|
476
479
|
if (req.accessToken === MD5(ppUtil$4.idNumDisturbing)) {
|
|
477
480
|
//todo: 检查IP
|
|
@@ -494,7 +497,7 @@ class apiUtil$1 {
|
|
|
494
497
|
return true;
|
|
495
498
|
} else {
|
|
496
499
|
// console.log('token error.', req.accessToken);
|
|
497
|
-
throw err$
|
|
500
|
+
throw err$2.TOKEN_INVALID;
|
|
498
501
|
}
|
|
499
502
|
}
|
|
500
503
|
/**
|
|
@@ -505,16 +508,16 @@ class apiUtil$1 {
|
|
|
505
508
|
|
|
506
509
|
|
|
507
510
|
static async checkRequestToken(req) {
|
|
508
|
-
req.accessToken = req.accessToken || apiUtil$
|
|
509
|
-
const tokenKey = apiUtil$
|
|
510
|
-
const expireTime = apiUtil$
|
|
511
|
-
return await apiUtil$
|
|
512
|
-
req.userInfo = apiUtil$
|
|
511
|
+
req.accessToken = req.accessToken || apiUtil$2.extractToken(req);
|
|
512
|
+
const tokenKey = apiUtil$2.userTokenStoreKey(req.accessToken);
|
|
513
|
+
const expireTime = apiUtil$2.tokenExpireTime(req);
|
|
514
|
+
return await apiUtil$2.restoreTokenData(tokenKey, expireTime).then(async function (data) {
|
|
515
|
+
req.userInfo = apiUtil$2.setUserIdNo(data, data._idNo);
|
|
513
516
|
if (req.tokenValidater) await req.tokenValidater(req.userInfo, req);
|
|
514
517
|
return true;
|
|
515
518
|
}, async function (e) {
|
|
516
519
|
// 如果给定的token不存在,看看是不是平台内部调用
|
|
517
|
-
return await apiUtil$
|
|
520
|
+
return await apiUtil$2.checkInternalToken(req);
|
|
518
521
|
});
|
|
519
522
|
}
|
|
520
523
|
/**
|
|
@@ -526,7 +529,7 @@ class apiUtil$1 {
|
|
|
526
529
|
|
|
527
530
|
static isDebugMode(req) {
|
|
528
531
|
if (req.__debug__ === undefined) {
|
|
529
|
-
let dbgToken = req.headers['__debug__'] || req.headers[apiUtil$
|
|
532
|
+
let dbgToken = req.headers['__debug__'] || req.headers[apiUtil$2.debugFlag];
|
|
530
533
|
|
|
531
534
|
if (dbgToken) {
|
|
532
535
|
let envId = process.env.ECS_DEPLOY_ID;
|
|
@@ -548,11 +551,11 @@ class apiUtil$1 {
|
|
|
548
551
|
|
|
549
552
|
static isTestMode(req) {
|
|
550
553
|
if (req.__postman__ === undefined) {
|
|
551
|
-
let dbgToken = req.headers["__postman__"] || req.headers[apiUtil$
|
|
554
|
+
let dbgToken = req.headers["__postman__"] || req.headers[apiUtil$2.testFlag];
|
|
552
555
|
|
|
553
556
|
if (dbgToken) {
|
|
554
557
|
let envId = process.env.ECS_DEPLOY_ID;
|
|
555
|
-
let testToken = MD5(req.headers.timestamp, apiUtil$
|
|
558
|
+
let testToken = MD5(req.headers.timestamp, apiUtil$2.extractToken(req, null, true) || req.headers.apikey);
|
|
556
559
|
req.__postman__ = dbgToken === testToken && (envId.indexOf("myfacesign.com") < 0 || envId.indexOf(".dev.") > 0);
|
|
557
560
|
} else {
|
|
558
561
|
req.__postman__ = false;
|
|
@@ -569,7 +572,7 @@ class apiUtil$1 {
|
|
|
569
572
|
|
|
570
573
|
|
|
571
574
|
static tokenExpireTime(req) {
|
|
572
|
-
return apiUtil$
|
|
575
|
+
return apiUtil$2.isDebugMode(req) ? 30 * 24 * 60 * 60 : apiUtil$2.isTestMode(req) ? 4 * 60 * 60 : appSetting$1.tokenExpireTime;
|
|
573
576
|
}
|
|
574
577
|
/**
|
|
575
578
|
* 获取用户令牌保存键
|
|
@@ -612,7 +615,7 @@ class apiUtil$1 {
|
|
|
612
615
|
static setUserIdNo(userInfo, idNum) {
|
|
613
616
|
if (userInfo && idNum) {
|
|
614
617
|
userInfo._idNo = idNum;
|
|
615
|
-
userInfo.isHKIC = apiUtil$
|
|
618
|
+
userInfo.isHKIC = apiUtil$2.checkIsHKIC(idNum);
|
|
616
619
|
}
|
|
617
620
|
|
|
618
621
|
return userInfo;
|
|
@@ -629,7 +632,7 @@ class apiUtil$1 {
|
|
|
629
632
|
|
|
630
633
|
static async storeToken(token, tokenData, dataId, req) {
|
|
631
634
|
// let timeout = tokenData.clientIp.substring(0, 8) == "192.168." ? 90 * 24 : 1;
|
|
632
|
-
let timeout = apiUtil$
|
|
635
|
+
let timeout = apiUtil$2.tokenExpireTime(req);
|
|
633
636
|
|
|
634
637
|
if (req.certPublicKey) {
|
|
635
638
|
tokenData.certPublicKey = req.certPublicKey;
|
|
@@ -777,7 +780,7 @@ class apiUtil$1 {
|
|
|
777
780
|
return certInfo;
|
|
778
781
|
}).catch(e => {
|
|
779
782
|
console.log('获取企业证书失败:\n', e);
|
|
780
|
-
throw [err$
|
|
783
|
+
throw [err$2.ACCESS_REFUSED, `获取企业证书失败:${err$2.ERROR(e).message}`];
|
|
781
784
|
});
|
|
782
785
|
}
|
|
783
786
|
/**
|
|
@@ -791,27 +794,27 @@ class apiUtil$1 {
|
|
|
791
794
|
static async verifyApiSignature(tokenData, req) {
|
|
792
795
|
try {
|
|
793
796
|
if (!req.headers.timestamp) {
|
|
794
|
-
throw [err$
|
|
797
|
+
throw [err$2.ACCESS_REFUSED, `必须在请求头中设置时戳`];
|
|
795
798
|
}
|
|
796
799
|
|
|
797
800
|
let timestamp = parseInt(req.headers.timestamp);
|
|
798
801
|
let currentTime = new Date().valueOf();
|
|
799
|
-
let maxTimeDiff = apiUtil$
|
|
802
|
+
let maxTimeDiff = apiUtil$2.isDebugMode(req) ? 7 * 24 * 3600 : apiUtil$2.isTestMode(req) ? 4 * 3600 : 100; // 100
|
|
800
803
|
|
|
801
804
|
if (timestamp.toString() == "NaN" || currentTime < timestamp - 5000 || currentTime - timestamp > maxTimeDiff * 1000) {
|
|
802
|
-
throw [err$
|
|
805
|
+
throw [err$2.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
|
|
803
806
|
}
|
|
804
807
|
|
|
805
808
|
let signature = req.headers.signature;
|
|
806
809
|
|
|
807
810
|
if (!signature) {
|
|
808
|
-
throw [err$
|
|
811
|
+
throw [err$2.ACCESS_REFUSED, `必须在请求头中提供签名`];
|
|
809
812
|
}
|
|
810
813
|
|
|
811
|
-
let signData = apiUtil$
|
|
814
|
+
let signData = apiUtil$2.extractToken(req, null, true) || tokenData.apiKey;
|
|
812
815
|
signData += timestamp;
|
|
813
816
|
|
|
814
|
-
if (apiUtil$
|
|
817
|
+
if (apiUtil$2.isDebugMode(req) || apiUtil$2.isTestMode(req)) {
|
|
815
818
|
let publicKey = req.headers.publickey || req.body.publicKey || req.query.publicKey;
|
|
816
819
|
|
|
817
820
|
if (publicKey) {
|
|
@@ -826,16 +829,16 @@ class apiUtil$1 {
|
|
|
826
829
|
return await verifyResult;
|
|
827
830
|
}
|
|
828
831
|
|
|
829
|
-
return apiUtil$
|
|
832
|
+
return apiUtil$2.getCompanyCertificate(tokenData.apiKey).then(info => {
|
|
830
833
|
tokenData.certPublicKey = info.certLiving;
|
|
831
834
|
tokenData.certPublicKeySpare = info.certSpare;
|
|
832
835
|
tokenData.certLivingId = info.certLivingId;
|
|
833
836
|
tokenData.certSpareId = info.certSpareId;
|
|
834
837
|
req.certPublicKey = info.certLiving;
|
|
835
|
-
let token = apiUtil$
|
|
838
|
+
let token = apiUtil$2.extractToken(req, null, true);
|
|
836
839
|
|
|
837
840
|
if (token) {
|
|
838
|
-
apiUtil$
|
|
841
|
+
apiUtil$2.storeToken(apiUtil$2.apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
|
|
839
842
|
}
|
|
840
843
|
}).then(() => {
|
|
841
844
|
return doVerify(signData, signature, tokenData.certPublicKey);
|
|
@@ -860,7 +863,7 @@ class apiUtil$1 {
|
|
|
860
863
|
|
|
861
864
|
if (!tokenData.certPublicKeySpare) {
|
|
862
865
|
throw {
|
|
863
|
-
eo: err$
|
|
866
|
+
eo: err$2.ACCESS_REFUSED,
|
|
864
867
|
msgArgv: "签名验证异常",
|
|
865
868
|
data: e
|
|
866
869
|
};
|
|
@@ -897,10 +900,10 @@ class apiUtil$1 {
|
|
|
897
900
|
delete tokenData.certLivingId;
|
|
898
901
|
delete tokenData.certSpareId;
|
|
899
902
|
delete tokenData.certPublicKeySpare;
|
|
900
|
-
let token = apiUtil$
|
|
903
|
+
let token = apiUtil$2.extractToken(req);
|
|
901
904
|
|
|
902
905
|
if (token) {
|
|
903
|
-
apiUtil$
|
|
906
|
+
apiUtil$2.storeToken(apiTokenStoreKey(token), tokenData, tokenData.apiKey, req);
|
|
904
907
|
}
|
|
905
908
|
|
|
906
909
|
console.log(`公司(${tokenData.apiKey})备用证书成功转换为正式证书`);
|
|
@@ -909,7 +912,7 @@ class apiUtil$1 {
|
|
|
909
912
|
} catch (e) {
|
|
910
913
|
console.log("SPO服务签名验证异常(备用证书), ", e);
|
|
911
914
|
throw {
|
|
912
|
-
eo: err$
|
|
915
|
+
eo: err$2.ACCESS_REFUSED,
|
|
913
916
|
msgArgv: "签名验证异常(spare)",
|
|
914
917
|
data: e
|
|
915
918
|
};
|
|
@@ -918,7 +921,7 @@ class apiUtil$1 {
|
|
|
918
921
|
|
|
919
922
|
if (!verifyOK) {
|
|
920
923
|
console.log("SPO服务签名验证失败, tokenData: ", tokenData);
|
|
921
|
-
throw [err$
|
|
924
|
+
throw [err$2.ACCESS_REFUSED, "签名验证未通过"];
|
|
922
925
|
}
|
|
923
926
|
|
|
924
927
|
return verifyOK;
|
|
@@ -934,32 +937,32 @@ class apiUtil$1 {
|
|
|
934
937
|
|
|
935
938
|
static async checkApiCallValid(tokenData, req) {
|
|
936
939
|
if (!tokenData.companyInfo) {
|
|
937
|
-
tokenData.companyInfo = await apiUtil$
|
|
940
|
+
tokenData.companyInfo = await apiUtil$2.queryCompanyInfo(tokenData.apiKey, true).catch(e => {
|
|
938
941
|
console.log("执行企业信息查询发生异常", e);
|
|
939
|
-
throw [err$
|
|
942
|
+
throw [err$2.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
|
|
940
943
|
});
|
|
941
944
|
}
|
|
942
945
|
|
|
943
946
|
const companyInfo = tokenData.companyInfo;
|
|
944
947
|
|
|
945
948
|
if (companyInfo != null) {
|
|
946
|
-
let secret = apiUtil$
|
|
949
|
+
let secret = apiUtil$2._getApiSecret(tokenData.apiKey);
|
|
947
950
|
|
|
948
|
-
if (secret !== tokenData.apiSecret) throw err$
|
|
951
|
+
if (secret !== tokenData.apiSecret) throw err$2.API_SCREPT_INVALID; // 不再检查 IP 白名单,改为验证证书签名
|
|
949
952
|
// console.log("fromIp:", tokenData.clientIp, "ipWhiteList:", companyInfo.ipWhiteList);
|
|
950
953
|
// let whiteList = companyInfo.ipWhiteList || "";
|
|
951
954
|
// // 没有设置ip白名单的就不检查了
|
|
952
955
|
// if (whiteList == "" || ipMatched(tokenData.clientIp, whiteList + ",127.0.0.1,1"))
|
|
953
956
|
|
|
954
|
-
if (apiUtil$
|
|
955
|
-
return apiUtil$
|
|
957
|
+
if (apiUtil$2.signatureVerified()) return companyInfo;
|
|
958
|
+
return apiUtil$2.verifyApiSignature(tokenData, req).then(x => {
|
|
956
959
|
return companyInfo;
|
|
957
960
|
}, e => {
|
|
958
961
|
throw e;
|
|
959
962
|
});
|
|
960
963
|
}
|
|
961
964
|
|
|
962
|
-
throw [err$
|
|
965
|
+
throw [err$2.API_KEY_INVALID, tokenData.apiKey];
|
|
963
966
|
}
|
|
964
967
|
/**
|
|
965
968
|
* 检查令牌数据是否存在
|
|
@@ -1010,7 +1013,7 @@ class apiUtil$1 {
|
|
|
1010
1013
|
paramExists = typeof params[paramName] != 'undefined' || typeof params[paramName + paramSufix] != 'undefined';
|
|
1011
1014
|
}
|
|
1012
1015
|
|
|
1013
|
-
if (!paramExists) return ppUtil$4.errorPormise(err$
|
|
1016
|
+
if (!paramExists) return ppUtil$4.errorPormise(err$2.ERROR(err$2.PARAMETER_NEEDED, paramName));
|
|
1014
1017
|
}
|
|
1015
1018
|
|
|
1016
1019
|
return Promise.resolve(paramSufix);
|
|
@@ -1058,7 +1061,7 @@ class apiUtil$1 {
|
|
|
1058
1061
|
|
|
1059
1062
|
|
|
1060
1063
|
static async hostIsMySelf(host, req) {
|
|
1061
|
-
let clientIp = apiUtil$
|
|
1064
|
+
let clientIp = apiUtil$2.getClientIp(req);
|
|
1062
1065
|
return ppUtil$4.getMyIp({
|
|
1063
1066
|
hosts: [host, clientIp]
|
|
1064
1067
|
});
|
|
@@ -1073,13 +1076,13 @@ class apiUtil$1 {
|
|
|
1073
1076
|
static async checkForwardsHost(options) {
|
|
1074
1077
|
configNeeded();
|
|
1075
1078
|
const params = options.replacements;
|
|
1076
|
-
const myEnvHosts = apiUtil$
|
|
1079
|
+
const myEnvHosts = apiUtil$2.getEnvHosts(params);
|
|
1077
1080
|
const myIp = ppUtil$4.getMyIp();
|
|
1078
1081
|
const host = params.host || myIp;
|
|
1079
|
-
if (!myEnvHosts.hosts.contains(host)) throw [err$
|
|
1082
|
+
if (!myEnvHosts.hosts.contains(host)) throw [err$2.ACCESS_REFUSED, `环境${conf$3.envId}貌似无此主机:${params.host}`];
|
|
1080
1083
|
|
|
1081
|
-
if (!apiUtil$
|
|
1082
|
-
let result = await apiUtil$
|
|
1084
|
+
if (!apiUtil$2.hostIsMySelf(host, options._res.req)) {
|
|
1085
|
+
let result = await apiUtil$2.forwardsTo(host, myEnvHosts.port, params, options._res.req, myIp);
|
|
1083
1086
|
|
|
1084
1087
|
options._res.send(result);
|
|
1085
1088
|
|
|
@@ -1115,7 +1118,7 @@ class apiUtil$1 {
|
|
|
1115
1118
|
|
|
1116
1119
|
if (result.status !== 200) {
|
|
1117
1120
|
console.log(`访问 ${reqOptions.url} 出错`, result.status, result.res.statusMessage);
|
|
1118
|
-
throw [err$
|
|
1121
|
+
throw [err$2.EXCEPTION, `[${result.status}] - ${result.res.statusMessage}`];
|
|
1119
1122
|
}
|
|
1120
1123
|
|
|
1121
1124
|
return result.data;
|
|
@@ -1131,7 +1134,7 @@ class apiUtil$1 {
|
|
|
1131
1134
|
let keys = Array.isArray(keyPath) ? keyPath : keyPath.split(".");
|
|
1132
1135
|
let parentKey = "";
|
|
1133
1136
|
let key = "config";
|
|
1134
|
-
let value = conf$
|
|
1137
|
+
let value = conf$3;
|
|
1135
1138
|
let parent = null;
|
|
1136
1139
|
|
|
1137
1140
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -1141,7 +1144,7 @@ class apiUtil$1 {
|
|
|
1141
1144
|
value = parent[key];
|
|
1142
1145
|
|
|
1143
1146
|
if (value === undefined) {
|
|
1144
|
-
throw [err$
|
|
1147
|
+
throw [err$2.INVALID_PARAM, `无此配置项: ${key}`];
|
|
1145
1148
|
}
|
|
1146
1149
|
}
|
|
1147
1150
|
|
|
@@ -1161,10 +1164,10 @@ class apiUtil$1 {
|
|
|
1161
1164
|
|
|
1162
1165
|
static async $checkToken(req, res, next) {
|
|
1163
1166
|
try {
|
|
1164
|
-
await apiUtil$
|
|
1167
|
+
await apiUtil$2.checkRequestToken(req);
|
|
1165
1168
|
await next();
|
|
1166
1169
|
} catch (e) {
|
|
1167
|
-
res.send(err$
|
|
1170
|
+
res.send(err$2.ERROR(e));
|
|
1168
1171
|
}
|
|
1169
1172
|
|
|
1170
1173
|
return false;
|
|
@@ -1181,7 +1184,7 @@ class apiUtil$1 {
|
|
|
1181
1184
|
let token = req.headers["access_token"] || req.headers['x-access-token']; //向后兼容
|
|
1182
1185
|
|
|
1183
1186
|
if (!token) {
|
|
1184
|
-
let params = apiUtil$
|
|
1187
|
+
let params = apiUtil$2.extractParams(req);
|
|
1185
1188
|
token = params["access_token"];
|
|
1186
1189
|
|
|
1187
1190
|
if (token) {
|
|
@@ -1204,15 +1207,15 @@ class apiUtil$1 {
|
|
|
1204
1207
|
|
|
1205
1208
|
try {
|
|
1206
1209
|
if (extractToken(req, res)) {
|
|
1207
|
-
await apiUtil$
|
|
1208
|
-
req.userInfo = apiUtil$
|
|
1210
|
+
await apiUtil$2.restoreTokenData(apiUtil$2.userTokenStoreKey(req.accessToken), apiUtil$2.tokenExpireTime(req)).then(function (data) {
|
|
1211
|
+
req.userInfo = apiUtil$2.setUserIdNo(data, data._idNo);
|
|
1209
1212
|
}, function (e) {//no token
|
|
1210
1213
|
});
|
|
1211
1214
|
}
|
|
1212
1215
|
|
|
1213
1216
|
return true;
|
|
1214
1217
|
} catch (e) {
|
|
1215
|
-
res.send(err$
|
|
1218
|
+
res.send(err$2.ERROR(e));
|
|
1216
1219
|
return false;
|
|
1217
1220
|
}
|
|
1218
1221
|
}
|
|
@@ -1235,7 +1238,7 @@ class apiUtil$1 {
|
|
|
1235
1238
|
req.isMobile = true;
|
|
1236
1239
|
|
|
1237
1240
|
if (!req.signatureVerified) {
|
|
1238
|
-
let params = apiUtil$
|
|
1241
|
+
let params = apiUtil$2.extractParams(req);
|
|
1239
1242
|
moveProperty(params, req.headers, "access_token");
|
|
1240
1243
|
moveProperty(params, req.headers, "timestamp");
|
|
1241
1244
|
|
|
@@ -1256,25 +1259,25 @@ class apiUtil$1 {
|
|
|
1256
1259
|
|
|
1257
1260
|
static $checkApiKeyOld(req, res, next) {
|
|
1258
1261
|
//检查post的信息或者url查询参数或者头信息
|
|
1259
|
-
let tokenData = apiUtil$
|
|
1260
|
-
let params = apiUtil$
|
|
1261
|
-
apiUtil$
|
|
1262
|
+
let tokenData = apiUtil$2.extractTokenData(req);
|
|
1263
|
+
let params = apiUtil$2.extractParams(req);
|
|
1264
|
+
apiUtil$2.createApiCallRec(tokenData, req);
|
|
1262
1265
|
let errResponse = null;
|
|
1263
1266
|
|
|
1264
1267
|
if (!tokenData.clientIp) {
|
|
1265
|
-
errResponse = apiUtil$
|
|
1268
|
+
errResponse = apiUtil$2.spoApiFail(err$2.GET_CLIENTIP_FAIL, req);
|
|
1266
1269
|
} else if (!tokenData.apiKey) {
|
|
1267
|
-
errResponse = apiUtil$
|
|
1270
|
+
errResponse = apiUtil$2.spoApiFail([err$2.PARAMETER_NEEDED, "apiKey"], req);
|
|
1268
1271
|
} else if (!tokenData.apiSecret) {
|
|
1269
|
-
errResponse = apiUtil$
|
|
1272
|
+
errResponse = apiUtil$2.spoApiFail([err$2.PARAMETER_NEEDED, "apiSecret"], req);
|
|
1270
1273
|
}
|
|
1271
1274
|
|
|
1272
1275
|
if (errResponse != null) {
|
|
1273
|
-
apiUtil$
|
|
1276
|
+
apiUtil$2._saveApiCallRec(req.apiCallRec, errResponse);
|
|
1274
1277
|
|
|
1275
|
-
apiUtil$
|
|
1278
|
+
apiUtil$2.sendOrRedirect(req, res, errResponse);
|
|
1276
1279
|
} else {
|
|
1277
|
-
apiUtil$
|
|
1280
|
+
apiUtil$2.checkApiCallValid(tokenData, req).then(companyInfo => {
|
|
1278
1281
|
params.companyId = params.companyId || companyInfo.companyId;
|
|
1279
1282
|
req.companyInfo = companyInfo;
|
|
1280
1283
|
next();
|
|
@@ -1282,9 +1285,9 @@ class apiUtil$1 {
|
|
|
1282
1285
|
console.log('apiCallInvalid:', e);
|
|
1283
1286
|
let errResponse = spoApiFail(e, req);
|
|
1284
1287
|
|
|
1285
|
-
apiUtil$
|
|
1288
|
+
apiUtil$2._saveApiCallRec(req.apiCallRec, errResponse);
|
|
1286
1289
|
|
|
1287
|
-
apiUtil$
|
|
1290
|
+
apiUtil$2.sendOrRedirect(req, res, errResponse);
|
|
1288
1291
|
});
|
|
1289
1292
|
}
|
|
1290
1293
|
}
|
|
@@ -1299,31 +1302,31 @@ class apiUtil$1 {
|
|
|
1299
1302
|
return;
|
|
1300
1303
|
}
|
|
1301
1304
|
|
|
1302
|
-
let accessToken = apiUtil$
|
|
1305
|
+
let accessToken = apiUtil$2.extractToken(req);
|
|
1303
1306
|
|
|
1304
1307
|
if (!accessToken) {
|
|
1305
|
-
res.send(apiUtil$
|
|
1308
|
+
res.send(apiUtil$2.spoApiFail(err$2.TOKEN_NEEDED, req)); // apiUtil.sendOrRedirect(req, res, spoApiFail(err.TOKEN_NEEDED, req));
|
|
1306
1309
|
|
|
1307
1310
|
return;
|
|
1308
1311
|
}
|
|
1309
1312
|
|
|
1310
|
-
apiUtil$
|
|
1313
|
+
apiUtil$2.restoreTokenData(apiUtil$2.apiTokenStoreKey(accessToken)).then(p => {
|
|
1311
1314
|
// req.headers[hnApiKey] = p.apiKey || '';
|
|
1312
1315
|
// req.headers[hnApiSecret] = p.apiSecret || '';
|
|
1313
1316
|
if (req.isMobile) {
|
|
1314
1317
|
// GET 请求的应该都是H5页面,由手机前端发起,需要把headers中的请求方ip换成服务端的
|
|
1315
1318
|
// todo: 如何在API访问记录中记住请求者(手机端)的真实IP
|
|
1316
|
-
req.headers['x-phone-ip'] = apiUtil$
|
|
1319
|
+
req.headers['x-phone-ip'] = apiUtil$2.getClientIp(req);
|
|
1317
1320
|
req.headers['x-real-ip'] = p.clientIp;
|
|
1318
1321
|
} else {
|
|
1319
|
-
p.clientIp = apiUtil$
|
|
1322
|
+
p.clientIp = apiUtil$2.getClientIp(req);
|
|
1320
1323
|
}
|
|
1321
1324
|
|
|
1322
1325
|
req.isApiCall = true;
|
|
1323
1326
|
req.tokenData = p;
|
|
1324
|
-
return apiUtil$
|
|
1327
|
+
return apiUtil$2.$checkApiKeyOld(req, res, next);
|
|
1325
1328
|
}).catch(e => {
|
|
1326
|
-
apiUtil$
|
|
1329
|
+
apiUtil$2.sendOrRedirect(req, res, apiUtil$2.spoApiFail(err$2.TOKEN_INVALID, req));
|
|
1327
1330
|
});
|
|
1328
1331
|
}
|
|
1329
1332
|
/**
|
|
@@ -1336,24 +1339,24 @@ class apiUtil$1 {
|
|
|
1336
1339
|
|
|
1337
1340
|
|
|
1338
1341
|
static async $checkTokenOrApiKey(req, res, next) {
|
|
1339
|
-
let accessToken = apiUtil$
|
|
1342
|
+
let accessToken = apiUtil$2.extractToken(req, res);
|
|
1340
1343
|
|
|
1341
1344
|
if (accessToken) {
|
|
1342
|
-
let tokenExist = await apiUtil$
|
|
1345
|
+
let tokenExist = await apiUtil$2.tokenDataExist(apiUtil$2.userTokenStoreKey(accessToken));
|
|
1343
1346
|
|
|
1344
1347
|
if (tokenExist) {
|
|
1345
|
-
return await apiUtil$
|
|
1348
|
+
return await apiUtil$2.$checkToken(req, res, next);
|
|
1346
1349
|
}
|
|
1347
1350
|
|
|
1348
|
-
tokenExist = await apiUtil$
|
|
1351
|
+
tokenExist = await apiUtil$2.tokenDataExist(apiUtil$2.apiTokenStoreKey(accessToken));
|
|
1349
1352
|
|
|
1350
1353
|
if (tokenExist) {
|
|
1351
|
-
return apiUtil$
|
|
1354
|
+
return apiUtil$2.$checkApiKey(req, res, next);
|
|
1352
1355
|
} // 如果给定的token不存在,看看是不是平台内部调用
|
|
1353
1356
|
|
|
1354
1357
|
|
|
1355
|
-
return await apiUtil$
|
|
1356
|
-
res.send(apiUtil$
|
|
1358
|
+
return await apiUtil$2.checkInternalToken(req).catch(e => {
|
|
1359
|
+
res.send(apiUtil$2.apiFail(e, req));
|
|
1357
1360
|
return false;
|
|
1358
1361
|
});
|
|
1359
1362
|
}
|
|
@@ -1373,8 +1376,8 @@ class apiUtil$1 {
|
|
|
1373
1376
|
const params = options.replacements;
|
|
1374
1377
|
let item = params.item;
|
|
1375
1378
|
delete params.item;
|
|
1376
|
-
if (await apiUtil$
|
|
1377
|
-
let c = apiUtil$
|
|
1379
|
+
if (await apiUtil$2.checkForwardsHost(options)) return true;
|
|
1380
|
+
let c = apiUtil$2.parseCfgPath(item);
|
|
1378
1381
|
delete c.parent;
|
|
1379
1382
|
c.host = ppUtil$4.getMyIp();
|
|
1380
1383
|
return c;
|
|
@@ -1393,11 +1396,11 @@ class apiUtil$1 {
|
|
|
1393
1396
|
delete params.item; // if (await checkForwardsHost(options))
|
|
1394
1397
|
// return true;
|
|
1395
1398
|
|
|
1396
|
-
await apiUtil$
|
|
1397
|
-
let c = apiUtil$
|
|
1399
|
+
await apiUtil$2.parametersOK(params, "value");
|
|
1400
|
+
let c = apiUtil$2.parseCfgPath(item);
|
|
1398
1401
|
|
|
1399
1402
|
if (typeof c.value === "object") {
|
|
1400
|
-
throw [err$
|
|
1403
|
+
throw [err$2.ACCESS_REFUSED, `暂不支持修改复杂配置`];
|
|
1401
1404
|
} // c.oldValue = c.value;
|
|
1402
1405
|
|
|
1403
1406
|
|
|
@@ -1406,27 +1409,46 @@ class apiUtil$1 {
|
|
|
1406
1409
|
delete c.parent;
|
|
1407
1410
|
c.host = ppUtil$4.getMyIp();
|
|
1408
1411
|
return c; // 应用层自行处理多机同步
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* 修改重启标志文件
|
|
1415
|
+
* 前提,PM2监视 restart,please.flag 文件,此文件若被修改则重启服务进程
|
|
1416
|
+
* 此服务假设 restart,please.flag 文件最后一行是一个整数,此整数+1后保存
|
|
1417
|
+
* @param options
|
|
1418
|
+
* @returns {Promise<number>}
|
|
1419
|
+
*/
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
static async updateRestartFlag(options) {
|
|
1423
|
+
const fileName = `restart,please.flag`;
|
|
1424
|
+
let text = await fs$1.async_readFile(fileName, 'utf8');
|
|
1425
|
+
const lines = text.split('\r\n');
|
|
1426
|
+
const n = +lines[lines.length - 1] + 1;
|
|
1427
|
+
lines[lines.length - 1] = ' '.repeat(50) + n.toString();
|
|
1428
|
+
text = lines.join('\r\n');
|
|
1429
|
+
await fs$1.async_writeFile(fileName, text);
|
|
1430
|
+
return n;
|
|
1409
1431
|
} //#endregion
|
|
1410
1432
|
|
|
1411
1433
|
|
|
1412
1434
|
}
|
|
1413
1435
|
|
|
1414
1436
|
function configNeeded() {
|
|
1415
|
-
if (!conf$
|
|
1437
|
+
if (!conf$3 || !err$2) {
|
|
1416
1438
|
ppUtil$4.configNeeded();
|
|
1417
|
-
conf$
|
|
1418
|
-
appSetting$1 = conf$
|
|
1419
|
-
err$
|
|
1439
|
+
conf$3 = ppUtil$4.appConfig;
|
|
1440
|
+
appSetting$1 = conf$3.appSetting;
|
|
1441
|
+
err$2 = ppUtil$4.appErrCfg;
|
|
1420
1442
|
}
|
|
1421
1443
|
}
|
|
1422
1444
|
|
|
1423
|
-
var ppUtilApi = apiUtil$
|
|
1445
|
+
var ppUtilApi = apiUtil$2;
|
|
1424
1446
|
|
|
1425
|
-
const fs = require$$
|
|
1447
|
+
const fs = require$$4;
|
|
1426
1448
|
const path = require$$1$1;
|
|
1427
1449
|
const ppUtil$3 = require$$1.ppUtil;
|
|
1428
1450
|
const redisUtil = require$$2.redisUtil;
|
|
1429
|
-
let conf$
|
|
1451
|
+
let conf$2, err$1; // const dbCheck = require('../dbupdate/dd-version');
|
|
1430
1452
|
|
|
1431
1453
|
/**
|
|
1432
1454
|
* API服务启动时前置条件检查
|
|
@@ -1446,9 +1468,9 @@ class preconditions$1 {
|
|
|
1446
1468
|
|
|
1447
1469
|
static setAppName(aName) {
|
|
1448
1470
|
ppUtil$3.configNeeded();
|
|
1449
|
-
conf$
|
|
1450
|
-
err = ppUtil$3.appErrCfg;
|
|
1451
|
-
preconditions$1.appName = aName || conf$
|
|
1471
|
+
conf$2 = ppUtil$3.appConfig;
|
|
1472
|
+
err$1 = ppUtil$3.appErrCfg;
|
|
1473
|
+
preconditions$1.appName = aName || conf$2.thisApp;
|
|
1452
1474
|
return preconditions$1;
|
|
1453
1475
|
}
|
|
1454
1476
|
|
|
@@ -1529,20 +1551,20 @@ async function createEnvSettingFile(fileName) {
|
|
|
1529
1551
|
try {
|
|
1530
1552
|
const cfgText = await ppUtil$3.doCreateEnvSettingFile(fileName);
|
|
1531
1553
|
|
|
1532
|
-
if (cfgText.indexOf(`cfgVersion: "${conf$
|
|
1554
|
+
if (cfgText.indexOf(`cfgVersion: "${conf$2._envSetting.cfgVersion}"`) > 0) {
|
|
1533
1555
|
console.log(`\n*** 已創建新的本機環境配置文件\n${fileName}\n请檢查各項內容是否正确(此项更新服务可正常运行)\n\n`);
|
|
1534
1556
|
return "";
|
|
1535
1557
|
}
|
|
1536
1558
|
|
|
1537
|
-
return `已創建新的本機環境配置文件\n${fileName}\n请檢查並正確設置各項內容,然後將配置版本號修改為${conf$
|
|
1559
|
+
return `已創建新的本機環境配置文件\n${fileName}\n请檢查並正確設置各項內容,然後將配置版本號修改為${conf$2._envSettings.default.cfgVersion}`;
|
|
1538
1560
|
} catch (e) {
|
|
1539
|
-
return `創建本機環境配置文件失敗\n《${fileName}》\n${err.ERROR(e).message}`;
|
|
1561
|
+
return `創建本機環境配置文件失敗\n《${fileName}》\n${err$1.ERROR(e).message}`;
|
|
1540
1562
|
}
|
|
1541
1563
|
}
|
|
1542
1564
|
|
|
1543
1565
|
async function checkExEnvSetting(loadjs) {
|
|
1544
|
-
if (!conf$
|
|
1545
|
-
let fileName = conf$
|
|
1566
|
+
if (!conf$2._envSetting.localSettingImported) {
|
|
1567
|
+
let fileName = conf$2.getEnvSettingFileName();
|
|
1546
1568
|
|
|
1547
1569
|
if (!fs.existsSync(fileName)) {
|
|
1548
1570
|
return await createEnvSettingFile(fileName);
|
|
@@ -1550,7 +1572,7 @@ async function checkExEnvSetting(loadjs) {
|
|
|
1550
1572
|
|
|
1551
1573
|
let envSettingEx = loadjs(fileName);
|
|
1552
1574
|
|
|
1553
|
-
if (envSettingEx.cfgVersion !== conf$
|
|
1575
|
+
if (envSettingEx.cfgVersion !== conf$2._envSettings.default.cfgVersion) {
|
|
1554
1576
|
if (envSettingEx.cfgVersion !== "0.0") {
|
|
1555
1577
|
let fp = path.parse(fileName);
|
|
1556
1578
|
let newFileName = path.join(fp.dir, fp.name + envSettingEx.cfgVersion + fp.ext);
|
|
@@ -1569,7 +1591,7 @@ async function checkExEnvSetting(loadjs) {
|
|
|
1569
1591
|
|
|
1570
1592
|
|
|
1571
1593
|
async function checkRedis() {
|
|
1572
|
-
if (!conf$
|
|
1594
|
+
if (!conf$2.redis.enabled) return "";
|
|
1573
1595
|
const redis = redisUtil.newClient("io"); // console.log(`checkRedis begin:`);
|
|
1574
1596
|
|
|
1575
1597
|
await ppUtil$3.wait(15 * 1000, param => {
|
|
@@ -1590,124 +1612,43 @@ async function checkRedis() {
|
|
|
1590
1612
|
|
|
1591
1613
|
var ppPrecond = preconditions$1;
|
|
1592
1614
|
|
|
1593
|
-
var require$$0 = require$$2;
|
|
1594
|
-
|
|
1595
|
-
function _interopDefaultLegacy(e) {
|
|
1596
|
-
return e && typeof e === 'object' && 'default' in e ? e : {
|
|
1597
|
-
'default': e
|
|
1598
|
-
};
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0); // const logger = require("log4js").getLogger();
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
const redis = require$$0__default["default"].redisUtil;
|
|
1605
|
-
|
|
1606
|
-
class Messenger {
|
|
1607
|
-
constructor(appConfig, appErrCfg) {
|
|
1608
|
-
if (appConfig) {
|
|
1609
|
-
redis.config(appConfig, appErrCfg);
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
this.channel = "ecs_messenger"; //default channel
|
|
1613
|
-
|
|
1614
|
-
this.publisher = redis.newClient("publisher");
|
|
1615
|
-
this.subscriber = redis.newClient("subscriber");
|
|
1616
|
-
this.subscriber.on("subscribe", function (channel, count) {
|
|
1617
|
-
console.log("chanel subscribed :", channel, count);
|
|
1618
|
-
});
|
|
1619
|
-
this.subscriber.on("message", this.handleMessage);
|
|
1620
|
-
}
|
|
1621
|
-
|
|
1622
|
-
setMessageHandle(handle, channel) {
|
|
1623
|
-
channel = channel || this.channel;
|
|
1624
|
-
Messenger.onmessage = Messenger.onmessage || {};
|
|
1625
|
-
Messenger.onmessage[channel] = Messenger.onmessage[channel] || [];
|
|
1626
|
-
const appMsgHandles = Messenger.onmessage[channel];
|
|
1627
|
-
|
|
1628
|
-
for (let i = 0; i < appMsgHandles.length; i++) {
|
|
1629
|
-
if (appMsgHandles[i] === handle) return this;
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
appMsgHandles.push(handle);
|
|
1633
|
-
return this;
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
subscribe(channel) {
|
|
1637
|
-
channel = channel || this.channel;
|
|
1638
|
-
this.subscriber.subscribe(channel);
|
|
1639
|
-
return this;
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
async handleMessage(channel, message) {
|
|
1643
|
-
console.log(`通道[${channel}]收到订阅消息:`, message);
|
|
1644
|
-
let appMsgHandles = Messenger.onmessage[channel] || [];
|
|
1645
|
-
|
|
1646
|
-
for (let i = 0; i < appMsgHandles.length; i++) {
|
|
1647
|
-
const appMsgHandle = appMsgHandles[i];
|
|
1648
|
-
|
|
1649
|
-
try {
|
|
1650
|
-
let msgObj = JSON.parse(message); // await appMsgHandle(msgObj);
|
|
1651
|
-
|
|
1652
|
-
appMsgHandle(msgObj);
|
|
1653
|
-
} catch (e) {
|
|
1654
|
-
console.log(e);
|
|
1655
|
-
}
|
|
1656
|
-
}
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1659
|
-
async publish(message, channel) {
|
|
1660
|
-
channel = channel || this.channel;
|
|
1661
|
-
let msgStr = typeof message === "object" ? JSON.stringify(message) : message.toString();
|
|
1662
|
-
console.log(`通道[${channel}]发布消息:`, message);
|
|
1663
|
-
await this.publisher.publish(channel, msgStr);
|
|
1664
|
-
return this;
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
}
|
|
1668
|
-
|
|
1669
|
-
var ppMessenger$1 = Messenger;
|
|
1670
|
-
const ppMessenger = ppMessenger$1;
|
|
1671
|
-
var ppUtil$2 = ppMessenger;
|
|
1672
|
-
var ppUtil_1 = ppUtil$2;
|
|
1673
|
-
|
|
1674
1615
|
// 若 redis 可用,则使用基于 redis 的消息订阅发布系统
|
|
1675
1616
|
// 若 redis 不可用,则将消息转发到其它主机
|
|
1676
1617
|
|
|
1677
1618
|
const {
|
|
1678
|
-
ppUtil: ppUtil$
|
|
1619
|
+
ppUtil: ppUtil$2
|
|
1679
1620
|
} = require$$1;
|
|
1680
|
-
const RedisMessenger =
|
|
1621
|
+
const RedisMessenger = require$$1$2;
|
|
1681
1622
|
const {
|
|
1682
1623
|
netUtil
|
|
1683
1624
|
} = require$$3;
|
|
1684
|
-
let conf;
|
|
1625
|
+
let conf$1;
|
|
1685
1626
|
|
|
1686
|
-
class commonMessenger$
|
|
1627
|
+
class commonMessenger$2 {
|
|
1687
1628
|
static myMsgAddr = "";
|
|
1688
1629
|
static redisMessenger = null;
|
|
1689
1630
|
static onMessage = [];
|
|
1690
1631
|
|
|
1691
1632
|
static initMessenger(appConfig, appErrCfg, msgChannel) {
|
|
1692
|
-
conf = appConfig;
|
|
1693
|
-
this.redisMessenger = conf.redis.enabled ? new RedisMessenger(appConfig, appErrCfg, msgChannel).subscribe(msgChannel) : null;
|
|
1694
|
-
this.myMsgAddr = commonMessenger$
|
|
1633
|
+
conf$1 = appConfig;
|
|
1634
|
+
this.redisMessenger = conf$1.redis.enabled ? new RedisMessenger(appConfig, appErrCfg, msgChannel).subscribe(msgChannel) : null;
|
|
1635
|
+
this.myMsgAddr = commonMessenger$2.getMyMsgAddr();
|
|
1695
1636
|
}
|
|
1696
1637
|
|
|
1697
1638
|
static getMyMsgAddr() {
|
|
1698
|
-
if (!conf.myMsgAddr) {
|
|
1699
|
-
conf.pm_id = process.env.pm_id || "0";
|
|
1700
|
-
let myIp = ppUtil$
|
|
1639
|
+
if (!conf$1.myMsgAddr) {
|
|
1640
|
+
conf$1.pm_id = process.env.pm_id || "0";
|
|
1641
|
+
let myIp = ppUtil$2.getMyIp();
|
|
1701
1642
|
|
|
1702
1643
|
if (this.redisMessenger) {
|
|
1703
|
-
myIp = `${conf.pm_id}@${myIp}`;
|
|
1644
|
+
myIp = `${conf$1.pm_id}@${myIp}`;
|
|
1704
1645
|
}
|
|
1705
1646
|
|
|
1706
|
-
conf.myMsgAddr = myIp;
|
|
1707
|
-
console.log(`myMsgAddr: `, conf.myMsgAddr);
|
|
1647
|
+
conf$1.myMsgAddr = myIp;
|
|
1648
|
+
console.log(`myMsgAddr: `, conf$1.myMsgAddr);
|
|
1708
1649
|
}
|
|
1709
1650
|
|
|
1710
|
-
return conf.myMsgAddr;
|
|
1651
|
+
return conf$1.myMsgAddr;
|
|
1711
1652
|
}
|
|
1712
1653
|
|
|
1713
1654
|
static setMessageHandle(messageHandle) {
|
|
@@ -1715,11 +1656,11 @@ class commonMessenger$1 {
|
|
|
1715
1656
|
return this.redisMessenger.setMessageHandle(messageHandle, msgChannel);
|
|
1716
1657
|
}
|
|
1717
1658
|
|
|
1718
|
-
if (commonMessenger$
|
|
1719
|
-
commonMessenger$
|
|
1659
|
+
if (commonMessenger$2.onMessage.indexOf(messageHandle) < 0) {
|
|
1660
|
+
commonMessenger$2.onMessage.push(messageHandle);
|
|
1720
1661
|
}
|
|
1721
1662
|
|
|
1722
|
-
return commonMessenger$
|
|
1663
|
+
return commonMessenger$2;
|
|
1723
1664
|
}
|
|
1724
1665
|
|
|
1725
1666
|
static async publishMessage(message) {
|
|
@@ -1730,10 +1671,10 @@ class commonMessenger$1 {
|
|
|
1730
1671
|
if (message.destAddr) {
|
|
1731
1672
|
await forwardMessage(message);
|
|
1732
1673
|
} else {
|
|
1733
|
-
for (let i = 0; i < conf.appSetting.serverHosts.length; i++) {
|
|
1734
|
-
message.destAddr = conf.appSetting.serverHosts[i];
|
|
1674
|
+
for (let i = 0; i < conf$1.appSetting.serverHosts.length; i++) {
|
|
1675
|
+
message.destAddr = conf$1.appSetting.serverHosts[i];
|
|
1735
1676
|
|
|
1736
|
-
if (message.destAddr !== conf.myMsgAddr) {
|
|
1677
|
+
if (message.destAddr !== conf$1.myMsgAddr) {
|
|
1737
1678
|
await forwardMessage(message);
|
|
1738
1679
|
}
|
|
1739
1680
|
}
|
|
@@ -1744,8 +1685,8 @@ class commonMessenger$1 {
|
|
|
1744
1685
|
static async handleInternalMessage(options) {
|
|
1745
1686
|
const message = options.replacements;
|
|
1746
1687
|
|
|
1747
|
-
for (let i = 0; i < commonMessenger$
|
|
1748
|
-
const appMsgHandle = commonMessenger$
|
|
1688
|
+
for (let i = 0; i < commonMessenger$2.onMessage.length; i++) {
|
|
1689
|
+
const appMsgHandle = commonMessenger$2.onMessage[i];
|
|
1749
1690
|
|
|
1750
1691
|
try {
|
|
1751
1692
|
await appMsgHandle(message);
|
|
@@ -1770,15 +1711,293 @@ async function forwardMessage(message) {
|
|
|
1770
1711
|
return res.data;
|
|
1771
1712
|
}
|
|
1772
1713
|
|
|
1773
|
-
var ppMessengerEx = commonMessenger$
|
|
1714
|
+
var ppMessengerEx = commonMessenger$2;
|
|
1715
|
+
|
|
1716
|
+
/**
|
|
1717
|
+
* CSCA 自动任务
|
|
1718
|
+
* ==============
|
|
1719
|
+
*/
|
|
1720
|
+
const CRON = require$$0$1;
|
|
1721
|
+
const {
|
|
1722
|
+
ppUtil: ppUtil$1
|
|
1723
|
+
} = require$$1;
|
|
1724
|
+
const apiUtil$1 = ppUtilApi;
|
|
1725
|
+
const commonMessenger$1 = ppMessengerEx;
|
|
1726
|
+
const MT_SCHEDULE_STATE = 'schedule-state',
|
|
1727
|
+
MT_SCHEDULE_STATE_REPLY = 'schedule-state-reply';
|
|
1728
|
+
let conf, err;
|
|
1729
|
+
|
|
1730
|
+
class schedule$1 {
|
|
1731
|
+
static tasks = {};
|
|
1732
|
+
/**
|
|
1733
|
+
* 注册一个计划任务
|
|
1734
|
+
* @param taskName
|
|
1735
|
+
* @param taskCaption
|
|
1736
|
+
* @param cronExp
|
|
1737
|
+
* @param taskFunc
|
|
1738
|
+
* @param autoStart
|
|
1739
|
+
* @returns {Promise<{}|{}|{cron: *, _message_: string}|any>}
|
|
1740
|
+
*/
|
|
1741
|
+
|
|
1742
|
+
static async registerTask(taskName, taskCaption, cronExp, taskFunc, autoStart) {
|
|
1743
|
+
if (!conf) {
|
|
1744
|
+
ppUtil$1.configNeeded();
|
|
1745
|
+
conf = ppUtil$1.appConfig;
|
|
1746
|
+
err = ppUtil$1.appErrCfg;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
if (!this.envAllowed()) return {};
|
|
1750
|
+
let task = this.findTask(taskName);
|
|
1751
|
+
|
|
1752
|
+
if (task) {
|
|
1753
|
+
if (task.cronExp !== cronExp || task.taskFunc !== taskFunc) {
|
|
1754
|
+
this.stop(taskName);
|
|
1755
|
+
task = null;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
if (!task) {
|
|
1760
|
+
task = {
|
|
1761
|
+
name: taskName,
|
|
1762
|
+
caption: taskCaption,
|
|
1763
|
+
cronExp: cronExp,
|
|
1764
|
+
taskFunc: taskFunc,
|
|
1765
|
+
schedule: null,
|
|
1766
|
+
doScheduleTask: async function () {
|
|
1767
|
+
let self = this;
|
|
1768
|
+
if (this._pp_task) self = this._pp_task;
|
|
1769
|
+
console.log(new Date().format('[yyyy/MM/dd hh:mm:ss:S]'), `开始执行${self.caption}任务 ...`);
|
|
1770
|
+
await self.taskFunc();
|
|
1771
|
+
console.log(new Date().format('[yyyy/MM/dd hh:mm:ss:S]'), `${self.caption}任务执行结束`);
|
|
1772
|
+
}
|
|
1773
|
+
};
|
|
1774
|
+
this.tasks[taskName] = task;
|
|
1775
|
+
|
|
1776
|
+
if (autoStart) {
|
|
1777
|
+
return await this.start(task);
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
return this.getTaskInfo(task, "任务已注册。");
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
return this.getTaskInfo(task, "任务已存在。");
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
static getTaskInfo(task, msg) {
|
|
1787
|
+
// return Object.assign({_message_: msg}, task);
|
|
1788
|
+
return {
|
|
1789
|
+
name: task.name,
|
|
1790
|
+
caption: task.caption,
|
|
1791
|
+
cronExp: task.cronExp,
|
|
1792
|
+
state: task.schedule ? "started" : "stopped",
|
|
1793
|
+
_message_: msg
|
|
1794
|
+
};
|
|
1795
|
+
}
|
|
1796
|
+
/**
|
|
1797
|
+
* 启动任务
|
|
1798
|
+
* @param taskOrName
|
|
1799
|
+
* @param cronExp
|
|
1800
|
+
* @returns {Promise<{}|{cron: *, _message_: string}>}
|
|
1801
|
+
*/
|
|
1802
|
+
|
|
1803
|
+
|
|
1804
|
+
static async start(taskOrName, cronExp) {
|
|
1805
|
+
if (!this.envAllowed()) return {};
|
|
1806
|
+
let task = taskOrName;
|
|
1807
|
+
|
|
1808
|
+
if (typeof task === "string") {
|
|
1809
|
+
task = this.findTask(taskOrName);
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
if (!task) throw [err.INVALID_PARAM, `任务${taskOrName}不存在`];
|
|
1813
|
+
cronExp = cronExp || task.cronExp;
|
|
1814
|
+
|
|
1815
|
+
if (task.cronExp !== cronExp) {
|
|
1816
|
+
this.stop(task);
|
|
1817
|
+
task.cronExp = cronExp;
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
if (task.schedule) {
|
|
1821
|
+
return this.getTaskInfo(task, "任务已启动,无需重复启动。");
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
task.schedule = CRON.schedule(cronExp, task.doScheduleTask);
|
|
1825
|
+
task.schedule._task._pp_task = task;
|
|
1826
|
+
return this.getTaskInfo(task, "任务已启动。");
|
|
1827
|
+
}
|
|
1828
|
+
/**
|
|
1829
|
+
* 停止任务
|
|
1830
|
+
* @param taskOrName
|
|
1831
|
+
* @returns {Promise<{}|{cron: *, _message_: string}|{_message_: string}>}
|
|
1832
|
+
*/
|
|
1833
|
+
|
|
1834
|
+
|
|
1835
|
+
static async stop(taskOrName) {
|
|
1836
|
+
if (!this.envAllowed()) return {};
|
|
1837
|
+
let task = taskOrName;
|
|
1838
|
+
|
|
1839
|
+
if (typeof task === "string") {
|
|
1840
|
+
task = this.findTask(taskOrName);
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
if (!task) throw [err.INVALID_PARAM, `任务${taskOrName}不存在`];
|
|
1844
|
+
|
|
1845
|
+
if (task.schedule) {
|
|
1846
|
+
task.schedule.stop();
|
|
1847
|
+
task.schedule = null;
|
|
1848
|
+
return this.getTaskInfo(task, "任务已停止。");
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
return this.getTaskInfo(task, "任务未启动,无需停止。");
|
|
1852
|
+
}
|
|
1853
|
+
/**
|
|
1854
|
+
* 获取或设置当前状态(来自远程的API调用)
|
|
1855
|
+
* @param options
|
|
1856
|
+
* @returns {Promise<unknown>}
|
|
1857
|
+
*/
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
static async state(options) {
|
|
1861
|
+
const params = options.replacements; // await commonMessenger.parametersOK(params, "taskName");
|
|
1862
|
+
|
|
1863
|
+
const req = options._res.req;
|
|
1864
|
+
|
|
1865
|
+
if (req) {
|
|
1866
|
+
if (req.method === 'GET') {
|
|
1867
|
+
delete params.state;
|
|
1868
|
+
} else {
|
|
1869
|
+
await apiUtil$1.parametersOK(params, 'taskName', "state");
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
if (this.envAllowed()) {
|
|
1874
|
+
return this._state(params);
|
|
1875
|
+
} // 环境变量启用计划任务,但当前环境不能执行,
|
|
1876
|
+
// 说明收到此API请求的进程不是第一个进程,或者此前服务器不是第一台服务器,
|
|
1877
|
+
// 这种情况下,将此请求作为消息发布出去,
|
|
1878
|
+
// 第一台服务器的第一个进程收到消息后进行处理,再将结果作为消息发布,
|
|
1879
|
+
// 本进程收到处理结果后果作为响应发送回客户端
|
|
1880
|
+
|
|
1881
|
+
|
|
1882
|
+
if (process.env.SCHEDULE_ENABLED) {
|
|
1883
|
+
let replyId = ppUtil$1.newGuid();
|
|
1884
|
+
return await new Promise((resolve, reject) => {
|
|
1885
|
+
commonMessenger$1.setMessageHandle(message => {
|
|
1886
|
+
if (message._type === MT_SCHEDULE_STATE_REPLY && message.replyId === replyId) {
|
|
1887
|
+
replyId = '';
|
|
1888
|
+
resolve(message.result);
|
|
1889
|
+
return;
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
if (message._type === MT_SCHEDULE_STATE) {
|
|
1893
|
+
if (schedule$1.enabled()) {
|
|
1894
|
+
message.result = schedule$1._state(message.params);
|
|
1895
|
+
message._type = MT_SCHEDULE_STATE_REPLY;
|
|
1896
|
+
message.destAddr = message.replyAddr;
|
|
1897
|
+
commonMessenger$1.publishMessage(message);
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
});
|
|
1901
|
+
commonMessenger$1.publishMessage({
|
|
1902
|
+
_type: MT_SCHEDULE_STATE,
|
|
1903
|
+
replyId,
|
|
1904
|
+
replyAddr: conf.myMsgAddr,
|
|
1905
|
+
params
|
|
1906
|
+
}).catch(e => {
|
|
1907
|
+
replyId = '';
|
|
1908
|
+
reject(e);
|
|
1909
|
+
});
|
|
1910
|
+
setTimeout(() => {
|
|
1911
|
+
if (replyId) {
|
|
1912
|
+
reject("schedule.state: 等待处理结果超时");
|
|
1913
|
+
}
|
|
1914
|
+
}, 2 * 60 * 1000);
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
return {
|
|
1919
|
+
_message_: "此环境无自动任务"
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
static async _state(params) {
|
|
1924
|
+
let apiResult = {};
|
|
1925
|
+
let task;
|
|
1926
|
+
|
|
1927
|
+
if (params.taskName) {
|
|
1928
|
+
task = this.findTask(params.taskName);
|
|
1929
|
+
if (!task) throw [err.INVALID_PARAM, `任务${params.taskName}不存在`];
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
if (params.state) {
|
|
1933
|
+
if ("started" === params.state) {
|
|
1934
|
+
apiResult = await this.start(task, params.cron);
|
|
1935
|
+
} else if ("stopped" === params.state) {
|
|
1936
|
+
apiResult = await this.stop(task);
|
|
1937
|
+
} else {
|
|
1938
|
+
throw [err.INVALID_PARAM, `(${params.state}), 只能是 started/stopped`];
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
if (params.runOnce) {
|
|
1942
|
+
task = this.findTask(params.taskName);
|
|
1943
|
+
apiResult._message_ += "\n正在手动执行任务"; // await
|
|
1944
|
+
|
|
1945
|
+
task.doScheduleTask();
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
return this.getTaskInfo(task, apiResult._message_);
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
if (task) {
|
|
1952
|
+
return this.getTaskInfo(task);
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
const result = [];
|
|
1956
|
+
|
|
1957
|
+
for (let k in this.tasks) {
|
|
1958
|
+
result.push(this.getTaskInfo(this.tasks[k]));
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
return result;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
static deleteTask(taskName) {
|
|
1965
|
+
delete this.tasks[taskName];
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
static findTask(taskName) {
|
|
1969
|
+
return this.tasks[taskName];
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* 确定当前进程环境是否启用自动任务
|
|
1973
|
+
*/
|
|
1974
|
+
|
|
1975
|
+
|
|
1976
|
+
static envAllowed() {
|
|
1977
|
+
let enabled = // PM2配置中指定了环境变量 SCHEDULE_ENABLED
|
|
1978
|
+
!!process.env.SCHEDULE_ENABLED // 如果PM2启动了多个进程,则只在第一个进程执行
|
|
1979
|
+
&& process.env.NODE_APP_INSTANCE === '0'; // 如果有多台服务器,则只在第一台执行
|
|
1980
|
+
|
|
1981
|
+
if (enabled && conf.appSetting.serverHosts && conf.appSetting.serverHosts.length > 1) {
|
|
1982
|
+
enabled = conf.myMsgAddr.indexOf(conf.appSetting.serverHosts[0]) === 0;
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
return enabled;
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
var ppSchedule = schedule$1;
|
|
1774
1991
|
|
|
1775
1992
|
const apiUtil = ppUtilApi;
|
|
1776
1993
|
const preconditions = ppPrecond;
|
|
1777
1994
|
const commonMessenger = ppMessengerEx;
|
|
1995
|
+
const schedule = ppSchedule;
|
|
1778
1996
|
var ppUtil = {
|
|
1779
1997
|
apiUtil,
|
|
1780
1998
|
preconditions,
|
|
1781
|
-
commonMessenger
|
|
1999
|
+
commonMessenger,
|
|
2000
|
+
schedule
|
|
1782
2001
|
};
|
|
1783
2002
|
|
|
1784
2003
|
export { ppUtil as default };
|