node-easywechat 3.5.9 → 3.5.10

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.5.10 (2023-12-19)
5
+
6
+ - Feat: 微信支付通知处理增加v2接口xml格式的消息处理 (#56)
7
+
8
+ - Fix: 修复计算v3签名时请求的querystring参数丢失导致签名错误的问题 (#60)
9
+ - Fix: 修复回调方法的消息类型推到错误的问题
10
+ - Fix: 修复获取平台证书时,响应数据解析异常的问题 (#57)
11
+
4
12
  ## v3.5.9 (2023-12-18)
5
13
 
6
14
  - Feat: 微信支付增加读取平台证书的方法loadPlatformCerts,并自动写入商户配置 (#57)
@@ -42,7 +42,7 @@ declare abstract class ServerRequestInterface extends RequestInterface {
42
42
  * 获取所有post参数
43
43
  * @returns
44
44
  */
45
- getParsedBody(): Record<string, any>;
45
+ getParsedBody(): Promise<Record<string, any>>;
46
46
  /**
47
47
  * 设置post参数
48
48
  * @param data
@@ -63,7 +63,8 @@ class MessageMixin {
63
63
  }
64
64
  withBody(body) {
65
65
  if (Buffer.isBuffer(body)) {
66
- this.content = body;
66
+ this.content = Buffer.from('');
67
+ this.content.copy(body);
67
68
  }
68
69
  else if (typeof body === 'string') {
69
70
  this.content = Buffer.from(body);
@@ -17,9 +17,9 @@ declare class ServerRequest implements ServerRequestInterface {
17
17
  constructor(method: string, url: string, headers?: Record<string, any>, body?: Buffer | Record<string, any> | string, version?: string, serverParams?: Record<string, any>);
18
18
  /**
19
19
  * 解析 body 内容
20
- * @param body 支持 Buffer、object对象、JSON字符串、XML字符串、QueryString等格式
20
+ * 支持 JSON字符串、XML字符串、QueryString等格式
21
21
  */
22
- protected parseBody(body: Buffer | Record<string, any> | string): void;
22
+ protected parseBody(): Promise<void>;
23
23
  getServerParams(): Record<string, any>;
24
24
  getCookieParams(): Record<string, any>;
25
25
  withCookieParams(cookies: Record<string, any>): this;
@@ -27,7 +27,7 @@ declare class ServerRequest implements ServerRequestInterface {
27
27
  withQueryParams(query: Record<string, any>): this;
28
28
  getUploadedFiles(): Record<string, any>;
29
29
  withUploadedFiles(files: Record<string, any>): this;
30
- getParsedBody(): Record<string, any>;
30
+ getParsedBody(): Promise<Record<string, any>>;
31
31
  withParsedBody(data: Record<string, any>): this;
32
32
  getAttributes(): Record<string, any>;
33
33
  getAttribute(name: string, defaultValue?: any): any;
@@ -35,42 +35,40 @@ class ServerRequest {
35
35
  .withProtocolVersion(version)
36
36
  .withQueryParams((0, url_1.parse)(url, true).query || {});
37
37
  if (body) {
38
- this.parseBody(body);
38
+ this.withBody(body);
39
39
  }
40
40
  }
41
41
  /**
42
42
  * 解析 body 内容
43
- * @param body 支持 Buffer、object对象、JSON字符串、XML字符串、QueryString等格式
43
+ * 支持 JSON字符串、XML字符串、QueryString等格式
44
44
  */
45
- parseBody(body) {
46
- if (Buffer.isBuffer(body)) {
47
- this.content = Buffer.from('');
48
- this.content.copy(body);
49
- }
50
- else if (typeof body === 'object' && Object.keys(body).length > 0) {
51
- this.parsedBody = body;
52
- this.content = Buffer.from(JSON.stringify(body));
53
- this.headers['content-type'] = 'application/json';
54
- }
55
- else if (typeof body === 'string') {
56
- try {
57
- this.parsedBody = JSON.parse(body);
58
- this.headers['content-type'] = 'application/json';
45
+ parseBody() {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ let body = this.content.toString();
48
+ if (body.startsWith('<xml')) {
49
+ let res = yield (0, Utils_1.parseXml)(body);
50
+ this.parsedBody = res;
51
+ this.headers['content-type'] = 'text/xml';
59
52
  }
60
- catch (e) {
61
- if (body.substring(0, 1) === '<') {
62
- (0, Utils_1.parseXml)(body).then(res => {
63
- this.parsedBody = res;
64
- this.headers['content-type'] = 'text/xml';
65
- });
53
+ else if (body.startsWith('{') || body.startsWith('[')) {
54
+ try {
55
+ this.parsedBody = JSON.parse(body);
56
+ this.headers['content-type'] = 'application/json';
66
57
  }
67
- else {
58
+ catch (e) {
59
+ this.parsedBody = {};
60
+ }
61
+ }
62
+ else {
63
+ try {
68
64
  this.parsedBody = (0, Utils_1.parseQueryString)(body);
69
65
  this.headers['content-type'] = 'application/x-www-form-urlencoded';
70
66
  }
67
+ catch (e) {
68
+ this.parsedBody = {};
69
+ }
71
70
  }
72
- this.content = Buffer.from(body);
73
- }
71
+ });
74
72
  }
75
73
  getServerParams() {
76
74
  return this.serverParams;
@@ -97,7 +95,12 @@ class ServerRequest {
97
95
  return this;
98
96
  }
99
97
  getParsedBody() {
100
- return this.parsedBody;
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ if (!this.parsedBody || Object.keys(this.parsedBody).length === 0) {
100
+ yield this.parseBody();
101
+ }
102
+ return this.parsedBody;
103
+ });
101
104
  }
102
105
  withParsedBody(data) {
103
106
  this.parsedBody = merge_1.default.recursive(true, data);
@@ -12,56 +12,56 @@ declare class HandlersMixin {
12
12
  * @param handler
13
13
  * @returns
14
14
  */
15
- createHandlerItem(handler: ServerHandlerClosure): ServerHandlerItem;
15
+ createHandlerItem(handler: ServerHandlerClosure<Message>): ServerHandlerItem;
16
16
  /**
17
17
  * 计算处理器hash
18
18
  * @param handler
19
19
  * @returns
20
20
  */
21
- protected getHandlerHash(handler: ServerHandlerClosure): string;
21
+ protected getHandlerHash(handler: ServerHandlerClosure<Message>): string;
22
22
  /**
23
23
  * @alias withHandler()
24
24
  */
25
- with(handler: ServerHandlerClosure): this;
25
+ with(handler: ServerHandlerClosure<Message>): this;
26
26
  /**
27
27
  * 从最后添加处理器
28
28
  * @param handler
29
29
  * @returns
30
30
  */
31
- withHandler(handler: ServerHandlerClosure): this;
31
+ withHandler(handler: ServerHandlerClosure<Message>): this;
32
32
  /**
33
33
  * @alias prependHandler()
34
34
  */
35
- prepend(handler: ServerHandlerClosure): this;
35
+ prepend(handler: ServerHandlerClosure<Message>): this;
36
36
  /**
37
37
  * 从最前添加处理器
38
38
  * @param handler
39
39
  * @returns
40
40
  */
41
- prependHandler(handler: ServerHandlerClosure): this;
41
+ prependHandler(handler: ServerHandlerClosure<Message>): this;
42
42
  /**
43
43
  * @alias withoutHandler()
44
44
  */
45
- without(handler: ServerHandlerClosure): this;
45
+ without(handler: ServerHandlerClosure<Message>): this;
46
46
  /**
47
47
  * 删除处理器
48
48
  * @param handler
49
49
  * @returns
50
50
  */
51
- withoutHandler(handler: ServerHandlerClosure): this;
51
+ withoutHandler(handler: ServerHandlerClosure<Message>): this;
52
52
  /**
53
53
  * 获取处理器的索引
54
54
  * @param handler
55
55
  * @returns
56
56
  */
57
- indexOf(handler: ServerHandlerClosure): number;
57
+ indexOf(handler: ServerHandlerClosure<Message>): number;
58
58
  /**
59
59
  * 当 value 为true或者返回true时,添加处理器
60
60
  * @param value
61
61
  * @param handler
62
62
  * @returns
63
63
  */
64
- when(value: boolean | Function | Promise<boolean>, handler: ServerHandlerClosure): this;
64
+ when(value: boolean | Function | Promise<boolean>, handler: ServerHandlerClosure<Message>): this;
65
65
  /**
66
66
  * 执行处理器
67
67
  * @param result
@@ -19,20 +19,28 @@ declare class Server extends ServerInterface {
19
19
  * @param handler
20
20
  * @returns
21
21
  */
22
- addMessageListener(type: ServerMessageType, handler: ServerHandlerClosure): this;
22
+ addMessageListener(type: ServerMessageType, handler: ServerHandlerClosure<Message>): this;
23
23
  /**
24
24
  * 添加事件消息处理器
25
25
  * @param event
26
26
  * @param handler
27
27
  * @returns
28
28
  */
29
- addEventListener(event: ServerEventType, handler: ServerHandlerClosure): this;
29
+ addEventListener(event: ServerEventType, handler: ServerHandlerClosure<Message>): this;
30
30
  /**
31
31
  * 获取来自微信服务器的推送消息
32
32
  * @param request 未设置该参数时,则从当前服务端收到的请求中获取
33
33
  * @returns
34
34
  */
35
35
  getRequestMessage(request?: ServerRequestInterface): Promise<Message>;
36
- protected decryptRequestMessage(query: Record<string, any>): ServerHandlerClosure;
36
+ protected decryptRequestMessage(query: Record<string, any>): ServerHandlerClosure<Message>;
37
+ }
38
+ interface Server {
39
+ with(next: ServerHandlerClosure<Message>): this;
40
+ withHandler(next: ServerHandlerClosure<Message>): this;
41
+ prepend(next: ServerHandlerClosure<Message>): this;
42
+ prependHandler(next: ServerHandlerClosure<Message>): this;
43
+ without(next: ServerHandlerClosure<Message>): this;
44
+ withoutHandler(next: ServerHandlerClosure<Message>): this;
37
45
  }
38
46
  export = Server;
@@ -7,7 +7,7 @@ import { ServerHandlerClosure } from '../Types/global';
7
7
  declare class Server extends ServerInterface {
8
8
  protected encryptor: Encryptor;
9
9
  protected request: ServerRequestInterface;
10
- protected defaultVerifyTicketHandler: ServerHandlerClosure;
10
+ protected defaultVerifyTicketHandler: ServerHandlerClosure<Message>;
11
11
  constructor(encryptor: Encryptor, request?: ServerRequestInterface);
12
12
  /**
13
13
  * 服务端消息处理
@@ -19,32 +19,32 @@ declare class Server extends ServerInterface {
19
19
  * @param handler
20
20
  * @returns
21
21
  */
22
- handleAuthorized(handler: ServerHandlerClosure): this;
22
+ handleAuthorized(handler: ServerHandlerClosure<Message>): this;
23
23
  /**
24
24
  * 处理取消授权通知
25
25
  * @param handler
26
26
  * @returns
27
27
  */
28
- handleUnauthorized(handler: ServerHandlerClosure): this;
28
+ handleUnauthorized(handler: ServerHandlerClosure<Message>): this;
29
29
  /**
30
30
  * 处理授权更新通知
31
31
  * @param handler
32
32
  * @returns
33
33
  */
34
- handleAuthorizeUpdated(handler: ServerHandlerClosure): this;
34
+ handleAuthorizeUpdated(handler: ServerHandlerClosure<Message>): this;
35
35
  /**
36
36
  * 设置默认的验证票据通知处理回调
37
37
  * @param handler
38
38
  * @returns
39
39
  */
40
- withDefaultVerifyTicketHandler(handler: ServerHandlerClosure): void;
40
+ withDefaultVerifyTicketHandler(handler: ServerHandlerClosure<Message>): void;
41
41
  /**
42
42
  * 处理验证票据通知
43
43
  * @param handler
44
44
  * @returns
45
45
  */
46
- handleVerifyTicketRefreshed(handler: ServerHandlerClosure): this;
47
- protected decryptRequestMessage(): ServerHandlerClosure;
46
+ handleVerifyTicketRefreshed(handler: ServerHandlerClosure<Message>): this;
47
+ protected decryptRequestMessage(): ServerHandlerClosure<Message>;
48
48
  /**
49
49
  * 获取来自微信服务器的推送消息
50
50
  * @param request 未设置该参数时,则从当前服务端收到的请求中获取
@@ -58,4 +58,12 @@ declare class Server extends ServerInterface {
58
58
  */
59
59
  getDecryptedMessage(request?: ServerRequestInterface): Promise<Message>;
60
60
  }
61
+ interface Server {
62
+ with(next: ServerHandlerClosure<Message>): this;
63
+ withHandler(next: ServerHandlerClosure<Message>): this;
64
+ prepend(next: ServerHandlerClosure<Message>): this;
65
+ prependHandler(next: ServerHandlerClosure<Message>): this;
66
+ without(next: ServerHandlerClosure<Message>): this;
67
+ withoutHandler(next: ServerHandlerClosure<Message>): this;
68
+ }
61
69
  export = Server;
@@ -8,91 +8,91 @@ declare class Server extends ServerInterface {
8
8
  protected encryptor: Encryptor;
9
9
  protected providerEncryptor: Encryptor;
10
10
  protected request: ServerRequestInterface;
11
- protected defaultSuiteTicketHandler: ServerHandlerClosure;
11
+ protected defaultSuiteTicketHandler: ServerHandlerClosure<Message>;
12
12
  constructor(encryptor: Encryptor, providerEncryptor: Encryptor, request?: ServerRequestInterface);
13
13
  /**
14
14
  * 服务端消息处理
15
15
  * @returns
16
16
  */
17
17
  serve(): Promise<Response>;
18
- withDefaultSuiteTicketHandler(handler: ServerHandlerClosure): this;
18
+ withDefaultSuiteTicketHandler(handler: ServerHandlerClosure<Message>): this;
19
19
  /**
20
20
  * 设置联系人变化的消息处理器
21
21
  * @param handler
22
22
  */
23
- handleSuiteTicketRefreshed(handler: ServerHandlerClosure): this;
23
+ handleSuiteTicketRefreshed(handler: ServerHandlerClosure<Message>): this;
24
24
  /**
25
25
  * 设置授权成功的消息处理器
26
26
  * @param handler
27
27
  */
28
- handleAuthCreated(handler: ServerHandlerClosure): this;
28
+ handleAuthCreated(handler: ServerHandlerClosure<Message>): this;
29
29
  /**
30
30
  * 设置变更授权的消息处理器
31
31
  * @param handler
32
32
  */
33
- handleAuthUpdated(handler: ServerHandlerClosure): this;
33
+ handleAuthUpdated(handler: ServerHandlerClosure<Message>): this;
34
34
  /**
35
35
  * 设置取消授权的消息处理器
36
36
  * @param handler
37
37
  */
38
- handleAuthCancelled(handler: ServerHandlerClosure): this;
38
+ handleAuthCancelled(handler: ServerHandlerClosure<Message>): this;
39
39
  /**
40
40
  * 设置用户创建的消息处理器
41
41
  * @param handler
42
42
  */
43
- handleUserCreated(handler: ServerHandlerClosure): this;
43
+ handleUserCreated(handler: ServerHandlerClosure<Message>): this;
44
44
  /**
45
45
  * 设置用户更新的消息处理器
46
46
  * @param handler
47
47
  */
48
- handleUserUpdated(handler: ServerHandlerClosure): this;
48
+ handleUserUpdated(handler: ServerHandlerClosure<Message>): this;
49
49
  /**
50
50
  * 设置用户删除的消息处理器
51
51
  * @param handler
52
52
  */
53
- handleUserDeleted(handler: ServerHandlerClosure): this;
53
+ handleUserDeleted(handler: ServerHandlerClosure<Message>): this;
54
54
  /**
55
55
  * 设置部门创建的消息处理器
56
56
  * @param handler
57
57
  */
58
- handlePartyCreated(handler: ServerHandlerClosure): this;
58
+ handlePartyCreated(handler: ServerHandlerClosure<Message>): this;
59
59
  /**
60
60
  * 设置部门更新的消息处理器
61
61
  * @param handler
62
62
  */
63
- handlePartyUpdated(handler: ServerHandlerClosure): this;
63
+ handlePartyUpdated(handler: ServerHandlerClosure<Message>): this;
64
64
  /**
65
65
  * 设置部门删除的消息处理器
66
66
  * @param handler
67
67
  */
68
- handlePartyDeleted(handler: ServerHandlerClosure): this;
68
+ handlePartyDeleted(handler: ServerHandlerClosure<Message>): this;
69
69
  /**
70
70
  * 设置用户标签变化的消息处理器
71
71
  * @param handler
72
72
  */
73
- handleUserTagUpdated(handler: ServerHandlerClosure): this;
73
+ handleUserTagUpdated(handler: ServerHandlerClosure<Message>): this;
74
74
  /**
75
75
  * 设置共享应用事件的消息处理器
76
76
  * @param handler
77
77
  */
78
- handleShareAgentChanged(handler: ServerHandlerClosure): this;
78
+ handleShareAgentChanged(handler: ServerHandlerClosure<Message>): this;
79
79
  /**
80
80
  * 设置重置永久授权码的消息处理器
81
81
  * @param handler
82
82
  */
83
- handleResetPermanentCode(handler: ServerHandlerClosure): this;
83
+ handleResetPermanentCode(handler: ServerHandlerClosure<Message>): this;
84
84
  /**
85
85
  * 设置应用管理员变更的消息处理器
86
86
  * @param handler
87
87
  */
88
- handleChangeAppAdmin(handler: ServerHandlerClosure): this;
88
+ handleChangeAppAdmin(handler: ServerHandlerClosure<Message>): this;
89
89
  /**
90
90
  * 获取来自微信服务器的推送消息
91
91
  * @param request 未设置该参数时,则从当前服务端收到的请求中获取
92
92
  * @returns
93
93
  */
94
94
  getRequestMessage(request?: ServerRequestInterface): Promise<Message>;
95
- protected decryptRequestMessage(query: Record<string, any>): ServerHandlerClosure;
95
+ protected decryptRequestMessage(query: Record<string, any>): ServerHandlerClosure<Message>;
96
96
  /**
97
97
  * 获取解密后的消息
98
98
  * @param request 未设置该参数时,则从当前服务端收到的请求中获取
@@ -100,4 +100,12 @@ declare class Server extends ServerInterface {
100
100
  */
101
101
  getDecryptedMessage(request?: ServerRequestInterface): Promise<import("../Core/Message")>;
102
102
  }
103
+ interface Server {
104
+ with(next: ServerHandlerClosure<Message>): this;
105
+ withHandler(next: ServerHandlerClosure<Message>): this;
106
+ prepend(next: ServerHandlerClosure<Message>): this;
107
+ prependHandler(next: ServerHandlerClosure<Message>): this;
108
+ without(next: ServerHandlerClosure<Message>): this;
109
+ withoutHandler(next: ServerHandlerClosure<Message>): this;
110
+ }
103
111
  export = Server;
@@ -138,10 +138,10 @@ class Application {
138
138
  if (force || !exists_certs || exists_certs.length === 0) {
139
139
  let response = yield this.getClient().get('/v3/certificates');
140
140
  let data = response.toObject();
141
- if (data && data.length > 0) {
141
+ if (data.data && data.data.length > 0) {
142
142
  let certs = {};
143
143
  let key = this.config.get('secret_key');
144
- data.forEach((item) => {
144
+ data.data.forEach((item) => {
145
145
  let content = AES_1.AES_GCM.decrypt(item.encrypt_certificate.ciphertext, key, item.encrypt_certificate.nonce, item.encrypt_certificate.associated_data).toString();
146
146
  certs[item.serial_no] = PublicKey_1.PublicKey.createByCertificateContent(content, item.serial_no);
147
147
  });
@@ -8,7 +8,7 @@ declare class Merchant implements MerchantInterface {
8
8
  protected platformCerts: Record<string, PublicKey>;
9
9
  protected privateKey: PrivateKey;
10
10
  protected certificate: PublicKey;
11
- constructor(mchId: string, privateKey: string | PrivateKey, certificate: string | PublicKey, secretKey: string, v2SecretKey?: string, platformCerts?: Record<string, string | PublicKey> | string[] | PublicKey[]);
11
+ constructor(mchId: string, privateKey: string | PrivateKey, certificate: string | PublicKey, secretKey: string, v2SecretKey: string, platformCerts?: Record<string, string | PublicKey> | string[] | PublicKey[]);
12
12
  /**
13
13
  * 统一规范化平台证书
14
14
  * @param platformCerts 平台证书列表
@@ -2,7 +2,7 @@
2
2
  const PrivateKey_1 = require("../Core/Support/PrivateKey");
3
3
  const PublicKey_1 = require("../Core/Support/PublicKey");
4
4
  class Merchant {
5
- constructor(mchId, privateKey, certificate, secretKey, v2SecretKey = null, platformCerts = []) {
5
+ constructor(mchId, privateKey, certificate, secretKey, v2SecretKey, platformCerts = []) {
6
6
  this.mchId = mchId;
7
7
  this.secretKey = secretKey;
8
8
  this.v2SecretKey = v2SecretKey;
@@ -19,6 +19,8 @@ declare class Server extends ServerInterface {
19
19
  * @returns
20
20
  */
21
21
  getRequestMessage(request?: ServerRequestInterface): Promise<Message>;
22
+ protected decodeXmlMessage(attributes: Record<string, any>): Promise<Record<string, any>>;
23
+ protected decodeJsonMessage(attributes: Record<string, any>): Record<string, any>;
22
24
  /**
23
25
  * 获取解密后的消息
24
26
  * @param request
@@ -30,12 +32,20 @@ declare class Server extends ServerInterface {
30
32
  * @param handler 消息处理器,需要接受两个参数,参数1是消息,参数2是下一个消息处理器
31
33
  * @returns
32
34
  */
33
- handlePaid(handler: ServerHandlerClosure): this;
35
+ handlePaid(handler: ServerHandlerClosure<Message>): this;
34
36
  /**
35
37
  * 处理退款回调
36
38
  * @param handler 消息处理器,需要接受两个参数,参数1是消息,参数2是下一个消息处理器
37
39
  * @returns
38
40
  */
39
- handleRefunded(handler: ServerHandlerClosure): this;
41
+ handleRefunded(handler: ServerHandlerClosure<Message>): this;
42
+ }
43
+ interface Server {
44
+ with(next: ServerHandlerClosure<Message>): this;
45
+ withHandler(next: ServerHandlerClosure<Message>): this;
46
+ prepend(next: ServerHandlerClosure<Message>): this;
47
+ prependHandler(next: ServerHandlerClosure<Message>): this;
48
+ without(next: ServerHandlerClosure<Message>): this;
49
+ withoutHandler(next: ServerHandlerClosure<Message>): this;
40
50
  }
41
51
  export = Server;
@@ -15,6 +15,7 @@ const ServerInterface_1 = __importDefault(require("../Core/Contracts/ServerInter
15
15
  const Response_1 = __importDefault(require("../Core/Http/Response"));
16
16
  const Message_1 = __importDefault(require("./Message"));
17
17
  const AES_1 = require("../Core/Support/AES");
18
+ const Utils_1 = require("../Core/Support/Utils");
18
19
  class Server extends ServerInterface_1.default {
19
20
  constructor(merchant = null, request = null) {
20
21
  super();
@@ -28,10 +29,15 @@ class Server extends ServerInterface_1.default {
28
29
  serve() {
29
30
  return __awaiter(this, void 0, void 0, function* () {
30
31
  let message = yield this.getRequestMessage();
32
+ let isV2Message = message.getOriginalContents().startsWith('<xml');
31
33
  try {
32
- let defaultResponse = new Response_1.default(200, {}, JSON.stringify({
33
- code: 'SUCCESS', message: '成功',
34
- }));
34
+ let defaultResponse;
35
+ if (isV2Message) {
36
+ defaultResponse = new Response_1.default(200, {}, (0, Utils_1.buildXml)({ return_code: 'SUCCESS', return_msg: '' }));
37
+ }
38
+ else {
39
+ defaultResponse = new Response_1.default(200, {}, JSON.stringify({ code: 'SUCCESS', message: '成功' }));
40
+ }
35
41
  let response = yield this.handle(defaultResponse, message);
36
42
  if (!(response instanceof Response_1.default)) {
37
43
  response = defaultResponse;
@@ -39,9 +45,12 @@ class Server extends ServerInterface_1.default {
39
45
  return response;
40
46
  }
41
47
  catch (e) {
42
- return new Response_1.default(200, {}, JSON.stringify({
43
- code: 'ERROR', message: e.message,
44
- }));
48
+ if (isV2Message) {
49
+ return new Response_1.default(200, {}, (0, Utils_1.buildXml)({ return_code: 'ERROR', return_msg: e.message }));
50
+ }
51
+ else {
52
+ return new Response_1.default(200, {}, JSON.stringify({ code: 'ERROR', message: e.message }));
53
+ }
45
54
  }
46
55
  });
47
56
  }
@@ -60,27 +69,47 @@ class Server extends ServerInterface_1.default {
60
69
  if (body) {
61
70
  originContent = body.toString();
62
71
  }
63
- let attributes = {};
64
- try {
65
- attributes = JSON.parse(originContent);
66
- }
67
- catch (e) { }
68
- if (Object.keys(attributes).length === 0) {
69
- throw new Error('Invalid request body.');
72
+ let attributes = yield request.getParsedBody();
73
+ if (originContent.startsWith('<xml')) {
74
+ attributes = yield this.decodeXmlMessage(attributes);
70
75
  }
71
- if (!attributes['resource']['ciphertext']) {
72
- throw new Error('Invalid request.');
76
+ else {
77
+ attributes = this.decodeJsonMessage(attributes);
73
78
  }
74
- try {
75
- let decryptMessage = AES_1.AES_GCM.decrypt(attributes['resource']['ciphertext'], this.merchant.getSecretKey(), attributes['resource']['nonce'], attributes['resource']['associated_data']);
76
- attributes = JSON.parse(decryptMessage.toString());
79
+ return new Message_1.default(attributes, originContent);
80
+ });
81
+ }
82
+ decodeXmlMessage(attributes) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ if (attributes['req_info']) {
85
+ let key = this.merchant.getV2SecretKey();
86
+ if (!key) {
87
+ throw new Error('V2 secret key is required');
88
+ }
89
+ attributes = yield (0, Utils_1.parseXml)(AES_1.AES.decrypt(attributes['req_info'], (0, Utils_1.createHash)(key, 'md5'), '', true, 'aes-256-ecb').toString());
77
90
  }
78
- catch (e) {
79
- throw new Error('Failed to decrypt request message.');
91
+ if (!attributes || Object.keys(attributes).length === 0) {
92
+ throw new Error('Failed to decrypt request message');
80
93
  }
81
- return new Message_1.default(attributes, originContent);
94
+ return attributes;
82
95
  });
83
96
  }
97
+ decodeJsonMessage(attributes) {
98
+ if (!attributes || Object.keys(attributes).length === 0) {
99
+ throw new Error('Invalid request body.');
100
+ }
101
+ if (!attributes['resource']['ciphertext']) {
102
+ throw new Error('Invalid request.');
103
+ }
104
+ try {
105
+ let decryptMessage = AES_1.AES_GCM.decrypt(attributes['resource']['ciphertext'], this.merchant.getSecretKey(), attributes['resource']['nonce'], attributes['resource']['associated_data']);
106
+ attributes = JSON.parse(decryptMessage.toString());
107
+ }
108
+ catch (e) {
109
+ throw new Error('Failed to decrypt request message.');
110
+ }
111
+ return attributes;
112
+ }
84
113
  /**
85
114
  * 获取解密后的消息
86
115
  * @param request
@@ -8,8 +8,10 @@ declare class Signature {
8
8
  * @param method 请求方式
9
9
  * @param url 请求地址
10
10
  * @param payload 请求载荷
11
+ * @param nonce 随机串,默认:随机生成
12
+ * @param timestamp 时间戳,默认:当前时间
11
13
  * @returns
12
14
  */
13
- createHeader(method: string, url: string, payload: AxiosRequestConfig<any>): string;
15
+ createHeader(method: string, url: string, payload: AxiosRequestConfig<any>, nonce?: string, timestamp?: number): string;
14
16
  }
15
17
  export = Signature;
@@ -14,17 +14,24 @@ class Signature {
14
14
  * @param method 请求方式
15
15
  * @param url 请求地址
16
16
  * @param payload 请求载荷
17
+ * @param nonce 随机串,默认:随机生成
18
+ * @param timestamp 时间戳,默认:当前时间
17
19
  * @returns
18
20
  */
19
- createHeader(method, url, payload) {
21
+ createHeader(method, url, payload, nonce = null, timestamp = null) {
20
22
  let pathname = url;
21
23
  if (url.startsWith('https://') || url.startsWith('http://')) {
22
24
  let urlObj = new URL(url);
23
25
  let search = (0, Utils_1.buildQueryString)((0, merge_1.default)(true, urlObj.searchParams, payload.params));
24
26
  pathname = urlObj.pathname + (search ? '?' + search : '');
25
27
  }
26
- let nonce = (0, Utils_1.randomString)();
27
- let timestamp = (0, Utils_1.getTimestamp)();
28
+ else {
29
+ pathname += (pathname.indexOf('?') > -1 ? '&' : '?') + (0, Utils_1.buildQueryString)(payload.params);
30
+ }
31
+ if (!nonce)
32
+ nonce = (0, Utils_1.randomString)();
33
+ if (!timestamp)
34
+ timestamp = (0, Utils_1.getTimestamp)();
28
35
  let body = '';
29
36
  if (payload.data) {
30
37
  if (typeof payload.data === 'object') {
@@ -87,4 +87,12 @@ declare class Server extends ServerInterface {
87
87
  */
88
88
  getDecryptedMessage(request?: ServerRequestInterface): Promise<import("../Core/Message")>;
89
89
  }
90
+ interface Server {
91
+ with(next: ServerHandlerClosure<Message>): this;
92
+ withHandler(next: ServerHandlerClosure<Message>): this;
93
+ prepend(next: ServerHandlerClosure<Message>): this;
94
+ prependHandler(next: ServerHandlerClosure<Message>): this;
95
+ without(next: ServerHandlerClosure<Message>): this;
96
+ withoutHandler(next: ServerHandlerClosure<Message>): this;
97
+ }
90
98
  export = Server;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-easywechat",
3
- "version": "3.5.9",
3
+ "version": "3.5.10",
4
4
  "description": "EasyWechat SDK for Node.js (NOT OFFICIAL)",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {