@tmsfe/tms-core 0.0.139 → 0.0.141

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmsfe/tms-core",
3
- "version": "0.0.139",
3
+ "version": "0.0.141",
4
4
  "description": "tms运行时框架",
5
5
  "repository": {
6
6
  "type": "git",
package/src/encrypt.js CHANGED
@@ -13,11 +13,11 @@ import JSEncrypt from './jsencrypt.min.js';
13
13
  const funAes = require('./aes.js');
14
14
  // 加密模式
15
15
  const ENCRYPT_MODE_ENUM = {
16
- ASYMMETRIC_ENCRYPT_1: 1, // 非对称加密
17
- NO_ENCRYPT_0: 0, // 不加密
18
- ENCRYPT_COMPRESS: 1, // 加密压缩
19
- ENCRYPT_NOCOMPRESS_2: 2, // 加密不压缩
20
- NOENCRYPT_NOCOMPRESS_0: 0, // 不加密不压缩
16
+ ASYMMETRIC_ENCRYPT_1: '1', // 非对称加密
17
+ NO_ENCRYPT_0: '0', // 不加密
18
+ ENCRYPT_COMPRESS: '1', // 加密压缩
19
+ ENCRYPT_NOCOMPRESS_2: '2', // 加密不压缩
20
+ NOENCRYPT_NOCOMPRESS_0: '0', // 不加密不压缩
21
21
  };
22
22
  // -----------------------------------------------工具函数定义开始-----------------------------------------------------
23
23
  // -----------------------------------------------------------------------------------------------------------------
@@ -66,6 +66,7 @@ const _getPrivateKeyInfo = (enforceUpdate) => {
66
66
  privateKeyInfo = {
67
67
  aesKey,
68
68
  encryptAesKey,
69
+ publicKeyId: _getEccPublicId(),
69
70
  };
70
71
  }
71
72
  return privateKeyInfo;
@@ -129,41 +130,46 @@ const _aesDecrypt = (cipherText, aesKey) => {
129
130
  */
130
131
  const reqEncrypt = (method, params = {}, header = {}, encryptedResponseHeaderName = '') => {
131
132
  let finalData = params;
133
+ const { aesKey, encryptAesKey, publicKeyId } = _getPrivateKeyInfo();
132
134
  // 1. 处理请求参数
133
135
  if (method.toUpperCase() === 'GET') {
134
136
  const searchParams = Object.keys(params)
135
137
  .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
136
138
  .join('&');
137
- const encodedParams = _aesEncrypt(searchParams, _getPrivateKeyInfo().aesKey);
139
+ const encodedParams = _aesEncrypt(searchParams, aesKey);
138
140
  finalData = { tmsec: encodedParams };
139
141
  } else {
140
- finalData = _aesEncrypt(JSON.stringify(params), _getPrivateKeyInfo().aesKey);
142
+ finalData = _aesEncrypt(JSON.stringify(params), aesKey);
141
143
  }
142
144
  // 2. 处理Headers
143
- const encodedHeaders = _aesEncrypt(JSON.stringify(header), _getPrivateKeyInfo().aesKey);
145
+ const encodedHeaders = _aesEncrypt(JSON.stringify(header), aesKey);
144
146
  return {
145
147
  header: {
146
148
  'X-Encrypt-Mode': ENCRYPT_MODE_ENUM.ASYMMETRIC_ENCRYPT_1,
147
149
  'X-Compress-Mode': 'none',
148
150
  'X-Encrypted-Headers': encodedHeaders,
149
- 'X-Encrypt-Pub': _getEccPublicId(),
150
- 'X-Encrypt-Key': _getPrivateKeyInfo().encryptAesKey,
151
+ 'X-Encrypt-Pub': publicKeyId,
152
+ 'X-Encrypt-Key': encryptAesKey,
151
153
  'X-Encrypt-Response': ENCRYPT_MODE_ENUM.ENCRYPT_NOCOMPRESS_2,
152
154
  'X-Response-Header-Name': encryptedResponseHeaderName,
153
155
  },
154
156
  data: finalData,
155
- aesKey: _getPrivateKeyInfo().aesKey,
157
+ aesKey,
156
158
  };
157
159
  };
158
160
 
159
161
  // 解密请求结果
160
162
  const resDecrypt = (aesKey, header, data) => {
163
+ const formatHeader = {};
164
+ Object.keys(header).forEach((key) => {
165
+ formatHeader[key.toLocaleLowerCase()] = header[key];
166
+ });
161
167
  const {
162
168
  // 'x-encrypt-key': encryptKey, // 使用ECC公钥加密后的AES秘钥
163
169
  'x-encrypt-response': encryptResponse, // 期望的响应加密模式1: 加密、压缩 2: 加密、不压缩
164
170
  'x-response-headfer-name': encryptedResponseHeaderName, // 需要加密的响应Header: X-Header1,X-Header2
165
171
  'x-encrypted-headers': encryptedHeaders, // 加密后的Header信息
166
- } = header;
172
+ } = formatHeader;
167
173
  if (!encryptResponse || encryptResponse === ENCRYPT_MODE_ENUM.NOENCRYPT_NOCOMPRESS_0) {
168
174
  // 不需要解密,直接返回
169
175
  return {
@@ -201,7 +207,12 @@ const resDecrypt = (aesKey, header, data) => {
201
207
  * 更新秘钥信息:更新公钥,同时生成新的私钥
202
208
  * @param {String: publicKey, Number: expireDate, String: id } param0
203
209
  */
204
- const updateDecryptKey = ({ publicKey, expireDate, id }) => {
210
+ const updateDecryptKey = (publicKeyInfo) => {
211
+ if (!publicKeyInfo) {
212
+ wx.$_publicKey = null;
213
+ return;
214
+ }
215
+ const { publicKey, expireDate, id } = publicKeyInfo;
205
216
  // 1. 存储新的公钥
206
217
  wx.$_publicKey = {
207
218
  publicKey,
@@ -73,6 +73,7 @@ function report2(...data: any[]): void {
73
73
  function reportPerformance(...data: any[]): void {
74
74
  data.unshift('tms-performance-log');
75
75
  fastReport2(...data);
76
+ console.log('tms-performance-log', ...data);
76
77
  }
77
78
 
78
79
  /**
package/src/request.js CHANGED
@@ -347,11 +347,17 @@ export default class Request {
347
347
  }
348
348
 
349
349
  // wx请求封装成promise
350
- async wxRequest(path, method, header, data) {
350
+ async wxRequest(path, method, header = {}, data, needReport = false) {
351
+ if (needReport && path.indexOf('basic/event/upload') < 0) {
352
+ reporter.reportPerformance(
353
+ 'request_encrypt_log', 'main', 'send_unencrypt_request', data.seqId,
354
+ !!wx.$_publicKey, Request.requestEncryptOpen, path,
355
+ );
356
+ }
351
357
  return new Promise((resolve, reject) => {
352
358
  wx.request({
353
359
  url: path,
354
- header,
360
+ header: { ...header, 'X-Trace-Id': data.seqId },
355
361
  method,
356
362
  data,
357
363
  enableHttp2: true,
@@ -366,8 +372,13 @@ export default class Request {
366
372
  }
367
373
 
368
374
  async refreshEncryptKey() {
369
- const res = await this.doRequest('/basic/crypto/lastkey', {}, 'GET', {});
370
- encryptObj.updateDecryptKey(res.data.resData);
375
+ try {
376
+ const res = await this.doRequest('/basic/crypto/lastkey', {}, 'GET', {});
377
+ encryptObj.updateDecryptKey(res.data.resData);
378
+ } catch (e) {
379
+ encryptObj.updateDecryptKey(null);
380
+ reporter.reportPerformance('request_encrypt_log', 'main', 'refresh_encrypt_key_false', e);
381
+ }
371
382
  }
372
383
 
373
384
  // 如果全局请求加密开关关闭 || 当前请求内容不满足加密规则(publickey不为空且走sinan网关且非性能上报埋点)
@@ -378,6 +389,27 @@ export default class Request {
378
389
  return true;
379
390
  }
380
391
 
392
+ async dealEncryptionSwitch(resHeader) {
393
+ if (!resHeader || this.dealEncryptionSwitching) {
394
+ return false;
395
+ }
396
+ this.dealEncryptionSwitching = true;
397
+ const formatHeader = {};
398
+ Object.keys(resHeader).forEach(key => formatHeader[key.toLowerCase()] = resHeader[key]);
399
+ const encryptionAvaliable = formatHeader['x-encryption-available'] === '0';
400
+ if (encryptionAvaliable) {
401
+ // 关闭接下来请求的加密开关
402
+ wx.$_publicKey = null;
403
+ return false;
404
+ }
405
+ // 打开开关,如果当前是关闭状态,则需要刷新加密key
406
+ if (!wx.$_publicKey) {
407
+ await this.refreshEncryptKey();
408
+ }
409
+ this.dealEncryptionSwitching = false;
410
+ return true;
411
+ }
412
+
381
413
  /**
382
414
  * 创建发送请求任务
383
415
  * @memberof Request
@@ -428,7 +460,7 @@ export default class Request {
428
460
  };
429
461
  // 当前请求不加密 || 不满足加密前提
430
462
  if (!doEncrypt || !this.checkIfNeedEncrypt(finalUrl, data)) {
431
- return this.wxRequest(finalUrl, method, header, data)
463
+ return this.wxRequest(finalUrl, method, header, data, true)
432
464
  .then((res) => {
433
465
  printLog(true, res.data);
434
466
  return res;
@@ -456,18 +488,25 @@ export default class Request {
456
488
  reporter.reportPerformance('request_encrypt_log', 'main', 'decrypt_response_success', data.seqId);
457
489
  // 4. 处理解密失败的响应
458
490
  switch (decryptData.errCode) {
459
- case 11: // 公钥id失效
460
- case 12: // 公钥已过期
461
- case 13: // aes秘钥无效
462
- if (retryTimes > 1) {
491
+ case 11: // 公钥id失效
492
+ case 12: // 公钥已过期
493
+ case 13: { // aes秘钥无效
494
+ reporter.reportPerformance(
495
+ 'request_encrypt_log', 'main', 'remote_response_decrypt_fail',
496
+ data.seqId, decryptData.errCode, retryTimes,
497
+ );
498
+ if (retryTimes > 2) {
463
499
  throw new Error('解密失败,请重试');
464
500
  }
465
- reporter.reportPerformance('request_encrypt_log', 'main', 'remote_response_decrypt_fail', data.seqId, decryptData.errCode);
466
501
  await this.refreshEncryptKey();
467
502
  return this.createRequestTask(path, param, method, header, true, retryTimes + 1);
503
+ }
468
504
  case 14: // 解密失败
469
505
  // 请求不加密重试
470
- reporter.reportPerformance('request_encrypt_log', 'main', 'remote_response_decrypt_fail', data.seqId, decryptData.errCode);
506
+ reporter.reportPerformance(
507
+ 'request_encrypt_log', 'main', 'remote_response_decrypt_fail',
508
+ data.seqId, decryptData.errCode, retryTimes,
509
+ );
471
510
  return this.createRequestTask(path, param, method, header, false);
472
511
  default:
473
512
  break;
@@ -475,6 +514,8 @@ export default class Request {
475
514
  result.header = decryptHeader;
476
515
  result.data = decryptData;
477
516
  printLog(true, result.data);
517
+ // 根据返回的响应头来控制接下来运行时的加密开关
518
+ this.dealEncryptionSwitch(resHeader);
478
519
  return result;
479
520
  } catch (err) {
480
521
  printLog(false, err);