node-easywechat 3.5.13 → 3.5.14

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,11 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v3.5.14 (2023-12-20)
5
+
6
+ - Fix: 修复个别情况下微信支付的敏感信息加密功能可能使用旧证书的问题 (#57)
7
+ - Fix: 获取微信支付平台证书时,忽略有效期少于1天的证书 (#57)
8
+
4
9
  ## v3.5.13 (2023-12-20)
5
10
 
6
11
  - Feat: 开放平台新增快速注册企业小程序审核事件的支持 (#62)
@@ -49,7 +49,7 @@ declare abstract class MerchantInterface {
49
49
  * 从缓存或者接口获取平台证书
50
50
  * @param force 是否强制刷新缓存,默认:false
51
51
  */
52
- loadPlatformCerts(force?: boolean): Promise<void>;
52
+ loadPlatformCerts(force?: boolean): Promise<Record<string, string>>;
53
53
  /**
54
54
  * 设置平台证书
55
55
  * @param certs 键名:序列号,键值:PublicKey实例或者文件内容字符串
@@ -48,7 +48,7 @@ class MerchantInterface {
48
48
  * 从缓存或者接口获取平台证书
49
49
  * @param force 是否强制刷新缓存,默认:false
50
50
  */
51
- loadPlatformCerts(force = false) { return; }
51
+ loadPlatformCerts(force = false) { return null; }
52
52
  /**
53
53
  * 设置平台证书
54
54
  * @param certs 键名:序列号,键值:PublicKey实例或者文件内容字符串
@@ -7,6 +7,7 @@ declare class Merchant implements MerchantInterface {
7
7
  protected secretKey: string;
8
8
  protected v2SecretKey: string;
9
9
  protected app: Application;
10
+ protected isConfigPlatformCerts: boolean;
10
11
  protected platformCerts: Record<string, PublicKey>;
11
12
  protected privateKey: PrivateKey;
12
13
  protected certificate: PublicKey;
@@ -28,6 +29,6 @@ declare class Merchant implements MerchantInterface {
28
29
  setPlatformCerts(certs: Record<string, PublicKey | string>): void;
29
30
  getPlatformCertKey(): string;
30
31
  setPlatformCertKey(key: string): this;
31
- loadPlatformCerts(force?: boolean): Promise<void>;
32
+ loadPlatformCerts(force?: boolean): Promise<Record<string, string>>;
32
33
  }
33
34
  export = Merchant;
@@ -17,6 +17,7 @@ class Merchant {
17
17
  this.secretKey = secretKey;
18
18
  this.v2SecretKey = v2SecretKey;
19
19
  this.app = app;
20
+ this.isConfigPlatformCerts = false;
20
21
  this.platformCerts = {};
21
22
  if (!(privateKey instanceof PrivateKey_1.PrivateKey)) {
22
23
  this.privateKey = new PrivateKey_1.PrivateKey(privateKey);
@@ -50,6 +51,9 @@ class Merchant {
50
51
  }
51
52
  certs[isArray ? publicKey.getSerialNo() : key] = publicKey;
52
53
  }
54
+ if (Object.keys(certs).length > 0) {
55
+ this.isConfigPlatformCerts = true;
56
+ }
53
57
  return certs;
54
58
  }
55
59
  getMerchantId() {
@@ -70,16 +74,20 @@ class Merchant {
70
74
  getPlatformCert(serial) {
71
75
  var _a;
72
76
  return __awaiter(this, void 0, void 0, function* () {
73
- if (!this.platformCerts || Object.keys(this.platformCerts).length === 0) {
74
- yield this.loadPlatformCerts();
77
+ if (!this.isConfigPlatformCerts) {
78
+ // 如果不是通过配置文件设置的平台证书,则每次都从缓存或者接口获取证书
79
+ let certs = yield this.loadPlatformCerts();
80
+ this.setPlatformCerts(certs);
75
81
  }
76
82
  return (_a = this.platformCerts[serial]) !== null && _a !== void 0 ? _a : null;
77
83
  });
78
84
  }
79
85
  getPlatformCerts() {
80
86
  return __awaiter(this, void 0, void 0, function* () {
81
- if (!this.platformCerts || Object.keys(this.platformCerts).length === 0) {
82
- yield this.loadPlatformCerts();
87
+ if (!this.isConfigPlatformCerts) {
88
+ // 如果不是通过配置文件设置的平台证书,则每次都从缓存或者接口获取证书
89
+ let certs = yield this.loadPlatformCerts();
90
+ this.setPlatformCerts(certs);
83
91
  }
84
92
  return this.platformCerts;
85
93
  });
@@ -89,6 +97,7 @@ class Merchant {
89
97
  for (let key of Object.keys(certs)) {
90
98
  let cert = certs[key];
91
99
  if (typeof cert === 'string') {
100
+ // 将证书内容封装为 PublicKey
92
101
  newCerts[key] = PublicKey_1.PublicKey.createByCertificateContent(cert, key);
93
102
  }
94
103
  else {
@@ -117,14 +126,21 @@ class Merchant {
117
126
  let response = yield this.app.getClient().get('/v3/certificates');
118
127
  let data = response.toObject();
119
128
  if (data && data.data && data.data.length > 0) {
129
+ let nowTime = Math.round((new Date()).getTime() / 1000);
120
130
  data.data.forEach((item) => {
131
+ // 跳过有效期少于1天的证书
132
+ let expireTime = Math.round((new Date(item.expire_time)).getTime() / 1000) - 86400;
133
+ if (expireTime < nowTime)
134
+ return;
121
135
  let content = AES_1.AES_GCM.decrypt(item.encrypt_certificate.ciphertext, this.app.getConfig().get('secret_key'), item.encrypt_certificate.nonce, item.encrypt_certificate.associated_data).toString();
122
136
  certs[item.serial_no] = content;
123
137
  });
124
- yield cache.set(cacheKey, certs, 36000); // 缓存10小时
138
+ if (Object.keys(certs).length > 0) {
139
+ yield cache.set(cacheKey, certs, 36000); // 缓存10小时
140
+ }
125
141
  }
126
142
  }
127
- this.setPlatformCerts(certs);
143
+ return certs;
128
144
  });
129
145
  }
130
146
  }
@@ -1,35 +1,21 @@
1
- /// <reference types="node" />
2
1
  import { PublicKey } from '../Core/Support/PublicKey';
2
+ import RSA from '../Core/Support/RSA';
3
3
  import { PayAppConfig, PayBridgeConfig, PaySdkConfig } from '../Types/global';
4
4
  import MerchantInterface from './Contracts/MerchantInterface';
5
5
  declare class Utils {
6
6
  protected merchant: MerchantInterface;
7
- protected platformCert: PublicKey;
8
7
  constructor(merchant: MerchantInterface);
9
- /**
10
- * 设置加密所用的平台证书
11
- * @param platformCert
12
- */
13
- setPlatformCert(platformCert: PublicKey): this;
14
8
  /**
15
9
  * 获取加密所用的平台证书
16
10
  * @returns
17
11
  */
18
12
  getPlatformCert(): Promise<PublicKey>;
19
13
  /**
20
- * 加密字符串
21
- * @param plaintext 原文
22
- * @param encoding 密文的编码格式,默认:base64
23
- * @param hashType 哈希算法,默认:sha256
24
- */
25
- encrypt(plaintext: string, encoding?: BufferEncoding, hashType?: string): Promise<string>;
26
- /**
27
- * 解密字符串
28
- * @param ciphertext 密文
29
- * @param encoding 密文的编码格式,默认:base64
30
- * @param hashType 哈希算法,默认:sha256
14
+ * 获取敏感信息加密机
15
+ * @param platformCert PublicKey封装过的平台证书
16
+ * @returns
31
17
  */
32
- decrypt(ciphertext: string, encoding?: BufferEncoding, hashType?: string): string;
18
+ getEncryptor(platformCert?: PublicKey): Promise<RSA>;
33
19
  /**
34
20
  * 创建签名(V3),并返回签名字符串
35
21
  * @param params 参数集合
package/dist/Pay/Utils.js CHANGED
@@ -11,61 +11,42 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
+ const PublicKey_1 = require("../Core/Support/PublicKey");
14
15
  const RSA_1 = __importDefault(require("../Core/Support/RSA"));
15
16
  const Utils_1 = require("../Core/Support/Utils");
16
17
  class Utils {
17
18
  constructor(merchant) {
18
19
  this.merchant = merchant;
19
20
  }
20
- /**
21
- * 设置加密所用的平台证书
22
- * @param platformCert
23
- */
24
- setPlatformCert(platformCert) {
25
- this.platformCert = platformCert;
26
- return this;
27
- }
28
21
  /**
29
22
  * 获取加密所用的平台证书
30
23
  * @returns
31
24
  */
32
25
  getPlatformCert() {
33
26
  return __awaiter(this, void 0, void 0, function* () {
34
- if (!this.platformCert) {
35
- let certs = yield this.merchant.getPlatformCerts();
36
- if (!certs || Object.keys(certs).length === 0) {
37
- throw new Error('Fail to get platform certs');
38
- }
39
- this.platformCert = certs[Object.keys(certs)[0]];
27
+ let certs = yield this.merchant.getPlatformCerts();
28
+ if (!certs || Object.keys(certs).length === 0) {
29
+ throw new Error('Fail to get platform certs');
40
30
  }
41
- return this.platformCert;
31
+ return certs[Object.keys(certs)[0]];
42
32
  });
43
33
  }
44
34
  /**
45
- * 加密字符串
46
- * @param plaintext 原文
47
- * @param encoding 密文的编码格式,默认:base64
48
- * @param hashType 哈希算法,默认:sha256
35
+ * 获取敏感信息加密机
36
+ * @param platformCert PublicKey封装过的平台证书
37
+ * @returns
49
38
  */
50
- encrypt(plaintext, encoding = 'base64', hashType = 'sha256') {
39
+ getEncryptor(platformCert = null) {
51
40
  return __awaiter(this, void 0, void 0, function* () {
52
41
  let rsa = new RSA_1.default;
53
- let cert = yield this.getPlatformCert();
54
- rsa.setPublicKey(cert.toString());
55
- return rsa.encrypt(plaintext, encoding, hashType);
42
+ if (!platformCert || !(platformCert instanceof PublicKey_1.PublicKey)) {
43
+ platformCert = yield this.getPlatformCert();
44
+ }
45
+ rsa.setPublicKey(platformCert.toString());
46
+ rsa.setPrivateKey(this.merchant.getPrivateKey().toString());
47
+ return rsa;
56
48
  });
57
49
  }
58
- /**
59
- * 解密字符串
60
- * @param ciphertext 密文
61
- * @param encoding 密文的编码格式,默认:base64
62
- * @param hashType 哈希算法,默认:sha256
63
- */
64
- decrypt(ciphertext, encoding = 'base64', hashType = 'sha256') {
65
- let rsa = new RSA_1.default;
66
- rsa.setPrivateKey(this.merchant.getPrivateKey().toString());
67
- return rsa.decrypt(ciphertext, encoding, hashType);
68
- }
69
50
  /**
70
51
  * 创建签名(V3),并返回签名字符串
71
52
  * @param params 参数集合
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-easywechat",
3
- "version": "3.5.13",
3
+ "version": "3.5.14",
4
4
  "description": "EasyWechat SDK for Node.js (NOT OFFICIAL)",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {