@tmsfe/tms-core 0.0.173 → 0.0.175
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/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 暴露出来的工具函数封装原则:不可以向外throw错误,返回执行结果统一格式:{ success: boolean, msg: string, res: any }
|
|
4
4
|
* https://iwiki.woa.com/p/4013041987#1.-RSA+AES-%E5%88%87%E6%8D%A2-Curve25519+XSalsa20%EF%BC%9A
|
|
5
5
|
*/
|
|
6
|
-
import md5 from './md5
|
|
6
|
+
import md5 from './md5';
|
|
7
7
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
8
8
|
const ecc = require('./nacl.min.js');
|
|
9
9
|
const base64Util = require('./nacl-util.min.js');
|
|
@@ -11,6 +11,18 @@ const base64Util = require('./nacl-util.min.js');
|
|
|
11
11
|
|
|
12
12
|
const logger = wx.getLogManager({});
|
|
13
13
|
|
|
14
|
+
interface BaseResp<T> {
|
|
15
|
+
success: boolean,
|
|
16
|
+
msg: string,
|
|
17
|
+
res: T,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface CryptoKeyInfo {
|
|
21
|
+
sharedByte: Uint8Array,
|
|
22
|
+
clientPublicKey: string,
|
|
23
|
+
serverPubId: string,
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
// 出行接口域名
|
|
15
27
|
const SERVER_HOST_MAP = {
|
|
16
28
|
production: 'https://tim.map.qq.com', // 出行服务正式环境域名
|
|
@@ -22,9 +34,9 @@ const SERVER_HOST_MAP = {
|
|
|
22
34
|
|
|
23
35
|
// 基础工具
|
|
24
36
|
const baseUtil = {
|
|
25
|
-
_isObject: obj => Object.prototype.toString.call(obj) === '[object Object]',
|
|
37
|
+
_isObject: (obj: any): boolean => Object.prototype.toString.call(obj) === '[object Object]',
|
|
26
38
|
// 统一格式化日志输出
|
|
27
|
-
_formatLog(args) {
|
|
39
|
+
_formatLog(args: any[]): any[] {
|
|
28
40
|
// 小程序日志管理器都只是精确到秒,我们补上毫秒方便分析
|
|
29
41
|
const time = new Date()
|
|
30
42
|
.toISOString()
|
|
@@ -42,7 +54,7 @@ const baseUtil = {
|
|
|
42
54
|
logger.log(...items);
|
|
43
55
|
},
|
|
44
56
|
// Uint8Array转为url安全的base64编码
|
|
45
|
-
encUrl: (input) => {
|
|
57
|
+
encUrl: (input: Uint8Array): string => {
|
|
46
58
|
let base64 = base64Util.encode(input);
|
|
47
59
|
base64 = base64
|
|
48
60
|
.replace(/\+/g, '-')
|
|
@@ -51,7 +63,7 @@ const baseUtil = {
|
|
|
51
63
|
return base64;
|
|
52
64
|
},
|
|
53
65
|
// url安全的base64解码
|
|
54
|
-
decUrl: (input) => {
|
|
66
|
+
decUrl: (input: string): Uint8Array => {
|
|
55
67
|
let base64 = input.replace(/-/g, '+').replace(/_/g, '/');
|
|
56
68
|
while (base64.length % 4) {
|
|
57
69
|
base64 += '=';
|
|
@@ -59,7 +71,7 @@ const baseUtil = {
|
|
|
59
71
|
return base64Util.decode(base64);
|
|
60
72
|
},
|
|
61
73
|
// header格式化,将header的key转换为小写
|
|
62
|
-
formatHeader: (header) => {
|
|
74
|
+
formatHeader: (header): any => {
|
|
63
75
|
if (!header || !baseUtil._isObject(header)) {
|
|
64
76
|
return {};
|
|
65
77
|
}
|
|
@@ -69,7 +81,7 @@ const baseUtil = {
|
|
|
69
81
|
});
|
|
70
82
|
return formatHeader;
|
|
71
83
|
},
|
|
72
|
-
formatGetData: (params) => {
|
|
84
|
+
formatGetData: (params: any): string => {
|
|
73
85
|
if (!params || !baseUtil._isObject(params)) {
|
|
74
86
|
return '';
|
|
75
87
|
}
|
|
@@ -77,19 +89,19 @@ const baseUtil = {
|
|
|
77
89
|
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
|
78
90
|
.join('&');
|
|
79
91
|
},
|
|
80
|
-
getSinanHost: () => {
|
|
92
|
+
getSinanHost: (): string => {
|
|
81
93
|
if (wx.$_encryptEnvInfo) {
|
|
82
94
|
return SERVER_HOST_MAP[wx.$_encryptEnvInfo.envName];
|
|
83
95
|
}
|
|
84
96
|
return '';
|
|
85
97
|
},
|
|
86
|
-
getClientEncryptOpen: () => wx.$_encryptEnvInfo?.requestEncryptOpen,
|
|
87
|
-
BaseRespFac: class BaseRespFac {
|
|
88
|
-
success;
|
|
89
|
-
msg;
|
|
90
|
-
res;
|
|
98
|
+
getClientEncryptOpen: (): boolean => wx.$_encryptEnvInfo?.requestEncryptOpen,
|
|
99
|
+
BaseRespFac: class BaseRespFac<T> implements BaseResp<T> {
|
|
100
|
+
success: boolean;
|
|
101
|
+
msg: string;
|
|
102
|
+
res: T;
|
|
91
103
|
|
|
92
|
-
constructor(res, success, msg) {
|
|
104
|
+
constructor(res: T, success?: boolean, msg?: string) {
|
|
93
105
|
this.success = success === undefined ? true : success;
|
|
94
106
|
this.msg = msg === undefined ? '' : msg;
|
|
95
107
|
this.res = res;
|
|
@@ -100,7 +112,7 @@ let composeParamsFunc = null; // 请求参数处理函数,加密初始化调
|
|
|
100
112
|
// 加密工具
|
|
101
113
|
const eccUtil = {
|
|
102
114
|
_refreshPromise: null,
|
|
103
|
-
_refreshPubKeyInfo: async (forceRefresh) => {
|
|
115
|
+
_refreshPubKeyInfo: async (forceRefresh: boolean): Promise<boolean> => {
|
|
104
116
|
// 未完成初始化,则不支持秘钥刷新
|
|
105
117
|
if (!composeParamsFunc) {
|
|
106
118
|
return false;
|
|
@@ -127,7 +139,7 @@ const eccUtil = {
|
|
|
127
139
|
return eccUtil._refreshPromise;
|
|
128
140
|
},
|
|
129
141
|
// 解析resHeader详情,更新全局公钥信息
|
|
130
|
-
_updateGlobalPublicKeyInfo: (clear, resHeader) => {
|
|
142
|
+
_updateGlobalPublicKeyInfo: (clear: boolean, resHeader?: {[key: string]: any}): BaseResp<boolean> => {
|
|
131
143
|
if (clear) {
|
|
132
144
|
wx.$_publicKey = null;
|
|
133
145
|
return;
|
|
@@ -142,7 +154,7 @@ const eccUtil = {
|
|
|
142
154
|
return new baseUtil.BaseRespFac(success);
|
|
143
155
|
},
|
|
144
156
|
_privateKeyInfo: null,
|
|
145
|
-
getPrivateKeyInfo: (forceUpdate = false) => {
|
|
157
|
+
getPrivateKeyInfo: (forceUpdate = false): CryptoKeyInfo => {
|
|
146
158
|
if (!wx.$_publicKey) return null;
|
|
147
159
|
const serverPubInfo = wx.$_publicKey;
|
|
148
160
|
if (forceUpdate || !eccUtil._privateKeyInfo || eccUtil._privateKeyInfo.serverPubId !== serverPubInfo.pubId) {
|
|
@@ -157,7 +169,7 @@ const eccUtil = {
|
|
|
157
169
|
},
|
|
158
170
|
// 解析gwCode
|
|
159
171
|
/* eslint-disable complexity */
|
|
160
|
-
resolveGwCode: async (codeStr) => {
|
|
172
|
+
resolveGwCode: async (codeStr: string): Promise<{ retry: boolean, success: boolean }> => {
|
|
161
173
|
if (!codeStr) return { retry: false, success: true };
|
|
162
174
|
const code = parseInt(codeStr, 10);
|
|
163
175
|
switch (code) {
|
|
@@ -190,7 +202,7 @@ const eccUtil = {
|
|
|
190
202
|
},
|
|
191
203
|
_getSignSharedByte: () => baseUtil.decUrl('mEufQpM1n5J8-OZZoJE7ucYMC2suTjfsHUq_6z5cyh8'),
|
|
192
204
|
// 计算客户端加密签名
|
|
193
|
-
getClientCryptoSign: (data = {}, header = {}, sharedByte) => {
|
|
205
|
+
getClientCryptoSign: (data = {}, header = {}, sharedByte): string => {
|
|
194
206
|
const obj = baseUtil.formatHeader(Object.assign({}, data, header));
|
|
195
207
|
// 1. 生成签名前的字符串
|
|
196
208
|
const str = Object.keys(obj).filter(item => obj[item])
|
|
@@ -211,12 +223,12 @@ const eccUtil = {
|
|
|
211
223
|
return baseUtil.encUrl(combined);
|
|
212
224
|
},
|
|
213
225
|
// 验证服务端加密签名
|
|
214
|
-
verifyServerCryptoSign: (traceId, resHeader = {}) => {
|
|
226
|
+
verifyServerCryptoSign: (traceId: string, resHeader = {}): { verified: boolean; msg: string; } => {
|
|
215
227
|
try {
|
|
216
228
|
const formatHeader = baseUtil.formatHeader(resHeader);
|
|
217
229
|
const signStr = formatHeader['x-crypto-sign'];
|
|
218
230
|
if (!signStr) {
|
|
219
|
-
return false;
|
|
231
|
+
return { verified: false, msg: '服务端无签名信息' };
|
|
220
232
|
}
|
|
221
233
|
const obj = {
|
|
222
234
|
'x-encrypt-key': formatHeader['x-encrypt-key'],
|
|
@@ -241,17 +253,17 @@ const eccUtil = {
|
|
|
241
253
|
return pre;
|
|
242
254
|
}, [])
|
|
243
255
|
.join('&');
|
|
244
|
-
baseUtil.logInfo('---验证服务端的客户端签名---:before', str, traceId);
|
|
245
256
|
const preHashArr = md5(str);
|
|
246
257
|
const verified = preHashArr.length === decrypted.length && preHashArr.every((v, i) => v === decrypted[i]);
|
|
247
|
-
return verified;
|
|
258
|
+
return { verified, msg: `客户端验证签名before:${str}` };
|
|
248
259
|
} catch (e) {
|
|
249
|
-
|
|
250
|
-
return false;
|
|
260
|
+
return { verified: false, msg: e.message };
|
|
251
261
|
}
|
|
252
262
|
},
|
|
253
263
|
/* eslint-enable complexity */
|
|
254
|
-
execEncrypt: (input, ignoreNull = false)
|
|
264
|
+
execEncrypt: (input: string, ignoreNull = false): BaseResp<{
|
|
265
|
+
cryptoKeyInfo: CryptoKeyInfo,
|
|
266
|
+
encryptedContent: any } | null> => {
|
|
255
267
|
try {
|
|
256
268
|
const eccKeyInfo = eccUtil.getPrivateKeyInfo();
|
|
257
269
|
if (!eccKeyInfo) {
|
|
@@ -276,7 +288,7 @@ const eccUtil = {
|
|
|
276
288
|
return new baseUtil.BaseRespFac(null, false, `execEncrypt失败:${JSON.stringify(e)}`);
|
|
277
289
|
}
|
|
278
290
|
},
|
|
279
|
-
execDecrypt: (msg, cryptoKeyInfo) => {
|
|
291
|
+
execDecrypt: (msg: Uint8Array, cryptoKeyInfo: CryptoKeyInfo): BaseResp<string> => {
|
|
280
292
|
try {
|
|
281
293
|
const { sharedByte } = cryptoKeyInfo;
|
|
282
294
|
const nonce = msg.slice(0, ecc.box.nonceLength);
|
|
@@ -288,12 +300,12 @@ const eccUtil = {
|
|
|
288
300
|
return new baseUtil.BaseRespFac('', false, `execDecrypt失败:${JSON.stringify(err)}`);;
|
|
289
301
|
}
|
|
290
302
|
},
|
|
291
|
-
checkCryptoOpen: () => !!eccUtil._privateKeyInfo,
|
|
303
|
+
checkCryptoOpen: (): boolean => !!eccUtil._privateKeyInfo,
|
|
292
304
|
closeCrypto: () => {
|
|
293
305
|
eccUtil._privateKeyInfo = null;
|
|
294
306
|
eccUtil._updateGlobalPublicKeyInfo(true);
|
|
295
307
|
},
|
|
296
|
-
openCrypto: async () => {
|
|
308
|
+
openCrypto: async (): Promise<boolean> => {
|
|
297
309
|
const genPubSuccess = await eccUtil._refreshPubKeyInfo(false); // 1. 获取公钥
|
|
298
310
|
if (!genPubSuccess) return false;
|
|
299
311
|
eccUtil.getPrivateKeyInfo(); // 2. 生成私钥
|
|
@@ -303,9 +315,9 @@ const eccUtil = {
|
|
|
303
315
|
// 加密规则判断工具
|
|
304
316
|
const cryptRuleUtil = {
|
|
305
317
|
// 远程加密服务是否开启
|
|
306
|
-
isServerOpen: () => !!wx.$_publicKey,
|
|
318
|
+
isServerOpen: (): boolean => !!wx.$_publicKey,
|
|
307
319
|
// 检查path是否符合下发的路由前缀
|
|
308
|
-
pathInEnablePrefix: (path) => {
|
|
320
|
+
pathInEnablePrefix: (path: string): boolean => {
|
|
309
321
|
if (!wx.$_publicKey) {
|
|
310
322
|
return false;
|
|
311
323
|
}
|
|
@@ -322,7 +334,7 @@ const cryptRuleUtil = {
|
|
|
322
334
|
return false;
|
|
323
335
|
},
|
|
324
336
|
// 判断是否是性能埋点上报接口
|
|
325
|
-
isPerformanceReport: (path, params) => {
|
|
337
|
+
isPerformanceReport: (path: string, params: any): boolean => {
|
|
326
338
|
// 如果是日志上报接口,需要过滤性能日志,不需要加密
|
|
327
339
|
if (path.indexOf('basic/event/upload') > -1) {
|
|
328
340
|
if (params.batch?.length === 1 && params.batch[0]?.[31] === 'tms-performance-log') {
|
|
@@ -366,13 +378,13 @@ const cryptRuleUtil = {
|
|
|
366
378
|
};
|
|
367
379
|
|
|
368
380
|
// 初始化加密工具
|
|
369
|
-
const init = (composeFunc) => {
|
|
381
|
+
const init = (composeFunc: Function): BaseResp<null> => {
|
|
370
382
|
composeParamsFunc = (...args) => composeFunc(...args); // 加密服务器公共参数
|
|
371
383
|
return new baseUtil.BaseRespFac(null);
|
|
372
384
|
};
|
|
373
385
|
|
|
374
386
|
// 判断是否满足加密规则
|
|
375
|
-
const isCryptoRuleMath = (path, reqData) => {
|
|
387
|
+
const isCryptoRuleMath = (path: string, reqData: any): BaseResp<boolean> => {
|
|
376
388
|
if (!wx.$_encryptEnvInfo.requestEncryptOpen) {
|
|
377
389
|
return new baseUtil.BaseRespFac(false, false, '本地加密未开启');
|
|
378
390
|
}
|
|
@@ -395,7 +407,12 @@ const isCryptoRuleMath = (path, reqData) => {
|
|
|
395
407
|
return new baseUtil.BaseRespFac(true);;
|
|
396
408
|
};
|
|
397
409
|
// 请求加密
|
|
398
|
-
const reqEncrypt = (method, data, header
|
|
410
|
+
const reqEncrypt = (method: string, data: any, header: {
|
|
411
|
+
[key: string]: any }, encryptedResponseHeaderName: string): BaseResp<{
|
|
412
|
+
cryptoKeyInfo: CryptoKeyInfo,
|
|
413
|
+
header: any,
|
|
414
|
+
data: any,
|
|
415
|
+
} | null> => {
|
|
399
416
|
const reqHeader = baseUtil.formatHeader(header);
|
|
400
417
|
if (reqHeader.contentType) {
|
|
401
418
|
return new baseUtil.BaseRespFac(null, false, '户自定义了请求contentType');
|
|
@@ -446,7 +463,11 @@ const reqEncrypt = (method, data, header, encryptedResponseHeaderName) => {
|
|
|
446
463
|
});
|
|
447
464
|
};
|
|
448
465
|
// 解密请求结果
|
|
449
|
-
const resDecrypt = async (requestTraceId, header, data, cryptoKeyInfo)
|
|
466
|
+
const resDecrypt = async (requestTraceId: string, header, data, cryptoKeyInfo: CryptoKeyInfo): Promise<BaseResp<{
|
|
467
|
+
retry: boolean, // 是否需要明文重试
|
|
468
|
+
header: any,
|
|
469
|
+
data: any,
|
|
470
|
+
}>> => {
|
|
450
471
|
try {
|
|
451
472
|
const formatHeader = baseUtil.formatHeader(header);
|
|
452
473
|
const {
|
|
@@ -468,10 +489,10 @@ const resDecrypt = async (requestTraceId, header, data, cryptoKeyInfo) => {
|
|
|
468
489
|
const { retry, success: gwSuccess } = await eccUtil.resolveGwCode(gatewayCode);
|
|
469
490
|
if (!gwSuccess) {
|
|
470
491
|
// 网关加密流程出现问题,需要验证网关签名
|
|
471
|
-
const verified = eccUtil.verifyServerCryptoSign(requestTraceId, header);
|
|
492
|
+
const { verified, msg } = eccUtil.verifyServerCryptoSign(requestTraceId, header);
|
|
472
493
|
if (!verified) {
|
|
473
494
|
// 验证失败,表示请求被篡改
|
|
474
|
-
return new baseUtil.BaseRespFac({ header: null, data: null, retry: false }, false,
|
|
495
|
+
return new baseUtil.BaseRespFac({ header: null, data: null, retry: false }, false, `响应被篡改:${msg}`);
|
|
475
496
|
}
|
|
476
497
|
return new baseUtil.BaseRespFac({ header: null, data: null, retry }, false, `网关返回错误码: ${gatewayCode}`);
|
|
477
498
|
}
|
|
@@ -505,21 +526,20 @@ const resDecrypt = async (requestTraceId, header, data, cryptoKeyInfo) => {
|
|
|
505
526
|
};
|
|
506
527
|
// 处理接下来的请求开关
|
|
507
528
|
let dealEncryptionSwitching = false;
|
|
508
|
-
const dealEncryptionSwitch = async (path, traceId, resHeader) => {
|
|
529
|
+
const dealEncryptionSwitch = async (path: string, traceId: string, resHeader): Promise<string> => {
|
|
509
530
|
if ((!resHeader || dealEncryptionSwitching)) {
|
|
510
|
-
return;
|
|
531
|
+
return '';
|
|
511
532
|
}
|
|
512
533
|
dealEncryptionSwitching = true;
|
|
513
534
|
const formatHeader = baseUtil.formatHeader(resHeader);
|
|
514
535
|
// 加密关闭或者`login接口和lastkey接口`,都需要先执行验签
|
|
515
536
|
const cryptoDisabled = formatHeader['x-crypto-enable'] === '0';
|
|
516
537
|
if ((eccUtil.checkCryptoOpen() && cryptoDisabled)) {
|
|
517
|
-
const verified = eccUtil.verifyServerCryptoSign(traceId, formatHeader);
|
|
538
|
+
const { verified, msg } = eccUtil.verifyServerCryptoSign(traceId, formatHeader);
|
|
518
539
|
if (!verified) {
|
|
519
540
|
// 验签失败,表示响应被篡改
|
|
520
541
|
dealEncryptionSwitching = false;
|
|
521
|
-
|
|
522
|
-
return;
|
|
542
|
+
return `验签失败: ${msg}`;
|
|
523
543
|
}
|
|
524
544
|
}
|
|
525
545
|
if (cryptoDisabled) {
|
|
@@ -528,7 +548,7 @@ const dealEncryptionSwitch = async (path, traceId, resHeader) => {
|
|
|
528
548
|
await eccUtil.openCrypto();
|
|
529
549
|
} // 0是关闭,1是开启, 2是保持
|
|
530
550
|
dealEncryptionSwitching = false;
|
|
531
|
-
return;
|
|
551
|
+
return '';
|
|
532
552
|
};
|
|
533
553
|
|
|
534
554
|
/**
|
|
@@ -536,17 +556,17 @@ const dealEncryptionSwitch = async (path, traceId, resHeader) => {
|
|
|
536
556
|
* @params path traceId resHeader reqData
|
|
537
557
|
* @returns 是否需要根据响应内容处理加密开关
|
|
538
558
|
*/
|
|
539
|
-
const dealRes = (path, traceId, resHeader, reqData) => {
|
|
559
|
+
const dealRes = (path: string, traceId: string, resHeader, reqData): BaseResp<boolean> => {
|
|
540
560
|
const specialPath = [
|
|
541
561
|
`${baseUtil.getSinanHost()}/user/login`,
|
|
542
562
|
`${baseUtil.getSinanHost()}/basic/crypto/lastkey2`,
|
|
543
563
|
].indexOf(path) > -1;
|
|
544
564
|
if (specialPath) {
|
|
545
565
|
const formatHeader = baseUtil.formatHeader(resHeader);
|
|
546
|
-
const verified = eccUtil.verifyServerCryptoSign(traceId, formatHeader);
|
|
566
|
+
const { verified, msg } = eccUtil.verifyServerCryptoSign(traceId, formatHeader);
|
|
547
567
|
if (!verified) {
|
|
548
568
|
// 验签失败,表示响应被篡改
|
|
549
|
-
return new baseUtil.BaseRespFac(false, false, `验签失败: ${
|
|
569
|
+
return new baseUtil.BaseRespFac(false, false, `验签失败: ${msg}`);
|
|
550
570
|
}
|
|
551
571
|
eccUtil._updateGlobalPublicKeyInfo(false, resHeader);
|
|
552
572
|
}
|
|
@@ -7,7 +7,8 @@ const util = {
|
|
|
7
7
|
reportFunc: (...args) => {
|
|
8
8
|
util.logInfo('reportFunc init fail:', ...args);
|
|
9
9
|
},
|
|
10
|
-
reqEncrypt: (obj)
|
|
10
|
+
reqEncrypt: (obj: { url: string, method: string, data: any, header: any }): {
|
|
11
|
+
data: any, header: any, msg: string, cryptoKeyInfo?: any } => {
|
|
11
12
|
const { url, method, data, header = {} } = obj;
|
|
12
13
|
// 判断请求是否满足加密要求,如果不满足则走默认请求
|
|
13
14
|
const { success, msg } = encryptUtil.isCryptoRuleMath(url, data);
|
|
@@ -45,12 +46,13 @@ const requestInit = (utilFunc) => {
|
|
|
45
46
|
}
|
|
46
47
|
};
|
|
47
48
|
|
|
48
|
-
function proxyWxRequest() {
|
|
49
|
+
function proxyWxRequest(): void {
|
|
49
50
|
Object.defineProperty(wx, 'request', {
|
|
50
51
|
writable: true,
|
|
51
52
|
enumerable: true,
|
|
52
53
|
configurable: true,
|
|
53
|
-
value(options) {
|
|
54
|
+
value(options: any) {
|
|
55
|
+
const startTime = Date.now();
|
|
54
56
|
const { url, method, data, header = {}, success, fail, complete, dataType, responseType } = options;
|
|
55
57
|
const traceparent = genTraceparent();
|
|
56
58
|
const traceId = traceparent.split('-')[1];
|
|
@@ -62,7 +64,9 @@ function proxyWxRequest() {
|
|
|
62
64
|
originalRequestApi.call(this, {
|
|
63
65
|
...originalOptions,
|
|
64
66
|
success: (res) => {
|
|
65
|
-
encryptUtil.dealEncryptionSwitch(url, traceId, res.header)
|
|
67
|
+
encryptUtil.dealEncryptionSwitch(url, traceId, res.header).then((msg) => {
|
|
68
|
+
msg && util.reportFunc(url, traceId, msg);
|
|
69
|
+
});
|
|
66
70
|
success?.call(this, res);
|
|
67
71
|
},
|
|
68
72
|
header: { ...header, Traceparent: traceparent },
|
|
@@ -79,13 +83,16 @@ function proxyWxRequest() {
|
|
|
79
83
|
...originalOptions,
|
|
80
84
|
success: async (res) => {
|
|
81
85
|
const {
|
|
82
|
-
success: dealSuccess,
|
|
86
|
+
success: dealSuccess,
|
|
87
|
+
msg, res: needDealHeader } = encryptUtil.dealRes(url, traceId, res.header, formatData);
|
|
83
88
|
// 性能埋点接口不走验签逻辑
|
|
84
89
|
if (dealSuccess) {
|
|
85
|
-
needDealHeader && encryptUtil.dealEncryptionSwitch(url, traceId, res.header)
|
|
90
|
+
needDealHeader && encryptUtil.dealEncryptionSwitch(url, traceId, res.header).then((msg) => {
|
|
91
|
+
msg && util.reportFunc(url, traceId, msg);
|
|
92
|
+
});
|
|
86
93
|
success?.call(this, res);
|
|
87
94
|
} else {
|
|
88
|
-
util.reportFunc(url, traceparent, `加密验签不通过: ${JSON.stringify(res)}`);
|
|
95
|
+
util.reportFunc(url, traceparent, msg, `加密验签不通过: ${JSON.stringify(res)}`);
|
|
89
96
|
fail?.call(this, new Error('加密验签不通过'));
|
|
90
97
|
}
|
|
91
98
|
},
|
|
@@ -105,9 +112,21 @@ function proxyWxRequest() {
|
|
|
105
112
|
dataType: '其他',
|
|
106
113
|
responseType: 'arraybuffer',
|
|
107
114
|
success: async (result) => {
|
|
115
|
+
// 网络响应耗时
|
|
116
|
+
wx.reportEvent?.('cost_encrypt_statistic', {
|
|
117
|
+
period: 'receive_data',
|
|
118
|
+
cost: Date.now() - startTime,
|
|
119
|
+
path: originalOptions.url,
|
|
120
|
+
});
|
|
108
121
|
const { header: resHeader, data: resData } = result;
|
|
109
122
|
const { success: decSuccess, msg, res } = await encryptUtil
|
|
110
123
|
.resDecrypt(traceId, resHeader, resData, cryptoKeyInfo);
|
|
124
|
+
// 解密响应耗时
|
|
125
|
+
wx.reportEvent?.('cost_encrypt_statistic', {
|
|
126
|
+
period: 'decrypt_data',
|
|
127
|
+
cost: Date.now() - startTime,
|
|
128
|
+
path: originalOptions.url,
|
|
129
|
+
});
|
|
111
130
|
if (res.retry) { // 解密出现问题,需要明文重试
|
|
112
131
|
util.reportFunc(url, traceparent, `解密失败:${msg}`);
|
|
113
132
|
const newTraceparent = genTraceparent();
|
|
@@ -115,8 +134,16 @@ function proxyWxRequest() {
|
|
|
115
134
|
originalRequestApi.call(this, {
|
|
116
135
|
...originalOptions,
|
|
117
136
|
success: (res) => {
|
|
118
|
-
encryptUtil.dealEncryptionSwitch(url, traceId, res.header)
|
|
137
|
+
encryptUtil.dealEncryptionSwitch(url, traceId, res.header).then((msg) => {
|
|
138
|
+
msg && util.reportFunc(url, traceId, msg);
|
|
139
|
+
});
|
|
119
140
|
success?.call(this, res);
|
|
141
|
+
// 接口重试耗时
|
|
142
|
+
wx.reportEvent?.('cost_encrypt_statistic', {
|
|
143
|
+
period: 'retry_request',
|
|
144
|
+
cost: Date.now() - startTime,
|
|
145
|
+
path: originalOptions.url,
|
|
146
|
+
});
|
|
120
147
|
},
|
|
121
148
|
header: { ...header, Traceparent: newTraceparent },
|
|
122
149
|
});
|
|
@@ -124,36 +151,50 @@ function proxyWxRequest() {
|
|
|
124
151
|
}
|
|
125
152
|
if (decSuccess) {
|
|
126
153
|
// util.logInfo(url, traceparent, '解密成功');
|
|
127
|
-
encryptUtil.dealEncryptionSwitch(url, traceId, resHeader)
|
|
154
|
+
encryptUtil.dealEncryptionSwitch(url, traceId, resHeader).then((msg) => {
|
|
155
|
+
msg && util.reportFunc(url, traceId, msg);
|
|
156
|
+
});
|
|
128
157
|
success?.call(this, res);
|
|
158
|
+
// 响应回调耗时
|
|
159
|
+
wx.reportEvent?.('cost_encrypt_statistic', {
|
|
160
|
+
period: 'response_callback',
|
|
161
|
+
cost: Date.now() - startTime,
|
|
162
|
+
path: originalOptions.url,
|
|
163
|
+
});
|
|
129
164
|
} else { // 不支持明文重试,且解密失败
|
|
130
165
|
util.reportFunc(url, traceparent, `解密失败:${msg}`);
|
|
131
166
|
fail?.call(this, new Error(msg));
|
|
132
167
|
}
|
|
133
|
-
const completeRes = await completePromp;
|
|
168
|
+
const completeRes: any = await completePromp;
|
|
134
169
|
completeRes.header = resHeader;
|
|
135
170
|
completeRes.data = resData;
|
|
136
171
|
complete?.call(this, completeRes);
|
|
137
172
|
},
|
|
138
173
|
fail: async (err) => {
|
|
139
174
|
fail?.call(this, err);
|
|
140
|
-
const completeRes = await completePromp;
|
|
175
|
+
const completeRes: any = await completePromp;
|
|
141
176
|
complete?.call(this, completeRes);
|
|
142
177
|
},
|
|
143
178
|
complete: (res) => {
|
|
144
179
|
completeResolver(res);
|
|
145
180
|
},
|
|
146
181
|
});
|
|
182
|
+
// 加密请求准备耗时
|
|
183
|
+
wx.reportEvent?.('cost_encrypt_statistic', {
|
|
184
|
+
period: 'before_request',
|
|
185
|
+
cost: Date.now() - startTime,
|
|
186
|
+
path: url,
|
|
187
|
+
});
|
|
147
188
|
},
|
|
148
189
|
});
|
|
149
190
|
}
|
|
150
191
|
|
|
151
|
-
function proxyWxUploadFile() {
|
|
192
|
+
function proxyWxUploadFile(): void {
|
|
152
193
|
Object.defineProperty(wx, 'uploadFile', {
|
|
153
194
|
writable: true,
|
|
154
195
|
enumerable: true,
|
|
155
196
|
configurable: true,
|
|
156
|
-
value(options) {
|
|
197
|
+
value(options: any) {
|
|
157
198
|
originalUploadFileApi.call(this, Object.assign(options, {
|
|
158
199
|
header: { ...options.header, Traceparent: genTraceparent() },
|
|
159
200
|
}));
|
|
@@ -161,7 +202,10 @@ function proxyWxUploadFile() {
|
|
|
161
202
|
});
|
|
162
203
|
}
|
|
163
204
|
|
|
164
|
-
export const encryptObjInit = (utilFunc
|
|
205
|
+
export const encryptObjInit = (utilFunc: {
|
|
206
|
+
composeParamsFunc: Function,
|
|
207
|
+
report: Function,
|
|
208
|
+
}) => {
|
|
165
209
|
// 劫持wx.request和wx.uploadFile函数
|
|
166
210
|
requestInit(utilFunc);
|
|
167
211
|
};
|
package/src/env.js
CHANGED
|
@@ -30,10 +30,10 @@ const getAuthInfoQueue = [];
|
|
|
30
30
|
* @example
|
|
31
31
|
* setAuthInfo({
|
|
32
32
|
firstLogin: 0
|
|
33
|
-
openId: "
|
|
34
|
-
token: "
|
|
35
|
-
uid: "
|
|
36
|
-
unionId: "
|
|
33
|
+
openId: "xxx"
|
|
34
|
+
token: "xxx"
|
|
35
|
+
uid: "xxx"
|
|
36
|
+
unionId: "xxx"
|
|
37
37
|
* })
|
|
38
38
|
*/
|
|
39
39
|
export const setAuthInfo = (authInfo, err) => {
|
|
@@ -54,10 +54,10 @@ export const setAuthInfo = (authInfo, err) => {
|
|
|
54
54
|
* const data = await getAuthInfo()
|
|
55
55
|
{
|
|
56
56
|
firstLogin: 0 // 是否第一次登录
|
|
57
|
-
openId: "
|
|
58
|
-
token: "
|
|
59
|
-
uid: "
|
|
60
|
-
unionId: "
|
|
57
|
+
openId: "xxx"
|
|
58
|
+
token: "xxx"
|
|
59
|
+
uid: "xxx"
|
|
60
|
+
unionId: "xxx"
|
|
61
61
|
}
|
|
62
62
|
*/
|
|
63
63
|
export const getAuthInfo = async () => {
|