@tmsfe/tms-core 0.0.154 → 0.0.156
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 +1 -1
- package/src/encrypt/encrypt-util.ts +14 -18
- package/src/encrypt/index.ts +35 -41
- package/src/index.js +1 -0
- package/src/request.js +11 -6
package/package.json
CHANGED
|
@@ -74,12 +74,7 @@ const baseUtil = {
|
|
|
74
74
|
}
|
|
75
75
|
return '';
|
|
76
76
|
},
|
|
77
|
-
getClientEncryptOpen: (): boolean =>
|
|
78
|
-
if (wx.$_encryptEnvInfo) {
|
|
79
|
-
return wx.$_encryptEnvInfo.requestEncryptOpen;
|
|
80
|
-
}
|
|
81
|
-
return false;
|
|
82
|
-
},
|
|
77
|
+
getClientEncryptOpen: (): boolean => wx.$_encryptEnvInfo?.requestEncryptOpen,
|
|
83
78
|
BaseRespFac: class BaseRespFac<T> implements BaseResp<T> {
|
|
84
79
|
success: boolean;
|
|
85
80
|
msg: string;
|
|
@@ -92,12 +87,12 @@ const baseUtil = {
|
|
|
92
87
|
}
|
|
93
88
|
},
|
|
94
89
|
};
|
|
95
|
-
let composeParamsFunc = null;
|
|
90
|
+
let composeParamsFunc = null; // 请求参数处理函数,加密初始化调用后之后会赋值
|
|
96
91
|
// 加密工具
|
|
97
92
|
const eccUtil = {
|
|
98
93
|
_refreshPromise: null,
|
|
99
94
|
_refreshPubKeyInfo: async (forceRefresh: boolean): Promise<boolean> => {
|
|
100
|
-
//
|
|
95
|
+
// 未完成初始化,则不支持秘钥刷新
|
|
101
96
|
if (!composeParamsFunc) {
|
|
102
97
|
return false;
|
|
103
98
|
}
|
|
@@ -147,12 +142,13 @@ const eccUtil = {
|
|
|
147
142
|
const keyPair = ecc.box.keyPair(); // 生成客户端公钥私钥
|
|
148
143
|
eccUtil._privateKeyInfo = {
|
|
149
144
|
serverPubId: serverPubInfo.pubId, // 服务端公钥id
|
|
150
|
-
sharedByte: ecc.box.before(baseUtil.decUrl(serverPubInfo.pubKey), keyPair.secretKey),
|
|
145
|
+
sharedByte: ecc.box.before(baseUtil.decUrl(serverPubInfo.pubKey), keyPair.secretKey), // 共享秘钥
|
|
151
146
|
clientPublicKey: baseUtil.encUrl(keyPair.publicKey), // base64 url safe 编码后的客户端公钥
|
|
152
147
|
};
|
|
153
148
|
}
|
|
154
149
|
return eccUtil._privateKeyInfo;
|
|
155
150
|
},
|
|
151
|
+
// 解析gwCode
|
|
156
152
|
resolveGwCode: async (codeStr: string): Promise<{ retry: boolean, success: boolean }> => {
|
|
157
153
|
if (!codeStr) return { retry: false, success: true };
|
|
158
154
|
const code = parseInt(codeStr, 10);
|
|
@@ -227,9 +223,9 @@ const eccUtil = {
|
|
|
227
223
|
// 加密规则判断工具
|
|
228
224
|
const cryptRuleUtil = {
|
|
229
225
|
// 远程加密服务是否开启
|
|
230
|
-
|
|
226
|
+
isServerOpen: (): boolean => !!wx.$_publicKey,
|
|
231
227
|
// 检查path是否符合下发的路由前缀
|
|
232
|
-
|
|
228
|
+
pathInEnablePrefix: (path: string): boolean => {
|
|
233
229
|
if (!wx.$_publicKey) {
|
|
234
230
|
return false;
|
|
235
231
|
}
|
|
@@ -246,7 +242,7 @@ const cryptRuleUtil = {
|
|
|
246
242
|
return false;
|
|
247
243
|
},
|
|
248
244
|
// 判断是否是性能埋点上报接口
|
|
249
|
-
|
|
245
|
+
isPerformanceReport: (path: string, params: any): boolean => {
|
|
250
246
|
// 如果是日志上报接口,需要过滤性能日志,不需要加密
|
|
251
247
|
if (path.indexOf('basic/event/upload') > -1) {
|
|
252
248
|
if (params.batch?.length === 1 && params.batch[0]?.[31] === 'tms-performance-log') {
|
|
@@ -265,7 +261,7 @@ const cryptRuleUtil = {
|
|
|
265
261
|
'^/tde', '^/basic/crypto/lastkey',
|
|
266
262
|
],
|
|
267
263
|
},
|
|
268
|
-
|
|
264
|
+
isHostValid: (url) => {
|
|
269
265
|
// 使用正则表达式解析URL
|
|
270
266
|
const urlPattern = /^(https?:\/\/)?([^/?#]+)([/?#].*)?$/;
|
|
271
267
|
const matches = url.match(urlPattern);
|
|
@@ -301,19 +297,19 @@ const isCryptoRuleMath = (path: string, reqData: any): BaseResp<boolean> => {
|
|
|
301
297
|
return new baseUtil.BaseRespFac(false, false, '本地加密未开启');
|
|
302
298
|
}
|
|
303
299
|
// 如果服务端下发的加密开关关闭,不走加密
|
|
304
|
-
if (!cryptRuleUtil.
|
|
300
|
+
if (!cryptRuleUtil.isServerOpen()) {
|
|
305
301
|
return new baseUtil.BaseRespFac(false, false, '服务端加密未开启');
|
|
306
302
|
}
|
|
307
303
|
// 请求路由不满足服务端下发的加密规则,不走加密
|
|
308
|
-
if (!cryptRuleUtil.
|
|
304
|
+
if (!cryptRuleUtil.pathInEnablePrefix(path)) {
|
|
309
305
|
return new baseUtil.BaseRespFac(false, false, '未命中服务端加密规则');
|
|
310
306
|
}
|
|
311
307
|
// 请求接口是加密性能埋点上报接口,不加密
|
|
312
|
-
if (cryptRuleUtil.
|
|
308
|
+
if (cryptRuleUtil.isPerformanceReport(path, reqData)) {
|
|
313
309
|
return new baseUtil.BaseRespFac(false, false, '性能埋点');
|
|
314
310
|
}
|
|
315
311
|
// 请求路由不走sinan网关,不加密
|
|
316
|
-
if (!cryptRuleUtil.
|
|
312
|
+
if (!cryptRuleUtil.isHostValid(path)) {
|
|
317
313
|
return new baseUtil.BaseRespFac(false, false, '非sinan网关加密接口');
|
|
318
314
|
}
|
|
319
315
|
return new baseUtil.BaseRespFac(true);;
|
|
@@ -431,7 +427,7 @@ const dealEncryptionSwitch = async (path: string, resHeader): Promise<void> => {
|
|
|
431
427
|
} else if (formatHeader['x-crypto-enable'] === '1') {
|
|
432
428
|
`${baseUtil.getSinanHost()}/user/login` === path && eccUtil._updateGlobalPublicKeyInfo(false, formatHeader);
|
|
433
429
|
await eccUtil.openCrypto();
|
|
434
|
-
} // 0是关闭,
|
|
430
|
+
} // 0是关闭,1是开启, 2是保持
|
|
435
431
|
dealEncryptionSwitching = false;
|
|
436
432
|
};
|
|
437
433
|
|
package/src/encrypt/index.ts
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import encryptUtil from './encrypt-util';
|
|
2
2
|
import { genTraceparent } from './traceUtils';
|
|
3
3
|
|
|
4
|
-
interface Params {
|
|
5
|
-
filePath?: string,
|
|
6
|
-
name?: string,
|
|
7
|
-
data?: any,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
4
|
const logger = wx.getLogManager({});
|
|
11
5
|
const util = {
|
|
12
6
|
// 统一格式化日志输出
|
|
@@ -22,20 +16,14 @@ const util = {
|
|
|
22
16
|
return args;
|
|
23
17
|
},
|
|
24
18
|
logInfo: (...args) => {
|
|
25
|
-
|
|
19
|
+
args.unshift('request_encrypt_log');
|
|
26
20
|
const items = util.formatLog(args);
|
|
21
|
+
console.log(...items);
|
|
27
22
|
logger.log(...items);
|
|
28
23
|
},
|
|
29
24
|
reportFunc: (...args) => {
|
|
30
25
|
util.logInfo('reportFunc init fail:', ...args);
|
|
31
26
|
},
|
|
32
|
-
// 判断是否需要加密
|
|
33
|
-
needsEncryption: (path: string, reqData: Params): Boolean => {
|
|
34
|
-
// 小程序构建环境的加密开关关闭,不走加密
|
|
35
|
-
if (!wx.$_encryptEnvInfo.requestEncryptOpen) return false;
|
|
36
|
-
const isCryptoRuleMathRes = encryptUtil.isCryptoRuleMath(path, reqData);
|
|
37
|
-
return isCryptoRuleMathRes.res;
|
|
38
|
-
},
|
|
39
27
|
reqEncrypt: (obj: { url: string, method: string, data: any, header: any }): {
|
|
40
28
|
data: any, header: any, msg: string, cryptoKeyInfo?: any } => {
|
|
41
29
|
const { url, method, data, header = {} } = obj;
|
|
@@ -52,16 +40,24 @@ const util = {
|
|
|
52
40
|
return Object.assign({ msg }, reqEncryptRes.res);
|
|
53
41
|
},
|
|
54
42
|
};
|
|
55
|
-
|
|
43
|
+
let originalRequestApi;
|
|
44
|
+
let originalUploadFileApi;
|
|
56
45
|
// 劫持wx.request和wx.uploadFile函数
|
|
57
|
-
const requestInit = () => {
|
|
46
|
+
const requestInit = (utilFunc) => {
|
|
58
47
|
if (!wx.request.cryptoFlag) {
|
|
59
|
-
|
|
48
|
+
originalRequestApi = wx.request;
|
|
49
|
+
// 初始化参数加签函数和性能上报函数
|
|
50
|
+
const { report, composeParamsFunc } = utilFunc;
|
|
51
|
+
encryptUtil.init(composeParamsFunc);
|
|
52
|
+
util.reportFunc = (...args) => {
|
|
53
|
+
util.logInfo(...args);
|
|
54
|
+
report('request_encrypt_log', ...args);
|
|
55
|
+
};
|
|
60
56
|
proxyWxRequest();
|
|
61
57
|
wx.request.cryptoFlag = true;
|
|
62
58
|
}
|
|
63
59
|
if (!wx.uploadFile.cryptoFlag) {
|
|
64
|
-
|
|
60
|
+
originalUploadFileApi = wx.uploadFile;
|
|
65
61
|
proxyWxUploadFile();
|
|
66
62
|
wx.uploadFile.cryptoFlag = true;
|
|
67
63
|
}
|
|
@@ -75,42 +71,47 @@ function proxyWxRequest(): void {
|
|
|
75
71
|
value(options: any) {
|
|
76
72
|
const { url, method, data, header = {}, success, fail, complete, dataType, responseType } = options;
|
|
77
73
|
const traceparent = genTraceparent();
|
|
74
|
+
const originalOptions = { ...options };
|
|
75
|
+
|
|
78
76
|
// 如果用户自定义了dataType或者responseType,则不做处理
|
|
79
77
|
if (dataType || responseType) {
|
|
80
78
|
util.reportFunc(url, traceparent, '用户自定义了dataType和responseType');
|
|
81
|
-
|
|
79
|
+
originalRequestApi.call(this, {
|
|
80
|
+
...originalOptions,
|
|
82
81
|
success: (res) => {
|
|
83
82
|
encryptUtil.dealEncryptionSwitch(url, res.header);
|
|
84
83
|
success?.call(this, res);
|
|
85
84
|
},
|
|
86
85
|
header: { ...header, Traceparent: traceparent },
|
|
87
|
-
})
|
|
86
|
+
});
|
|
88
87
|
return;
|
|
89
88
|
}
|
|
90
89
|
// 加密请求数据
|
|
91
|
-
const { data: formatData, header: formatHeader, msg, cryptoKeyInfo } = util
|
|
92
|
-
.reqEncrypt({ url, method, data, header });
|
|
90
|
+
const { data: formatData, header: formatHeader, msg, cryptoKeyInfo } = util.reqEncrypt({ url, method, data, header });
|
|
93
91
|
if (!cryptoKeyInfo) {
|
|
94
92
|
// 如果没有加密信息,则不走加密
|
|
95
93
|
util.logInfo(url, traceparent, msg);
|
|
96
|
-
|
|
94
|
+
originalRequestApi.call(this, {
|
|
95
|
+
...originalOptions,
|
|
97
96
|
success: (res) => {
|
|
98
97
|
encryptUtil.dealEncryptionSwitch(url, res.header);
|
|
99
98
|
success?.call(this, res);
|
|
100
99
|
},
|
|
101
100
|
header: { ...header, Traceparent: traceparent },
|
|
102
|
-
})
|
|
101
|
+
});
|
|
103
102
|
return;
|
|
104
103
|
}
|
|
104
|
+
|
|
105
105
|
let completeResolver;
|
|
106
|
-
// eslint-disable-next-line
|
|
107
106
|
const completePromp = new Promise(resolve => { completeResolver = resolve; });
|
|
108
|
-
|
|
107
|
+
|
|
108
|
+
originalRequestApi.call(this, {
|
|
109
|
+
...originalOptions,
|
|
109
110
|
data: formatData,
|
|
111
|
+
header: { ...formatHeader, Traceparent: traceparent },
|
|
110
112
|
dataType: '其他',
|
|
111
113
|
responseType: 'arraybuffer',
|
|
112
114
|
success: async (result) => {
|
|
113
|
-
// 解密响应
|
|
114
115
|
const { header: resHeader, data: resData } = result;
|
|
115
116
|
const { success: resSuccess, msg, res } = await encryptUtil.resDecrypt(resHeader, resData, cryptoKeyInfo);
|
|
116
117
|
if (resSuccess) {
|
|
@@ -122,13 +123,14 @@ function proxyWxRequest(): void {
|
|
|
122
123
|
complete?.call(this, completeRes);
|
|
123
124
|
} else {
|
|
124
125
|
util.reportFunc(url, traceparent, `解密失败:${msg}`);
|
|
125
|
-
|
|
126
|
+
originalRequestApi.call(this, {
|
|
127
|
+
...originalOptions,
|
|
126
128
|
success: (res) => {
|
|
127
129
|
encryptUtil.dealEncryptionSwitch(url, res.header);
|
|
128
130
|
success?.call(this, res);
|
|
129
131
|
},
|
|
130
|
-
header: { ...header, Traceparent:
|
|
131
|
-
})
|
|
132
|
+
header: { ...header, Traceparent: genTraceparent() },
|
|
133
|
+
});
|
|
132
134
|
}
|
|
133
135
|
},
|
|
134
136
|
fail: async (err) => {
|
|
@@ -139,8 +141,7 @@ function proxyWxRequest(): void {
|
|
|
139
141
|
complete: (res) => {
|
|
140
142
|
completeResolver(res);
|
|
141
143
|
},
|
|
142
|
-
|
|
143
|
-
}));
|
|
144
|
+
});
|
|
144
145
|
},
|
|
145
146
|
});
|
|
146
147
|
}
|
|
@@ -151,7 +152,7 @@ function proxyWxUploadFile(): void {
|
|
|
151
152
|
enumerable: true,
|
|
152
153
|
configurable: true,
|
|
153
154
|
value(options: any) {
|
|
154
|
-
|
|
155
|
+
originalUploadFileApi.call(this, Object.assign(options, {
|
|
155
156
|
header: { ...options.header, Traceparent: genTraceparent() },
|
|
156
157
|
}));
|
|
157
158
|
},
|
|
@@ -162,14 +163,7 @@ export const encryptObjInit = (utilFunc: {
|
|
|
162
163
|
composeParamsFunc: Function,
|
|
163
164
|
report: Function,
|
|
164
165
|
}) => {
|
|
165
|
-
// 初始化参数加签函数和性能上报函数
|
|
166
|
-
const { report, composeParamsFunc } = utilFunc;
|
|
167
|
-
encryptUtil.init(composeParamsFunc);
|
|
168
|
-
util.reportFunc = (...args) => {
|
|
169
|
-
util.logInfo('request_encrypt_log', ...args);
|
|
170
|
-
report('request_encrypt_log', ...args);
|
|
171
|
-
};
|
|
172
166
|
// 劫持wx.request和wx.uploadFile函数
|
|
173
|
-
requestInit();
|
|
167
|
+
requestInit(utilFunc);
|
|
174
168
|
};
|
|
175
169
|
|
package/src/index.js
CHANGED
package/src/request.js
CHANGED
|
@@ -16,12 +16,6 @@ import reporter from './report/index';
|
|
|
16
16
|
|
|
17
17
|
const logger = wx.getLogManager({});
|
|
18
18
|
|
|
19
|
-
// 加密模块初始化
|
|
20
|
-
encryptObjInit({
|
|
21
|
-
composeParamsFunc: data => composeParam(data, true, {}),
|
|
22
|
-
report: (...args) => reporter.reportPerformance(...args),
|
|
23
|
-
});
|
|
24
|
-
|
|
25
19
|
/**
|
|
26
20
|
* 用于序列化需要签名的参数
|
|
27
21
|
* @private
|
|
@@ -165,6 +159,17 @@ export default class Request {
|
|
|
165
159
|
*/
|
|
166
160
|
static defaultSecretKey = '';
|
|
167
161
|
|
|
162
|
+
static encryptInit(secretKey) {
|
|
163
|
+
// 加密模块初始化
|
|
164
|
+
encryptObjInit({
|
|
165
|
+
composeParamsFunc: async (data) => {
|
|
166
|
+
const params = await composeParam(data, true, {});
|
|
167
|
+
return sign(params, secretKey);
|
|
168
|
+
},
|
|
169
|
+
report: (...args) => reporter.reportPerformance(...args),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
168
173
|
static getInstance() {
|
|
169
174
|
if (reqInstance === null) {
|
|
170
175
|
reqInstance = new Request();
|