@tmsfe/tms-core 0.0.141 → 0.0.143

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.141",
3
+ "version": "0.0.143",
4
4
  "description": "tms运行时框架",
5
5
  "repository": {
6
6
  "type": "git",
package/src/encrypt.js CHANGED
@@ -60,7 +60,7 @@ function _getEccPublicId() {
60
60
  // 获取私钥
61
61
  let privateKeyInfo = null;
62
62
  const _getPrivateKeyInfo = (enforceUpdate) => {
63
- if (!privateKeyInfo || enforceUpdate) {
63
+ if (!privateKeyInfo || enforceUpdate || privateKeyInfo.publicKeyId !== _getEccPublicId()) {
64
64
  const aesKey = _generateRandomKey();
65
65
  const encryptAesKey = _encryptWithPublicKey(aesKey, _getEccPublicKey());
66
66
  privateKeyInfo = {
@@ -268,11 +268,39 @@ function needsEncryption(url, params) {
268
268
  return true; // 没有匹配到规则,需要加密
269
269
  }
270
270
 
271
+ // 判断是否是加密相关的错误类型(因为rawresponse的配置,需要errcode和errmessage共同来确定加密错误类型)
272
+ const ErrCodeType = {
273
+ pubKeyIdInvalid: '11_Invalid public key!',
274
+ pubKeyExpired: '12_Expired public key!',
275
+ aesCipherInvalid: '13_Invalid AES cipher!',
276
+ decryptError: '14_Decrypt error!',
277
+ cryptoDisabled: '15_Crypto disabled!',
278
+ };
279
+ const reqErrType = {
280
+ pubKeyInvalid: 'pubKeyInvalid',
281
+ decryptError: 'decryptError',
282
+ cryptoDisabled: 'cryptoDisabled',
283
+ };
284
+ const getErrcodeType = (errCode, errMsg) => {
285
+ const errType = `${errCode}_${errMsg}`;
286
+ if (ErrCodeType.decryptError === errType) {
287
+ return reqErrType.decryptError;
288
+ }
289
+ if (ErrCodeType.cryptoDisabled === errType) {
290
+ return reqErrType.cryptoDisabled;
291
+ }
292
+ if ([ErrCodeType.pubKeyIdInvalid, ErrCodeType.pubKeyExpired, ErrCodeType.aesCipherInvalid].indexOf(errType) > -1) {
293
+ return reqErrType.pubKeyInvalid;
294
+ }
295
+ };
296
+
271
297
  const encryptObj = {
272
298
  reqEncrypt,
273
299
  resDecrypt,
274
300
  updateDecryptKey,
275
301
  needsEncryption,
302
+ getErrcodeType,
303
+ reqErrType,
276
304
  };
277
305
 
278
306
 
package/src/index.js CHANGED
@@ -130,8 +130,15 @@ const init = (options = {}) => {
130
130
  getLocation: async () => {
131
131
  try {
132
132
  const res = await getLocationManager().getIpLocation();
133
- const ad = res.ad_info;
134
- return { province: ad.province, cityName: ad.city };
133
+ const { ad_info: ad, location } = res;
134
+ return {
135
+ province: ad.province,
136
+ cityName: ad.city,
137
+ district: ad.district,
138
+ cityCode: ad.cityCode,
139
+ latitude: location.lat,
140
+ longitude: location.lng,
141
+ };
135
142
  } catch {
136
143
  return null;
137
144
  }
@@ -68,7 +68,9 @@ function getBaseData(page: IPage, deviceData: IDeviceData): { arr: DataItem[], n
68
68
  arr[27] = helper.getTmsUUID();
69
69
  // 28: f28,实际执行页面url
70
70
  arr[28] = page.execRoute;
71
- // 29 ~ 30: 预留字段给后续扩展使用
71
+ // 29: f29,定位相关信息
72
+ arr[29] = JSON.stringify(location);
73
+ // 30 ~ 30: 预留字段给后续扩展使用
72
74
  // 31 ~ 40: 提供给开发自定义
73
75
  // --------------------------字段列表--------------------------
74
76
  return { arr, nextIndex: 31 };
@@ -255,6 +255,9 @@ function getDeviceData(): Promise<IDeviceData> {
255
255
  if (loc) {
256
256
  deviceData.location.province = loc.province;
257
257
  deviceData.location.cityName = loc.cityName;
258
+ deviceData.location.district = loc.district;
259
+ deviceData.location.latitude = loc.latitude;
260
+ deviceData.location.longitude = loc.longitude;
258
261
  }
259
262
  resolve();
260
263
  })
@@ -9,7 +9,7 @@ export interface IInitOptions {
9
9
  // 小程序版本号
10
10
  appVersion: string,
11
11
  // 获取定位信息
12
- getLocation: () => Promise<{ province: string, cityName: string } | null>,
12
+ getLocation: () => Promise<ILocation | null>,
13
13
  // 允许自定义日志输出
14
14
  logger: ILogger,
15
15
  // post方法,用于发送埋点
@@ -53,6 +53,9 @@ export interface ISystemInfo {
53
53
  export interface ILocation {
54
54
  province: string,
55
55
  cityName: string,
56
+ district: string
57
+ latitude: number,
58
+ longitude: number,
56
59
  }
57
60
 
58
61
  export interface IDeviceData {
package/src/request.js CHANGED
@@ -347,17 +347,17 @@ export default class Request {
347
347
  }
348
348
 
349
349
  // wx请求封装成promise
350
- async wxRequest(path, method, header = {}, data, needReport = false) {
350
+ async wxRequest(path, method, header = {}, data, needReport, seqId) {
351
351
  if (needReport && path.indexOf('basic/event/upload') < 0) {
352
352
  reporter.reportPerformance(
353
- 'request_encrypt_log', 'main', 'send_unencrypt_request', data.seqId,
353
+ 'request_encrypt_log', 'main', 'send_unencrypt_request', seqId,
354
354
  !!wx.$_publicKey, Request.requestEncryptOpen, path,
355
355
  );
356
356
  }
357
357
  return new Promise((resolve, reject) => {
358
358
  wx.request({
359
359
  url: path,
360
- header: { ...header, 'X-Trace-Id': data.seqId },
360
+ header: { ...header, 'X-Trace-Id': seqId },
361
361
  method,
362
362
  data,
363
363
  enableHttp2: true,
@@ -373,7 +373,10 @@ export default class Request {
373
373
 
374
374
  async refreshEncryptKey() {
375
375
  try {
376
- const res = await this.doRequest('/basic/crypto/lastkey', {}, 'GET', {});
376
+ const requestParam = await composeParam({}, true, {});
377
+ const data = sign(requestParam, this.secretKey);
378
+ const finalUrl = this.makeUrl('basic/crypto/lastkey');
379
+ const res = await this.wxRequest(finalUrl, 'GET', {}, data, true, data.seqId);
377
380
  encryptObj.updateDecryptKey(res.data.resData);
378
381
  } catch (e) {
379
382
  encryptObj.updateDecryptKey(null);
@@ -389,8 +392,8 @@ export default class Request {
389
392
  return true;
390
393
  }
391
394
 
392
- async dealEncryptionSwitch(resHeader) {
393
- if (!resHeader || this.dealEncryptionSwitching) {
395
+ async dealEncryptionSwitch(resHeader, forceRefresh = false) {
396
+ if (!forceRefresh && (!resHeader || this.dealEncryptionSwitching)) {
394
397
  return false;
395
398
  }
396
399
  this.dealEncryptionSwitching = true;
@@ -403,7 +406,7 @@ export default class Request {
403
406
  return false;
404
407
  }
405
408
  // 打开开关,如果当前是关闭状态,则需要刷新加密key
406
- if (!wx.$_publicKey) {
409
+ if (forceRefresh || !wx.$_publicKey) {
407
410
  await this.refreshEncryptKey();
408
411
  }
409
412
  this.dealEncryptionSwitching = false;
@@ -458,58 +461,55 @@ export default class Request {
458
461
  logger.warn(`接口请求失败:\n${str}`);
459
462
  }
460
463
  };
461
- // 当前请求不加密 || 不满足加密前提
462
- if (!doEncrypt || !this.checkIfNeedEncrypt(finalUrl, data)) {
463
- return this.wxRequest(finalUrl, method, header, data, true)
464
- .then((res) => {
465
- printLog(true, res.data);
466
- return res;
467
- })
468
- .catch((err) => {
469
- printLog(false, err);
470
- throw err;
471
- });
472
- }
473
- // 1. 加密请求
474
- const {
475
- header: encryptHeader, data: encryptData, aesKey,
476
- } = encryptObj.reqEncrypt(method, data, header, '');
477
- // 2. 发送请求
464
+ const { seqId } = data;
478
465
  try {
479
- reporter.reportPerformance('request_encrypt_log', 'main', 'send_encrypt_request', data.seqId);
480
- const result = await this.wxRequest(finalUrl, method, encryptHeader, encryptData);
466
+ // 当前请求不加密 || 不满足加密前提
467
+ if (!doEncrypt || !this.checkIfNeedEncrypt(finalUrl, data)) {
468
+ const result = await this.wxRequest(finalUrl, method, header, data, true, seqId);
469
+ const { header: resHeader, data: resData } = result;
470
+ // 根据返回的响应头来控制接下来运行时的加密开关
471
+ this.dealEncryptionSwitch(resHeader);
472
+ printLog(true, resData);
473
+ return result;
474
+ }
475
+ // 1. 加密请求
476
+ const {
477
+ header: encryptHeader, data: encryptData, aesKey,
478
+ } = encryptObj.reqEncrypt(method, data, header, '');
479
+ // 2. 发送请求
480
+ reporter.reportPerformance('request_encrypt_log', 'main', 'send_encrypt_request', seqId);
481
+ const result = await this.wxRequest(finalUrl, method, encryptHeader, encryptData, false, seqId);
481
482
  const { header: resHeader, data: resData } = result;
482
483
  // 3. 解密响应
483
484
  const { success, header: decryptHeader, data: decryptData } = encryptObj.resDecrypt(aesKey, resHeader, resData);
484
485
  if (!success) {
485
- reporter.reportPerformance('request_encrypt_log', 'main', 'local_response_decrypt_fail', data.seqId);
486
+ reporter.reportPerformance('request_encrypt_log', 'main', 'local_response_decrypt_fail', seqId);
486
487
  return this.createRequestTask(path, param, method, header, false);
487
488
  }
488
- reporter.reportPerformance('request_encrypt_log', 'main', 'decrypt_response_success', data.seqId);
489
+ reporter.reportPerformance('request_encrypt_log', 'main', 'decrypt_response_success', seqId);
489
490
  // 4. 处理解密失败的响应
490
- switch (decryptData.errCode) {
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) {
499
- throw new Error('解密失败,请重试');
500
- }
501
- await this.refreshEncryptKey();
502
- return this.createRequestTask(path, param, method, header, true, retryTimes + 1);
491
+ const errCodeType = encryptObj.getErrcodeType(decryptData.errCode, decryptData.errMsg);
492
+ if (errCodeType === encryptObj.reqErrType.pubKeyInvalid) { // 秘钥失效
493
+ reporter.reportPerformance(
494
+ 'request_encrypt_log', 'main', 'remote_response_decrypt_fail',
495
+ seqId, decryptData.errCode, retryTimes,
496
+ );
497
+ const encryptSwitch = await this.dealEncryptionSwitch(resHeader, true);
498
+ if (retryTimes > 2) {
499
+ throw new Error('解密失败,请重试');
503
500
  }
504
- case 14: // 解密失败
505
- // 请求不加密重试
506
- reporter.reportPerformance(
507
- 'request_encrypt_log', 'main', 'remote_response_decrypt_fail',
508
- data.seqId, decryptData.errCode, retryTimes,
509
- );
510
- return this.createRequestTask(path, param, method, header, false);
511
- default:
512
- break;
501
+ return this.createRequestTask(path, param, method, header, encryptSwitch, retryTimes + 1);
502
+ }
503
+ if (errCodeType === encryptObj.reqErrType.decryptError) { // 解密失败
504
+ reporter.reportPerformance(
505
+ 'request_encrypt_log', 'main', 'remote_response_decrypt_fail',
506
+ seqId, decryptData.errCode, retryTimes,
507
+ );
508
+ return this.createRequestTask(path, param, method, header, false);
509
+ }
510
+ if (errCodeType === encryptObj.reqErrType.cryptoDisabled) { // 加密关闭
511
+ wx.$_publicKey = null;
512
+ return this.createRequestTask(path, param, method, header, false);
513
513
  }
514
514
  result.header = decryptHeader;
515
515
  result.data = decryptData;