node-easywechat 3.5.6 → 3.5.8

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/Core/HttpClient/HttpClient.js +4 -0
  3. package/dist/Core/HttpClient/HttpClientResponse.d.ts +5 -0
  4. package/dist/Core/HttpClient/HttpClientResponse.js +7 -0
  5. package/dist/Core/Mixins/HttpClientMixin.d.ts +2 -2
  6. package/dist/Core/Mixins/HttpClientMixin.js +8 -3
  7. package/dist/Core/Support/Utils.d.ts +2 -0
  8. package/dist/MiniApp/Application.d.ts +6 -0
  9. package/dist/MiniApp/Application.js +12 -1
  10. package/dist/OfficialAccount/Application.d.ts +6 -0
  11. package/dist/OfficialAccount/Application.js +12 -1
  12. package/dist/OpenPlatform/Application.d.ts +1 -1
  13. package/dist/OpenPlatform/Application.js +2 -2
  14. package/dist/OpenPlatform/Authorizer/MiniApp/Application.d.ts +14 -0
  15. package/dist/OpenPlatform/Authorizer/MiniApp/Application.js +28 -0
  16. package/dist/OpenPlatform/Authorizer/MiniApp/Utils.d.ts +14 -0
  17. package/dist/OpenPlatform/Authorizer/MiniApp/Utils.js +48 -0
  18. package/dist/Pay/Application.d.ts +14 -0
  19. package/dist/Pay/Application.js +28 -1
  20. package/dist/Pay/Contracts/ApplicationInterface.d.ts +6 -0
  21. package/dist/Pay/Contracts/ApplicationInterface.js +5 -0
  22. package/dist/Pay/Contracts/ValidatorInterface.d.ts +8 -0
  23. package/dist/Pay/Contracts/ValidatorInterface.js +9 -0
  24. package/dist/Pay/Utils.d.ts +16 -1
  25. package/dist/Pay/Utils.js +22 -1
  26. package/dist/Pay/Validator.d.ts +14 -0
  27. package/dist/Pay/Validator.js +48 -0
  28. package/dist/Types/common.d.ts +2 -0
  29. package/dist/Types/global.d.ts +4 -3
  30. package/dist/Types/shim-axios.d.ts +8 -8
  31. package/dist/Work/Application.d.ts +6 -0
  32. package/dist/Work/Application.js +12 -1
  33. package/package.json +3 -3
  34. package/tsconfig.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,6 +1,25 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v3.5.8 (2023-12-18)
5
+
6
+ - Feat: thirdpartyCode2Session方法重命名为code2Session (#54)
7
+ - Feat: 新增将请求响应类转换为标准http响应类的方法toHttpResponse
8
+
9
+ - Fix: 修复验证器类型错误 (#58)
10
+ - Fix: 修复验证器类型错误的问题 (#56)
11
+ - Fix: 修复ts类型错误
12
+
13
+ ## v3.5.7 (2023-12-18)
14
+
15
+ - Feat: 企业微信工具类增加encrypt、decrypt加解密方法 (#58)
16
+ - Feat: 微信支付增加验证器api (#56)
17
+ - Feat: 开放平台新增代理小程序登录接口thirdpartyCode2Session (#54)
18
+ - Feat: 各模块增加自定义工具类的API
19
+
20
+ - Fix: 修复http相关配置项无效的问题 (#59)
21
+ - Fix: 升级ts,并修复ts类型错误 (#50)
22
+
4
23
  ## v3.5.6 (2023-12-17)
5
24
 
6
25
  - Fix: 修复获取代理公众号或小程序实例时,未设置配置项导致
@@ -99,6 +99,10 @@ class HttpClient {
99
99
  if (options.data && options.data instanceof form_data_1.default) {
100
100
  options.headers = Object.assign(Object.assign({}, (yield this.getFormDataHeaders(options.data))), options.headers);
101
101
  }
102
+ // 是否抛出异常
103
+ options.validateStatus = (status) => {
104
+ return this.throwError ? status >= 200 && status < 300 : true;
105
+ };
102
106
  let starttime = Date.now();
103
107
  if (typeof this.logger === 'function') {
104
108
  yield this.logger('before', options);
@@ -1,6 +1,7 @@
1
1
  import { AxiosResponse } from "axios";
2
2
  import { HttpClientFailureJudgeClosure, WeixinResponse } from "../../Types/global";
3
3
  import HttpClientResponseInterface from "./Contracts/HttpClientResponseInterface";
4
+ import Response from "../Http/Response";
4
5
  declare class HttpClientResponse implements HttpClientResponseInterface {
5
6
  protected response: AxiosResponse;
6
7
  protected failureJudge: HttpClientFailureJudgeClosure;
@@ -89,5 +90,9 @@ declare class HttpClientResponse implements HttpClientResponseInterface {
89
90
  getInfo(type?: string): import("axios").InternalAxiosRequestConfig<any>;
90
91
  offsetExists(key: any): Promise<boolean>;
91
92
  offsetGet(key: any): Promise<any>;
93
+ /**
94
+ * 转换为标准的 http 响应类
95
+ */
96
+ toHttpResponse(): Response;
92
97
  }
93
98
  export = HttpClientResponse;
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  const fs_1 = __importDefault(require("fs"));
15
15
  const Utils_1 = require("../Support/Utils");
16
+ const Response_1 = __importDefault(require("../Http/Response"));
16
17
  class HttpClientResponse {
17
18
  constructor(response, failureJudge = null, throwError = false) {
18
19
  this.response = response;
@@ -241,5 +242,11 @@ class HttpClientResponse {
241
242
  return (yield this.toObject())[key] || null;
242
243
  });
243
244
  }
245
+ /**
246
+ * 转换为标准的 http 响应类
247
+ */
248
+ toHttpResponse() {
249
+ return new Response_1.default(this.response.status, this.getHeaders(), this.toString());
250
+ }
244
251
  }
245
252
  module.exports = HttpClientResponse;
@@ -13,10 +13,10 @@ declare class HttpClientMixin {
13
13
  */
14
14
  setHttpClient(httpClient: HttpClientInterface): this;
15
15
  /**
16
- * 创建请求客户端实例
16
+ * 创建默认请求客户端实例
17
17
  * @returns
18
18
  */
19
- protected createHttpClient(): HttpClientInterface;
19
+ protected createDefaultHttpClient(): HttpClientInterface;
20
20
  /**
21
21
  * 获取请求默认配置
22
22
  * @returns
@@ -13,7 +13,12 @@ class HttpClientMixin {
13
13
  */
14
14
  getHttpClient() {
15
15
  if (!this.httpClient) {
16
- this.httpClient = this.createHttpClient();
16
+ if (typeof this['createHttpClient'] === 'function') {
17
+ this.httpClient = this['createHttpClient']();
18
+ }
19
+ else {
20
+ this.httpClient = this.createDefaultHttpClient();
21
+ }
17
22
  }
18
23
  return this.httpClient;
19
24
  }
@@ -27,10 +32,10 @@ class HttpClientMixin {
27
32
  return this;
28
33
  }
29
34
  /**
30
- * 创建请求客户端实例
35
+ * 创建默认请求客户端实例
31
36
  * @returns
32
37
  */
33
- createHttpClient() {
38
+ createDefaultHttpClient() {
34
39
  return HttpClient_1.default.create(this.getHttpClientDefaultOptions());
35
40
  }
36
41
  /**
@@ -1,3 +1,5 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
1
3
  import Crypto from 'crypto';
2
4
  import Stream from 'stream';
3
5
  export declare const createHash: (str: Crypto.BinaryLike, type?: string, target?: Crypto.BinaryToTextEncoding) => any;
@@ -21,6 +21,7 @@ declare class Application implements ApplicationInterface {
21
21
  protected encryptor: Encryptor;
22
22
  protected server: Server;
23
23
  protected accessToken: AccessTokenInterface;
24
+ protected utils: Utils;
24
25
  getAccount(): AccountInterface;
25
26
  /**
26
27
  * 设置当前账户实例
@@ -49,6 +50,11 @@ declare class Application implements ApplicationInterface {
49
50
  * @returns
50
51
  */
51
52
  setAccessToken(accessToken: AccessTokenInterface): this;
53
+ /**
54
+ * 设置工具实例
55
+ * @param utils
56
+ */
57
+ setUtils(utils: Utils): void;
52
58
  getUtils(): Utils;
53
59
  createClient(): AccessTokenAwareClient;
54
60
  /**
@@ -26,6 +26,7 @@ class Application {
26
26
  this.encryptor = null;
27
27
  this.server = null;
28
28
  this.accessToken = null;
29
+ this.utils = null;
29
30
  if (config instanceof ConfigInterface_1.default) {
30
31
  this.setConfig(config);
31
32
  }
@@ -106,8 +107,18 @@ class Application {
106
107
  this.accessToken = accessToken;
107
108
  return this;
108
109
  }
110
+ /**
111
+ * 设置工具实例
112
+ * @param utils
113
+ */
114
+ setUtils(utils) {
115
+ this.utils = utils;
116
+ }
109
117
  getUtils() {
110
- return new Utils_2.default(this);
118
+ if (!this.utils) {
119
+ this.utils = new Utils_2.default(this);
120
+ }
121
+ return this.utils;
111
122
  }
112
123
  createClient() {
113
124
  return (new AccessTokenAwareClient_1.default(this.getHttpClient(), this.getAccessToken(), (response) => { var _a; return ((_a = response.toObject()['errcode']) !== null && _a !== void 0 ? _a : 0) || (response.toObject()['error'] !== null && response.toObject()['error'] !== undefined); }, this.getConfig().get('http.throw', true)))
@@ -25,6 +25,7 @@ declare class Application implements ApplicationInterface {
25
25
  protected accessToken: AccessTokenInterface;
26
26
  protected oauthFactory: OfficialAccountOAuthFactory;
27
27
  protected ticket: JsApiTicket;
28
+ protected utils: Utils;
28
29
  getAccount(): AccountInterface;
29
30
  /**
30
31
  * 设置当前账户实例
@@ -62,6 +63,11 @@ declare class Application implements ApplicationInterface {
62
63
  * @returns
63
64
  */
64
65
  setTicket(ticket: JsApiTicket): this;
66
+ /**
67
+ * 设置工具实例
68
+ * @param utils
69
+ */
70
+ setUtils(utils: Utils): void;
65
71
  getUtils(): Utils;
66
72
  createClient(): AccessTokenAwareClient;
67
73
  /**
@@ -31,6 +31,7 @@ class Application {
31
31
  this.accessToken = null;
32
32
  this.oauthFactory = null;
33
33
  this.ticket = null;
34
+ this.utils = null;
34
35
  if (config instanceof ConfigInterface_1.default) {
35
36
  this.setConfig(config);
36
37
  }
@@ -141,8 +142,18 @@ class Application {
141
142
  this.ticket = ticket;
142
143
  return this;
143
144
  }
145
+ /**
146
+ * 设置工具实例
147
+ * @param utils
148
+ */
149
+ setUtils(utils) {
150
+ this.utils = utils;
151
+ }
144
152
  getUtils() {
145
- return new Utils_2.default(this);
153
+ if (!this.utils) {
154
+ this.utils = new Utils_2.default(this);
155
+ }
156
+ return this.utils;
146
157
  }
147
158
  createClient() {
148
159
  return (new AccessTokenAwareClient_1.default(this.getHttpClient(), this.getAccessToken(), (response) => { var _a; return (_a = response.toObject()['errcode']) !== null && _a !== void 0 ? _a : 0; }, this.getConfig().get('http.throw', true)))
@@ -8,7 +8,7 @@ import ConfigMixin from '../Core/Mixins/ConfigMixin';
8
8
  import HttpClientMixin from '../Core/Mixins/HttpClientMixin';
9
9
  import ServerRequestMixin from '../Core/Mixins/ServerRequestMixin';
10
10
  import OfficialAccountApplication from '../OfficialAccount/Application';
11
- import MiniAppApplication from '../MiniApp/Application';
11
+ import MiniAppApplication from './Authorizer/MiniApp/Application';
12
12
  import { OpenPlatformConfig, OfficialAccountConfig, OfficialAccountOAuthFactory, MiniAppConfig } from '../Types/global';
13
13
  import AccountInterface from './Contracts/AccountInterface';
14
14
  import ApplicationInterface from './Contracts/ApplicationInterface';
@@ -25,7 +25,7 @@ const HttpClientMixin_1 = __importDefault(require("../Core/Mixins/HttpClientMixi
25
25
  const ServerRequestMixin_1 = __importDefault(require("../Core/Mixins/ServerRequestMixin"));
26
26
  const Utils_1 = require("../Core/Support/Utils");
27
27
  const Application_1 = __importDefault(require("../OfficialAccount/Application"));
28
- const Application_2 = __importDefault(require("../MiniApp/Application"));
28
+ const Application_2 = __importDefault(require("./Authorizer/MiniApp/Application"));
29
29
  const Account_1 = __importDefault(require("./Account"));
30
30
  const Server_1 = __importDefault(require("./Server"));
31
31
  const VerifyTicket_1 = __importDefault(require("./VerifyTicket"));
@@ -350,7 +350,7 @@ class Application {
350
350
  config.set('aes_key', this.config.get('aes_key'));
351
351
  config.set('http', this.config.get('http'));
352
352
  }
353
- let app = new Application_2.default(config);
353
+ const app = new Application_2.default(config, this);
354
354
  app.setAccessToken(authorizerAccessToken);
355
355
  app.setEncryptor(this.getEncryptor());
356
356
  return app;
@@ -0,0 +1,14 @@
1
+ import ConfigInterface from '../../../Core/Contracts/ConfigInterface';
2
+ import BaseApplication from '../../../MiniApp/Application';
3
+ import ComponentApplication from '../../Application';
4
+ import { MiniAppConfig } from '../../../Types/global';
5
+ import Utils from './Utils';
6
+ declare class Application extends BaseApplication {
7
+ protected componentApp: ComponentApplication;
8
+ protected utils: Utils;
9
+ constructor(config: ConfigInterface | MiniAppConfig, componentApp: ComponentApplication);
10
+ getComponentApp(): ComponentApplication;
11
+ setUtils(utils: Utils): void;
12
+ getUtils(): Utils;
13
+ }
14
+ export = Application;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const Application_1 = __importDefault(require("../../../MiniApp/Application"));
6
+ const Utils_1 = __importDefault(require("./Utils"));
7
+ class Application extends Application_1.default {
8
+ constructor(config, componentApp) {
9
+ super(config);
10
+ this.componentApp = null;
11
+ this.utils = null;
12
+ this.componentApp = componentApp;
13
+ }
14
+ getComponentApp() {
15
+ return this.componentApp;
16
+ }
17
+ setUtils(utils) {
18
+ this.utils = utils;
19
+ }
20
+ getUtils() {
21
+ if (!this.utils) {
22
+ this.utils = new Utils_1.default(this);
23
+ }
24
+ return this.utils;
25
+ }
26
+ }
27
+ ;
28
+ module.exports = Application;
@@ -0,0 +1,14 @@
1
+ import Application from '../../Authorizer/MiniApp/Application';
2
+ import BaseUtils from '../../../MiniApp/Utils';
3
+ declare class Utils extends BaseUtils {
4
+ protected app: Application;
5
+ constructor(app: Application);
6
+ /**
7
+ * 代理小程序登录
8
+ * @see https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/login/thirdpartyCode2Session.html
9
+ * @param code
10
+ * @returns
11
+ */
12
+ code2Session(code: string): Promise<import("../../../Types/global").WeixinResponse>;
13
+ }
14
+ export = Utils;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ const Utils_1 = __importDefault(require("../../../MiniApp/Utils"));
15
+ class Utils extends Utils_1.default {
16
+ constructor(app) {
17
+ super(app);
18
+ this.app = null;
19
+ this.app = app;
20
+ }
21
+ /**
22
+ * 代理小程序登录
23
+ * @see https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/login/thirdpartyCode2Session.html
24
+ * @param code
25
+ * @returns
26
+ */
27
+ code2Session(code) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ let client = this.app.getHttpClient();
30
+ let response = yield client.request('GET', '/sns/component/jscode2session', {
31
+ params: {
32
+ component_access_token: yield this.app.getComponentApp().getAccessToken().getToken(),
33
+ component_appid: this.app.getComponentApp().getAccount().getAppId(),
34
+ appid: this.app.getAccount().getAppId(),
35
+ js_code: code,
36
+ grant_type: 'authorization_code',
37
+ }
38
+ });
39
+ let data = response.toObject();
40
+ if (!data['openid']) {
41
+ throw new Error(`code2Session error: ${JSON.stringify(data)}`);
42
+ }
43
+ return data;
44
+ });
45
+ }
46
+ }
47
+ ;
48
+ module.exports = Utils;
@@ -10,6 +10,7 @@ import ApplicationInterface from './Contracts/ApplicationInterface';
10
10
  import Server from './Server';
11
11
  import Utils from './Utils';
12
12
  import Client from './Client';
13
+ import Validator from './Validator';
13
14
  /**
14
15
  * 微信支付应用
15
16
  */
@@ -19,6 +20,8 @@ declare class Application implements ApplicationInterface {
19
20
  protected encryptor: Encryptor;
20
21
  protected server: Server;
21
22
  protected client: Client;
23
+ protected utils: Utils;
24
+ protected validator: Validator;
22
25
  getMerchant(): MerchantInterface;
23
26
  /**
24
27
  * 设置当前账户实例
@@ -33,7 +36,18 @@ declare class Application implements ApplicationInterface {
33
36
  * @returns
34
37
  */
35
38
  setServer(server: Server): this;
39
+ /**
40
+ * 设置工具实例
41
+ * @param utils
42
+ */
43
+ setUtils(utils: Utils): void;
36
44
  getUtils(): Utils;
45
+ /**
46
+ * 设置验证器实例
47
+ * @param validator
48
+ */
49
+ setValidator(validator: Validator): void;
50
+ getValidator(): Validator;
37
51
  getClient(): Client;
38
52
  /**
39
53
  * 设置客户端
@@ -14,6 +14,7 @@ const Server_1 = __importDefault(require("./Server"));
14
14
  const Utils_2 = __importDefault(require("./Utils"));
15
15
  const Config_1 = __importDefault(require("../OfficialAccount/Config"));
16
16
  const Client_1 = __importDefault(require("./Client"));
17
+ const Validator_1 = __importDefault(require("./Validator"));
17
18
  /**
18
19
  * 微信支付应用
19
20
  */
@@ -22,6 +23,9 @@ class Application {
22
23
  this.merchant = null;
23
24
  this.encryptor = null;
24
25
  this.server = null;
26
+ this.client = null;
27
+ this.utils = null;
28
+ this.validator = null;
25
29
  if (config instanceof ConfigInterface_1.default) {
26
30
  this.setConfig(config);
27
31
  }
@@ -63,8 +67,31 @@ class Application {
63
67
  this.server = server;
64
68
  return this;
65
69
  }
70
+ /**
71
+ * 设置工具实例
72
+ * @param utils
73
+ */
74
+ setUtils(utils) {
75
+ this.utils = utils;
76
+ }
66
77
  getUtils() {
67
- return new Utils_2.default(this.getMerchant());
78
+ if (!this.utils) {
79
+ this.utils = new Utils_2.default(this.getMerchant());
80
+ }
81
+ return this.utils;
82
+ }
83
+ /**
84
+ * 设置验证器实例
85
+ * @param validator
86
+ */
87
+ setValidator(validator) {
88
+ this.validator = validator;
89
+ }
90
+ getValidator() {
91
+ if (!this.validator) {
92
+ this.validator = new Validator_1.default(this.getMerchant());
93
+ }
94
+ return this.validator;
68
95
  }
69
96
  getClient() {
70
97
  if (!this.client) {
@@ -5,6 +5,7 @@ import ServerInterface from "../../Core/Contracts/ServerInterface";
5
5
  import ServerRequestInterface from "../../Core/Http/Contracts/ServerRequestInterface";
6
6
  import MerchantInterface from "./MerchantInterface";
7
7
  import Utils from "../Utils";
8
+ import ValidatorInterface from "./ValidatorInterface";
8
9
  declare abstract class ApplicationInterface {
9
10
  /**
10
11
  * 获取当前账户实例
@@ -46,5 +47,10 @@ declare abstract class ApplicationInterface {
46
47
  * @returns
47
48
  */
48
49
  getUtils(): Utils;
50
+ /**
51
+ * 获取验证器实例
52
+ * @returns
53
+ */
54
+ getValidator(): ValidatorInterface;
49
55
  }
50
56
  export = ApplicationInterface;
@@ -40,6 +40,11 @@ class ApplicationInterface {
40
40
  * @returns
41
41
  */
42
42
  getUtils() { return null; }
43
+ /**
44
+ * 获取验证器实例
45
+ * @returns
46
+ */
47
+ getValidator() { return null; }
43
48
  }
44
49
  ;
45
50
  module.exports = ApplicationInterface;
@@ -0,0 +1,8 @@
1
+ import Request from "../../Core/Http/Request";
2
+ declare abstract class ValidatorInterface {
3
+ /**
4
+ * 验证请求是否正确
5
+ */
6
+ validate(request: Request): boolean;
7
+ }
8
+ export = ValidatorInterface;
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+ class ValidatorInterface {
3
+ /**
4
+ * 验证请求是否正确
5
+ */
6
+ validate(request) { return true; }
7
+ }
8
+ ;
9
+ module.exports = ValidatorInterface;
@@ -1,14 +1,29 @@
1
+ /// <reference types="node" />
1
2
  import { PayAppConfig, PayBridgeConfig, PaySdkConfig } from '../Types/global';
2
3
  import MerchantInterface from './Contracts/MerchantInterface';
3
4
  declare class Utils {
4
5
  protected merchant: MerchantInterface;
5
6
  constructor(merchant: MerchantInterface);
7
+ /**
8
+ * 加密字符串
9
+ * @param plaintext 原文
10
+ * @param encoding 密文的编码格式,默认:base64
11
+ * @param hashType 哈希算法,默认:sha256
12
+ */
13
+ encrypt(plaintext: string, encoding?: BufferEncoding, hashType?: string): string;
14
+ /**
15
+ * 解密字符串
16
+ * @param ciphertext 密文
17
+ * @param encoding 密文的编码格式,默认:base64
18
+ * @param hashType 哈希算法,默认:sha256
19
+ */
20
+ decrypt(ciphertext: string, encoding?: BufferEncoding, hashType?: string): string;
6
21
  /**
7
22
  * 创建签名(V3),并返回签名字符串
8
23
  * @param params 参数集合
9
24
  * @returns
10
25
  */
11
- protected createSignature(message: string): string;
26
+ createSignature(message: string): string;
12
27
  /**
13
28
  * 创建签名(V2),并返回签名字符串
14
29
  * @param params 参数集合
package/dist/Pay/Utils.js CHANGED
@@ -8,6 +8,28 @@ class Utils {
8
8
  constructor(merchant) {
9
9
  this.merchant = merchant;
10
10
  }
11
+ /**
12
+ * 加密字符串
13
+ * @param plaintext 原文
14
+ * @param encoding 密文的编码格式,默认:base64
15
+ * @param hashType 哈希算法,默认:sha256
16
+ */
17
+ encrypt(plaintext, encoding = 'base64', hashType = 'sha256') {
18
+ let rsa = new RSA_1.default;
19
+ rsa.setPublicKey(this.merchant.getCertificate().toString());
20
+ return rsa.encrypt(plaintext, encoding, hashType);
21
+ }
22
+ /**
23
+ * 解密字符串
24
+ * @param ciphertext 密文
25
+ * @param encoding 密文的编码格式,默认:base64
26
+ * @param hashType 哈希算法,默认:sha256
27
+ */
28
+ decrypt(ciphertext, encoding = 'base64', hashType = 'sha256') {
29
+ let rsa = new RSA_1.default;
30
+ rsa.setPrivateKey(this.merchant.getPrivateKey().toString());
31
+ return rsa.decrypt(ciphertext, encoding, hashType);
32
+ }
11
33
  /**
12
34
  * 创建签名(V3),并返回签名字符串
13
35
  * @param params 参数集合
@@ -15,7 +37,6 @@ class Utils {
15
37
  */
16
38
  createSignature(message) {
17
39
  let rsa = new RSA_1.default;
18
- rsa.setPublicKey(this.merchant.getCertificate().toString());
19
40
  rsa.setPrivateKey(this.merchant.getPrivateKey().toString());
20
41
  return rsa.sign(message);
21
42
  }
@@ -0,0 +1,14 @@
1
+ import ValidatorInterface from "./Contracts/ValidatorInterface";
2
+ import MessageInterface from "../Core/Http/Contracts/MessageInterface";
3
+ import MerchantInterface from "./Contracts/MerchantInterface";
4
+ declare class Validator implements ValidatorInterface {
5
+ protected merchant: MerchantInterface;
6
+ static MAX_ALLOWED_CLOCK_OFFSET: number;
7
+ static HEADER_TIMESTAMP: string;
8
+ static HEADER_NONCE: string;
9
+ static HEADER_SERIAL: string;
10
+ static HEADER_SIGNATURE: string;
11
+ constructor(merchant: MerchantInterface);
12
+ validate(request: MessageInterface): boolean;
13
+ }
14
+ export = Validator;
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const Utils_1 = require("../Core/Support/Utils");
6
+ const RSA_1 = __importDefault(require("../Core/Support/RSA"));
7
+ class Validator {
8
+ constructor(merchant) {
9
+ this.merchant = merchant;
10
+ }
11
+ validate(request) {
12
+ [
13
+ Validator.HEADER_TIMESTAMP,
14
+ Validator.HEADER_NONCE,
15
+ Validator.HEADER_SERIAL,
16
+ Validator.HEADER_SIGNATURE,
17
+ ].forEach(key => {
18
+ if (!request.hasHeader(key)) {
19
+ throw new Error(`Missing Header: ${key}`);
20
+ }
21
+ });
22
+ let timestamp = request.getHeader(Validator.HEADER_TIMESTAMP) || '';
23
+ let nonce = request.getHeader(Validator.HEADER_NONCE) || '';
24
+ let serial = request.getHeader(Validator.HEADER_SERIAL) || '';
25
+ let signature = request.getHeader(Validator.HEADER_SIGNATURE) || '';
26
+ let body = request.getBody().toString();
27
+ let message = `${timestamp}\n${nonce}\n${body}\n`;
28
+ if ((0, Utils_1.getTimestamp)() - parseInt(timestamp) > Validator.MAX_ALLOWED_CLOCK_OFFSET) {
29
+ throw new Error('Clock Offset Exceeded');
30
+ }
31
+ let publicKey = this.merchant.getPlatformCert(serial);
32
+ if (!publicKey) {
33
+ throw new Error(`No platform certs found for serial: ${serial}, please download from wechat pay and set it in merchant config with key \`platform_certs\`.`);
34
+ }
35
+ let rsa = new RSA_1.default;
36
+ rsa.setPublicKey(publicKey.getValue());
37
+ if (false === rsa.verify(signature, message)) {
38
+ throw new Error('Invalid Signature');
39
+ }
40
+ return true;
41
+ }
42
+ }
43
+ Validator.MAX_ALLOWED_CLOCK_OFFSET = 300;
44
+ Validator.HEADER_TIMESTAMP = 'Wechatpay-Timestamp';
45
+ Validator.HEADER_NONCE = 'Wechatpay-Nonce';
46
+ Validator.HEADER_SERIAL = 'Wechatpay-Serial';
47
+ Validator.HEADER_SIGNATURE = 'Wechatpay-Signature';
48
+ module.exports = Validator;
@@ -0,0 +1,2 @@
1
+
2
+ type Recordable<T = any> = Record<string, T>;
@@ -10,6 +10,7 @@ import OpenPlatformMessage from '../OpenPlatform/Message';
10
10
  import OpenWorkMessage from '../OpenWork/Message';
11
11
  import HttpClientResponseInterface from '../Core/HttpClient/Contracts/HttpClientResponseInterface';
12
12
  import { PublicKey } from "../Core/Support/PublicKey";
13
+ import { IAxiosRetryConfig } from 'axios-retry';
13
14
 
14
15
  /**
15
16
  * 微信接口响应数据格式
@@ -75,7 +76,7 @@ export interface HttpConfig extends AxiosRequestConfig {
75
76
  * 是否抛出异常
76
77
  * @see https://github.com/softonic/axios-retry#options
77
78
  */
78
- retry?: IAxiosRetry.IAxiosRetryConfig;
79
+ retry?: IAxiosRetryConfig;
79
80
  // retry?: {
80
81
  // /**
81
82
  // * 仅以下状态码重试
@@ -318,7 +319,7 @@ export type WorkOAuthFactory = (app: WorkApplicationInterface) => ProviderInterf
318
319
  export interface ServerHandlerItem {
319
320
  hash: string;
320
321
  handler: ServerHandlerClosure;
321
- };
322
+ }
322
323
 
323
324
  /**
324
325
  * 服务端普通消息类型
@@ -335,7 +336,7 @@ export type ServerEventType = 'subscribe' | 'unsubscribe' | 'SCAN' | 'LOCATION'
335
336
  * @param message 微信信息
336
337
  * @param next 下一个消息处理器
337
338
  */
338
- export type ServerHandlerClosure<T = Message> = (message: T extends OfficialAccountMessage | PayMessage | WorkMessage | OpenPlatformMessage | OpenWorkMessage ? T : Message, next?: ServerHandler<T>) => any;
339
+ export type ServerHandlerClosure<T = Message> = (message: T extends OfficialAccountMessage | PayMessage | WorkMessage | OpenPlatformMessage | OpenWorkMessage ? T : Message, next?: ServerHandlerClosure<T>) => any;
339
340
 
340
341
  /**
341
342
  * HttpClient错误判定回调
@@ -4,14 +4,14 @@ import axios from 'axios';
4
4
  declare module 'axios' {
5
5
 
6
6
  interface AxiosInstance {
7
- <T = Recordable, R = ApiResponse<T>>(config: AxiosRequestConfig): Promise<R>;
8
- request<T = Recordable, R = ApiResponse<T>>(config: AxiosRequestConfig): Promise<R>;
9
- get<T = Recordable, R = ApiResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
10
- delete<T = Recordable, R = ApiResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
11
- head<T = Recordable, R = ApiResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
12
- post<T = Recordable, R = ApiResponse<T>>(url: string, data?: Recordable, config?: AxiosRequestConfig): Promise<R>;
13
- put<T = Recordable, R = ApiResponse<T>>(url: string, data?: Recordable, config?: AxiosRequestConfig): Promise<R>;
14
- patch<T = Recordable, R = ApiResponse<T>>(url: string, data?: Recordable, config?: AxiosRequestConfig): Promise<R>;
7
+ <T = Recordable, R = AxiosResponse<T>>(config: AxiosRequestConfig): Promise<R>;
8
+ request<T = Recordable, R = AxiosResponse<T>>(config: AxiosRequestConfig): Promise<R>;
9
+ get<T = Recordable, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
10
+ delete<T = Recordable, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
11
+ head<T = Recordable, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
12
+ post<T = Recordable, R = AxiosResponse<T>>(url: string, data?: Recordable, config?: AxiosRequestConfig): Promise<R>;
13
+ put<T = Recordable, R = AxiosResponse<T>>(url: string, data?: Recordable, config?: AxiosRequestConfig): Promise<R>;
14
+ patch<T = Recordable, R = AxiosResponse<T>>(url: string, data?: Recordable, config?: AxiosRequestConfig): Promise<R>;
15
15
  }
16
16
 
17
17
  interface AxiosRequestConfig {
@@ -25,6 +25,7 @@ declare class Application implements ApplicationInterface {
25
25
  protected accessToken: AccessTokenInterface;
26
26
  protected oauthFactory: WorkOAuthFactory;
27
27
  protected ticket: JsApiTicket;
28
+ protected utils: Utils;
28
29
  getAccount(): AccountInterface;
29
30
  /**
30
31
  * 设置当前账户实例
@@ -62,6 +63,11 @@ declare class Application implements ApplicationInterface {
62
63
  * @returns
63
64
  */
64
65
  setTicket(ticket: JsApiTicket): this;
66
+ /**
67
+ * 设置工具实例
68
+ * @param utils
69
+ */
70
+ setUtils(utils: Utils): void;
65
71
  getUtils(): Utils;
66
72
  createClient(): AccessTokenAwareClient;
67
73
  /**
@@ -39,6 +39,7 @@ class Application {
39
39
  this.accessToken = null;
40
40
  this.oauthFactory = null;
41
41
  this.ticket = null;
42
+ this.utils = null;
42
43
  if (config instanceof ConfigInterface_1.default) {
43
44
  this.setConfig(config);
44
45
  }
@@ -157,8 +158,18 @@ class Application {
157
158
  this.ticket = ticket;
158
159
  return this;
159
160
  }
161
+ /**
162
+ * 设置工具实例
163
+ * @param utils
164
+ */
165
+ setUtils(utils) {
166
+ this.utils = utils;
167
+ }
160
168
  getUtils() {
161
- return new Utils_2.default(this);
169
+ if (!this.utils) {
170
+ this.utils = new Utils_2.default(this);
171
+ }
172
+ return this.utils;
162
173
  }
163
174
  createClient() {
164
175
  return (new AccessTokenAwareClient_1.default(this.getHttpClient(), this.getAccessToken(), (response) => { var _a; return (_a = response.toObject()['errcode']) !== null && _a !== void 0 ? _a : 0; }, this.getConfig().get('http.throw', true)))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-easywechat",
3
- "version": "3.5.6",
3
+ "version": "3.5.8",
4
4
  "description": "EasyWechat SDK for Node.js (NOT OFFICIAL)",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -22,11 +22,11 @@
22
22
  "node": ">=15.6.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@types/node": "^17.0.23",
25
+ "@types/node": "^20.10.5",
26
26
  "axios-mock-adapter": "^1.22.0",
27
27
  "mocha": "^9.2.2",
28
28
  "package-release": "^1.0.3",
29
- "typescript": "^4.6.3"
29
+ "typescript": "^5.3.3"
30
30
  },
31
31
  "dependencies": {
32
32
  "axios": "^1.6.1",
package/tsconfig.json CHANGED
@@ -58,7 +58,7 @@
58
58
  // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
59
59
  // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
60
60
  /* Advanced Options */
61
- "skipLibCheck": true, /* Skip type checking of declaration files. */
61
+ "skipLibCheck": false, /* Skip type checking of declaration files. */
62
62
  "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
63
63
  },
64
64
  "include": [