node-easywechat 3.5.12 → 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,17 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v3.5.14 (2023-12-20)
5
+
6
+ - Fix: 修复个别情况下微信支付的敏感信息加密功能可能使用旧证书的问题 (#57)
7
+ - Fix: 获取微信支付平台证书时,忽略有效期少于1天的证书 (#57)
8
+
9
+ ## v3.5.13 (2023-12-20)
10
+
11
+ - Feat: 开放平台新增快速注册企业小程序审核事件的支持 (#62)
12
+
13
+ - Fix: 修复微信支付敏感信息加密方法证书错误的问题 (#57)
14
+
4
15
  ## v3.5.12 (2023-12-19)
5
16
 
6
17
  - Fix: 修复类型错误
@@ -63,8 +63,7 @@ class MessageMixin {
63
63
  }
64
64
  withBody(body) {
65
65
  if (Buffer.isBuffer(body)) {
66
- this.content = Buffer.from('');
67
- this.content.copy(body);
66
+ this.content = body;
68
67
  }
69
68
  else if (typeof body === 'string') {
70
69
  this.content = Buffer.from(body);
@@ -16,10 +16,12 @@ interface Message {
16
16
  * - unauthorized:取消授权
17
17
  * - updateauthorized:更新授权
18
18
  * - component_verify_ticket:验证票据
19
+ * - notify_third_fasteregister:快速注册企业小程序审核事件
19
20
  * @see [授权变更通知推送](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/Before_Develop/authorize_event.html)
20
21
  * @see [验证票据](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/Before_Develop/component_verify_ticket.html)
22
+ * @see [快速注册企业小程序审核事件](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/Register_Mini_Programs/Fast_Registration_Interface_document.html#三、注册审核事件推送)
21
23
  */
22
- InfoType?: 'authorized' | 'unauthorized' | 'updateauthorized' | 'component_verify_ticket';
24
+ InfoType?: 'authorized' | 'unauthorized' | 'updateauthorized' | 'component_verify_ticket' | 'notify_third_fasteregister' | string;
23
25
  /**
24
26
  * 公众号或小程序的 appid
25
27
  */
@@ -44,6 +44,12 @@ declare class Server extends ServerInterface {
44
44
  * @returns
45
45
  */
46
46
  handleVerifyTicketRefreshed(handler: ServerHandlerClosure<Message>): this;
47
+ /**
48
+ * 处理快速注册企业小程序审核通知
49
+ * @param handler
50
+ * @returns
51
+ */
52
+ handleThirdFastRegister(handler: ServerHandlerClosure<Message>): this;
47
53
  protected decryptRequestMessage(): ServerHandlerClosure<Message>;
48
54
  /**
49
55
  * 获取来自微信服务器的推送消息
@@ -102,6 +102,18 @@ class Server extends ServerInterface_1.default {
102
102
  });
103
103
  });
104
104
  }
105
+ /**
106
+ * 处理快速注册企业小程序审核通知
107
+ * @param handler
108
+ * @returns
109
+ */
110
+ handleThirdFastRegister(handler) {
111
+ return this.with(function (message, next) {
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ return message.InfoType === 'notify_third_fasteregister' ? handler(message, next) : next(message);
114
+ });
115
+ });
116
+ }
105
117
  decryptRequestMessage() {
106
118
  let query = this.request.getQueryParams();
107
119
  return (message, next) => __awaiter(this, void 0, void 0, function* () {
@@ -35,16 +35,21 @@ declare abstract class MerchantInterface {
35
35
  */
36
36
  setPlatformCertKey(key: string): this;
37
37
  /**
38
- * 更具证书序列号获取平台证书
38
+ * 根据证书序列号获取平台证书
39
39
  * @param serial
40
40
  * @returns
41
41
  */
42
42
  getPlatformCert(serial: string): Promise<PublicKey>;
43
43
  /**
44
- * 获取平台证书
44
+ * 获取所有平台证书
45
+ * @returns
46
+ */
47
+ getPlatformCerts(): Promise<Record<string, PublicKey>>;
48
+ /**
49
+ * 从缓存或者接口获取平台证书
45
50
  * @param force 是否强制刷新缓存,默认:false
46
51
  */
47
- loadPlatformCerts(force?: boolean): Promise<void>;
52
+ loadPlatformCerts(force?: boolean): Promise<Record<string, string>>;
48
53
  /**
49
54
  * 设置平台证书
50
55
  * @param certs 键名:序列号,键值:PublicKey实例或者文件内容字符串
@@ -34,16 +34,21 @@ class MerchantInterface {
34
34
  */
35
35
  setPlatformCertKey(key) { return this; }
36
36
  /**
37
- * 更具证书序列号获取平台证书
37
+ * 根据证书序列号获取平台证书
38
38
  * @param serial
39
39
  * @returns
40
40
  */
41
41
  getPlatformCert(serial) { return null; }
42
42
  /**
43
- * 获取平台证书
43
+ * 获取所有平台证书
44
+ * @returns
45
+ */
46
+ getPlatformCerts() { return null; }
47
+ /**
48
+ * 从缓存或者接口获取平台证书
44
49
  * @param force 是否强制刷新缓存,默认:false
45
50
  */
46
- loadPlatformCerts(force = false) { return; }
51
+ loadPlatformCerts(force = false) { return null; }
47
52
  /**
48
53
  * 设置平台证书
49
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;
@@ -24,9 +25,10 @@ declare class Merchant implements MerchantInterface {
24
25
  getV2SecretKey(): string;
25
26
  getCertificate(): PublicKey;
26
27
  getPlatformCert(serial: string): Promise<PublicKey>;
28
+ getPlatformCerts(): Promise<Record<string, PublicKey>>;
27
29
  setPlatformCerts(certs: Record<string, PublicKey | string>): void;
28
30
  getPlatformCertKey(): string;
29
31
  setPlatformCertKey(key: string): this;
30
- loadPlatformCerts(force?: boolean): Promise<void>;
32
+ loadPlatformCerts(force?: boolean): Promise<Record<string, string>>;
31
33
  }
32
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,17 +74,30 @@ 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
  }
85
+ getPlatformCerts() {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ if (!this.isConfigPlatformCerts) {
88
+ // 如果不是通过配置文件设置的平台证书,则每次都从缓存或者接口获取证书
89
+ let certs = yield this.loadPlatformCerts();
90
+ this.setPlatformCerts(certs);
91
+ }
92
+ return this.platformCerts;
93
+ });
94
+ }
79
95
  setPlatformCerts(certs) {
80
96
  let newCerts = {};
81
97
  for (let key of Object.keys(certs)) {
82
98
  let cert = certs[key];
83
99
  if (typeof cert === 'string') {
100
+ // 将证书内容封装为 PublicKey
84
101
  newCerts[key] = PublicKey_1.PublicKey.createByCertificateContent(cert, key);
85
102
  }
86
103
  else {
@@ -109,14 +126,21 @@ class Merchant {
109
126
  let response = yield this.app.getClient().get('/v3/certificates');
110
127
  let data = response.toObject();
111
128
  if (data && data.data && data.data.length > 0) {
129
+ let nowTime = Math.round((new Date()).getTime() / 1000);
112
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;
113
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();
114
136
  certs[item.serial_no] = content;
115
137
  });
116
- yield cache.set(cacheKey, certs, 36000); // 缓存10小时
138
+ if (Object.keys(certs).length > 0) {
139
+ yield cache.set(cacheKey, certs, 36000); // 缓存10小时
140
+ }
117
141
  }
118
142
  }
119
- this.setPlatformCerts(certs);
143
+ return certs;
120
144
  });
121
145
  }
122
146
  }
@@ -125,6 +125,10 @@ class Server extends ServerInterface_1.default {
125
125
  */
126
126
  handlePaid(handler) {
127
127
  this.with((message, next) => __awaiter(this, void 0, void 0, function* () {
128
+ let isV2Message = message.getOriginalContents().startsWith('<xml');
129
+ if (isV2Message) {
130
+ return handler(message, next);
131
+ }
128
132
  return message.getEventType() === 'TRANSACTION.SUCCESS' && message.trade_state === 'SUCCESS'
129
133
  ? handler(message, next) : next(message);
130
134
  }));
@@ -1,23 +1,21 @@
1
- /// <reference types="node" />
1
+ import { PublicKey } from '../Core/Support/PublicKey';
2
+ import RSA from '../Core/Support/RSA';
2
3
  import { PayAppConfig, PayBridgeConfig, PaySdkConfig } from '../Types/global';
3
4
  import MerchantInterface from './Contracts/MerchantInterface';
4
5
  declare class Utils {
5
6
  protected merchant: MerchantInterface;
6
7
  constructor(merchant: MerchantInterface);
7
8
  /**
8
- * 加密字符串
9
- * @param plaintext 原文
10
- * @param encoding 密文的编码格式,默认:base64
11
- * @param hashType 哈希算法,默认:sha256
9
+ * 获取加密所用的平台证书
10
+ * @returns
12
11
  */
13
- encrypt(plaintext: string, encoding?: BufferEncoding, hashType?: string): string;
12
+ getPlatformCert(): Promise<PublicKey>;
14
13
  /**
15
- * 解密字符串
16
- * @param ciphertext 密文
17
- * @param encoding 密文的编码格式,默认:base64
18
- * @param hashType 哈希算法,默认:sha256
14
+ * 获取敏感信息加密机
15
+ * @param platformCert PublicKey封装过的平台证书
16
+ * @returns
19
17
  */
20
- decrypt(ciphertext: string, encoding?: BufferEncoding, hashType?: string): string;
18
+ getEncryptor(platformCert?: PublicKey): Promise<RSA>;
21
19
  /**
22
20
  * 创建签名(V3),并返回签名字符串
23
21
  * @param params 参数集合
package/dist/Pay/Utils.js CHANGED
@@ -1,7 +1,17 @@
1
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
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
14
+ const PublicKey_1 = require("../Core/Support/PublicKey");
5
15
  const RSA_1 = __importDefault(require("../Core/Support/RSA"));
6
16
  const Utils_1 = require("../Core/Support/Utils");
7
17
  class Utils {
@@ -9,26 +19,33 @@ class Utils {
9
19
  this.merchant = merchant;
10
20
  }
11
21
  /**
12
- * 加密字符串
13
- * @param plaintext 原文
14
- * @param encoding 密文的编码格式,默认:base64
15
- * @param hashType 哈希算法,默认:sha256
22
+ * 获取加密所用的平台证书
23
+ * @returns
16
24
  */
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);
25
+ getPlatformCert() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ let certs = yield this.merchant.getPlatformCerts();
28
+ if (!certs || Object.keys(certs).length === 0) {
29
+ throw new Error('Fail to get platform certs');
30
+ }
31
+ return certs[Object.keys(certs)[0]];
32
+ });
21
33
  }
22
34
  /**
23
- * 解密字符串
24
- * @param ciphertext 密文
25
- * @param encoding 密文的编码格式,默认:base64
26
- * @param hashType 哈希算法,默认:sha256
35
+ * 获取敏感信息加密机
36
+ * @param platformCert PublicKey封装过的平台证书
37
+ * @returns
27
38
  */
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);
39
+ getEncryptor(platformCert = null) {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ let rsa = new RSA_1.default;
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;
48
+ });
32
49
  }
33
50
  /**
34
51
  * 创建签名(V3),并返回签名字符串
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-easywechat",
3
- "version": "3.5.12",
3
+ "version": "3.5.14",
4
4
  "description": "EasyWechat SDK for Node.js (NOT OFFICIAL)",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {