node-easywechat 3.3.5 → 3.4.0

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/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v3.4.0 (2023-06-13)
5
+
6
+ - Feat: 公众号、小程序配置项新增是否使用稳定版接口调用凭据的选项
7
+
8
+ ## v3.3.6 (2023-05-12)
9
+
10
+ - Fix: 修复微信支付v3签名错误
11
+
4
12
  ## v3.3.5 (2023-04-28)
5
13
 
6
14
  - Fix: 修复部分接口请求方式及请求参数设置方式异常的问题
package/README.md CHANGED
@@ -127,7 +127,9 @@ let data = response.toObject();
127
127
  scope: 'snsapi_userinfo',
128
128
  // 网页授权回调地址,完整的URL
129
129
  redirect: 'http://node-easywechat.hpyer.cn/wxlogin/callback'
130
- }
130
+ },
131
+ // 是否使用稳定版接口调用凭据,默认:false
132
+ use_stable_access_token: false
131
133
  }
132
134
  ```
133
135
 
@@ -141,7 +143,9 @@ let data = response.toObject();
141
143
  // 小程序的 token
142
144
  token: '',
143
145
  // EncodingAESKey
144
- aes_key: ''
146
+ aes_key: '',
147
+ // 是否使用稳定版接口调用凭据,默认:false
148
+ use_stable_access_token: false
145
149
  }
146
150
  ```
147
151
 
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import crypto from 'crypto';
2
+ import crypto, { BinaryToTextEncoding } from 'crypto';
3
3
  declare class RSA {
4
4
  protected publicKey: crypto.KeyObject;
5
5
  /**
@@ -40,21 +40,19 @@ declare class RSA {
40
40
  /**
41
41
  * 计算签名
42
42
  * @param data 待解密文本
43
- * @param hashType 哈希方式,默认:'sha256'
43
+ * @param hashType 哈希方式,默认:'RSA-SHA256'
44
44
  * @param encoding 编码,默认:'base64'
45
- * @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
46
45
  * @returns
47
46
  */
48
- sign(data: string, hashType?: string, encoding?: BufferEncoding, padding?: number): string;
47
+ sign(data: string, hashType?: string, encoding?: BinaryToTextEncoding): string;
49
48
  /**
50
49
  * 验证签名
51
50
  * @param signature 待验证签名字符串
52
51
  * @param data 待解密文本
53
- * @param hashType 哈希方式,默认:'sha256'
52
+ * @param hashType 哈希方式,默认:'RSA-SHA256'
54
53
  * @param encoding 编码,默认:'base64'
55
- * @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
56
54
  * @returns
57
55
  */
58
- verify(signature: string, data: string, hashType: string, encoding?: BufferEncoding, padding?: number): boolean;
56
+ verify(signature: string, data: string, hashType?: string, encoding?: BinaryToTextEncoding): boolean;
59
57
  }
60
58
  export = RSA;
@@ -65,33 +65,28 @@ class RSA {
65
65
  /**
66
66
  * 计算签名
67
67
  * @param data 待解密文本
68
- * @param hashType 哈希方式,默认:'sha256'
68
+ * @param hashType 哈希方式,默认:'RSA-SHA256'
69
69
  * @param encoding 编码,默认:'base64'
70
- * @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
71
70
  * @returns
72
71
  */
73
- sign(data, hashType = 'sha256', encoding = 'base64', padding = crypto_1.default.constants.RSA_PKCS1_PSS_PADDING) {
74
- let signature = crypto_1.default.sign(hashType, Buffer.from(data), {
75
- key: this.privateKey,
76
- padding,
77
- });
78
- return signature.toString(encoding);
72
+ sign(data, hashType = 'RSA-SHA256', encoding = 'base64') {
73
+ return crypto_1.default
74
+ .createSign(hashType)
75
+ .update(data)
76
+ .sign(this.privateKey, encoding);
79
77
  }
80
78
  /**
81
79
  * 验证签名
82
80
  * @param signature 待验证签名字符串
83
81
  * @param data 待解密文本
84
- * @param hashType 哈希方式,默认:'sha256'
82
+ * @param hashType 哈希方式,默认:'RSA-SHA256'
85
83
  * @param encoding 编码,默认:'base64'
86
- * @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
87
84
  * @returns
88
85
  */
89
- verify(signature, data, hashType, encoding = 'base64', padding = crypto_1.default.constants.RSA_PKCS1_PSS_PADDING) {
90
- let isVerified = crypto_1.default.verify(hashType, Buffer.from(data), {
91
- key: this.publicKey,
92
- padding,
93
- }, Buffer.from(signature, encoding));
94
- return !!isVerified;
86
+ verify(signature, data, hashType = 'RSA-SHA256', encoding = 'base64') {
87
+ const verify = crypto_1.default.createVerify(hashType);
88
+ verify.update(data);
89
+ return verify.verify(this.publicKey, signature, encoding);
95
90
  }
96
91
  }
97
92
  ;
@@ -90,7 +90,7 @@ class Application {
90
90
  }
91
91
  getAccessToken() {
92
92
  if (!this.accessToken) {
93
- this.accessToken = new AccessToken_1.default(this.getAccount().getAppId(), this.getAccount().getSecret(), null, this.getCache(), this.getHttpClient());
93
+ this.accessToken = new AccessToken_1.default(this.getAccount().getAppId(), this.getAccount().getSecret(), null, this.getCache(), this.getHttpClient(), this.config.get('use_stable_access_token', false));
94
94
  }
95
95
  return this.accessToken;
96
96
  }
@@ -7,7 +7,8 @@ declare class AccessToken implements RefreshableAccessTokenInterface {
7
7
  protected key: string;
8
8
  protected cache: CacheInterface;
9
9
  protected httpClient: HttpClientInterface;
10
- constructor(appId: string, secret: string, key?: string, cache?: CacheInterface, httpClient?: HttpClientInterface);
10
+ protected stable: boolean;
11
+ constructor(appId: string, secret: string, key?: string, cache?: CacheInterface, httpClient?: HttpClientInterface, stable?: boolean);
11
12
  /**
12
13
  * 获取access_token的缓存名称
13
14
  * @returns
@@ -22,5 +23,14 @@ declare class AccessToken implements RefreshableAccessTokenInterface {
22
23
  getToken(): Promise<string>;
23
24
  toQuery(): Promise<Record<string, any>>;
24
25
  refresh(): Promise<string>;
26
+ /**
27
+ * 获取稳定版接口调用凭据
28
+ * @param forceRefresh 是否强制刷新,默认:false
29
+ */
30
+ getStableAccessToken(forceRefresh?: boolean): Promise<string>;
31
+ /**
32
+ * 获取接口调用凭据
33
+ */
34
+ getAccessToken(): Promise<string>;
25
35
  }
26
36
  export = AccessToken;
@@ -13,12 +13,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  const HttpClient_1 = __importDefault(require("../Core/HttpClient/HttpClient"));
15
15
  class AccessToken {
16
- constructor(appId, secret, key = null, cache = null, httpClient = null) {
16
+ constructor(appId, secret, key = null, cache = null, httpClient = null, stable = false) {
17
17
  this.appId = appId;
18
18
  this.secret = secret;
19
19
  this.key = key;
20
20
  this.cache = cache;
21
21
  this.httpClient = httpClient;
22
+ this.stable = stable;
22
23
  if (!this.httpClient) {
23
24
  this.httpClient = HttpClient_1.default.create({
24
25
  baseURL: 'https://api.weixin.qq.com/',
@@ -64,6 +65,35 @@ class AccessToken {
64
65
  });
65
66
  }
66
67
  refresh() {
68
+ return this.stable ? this.getStableAccessToken() : this.getAccessToken();
69
+ }
70
+ /**
71
+ * 获取稳定版接口调用凭据
72
+ * @param forceRefresh 是否强制刷新,默认:false
73
+ */
74
+ getStableAccessToken(forceRefresh = false) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ let response = (yield this.httpClient.request('post', 'cgi-bin/stable_token', {
77
+ json: {
78
+ grant_type: 'client_credential',
79
+ appid: this.appId,
80
+ secret: this.secret,
81
+ force_refresh: forceRefresh,
82
+ }
83
+ })).toObject();
84
+ if (!response['access_token']) {
85
+ throw new Error('Failed to get stable access_token: ' + JSON.stringify(response));
86
+ }
87
+ if (this.cache) {
88
+ yield this.cache.set(this.getKey(), response['access_token'], parseInt(response['expires_in']));
89
+ }
90
+ return response['access_token'];
91
+ });
92
+ }
93
+ /**
94
+ * 获取接口调用凭据
95
+ */
96
+ getAccessToken() {
67
97
  return __awaiter(this, void 0, void 0, function* () {
68
98
  let response = (yield this.httpClient.request('get', 'cgi-bin/token', {
69
99
  params: {
@@ -90,7 +90,7 @@ class Application {
90
90
  }
91
91
  getAccessToken() {
92
92
  if (!this.accessToken) {
93
- this.accessToken = new AccessToken_1.default(this.getAccount().getAppId(), this.getAccount().getSecret(), null, this.getCache(), this.getHttpClient());
93
+ this.accessToken = new AccessToken_1.default(this.getAccount().getAppId(), this.getAccount().getSecret(), null, this.getCache(), this.getHttpClient(), this.config.get('use_stable_access_token', false));
94
94
  }
95
95
  return this.accessToken;
96
96
  }
@@ -84,7 +84,7 @@ class Application {
84
84
  */
85
85
  getHttpClientDefaultOptions() {
86
86
  return (0, merge_1.default)(true, {
87
- baseURL: 'https://api.weixin.qq.com/',
87
+ baseURL: 'https://api.mch.weixin.qq.com',
88
88
  }, this.getConfig().get('http'));
89
89
  }
90
90
  }
@@ -34,7 +34,7 @@ class Signature {
34
34
  body = payload.data;
35
35
  }
36
36
  }
37
- let signString = `${method.toUpperCase()}\n${pathname}\n${timestamp}\n${nonce}\n${body}`;
37
+ let signString = `${method.toUpperCase()}\n${pathname}\n${timestamp}\n${nonce}\n${body}\n`;
38
38
  let rsa = new RSA_1.default;
39
39
  rsa.setPublicKey(this.merchant.getCertificate().getValue());
40
40
  rsa.setPrivateKey(this.merchant.getPrivateKey().getKey());
@@ -147,6 +147,12 @@ export declare interface OfficialAccountConfig extends BaseConfig {
147
147
  * 网页授权相关配置
148
148
  */
149
149
  oauth?: OauthConfig;
150
+
151
+ /**
152
+ * 是否使用稳定版接口调用凭据,默认:false
153
+ * @see https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/getStableAccessToken.html
154
+ */
155
+ use_stable_access_token?: boolean;
150
156
  }
151
157
 
152
158
  /**
@@ -172,6 +178,12 @@ export declare interface MiniAppConfig extends BaseConfig {
172
178
  * 服务端消息加解密密钥 aes_key
173
179
  */
174
180
  aes_key?: string;
181
+
182
+ /**
183
+ * 是否使用稳定版接口调用凭据,默认:false
184
+ * @see https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html
185
+ */
186
+ use_stable_access_token?: boolean;
175
187
  }
176
188
 
177
189
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-easywechat",
3
- "version": "3.3.5",
3
+ "version": "3.4.0",
4
4
  "description": "EasyWechat SDK for Node.js (NOT OFFICIAL)",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {