zmdms-utils 0.0.97 → 0.0.98

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.
@@ -23,6 +23,11 @@ declare class AxiosRequest {
23
23
  private responseError;
24
24
  private logoutHandle;
25
25
  request(options: IOptions): Promise<AxiosResponse<any, any>>;
26
+ /**
27
+ * 推断密钥接口的请求前缀地址
28
+ * 绝对地址的请求取其origin 其他情况取实例的baseURL(同源场景为空串)
29
+ */
30
+ private getSecurityKeyBaseURL;
26
31
  }
27
32
  interface IOptions extends AxiosRequestConfig {
28
33
  isFormData?: boolean;
@@ -75,6 +80,12 @@ interface IOtherOptions {
75
80
  baseURL?: string;
76
81
  /** 加密实例方法 */
77
82
  crypto?: Crypto;
83
+ /**
84
+ * 开启自动密钥模式
85
+ * 开启后无需传crypto 加密请求会自动等待密钥就绪后加密
86
+ * 带token的请求会顺带预热密钥
87
+ */
88
+ securityKey?: boolean;
78
89
  /** 超时是否需要弹框 */
79
90
  isTimeoutConfirm?: boolean;
80
91
  /** 超时弹框提示内容 */
@@ -1,6 +1,7 @@
1
- import { __rest, __assign } from './_virtual/_tslib.js';
1
+ import { __awaiter, __rest, __assign, __generator } from './_virtual/_tslib.js';
2
2
  import axios from 'axios';
3
3
  import { removeToken, getPreToken } from './auth.js';
4
+ import { getApiCrypto, initSecurityKeys } from './securityKey.js';
4
5
  import { TOKEN_KEY } from './constants.js';
5
6
 
6
7
  var defaultOptions = {
@@ -236,67 +237,106 @@ var AxiosRequest = /** @class */ (function () {
236
237
  };
237
238
  // 实例方法
238
239
  AxiosRequest.prototype.request = function (options) {
239
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
240
- var isFormData = options.isFormData, _k = options.isAuth, isAuth = _k === void 0 ? true : _k, resetOptions = __rest(options, ["isFormData", "isAuth"]);
241
- var newOptions = resetOptions;
242
- // 自定义请求头
243
- if (!newOptions.headers) {
244
- newOptions.headers = {};
245
- }
246
- if (isAuth) {
247
- var token = getPreToken();
248
- if (token) {
249
- newOptions.headers[this.tokenKey] = token;
250
- }
251
- }
252
- // 遍历params,将undefined值 转为null值
253
- if (newOptions.data) {
254
- newOptions.data = transformData(newOptions.data);
255
- }
256
- if (newOptions.params) {
257
- newOptions.params = transformData(newOptions.params);
258
- }
259
- // 处理特殊请求
260
- var specialMethod = ["POST", "PUT", "PATCH"];
261
- var method = ((_a = newOptions.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || "";
262
- if (specialMethod.includes(method)) {
263
- if (isFormData) {
264
- var formData = new FormData();
265
- var dataObj = newOptions.data || {};
266
- var dataKey = Object.keys(dataObj);
267
- var dataVal = Object.values(dataObj);
268
- for (var i = 0; i < dataKey.length; i++) {
269
- if (dataVal[i]) {
270
- formData.append(dataKey[i], dataVal[i]);
271
- }
240
+ var _a, _b, _c, _d, _e;
241
+ return __awaiter(this, void 0, void 0, function () {
242
+ var isFormData, _f, isAuth, resetOptions, newOptions, token, specialMethod, method, formData, dataObj, dataKey, dataVal, i, crypto;
243
+ return __generator(this, function (_g) {
244
+ switch (_g.label) {
245
+ case 0:
246
+ isFormData = options.isFormData, _f = options.isAuth, isAuth = _f === void 0 ? true : _f, resetOptions = __rest(options, ["isFormData", "isAuth"]);
247
+ newOptions = resetOptions;
248
+ // 自定义请求头
249
+ if (!newOptions.headers) {
250
+ newOptions.headers = {};
251
+ }
252
+ if (isAuth) {
253
+ token = getPreToken();
254
+ if (token) {
255
+ newOptions.headers[this.tokenKey] = token;
256
+ }
257
+ // 自动密钥模式:带token的请求顺带预热密钥 不阻塞当前请求
258
+ // 预热失败静默处理 真正需要密钥的请求会再走到等待逻辑并报错
259
+ if (this.otherOptions.securityKey) {
260
+ initSecurityKeys({
261
+ baseURL: this.getSecurityKeyBaseURL(options),
262
+ }).catch(function () { });
263
+ }
264
+ }
265
+ if (!(newOptions.isCrypto && !this.crypto && this.otherOptions.securityKey)) return [3 /*break*/, 2];
266
+ return [4 /*yield*/, initSecurityKeys({
267
+ baseURL: this.getSecurityKeyBaseURL(options),
268
+ })];
269
+ case 1:
270
+ _g.sent();
271
+ _g.label = 2;
272
+ case 2:
273
+ // 遍历params,将undefined值 转为null值
274
+ if (newOptions.data) {
275
+ newOptions.data = transformData(newOptions.data);
276
+ }
277
+ if (newOptions.params) {
278
+ newOptions.params = transformData(newOptions.params);
279
+ }
280
+ specialMethod = ["POST", "PUT", "PATCH"];
281
+ method = ((_a = newOptions.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || "";
282
+ if (specialMethod.includes(method)) {
283
+ if (isFormData) {
284
+ formData = new FormData();
285
+ dataObj = newOptions.data || {};
286
+ dataKey = Object.keys(dataObj);
287
+ dataVal = Object.values(dataObj);
288
+ for (i = 0; i < dataKey.length; i++) {
289
+ if (dataVal[i]) {
290
+ formData.append(dataKey[i], dataVal[i]);
291
+ }
292
+ }
293
+ newOptions.headers["Content-Type"] = "multipart/form-data";
294
+ newOptions.data = formData;
295
+ }
296
+ else {
297
+ newOptions.headers = __assign({ "Content-Type": "application/json" }, newOptions.headers);
298
+ }
299
+ }
300
+ crypto = this.crypto ||
301
+ (this.otherOptions.securityKey ? getApiCrypto() : undefined);
302
+ // 将参数进行aes加密
303
+ if (newOptions.isCrypto === true || newOptions.isCrypto === "aes") {
304
+ if (newOptions.data) {
305
+ newOptions.data = (_b = crypto === null || crypto === void 0 ? void 0 : crypto.encrypt) === null || _b === void 0 ? void 0 : _b.call(crypto, JSON.stringify(newOptions.data));
306
+ }
307
+ if (newOptions.params) {
308
+ newOptions.params = (_c = crypto === null || crypto === void 0 ? void 0 : crypto.encrypt) === null || _c === void 0 ? void 0 : _c.call(crypto, JSON.stringify(newOptions.params));
309
+ }
310
+ }
311
+ // 将参数进行des加密
312
+ if (newOptions.isCrypto === "des") {
313
+ if (newOptions.data) {
314
+ newOptions.data = (_d = crypto === null || crypto === void 0 ? void 0 : crypto.encrypt_des) === null || _d === void 0 ? void 0 : _d.call(crypto, JSON.stringify(newOptions.data));
315
+ }
316
+ if (newOptions.params) {
317
+ newOptions.params = (_e = crypto === null || crypto === void 0 ? void 0 : crypto.encrypt_des) === null || _e === void 0 ? void 0 : _e.call(crypto, JSON.stringify(newOptions.params));
318
+ }
319
+ }
320
+ return [2 /*return*/, this.instanceAxios(newOptions)];
272
321
  }
273
- newOptions.headers["Content-Type"] = "multipart/form-data";
274
- newOptions.data = formData;
275
- }
276
- else {
277
- newOptions.headers = __assign({ "Content-Type": "application/json" }, newOptions.headers);
278
- }
279
- }
280
- // 数据加密处理 TODO:
281
- // 将参数进行aes加密
282
- if (newOptions.isCrypto === true || newOptions.isCrypto === "aes") {
283
- if (newOptions.data) {
284
- newOptions.data = (_c = (_b = this.crypto) === null || _b === void 0 ? void 0 : _b.encrypt) === null || _c === void 0 ? void 0 : _c.call(_b, JSON.stringify(newOptions.data));
285
- }
286
- if (newOptions.params) {
287
- newOptions.params = (_e = (_d = this.crypto) === null || _d === void 0 ? void 0 : _d.encrypt) === null || _e === void 0 ? void 0 : _e.call(_d, JSON.stringify(newOptions.params));
288
- }
289
- }
290
- // 将参数进行des加密
291
- if (newOptions.isCrypto === "des") {
292
- if (newOptions.data) {
293
- newOptions.data = (_g = (_f = this.crypto) === null || _f === void 0 ? void 0 : _f.encrypt_des) === null || _g === void 0 ? void 0 : _g.call(_f, JSON.stringify(newOptions.data));
322
+ });
323
+ });
324
+ };
325
+ /**
326
+ * 推断密钥接口的请求前缀地址
327
+ * 绝对地址的请求取其origin 其他情况取实例的baseURL(同源场景为空串)
328
+ */
329
+ AxiosRequest.prototype.getSecurityKeyBaseURL = function (options) {
330
+ var url = options.url || "";
331
+ if (/^https?:\/\//i.test(url)) {
332
+ try {
333
+ return new URL(url).origin;
294
334
  }
295
- if (newOptions.params) {
296
- newOptions.params = (_j = (_h = this.crypto) === null || _h === void 0 ? void 0 : _h.encrypt_des) === null || _j === void 0 ? void 0 : _j.call(_h, JSON.stringify(newOptions.params));
335
+ catch (err) {
336
+ console.log(err);
297
337
  }
298
338
  }
299
- return this.instanceAxios(newOptions);
339
+ return this.otherOptions.baseURL || "";
300
340
  };
301
341
  return AxiosRequest;
302
342
  }());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zmdms-utils",
3
- "version": "0.0.97",
3
+ "version": "0.0.98",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
package/src/request.ts CHANGED
@@ -7,6 +7,7 @@ import axios, {
7
7
  } from "axios";
8
8
  import { getPreToken, removeToken } from "./auth";
9
9
  import { Crypto } from "./crypto";
10
+ import { initSecurityKeys, getApiCrypto } from "./securityKey";
10
11
  import { TOKEN_KEY } from "./constants";
11
12
 
12
13
  const defaultOptions: IOtherOptions = {
@@ -286,7 +287,7 @@ export class AxiosRequest {
286
287
  }
287
288
 
288
289
  // 实例方法
289
- public request(options: IOptions) {
290
+ public async request(options: IOptions) {
290
291
  const { isFormData, isAuth = true, ...resetOptions } = options;
291
292
 
292
293
  const newOptions = resetOptions;
@@ -300,6 +301,20 @@ export class AxiosRequest {
300
301
  if (token) {
301
302
  newOptions.headers[this.tokenKey] = token;
302
303
  }
304
+ // 自动密钥模式:带token的请求顺带预热密钥 不阻塞当前请求
305
+ // 预热失败静默处理 真正需要密钥的请求会再走到等待逻辑并报错
306
+ if (this.otherOptions.securityKey) {
307
+ initSecurityKeys({
308
+ baseURL: this.getSecurityKeyBaseURL(options),
309
+ }).catch(() => {});
310
+ }
311
+ }
312
+
313
+ // 自动密钥模式:加密请求优先等待密钥就绪(外部已传入crypto实例时除外)
314
+ if (newOptions.isCrypto && !this.crypto && this.otherOptions.securityKey) {
315
+ await initSecurityKeys({
316
+ baseURL: this.getSecurityKeyBaseURL(options),
317
+ });
303
318
  }
304
319
 
305
320
  // 遍历params,将undefined值 转为null值
@@ -335,15 +350,17 @@ export class AxiosRequest {
335
350
  }
336
351
 
337
352
  // 数据加密处理 TODO:
353
+ // 优先使用外部传入的crypto实例 自动密钥模式下使用密钥管理器的实例
354
+ const crypto =
355
+ this.crypto ||
356
+ (this.otherOptions.securityKey ? getApiCrypto() : undefined);
338
357
  // 将参数进行aes加密
339
358
  if (newOptions.isCrypto === true || newOptions.isCrypto === "aes") {
340
359
  if (newOptions.data) {
341
- newOptions.data = this.crypto?.encrypt?.(
342
- JSON.stringify(newOptions.data),
343
- );
360
+ newOptions.data = crypto?.encrypt?.(JSON.stringify(newOptions.data));
344
361
  }
345
362
  if (newOptions.params) {
346
- newOptions.params = this.crypto?.encrypt?.(
363
+ newOptions.params = crypto?.encrypt?.(
347
364
  JSON.stringify(newOptions.params),
348
365
  );
349
366
  }
@@ -351,12 +368,12 @@ export class AxiosRequest {
351
368
  // 将参数进行des加密
352
369
  if (newOptions.isCrypto === "des") {
353
370
  if (newOptions.data) {
354
- newOptions.data = this.crypto?.encrypt_des?.(
371
+ newOptions.data = crypto?.encrypt_des?.(
355
372
  JSON.stringify(newOptions.data),
356
373
  );
357
374
  }
358
375
  if (newOptions.params) {
359
- newOptions.params = this.crypto?.encrypt_des?.(
376
+ newOptions.params = crypto?.encrypt_des?.(
360
377
  JSON.stringify(newOptions.params),
361
378
  );
362
379
  }
@@ -364,6 +381,22 @@ export class AxiosRequest {
364
381
 
365
382
  return this.instanceAxios(newOptions);
366
383
  }
384
+
385
+ /**
386
+ * 推断密钥接口的请求前缀地址
387
+ * 绝对地址的请求取其origin 其他情况取实例的baseURL(同源场景为空串)
388
+ */
389
+ private getSecurityKeyBaseURL(options: IOptions): string {
390
+ const url = options.url || "";
391
+ if (/^https?:\/\//i.test(url)) {
392
+ try {
393
+ return new URL(url).origin;
394
+ } catch (err) {
395
+ console.log(err);
396
+ }
397
+ }
398
+ return this.otherOptions.baseURL || "";
399
+ }
367
400
  }
368
401
 
369
402
  function transformData(data?: any): any {
@@ -442,6 +475,12 @@ export interface IOtherOptions {
442
475
  baseURL?: string;
443
476
  /** 加密实例方法 */
444
477
  crypto?: Crypto;
478
+ /**
479
+ * 开启自动密钥模式
480
+ * 开启后无需传crypto 加密请求会自动等待密钥就绪后加密
481
+ * 带token的请求会顺带预热密钥
482
+ */
483
+ securityKey?: boolean;
445
484
  /** 超时是否需要弹框 */
446
485
  isTimeoutConfirm?: boolean;
447
486
  /** 超时弹框提示内容 */