node-easywechat 2.6.9 → 2.7.2
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/README.md +34 -4
- package/dist/BaseService/ContentSecurity/ContentSecurityClient.d.ts +5 -3
- package/dist/BaseService/ContentSecurity/ContentSecurityClient.js +2 -2
- package/dist/BaseService/Jssdk/JssdkClient.d.ts +15 -15
- package/dist/BaseService/Jssdk/JssdkClient.js +15 -15
- package/dist/BaseService/Media/MediaClient.d.ts +22 -20
- package/dist/BaseService/Media/MediaClient.js +14 -14
- package/dist/BaseService/Url/UrlClient.d.ts +1 -1
- package/dist/Core/AES.d.ts +46 -0
- package/dist/Core/AES.js +95 -0
- package/dist/Core/BaseApplication.js +9 -5
- package/dist/Core/Encryptor.d.ts +2 -14
- package/dist/Core/Encryptor.js +9 -39
- package/dist/Core/Http/Request.js +2 -6
- package/dist/Core/Messages/Message.js +2 -16
- package/dist/Core/PKCS.d.ts +15 -0
- package/dist/Core/PKCS.js +44 -0
- package/dist/Core/RSA.d.ts +59 -0
- package/dist/Core/RSA.js +99 -0
- package/dist/Core/ServerGuard.d.ts +1 -1
- package/dist/Core/ServerGuard.js +5 -33
- package/dist/Core/Types.d.ts +29 -4
- package/dist/Core/Utils.d.ts +8 -2
- package/dist/Core/Utils.js +61 -20
- package/dist/MicroMerchant/Application.d.ts +27 -0
- package/dist/MicroMerchant/Application.js +105 -0
- package/dist/MicroMerchant/Base/MicroMerchantBase.d.ts +7 -0
- package/dist/MicroMerchant/Base/MicroMerchantBase.js +52 -0
- package/dist/MicroMerchant/Certficates/CertficatesClient.d.ts +5 -0
- package/dist/MicroMerchant/Certficates/CertficatesClient.js +52 -0
- package/dist/MicroMerchant/Core/BaseClient.d.ts +9 -0
- package/dist/MicroMerchant/Core/BaseClient.js +106 -0
- package/dist/MicroMerchant/Media/MediaClient.d.ts +6 -0
- package/dist/MicroMerchant/Media/MediaClient.js +33 -0
- package/dist/MicroMerchant/MerchantConfig/MerchantConfigClient.d.ts +8 -0
- package/dist/MicroMerchant/MerchantConfig/MerchantConfigClient.js +49 -0
- package/dist/MicroMerchant/Meterial/MeterialClient.d.ts +5 -0
- package/dist/MicroMerchant/Meterial/MeterialClient.js +30 -0
- package/dist/MicroMerchant/Withdraw/WithdrawClient.d.ts +5 -0
- package/dist/MicroMerchant/Withdraw/WithdrawClient.js +28 -0
- package/dist/MiniProgram/Encryptor.js +2 -6
- package/dist/Payment/Bill/BillClient.js +1 -1
- package/dist/Payment/Core/BaseClient.d.ts +0 -1
- package/dist/Payment/Core/BaseClient.js +2 -20
- package/dist/Payment/Notify/Handler.js +3 -11
- package/dist/Payment/Notify/Refunded.d.ts +0 -1
- package/dist/Payment/Notify/Refunded.js +1 -11
- package/dist/Payment/Transfer/TransferClient.js +4 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -0
- package/node-easywechat.file_cache.easywechat.kernel.access_token.8a9684b45da7de42a06a70ba01a7005a.cache +1 -1
- package/node-easywechat.file_cache.easywechat.kernel.access_token.c3d06edaf326aad75d32f31348df787a.cache +1 -1
- package/package.json +9 -7
package/dist/Core/Encryptor.js
CHANGED
|
@@ -5,6 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const crypto_1 = __importDefault(require("crypto"));
|
|
7
7
|
const Utils_1 = require("./Utils");
|
|
8
|
+
const AES_1 = require("./AES");
|
|
9
|
+
const PKCS_1 = require("./PKCS");
|
|
8
10
|
class Encryptor {
|
|
9
11
|
constructor(appId, token, aesKey) {
|
|
10
12
|
this.appId = null;
|
|
@@ -20,9 +22,7 @@ class Encryptor {
|
|
|
20
22
|
}
|
|
21
23
|
signature(...args) {
|
|
22
24
|
args.sort();
|
|
23
|
-
|
|
24
|
-
shasum.update(args.join(''));
|
|
25
|
-
return shasum.digest('hex');
|
|
25
|
+
return Utils_1.createHash(args.join(''), 'sha1');
|
|
26
26
|
}
|
|
27
27
|
encrypt(text, nonce = null, timestamp = null) {
|
|
28
28
|
let encrypted = '';
|
|
@@ -32,10 +32,8 @@ class Encryptor {
|
|
|
32
32
|
let msg = Buffer.from(text);
|
|
33
33
|
let msgLength = Buffer.alloc(4);
|
|
34
34
|
msgLength.writeUInt32BE(msg.length, 0);
|
|
35
|
-
let encoded =
|
|
36
|
-
|
|
37
|
-
cipher.setAutoPadding(false);
|
|
38
|
-
encrypted = Buffer.concat([cipher.update(encoded), cipher.final()]).toString('base64');
|
|
35
|
+
let encoded = PKCS_1.PKCS7.pad(Buffer.concat([randomString, msgLength, msg, Buffer.from(this.appId)]), this.blockSize);
|
|
36
|
+
encrypted = AES_1.AES.encrypt(encoded, this.aesKey, this.aesKey.slice(0, 16), false, 'aes-256-cbc').toString('base64');
|
|
39
37
|
}
|
|
40
38
|
catch (e) {
|
|
41
39
|
throw new Error('Fail to encrypt data');
|
|
@@ -44,22 +42,21 @@ class Encryptor {
|
|
|
44
42
|
nonce = this.appId.slice(0, 10);
|
|
45
43
|
if (!timestamp)
|
|
46
44
|
timestamp = Utils_1.getTimestamp();
|
|
47
|
-
|
|
45
|
+
let response = {
|
|
48
46
|
Encrypt: encrypted,
|
|
49
47
|
MsgSignature: this.signature(this.token, timestamp, nonce, encrypted),
|
|
50
48
|
TimeStamp: timestamp,
|
|
51
49
|
Nonce: nonce,
|
|
52
50
|
};
|
|
51
|
+
return Utils_1.buildXml(response);
|
|
53
52
|
}
|
|
54
53
|
decrypt(text, msgSignature, nonce, timestamp) {
|
|
55
54
|
let signature = this.signature(this.token, nonce, timestamp, text);
|
|
56
55
|
if (signature !== msgSignature) {
|
|
57
56
|
throw new Error('Invalid Signature.');
|
|
58
57
|
}
|
|
59
|
-
let
|
|
60
|
-
|
|
61
|
-
let deciphered = Buffer.concat([decipher.update(text, 'base64'), decipher.final()]);
|
|
62
|
-
deciphered = this.pkcs7Unpad(deciphered);
|
|
58
|
+
let deciphered = AES_1.AES.decrypt(Buffer.from(text, 'base64'), this.aesKey, this.aesKey.slice(0, 16), false, 'aes-256-cbc');
|
|
59
|
+
deciphered = PKCS_1.PKCS7.unpad(deciphered, this.blockSize);
|
|
63
60
|
let content = deciphered.slice(16);
|
|
64
61
|
let length = content.slice(0, 4).readUInt32BE(0);
|
|
65
62
|
if (content.slice(length + 4).toString() !== this.appId) {
|
|
@@ -67,33 +64,6 @@ class Encryptor {
|
|
|
67
64
|
}
|
|
68
65
|
return content.slice(4, length + 4).toString();
|
|
69
66
|
}
|
|
70
|
-
/**
|
|
71
|
-
* 删除解密后明文的补位字符
|
|
72
|
-
* @param {Buffer} text 解密后的明文
|
|
73
|
-
* @return {Buffer}
|
|
74
|
-
*/
|
|
75
|
-
pkcs7Unpad(text) {
|
|
76
|
-
var pad = text[text.length - 1];
|
|
77
|
-
if (pad < 1 || pad > this.blockSize) {
|
|
78
|
-
pad = 0;
|
|
79
|
-
}
|
|
80
|
-
return text.slice(0, text.length - pad);
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* 对需要加密的明文进行填充补位
|
|
84
|
-
* @param {Buffer} text 需要进行填充补位操作的明文
|
|
85
|
-
* @return {Buffer}
|
|
86
|
-
*/
|
|
87
|
-
pkcs7Pad(text, blockSize) {
|
|
88
|
-
if (blockSize > 256) {
|
|
89
|
-
throw new Error('blockSize may not be more than 256');
|
|
90
|
-
}
|
|
91
|
-
//计算需要填充的位数
|
|
92
|
-
let amountToPad = blockSize - (text.length % blockSize);
|
|
93
|
-
let result = Buffer.alloc(amountToPad);
|
|
94
|
-
result.fill(amountToPad);
|
|
95
|
-
return Buffer.concat([text, result]);
|
|
96
|
-
}
|
|
97
67
|
}
|
|
98
68
|
exports.default = Encryptor;
|
|
99
69
|
;
|
|
@@ -15,7 +15,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const url_1 = __importDefault(require("url"));
|
|
16
16
|
const Utils_1 = require("../Utils");
|
|
17
17
|
const raw_body_1 = __importDefault(require("raw-body"));
|
|
18
|
-
const xml2js_1 = __importDefault(require("xml2js"));
|
|
19
18
|
class Request {
|
|
20
19
|
constructor(req = null, content = null) {
|
|
21
20
|
this._req = null;
|
|
@@ -42,17 +41,14 @@ class Request {
|
|
|
42
41
|
this._content = Buffer.from(JSON.stringify(content));
|
|
43
42
|
this._contentType = 'application/json';
|
|
44
43
|
}
|
|
45
|
-
else if (
|
|
44
|
+
else if (typeof content === 'string') {
|
|
46
45
|
try {
|
|
47
46
|
this._post = JSON.parse(content);
|
|
48
47
|
this._contentType = 'application/json';
|
|
49
48
|
}
|
|
50
49
|
catch (e) {
|
|
51
50
|
if (content.substr(0, 1) === '<') {
|
|
52
|
-
|
|
53
|
-
res = Utils_1.singleItem(res);
|
|
54
|
-
if (res['xml'])
|
|
55
|
-
res = res['xml'];
|
|
51
|
+
Utils_1.parseXml(content).then(res => {
|
|
56
52
|
this._post = res;
|
|
57
53
|
this._contentType = 'text/xml';
|
|
58
54
|
});
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.Message = void 0;
|
|
7
|
-
const xml2js_1 = __importDefault(require("xml2js"));
|
|
8
4
|
const Utils_1 = require("../Utils");
|
|
9
5
|
class Message {
|
|
10
6
|
constructor(attributes = {}) {
|
|
@@ -21,21 +17,11 @@ class Message {
|
|
|
21
17
|
this.type = type;
|
|
22
18
|
}
|
|
23
19
|
transformToXml(appends = {}, returnAsObject = false) {
|
|
24
|
-
let data = {
|
|
25
|
-
xml: Utils_1.merge(Utils_1.merge({ MsgType: this.getType() }, this.toXmlArray()), appends)
|
|
26
|
-
};
|
|
20
|
+
let data = Utils_1.merge(Utils_1.merge({ MsgType: this.getType() }, this.toXmlArray()), appends);
|
|
27
21
|
if (returnAsObject) {
|
|
28
22
|
return data;
|
|
29
23
|
}
|
|
30
|
-
|
|
31
|
-
cdata: true,
|
|
32
|
-
renderOpts: {
|
|
33
|
-
pretty: false,
|
|
34
|
-
indent: '',
|
|
35
|
-
newline: '',
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
return XmlBuilder.buildObject(data);
|
|
24
|
+
return Utils_1.buildXml(data);
|
|
39
25
|
}
|
|
40
26
|
toXmlArray() {
|
|
41
27
|
throw new Error(`Class "${this.constructor.name}" cannot support transform to XML message.`);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export declare class PKCS7 {
|
|
3
|
+
/**
|
|
4
|
+
* 对需要加密的明文进行填充补位
|
|
5
|
+
* @param text 需要进行填充补位操作的明文
|
|
6
|
+
* @param blockSize 补位大小,默认:32
|
|
7
|
+
*/
|
|
8
|
+
static pad(text: string | Buffer, blockSize?: number): Buffer;
|
|
9
|
+
/**
|
|
10
|
+
* 删除解密后明文的补位字符
|
|
11
|
+
* @param text 解密后的明文
|
|
12
|
+
* @param blockSize 补位大小,默认:32
|
|
13
|
+
*/
|
|
14
|
+
static unpad(text: string | Buffer, blockSize?: number): Buffer;
|
|
15
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PKCS7 = void 0;
|
|
4
|
+
class PKCS7 {
|
|
5
|
+
/**
|
|
6
|
+
* 对需要加密的明文进行填充补位
|
|
7
|
+
* @param text 需要进行填充补位操作的明文
|
|
8
|
+
* @param blockSize 补位大小,默认:32
|
|
9
|
+
*/
|
|
10
|
+
static pad(text, blockSize = 32) {
|
|
11
|
+
let buf = null;
|
|
12
|
+
if (Buffer.isBuffer(text)) {
|
|
13
|
+
buf = text;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
buf = Buffer.from(text);
|
|
17
|
+
}
|
|
18
|
+
//计算需要填充的位数
|
|
19
|
+
let amountToPad = blockSize - (buf.length % blockSize);
|
|
20
|
+
let result = Buffer.alloc(amountToPad);
|
|
21
|
+
result.fill(amountToPad);
|
|
22
|
+
return Buffer.concat([buf, result]);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 删除解密后明文的补位字符
|
|
26
|
+
* @param text 解密后的明文
|
|
27
|
+
* @param blockSize 补位大小,默认:32
|
|
28
|
+
*/
|
|
29
|
+
static unpad(text, blockSize = 32) {
|
|
30
|
+
let buf = null;
|
|
31
|
+
if (Buffer.isBuffer(text)) {
|
|
32
|
+
buf = text;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
buf = Buffer.from(text);
|
|
36
|
+
}
|
|
37
|
+
var pad = buf[buf.length - 1];
|
|
38
|
+
if (pad < 1 || pad > blockSize) {
|
|
39
|
+
pad = 0;
|
|
40
|
+
}
|
|
41
|
+
return buf.slice(0, buf.length - pad);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.PKCS7 = PKCS7;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
export default class RSA {
|
|
4
|
+
protected publicKey: crypto.KeyObject;
|
|
5
|
+
/**
|
|
6
|
+
* 设置公钥
|
|
7
|
+
* @param key 公钥内容
|
|
8
|
+
*/
|
|
9
|
+
setPublicKey(key: string | crypto.KeyObject | Buffer | crypto.PublicKeyInput): void;
|
|
10
|
+
protected privateKey: crypto.KeyObject;
|
|
11
|
+
/**
|
|
12
|
+
* 设置私钥
|
|
13
|
+
* @param key 私钥内容
|
|
14
|
+
*/
|
|
15
|
+
setPrivateKey(key: string | Buffer | crypto.PrivateKeyInput): void;
|
|
16
|
+
/**
|
|
17
|
+
* 生成密钥对
|
|
18
|
+
* @param options 密钥选项
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
static keyPair(options: crypto.RSAKeyPairKeyObjectOptions): crypto.KeyPairKeyObjectResult;
|
|
22
|
+
/**
|
|
23
|
+
* 加密
|
|
24
|
+
* @param plaintext 待加密文本
|
|
25
|
+
* @param encoding 编码,默认:'base64'
|
|
26
|
+
* @param hashType 哈希方式,默认:'sha1'
|
|
27
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
encrypt(plaintext: string, encoding?: BufferEncoding, hashType?: string, padding?: number): string;
|
|
31
|
+
/**
|
|
32
|
+
* 解密
|
|
33
|
+
* @param ciphertext 待解密文本
|
|
34
|
+
* @param encoding 编码,默认:'base64'
|
|
35
|
+
* @param hashType 哈希方式,默认:'sha1'
|
|
36
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
decrypt(ciphertext: string, encoding?: BufferEncoding, hashType?: string, padding?: number): string;
|
|
40
|
+
/**
|
|
41
|
+
* 计算签名
|
|
42
|
+
* @param data 待解密文本
|
|
43
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
44
|
+
* @param encoding 编码,默认:'base64'
|
|
45
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
sign(data: string, hashType?: string, encoding?: BufferEncoding, padding?: number): string;
|
|
49
|
+
/**
|
|
50
|
+
* 验证签名
|
|
51
|
+
* @param signature 待验证签名字符串
|
|
52
|
+
* @param data 待解密文本
|
|
53
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
54
|
+
* @param encoding 编码,默认:'base64'
|
|
55
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
verify(signature: string, data: string, hashType: string, encoding?: BufferEncoding, padding?: number): boolean;
|
|
59
|
+
}
|
package/dist/Core/RSA.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
7
|
+
class RSA {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.publicKey = null;
|
|
10
|
+
this.privateKey = null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 设置公钥
|
|
14
|
+
* @param key 公钥内容
|
|
15
|
+
*/
|
|
16
|
+
setPublicKey(key) {
|
|
17
|
+
this.publicKey = crypto_1.default.createPublicKey(key);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 设置私钥
|
|
21
|
+
* @param key 私钥内容
|
|
22
|
+
*/
|
|
23
|
+
setPrivateKey(key) {
|
|
24
|
+
this.privateKey = crypto_1.default.createPrivateKey(key);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 生成密钥对
|
|
28
|
+
* @param options 密钥选项
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
static keyPair(options) {
|
|
32
|
+
return crypto_1.default.generateKeyPairSync('rsa', options);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 加密
|
|
36
|
+
* @param plaintext 待加密文本
|
|
37
|
+
* @param encoding 编码,默认:'base64'
|
|
38
|
+
* @param hashType 哈希方式,默认:'sha1'
|
|
39
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
40
|
+
* @returns
|
|
41
|
+
*/
|
|
42
|
+
encrypt(plaintext, encoding = 'base64', hashType = 'sha1', padding = crypto_1.default.constants.RSA_PKCS1_OAEP_PADDING) {
|
|
43
|
+
let encryptedData = crypto_1.default.publicEncrypt({
|
|
44
|
+
key: this.publicKey,
|
|
45
|
+
padding,
|
|
46
|
+
oaepHash: hashType,
|
|
47
|
+
}, Buffer.from(plaintext));
|
|
48
|
+
return encryptedData.toString(encoding);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 解密
|
|
52
|
+
* @param ciphertext 待解密文本
|
|
53
|
+
* @param encoding 编码,默认:'base64'
|
|
54
|
+
* @param hashType 哈希方式,默认:'sha1'
|
|
55
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
decrypt(ciphertext, encoding = 'base64', hashType = 'sha1', padding = crypto_1.default.constants.RSA_PKCS1_OAEP_PADDING) {
|
|
59
|
+
let decryptedData = crypto_1.default.privateDecrypt({
|
|
60
|
+
key: this.privateKey,
|
|
61
|
+
padding,
|
|
62
|
+
oaepHash: hashType,
|
|
63
|
+
}, Buffer.from(ciphertext, encoding));
|
|
64
|
+
return decryptedData.toString();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 计算签名
|
|
68
|
+
* @param data 待解密文本
|
|
69
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
70
|
+
* @param encoding 编码,默认:'base64'
|
|
71
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
sign(data, hashType = 'sha256', encoding = 'base64', padding = crypto_1.default.constants.RSA_PKCS1_PSS_PADDING) {
|
|
75
|
+
let signature = crypto_1.default.sign(hashType, Buffer.from(data), {
|
|
76
|
+
key: this.privateKey,
|
|
77
|
+
padding,
|
|
78
|
+
});
|
|
79
|
+
return signature.toString(encoding);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 验证签名
|
|
83
|
+
* @param signature 待验证签名字符串
|
|
84
|
+
* @param data 待解密文本
|
|
85
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
86
|
+
* @param encoding 编码,默认:'base64'
|
|
87
|
+
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_PSS_PADDING
|
|
88
|
+
* @returns
|
|
89
|
+
*/
|
|
90
|
+
verify(signature, data, hashType, encoding = 'base64', padding = crypto_1.default.constants.RSA_PKCS1_PSS_PADDING) {
|
|
91
|
+
let isVerified = crypto_1.default.verify(hashType, Buffer.from(data), {
|
|
92
|
+
key: this.publicKey,
|
|
93
|
+
padding,
|
|
94
|
+
}, Buffer.from(signature, encoding));
|
|
95
|
+
return !!isVerified;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
exports.default = RSA;
|
|
99
|
+
;
|
|
@@ -27,6 +27,7 @@ export default class ServerGuard {
|
|
|
27
27
|
* @param condition EasyWechat.Messages.Message.xxx,用于处理特定消息类型,默认:* 表示全部
|
|
28
28
|
*/
|
|
29
29
|
push(handler: ServerHandler, condition?: string): void;
|
|
30
|
+
setHandlers(handlers?: ServerHandlers): void;
|
|
30
31
|
protected dispatch(event: string, payload: any): Promise<any>;
|
|
31
32
|
protected notify(event: string, payload: any): Promise<any>;
|
|
32
33
|
protected _callHandler(handler: ServerHandler, payload: any): Promise<any>;
|
|
@@ -49,6 +50,5 @@ export default class ServerGuard {
|
|
|
49
50
|
*/
|
|
50
51
|
getMessage(): Promise<object>;
|
|
51
52
|
protected parseMessage(content: string): Promise<any>;
|
|
52
|
-
protected parseXmlMessage(xml: any): Promise<any>;
|
|
53
53
|
protected decryptMessage(message: object): Promise<string>;
|
|
54
54
|
}
|
package/dist/Core/ServerGuard.js
CHANGED
|
@@ -15,7 +15,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const Response_1 = __importDefault(require("./Http/Response"));
|
|
16
16
|
const Messages_1 = require("./Messages");
|
|
17
17
|
const Utils_1 = require("./Utils");
|
|
18
|
-
const xml2js_1 = __importDefault(require("xml2js"));
|
|
19
18
|
const FinallResult_1 = __importDefault(require("./Decorators/FinallResult"));
|
|
20
19
|
const TerminateResult_1 = __importDefault(require("./Decorators/TerminateResult"));
|
|
21
20
|
class ServerGuard {
|
|
@@ -52,6 +51,9 @@ class ServerGuard {
|
|
|
52
51
|
}
|
|
53
52
|
this.handlers[condition].push(handler);
|
|
54
53
|
}
|
|
54
|
+
setHandlers(handlers = {}) {
|
|
55
|
+
this.handlers = handlers;
|
|
56
|
+
}
|
|
55
57
|
dispatch(event, payload) {
|
|
56
58
|
return this.notify(event, payload);
|
|
57
59
|
}
|
|
@@ -190,15 +192,7 @@ class ServerGuard {
|
|
|
190
192
|
let res = message.transformToXml(prepends);
|
|
191
193
|
if (yield this.isSafeMode()) {
|
|
192
194
|
this.app['log']('Messages safe mode is enabled.');
|
|
193
|
-
|
|
194
|
-
cdata: true,
|
|
195
|
-
renderOpts: {
|
|
196
|
-
pretty: false,
|
|
197
|
-
indent: '',
|
|
198
|
-
newline: '',
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
return XmlBuilder.buildObject(this.app['encryptor'].encrypt(res));
|
|
195
|
+
return this.app['encryptor'].encrypt(res);
|
|
202
196
|
}
|
|
203
197
|
return res;
|
|
204
198
|
});
|
|
@@ -253,7 +247,7 @@ class ServerGuard {
|
|
|
253
247
|
return {};
|
|
254
248
|
}
|
|
255
249
|
else if (0 === content.indexOf('<')) {
|
|
256
|
-
content = yield
|
|
250
|
+
content = yield Utils_1.parseXml(content);
|
|
257
251
|
}
|
|
258
252
|
else {
|
|
259
253
|
// Handle JSON format.
|
|
@@ -269,28 +263,6 @@ class ServerGuard {
|
|
|
269
263
|
}
|
|
270
264
|
});
|
|
271
265
|
}
|
|
272
|
-
parseXmlMessage(xml) {
|
|
273
|
-
return new Promise((resolve, reject) => {
|
|
274
|
-
xml2js_1.default.parseString(xml, (err, result) => {
|
|
275
|
-
if (err) {
|
|
276
|
-
reject(err);
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
let message;
|
|
280
|
-
if (result && result.xml) {
|
|
281
|
-
message = {};
|
|
282
|
-
for (let k in result.xml) {
|
|
283
|
-
message[k] = result.xml[k][0];
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
resolve(message);
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
})
|
|
290
|
-
.catch((err) => {
|
|
291
|
-
this.app['log']('server.parseMessage()', err);
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
266
|
decryptMessage(message) {
|
|
295
267
|
return __awaiter(this, void 0, void 0, function* () {
|
|
296
268
|
return this.app['encryptor'].decrypt(message['Encrypt'], yield this.app['request'].get('msg_signature'), yield this.app['request'].get('nonce'), yield this.app['request'].get('timestamp'));
|
package/dist/Core/Types.d.ts
CHANGED
|
@@ -37,6 +37,11 @@ export declare interface EasyWechatConfigCacheFile {
|
|
|
37
37
|
* 通用配置
|
|
38
38
|
*/
|
|
39
39
|
export declare interface EasyWechatConfig {
|
|
40
|
+
/**
|
|
41
|
+
* 是否开启调试,开启后会在控制台输出日志,默认:false
|
|
42
|
+
* @scope ALL
|
|
43
|
+
*/
|
|
44
|
+
debug?: boolean;
|
|
40
45
|
/**
|
|
41
46
|
* 应用 id
|
|
42
47
|
* @scope ALL
|
|
@@ -74,7 +79,7 @@ export declare interface EasyWechatConfig {
|
|
|
74
79
|
oauth?: EasyWechatConfigOauth;
|
|
75
80
|
/**
|
|
76
81
|
* 微信支付签名密钥
|
|
77
|
-
* @scope Payment
|
|
82
|
+
* @scope Payment | MicroMerchant
|
|
78
83
|
*/
|
|
79
84
|
key?: string;
|
|
80
85
|
/**
|
|
@@ -84,17 +89,17 @@ export declare interface EasyWechatConfig {
|
|
|
84
89
|
sub_appid?: string;
|
|
85
90
|
/**
|
|
86
91
|
* 商户号
|
|
87
|
-
* @scope Payment
|
|
92
|
+
* @scope Payment | MicroMerchant
|
|
88
93
|
*/
|
|
89
94
|
mch_id?: string;
|
|
90
95
|
/**
|
|
91
96
|
* 子商户号
|
|
92
|
-
* @scope Payment
|
|
97
|
+
* @scope Payment | MicroMerchant
|
|
93
98
|
*/
|
|
94
99
|
sub_mch_id?: string;
|
|
95
100
|
/**
|
|
96
101
|
* pfx 证书路径(敏感接口(如退款、发送红包等)需要)
|
|
97
|
-
* @scope Payment
|
|
102
|
+
* @scope Payment | MicroMerchant
|
|
98
103
|
*/
|
|
99
104
|
cert_path?: string;
|
|
100
105
|
/**
|
|
@@ -117,6 +122,26 @@ export declare interface EasyWechatConfig {
|
|
|
117
122
|
* @scope Payment
|
|
118
123
|
*/
|
|
119
124
|
sandbox?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* 获取证书接口获取到的平台证书序列号
|
|
127
|
+
* @scope MicroMerchant
|
|
128
|
+
*/
|
|
129
|
+
serial_no?: string;
|
|
130
|
+
/**
|
|
131
|
+
* 获取证书接口获取到的证书内容
|
|
132
|
+
* @scope MicroMerchant
|
|
133
|
+
*/
|
|
134
|
+
certificate?: string;
|
|
135
|
+
/**
|
|
136
|
+
* 服务商的公众账号 ID
|
|
137
|
+
* @scope MicroMerchant
|
|
138
|
+
*/
|
|
139
|
+
appid?: string;
|
|
140
|
+
/**
|
|
141
|
+
* APIv3 密钥
|
|
142
|
+
* @scope MicroMerchant
|
|
143
|
+
*/
|
|
144
|
+
apiv3_key?: string;
|
|
120
145
|
/**
|
|
121
146
|
* 刷新token
|
|
122
147
|
* @scope OpenPlatform
|
package/dist/Core/Utils.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import Stream from 'stream';
|
|
1
2
|
export declare const merge: (target: any, source: any) => any;
|
|
2
3
|
export declare const createHash: (str: string, type?: string) => any;
|
|
3
4
|
export declare const createHmac: (str: string, key: string, type?: string) => any;
|
|
5
|
+
/**
|
|
6
|
+
* 计算文件的 md5 值
|
|
7
|
+
* @param path 文件路径或文件可读流
|
|
8
|
+
*/
|
|
9
|
+
export declare const md5File: (path: string | Stream.Readable) => Promise<string>;
|
|
4
10
|
export declare const getTimestamp: (datetime?: string) => number;
|
|
5
11
|
export declare const buildQueryString: (data: object, options?: object) => string;
|
|
6
12
|
export declare const parseQueryString: (data: string, options?: object) => object;
|
|
@@ -21,5 +27,5 @@ export declare const strLcwords: (str: string) => string;
|
|
|
21
27
|
export declare const strStudly: (value: string) => string;
|
|
22
28
|
export declare const strCamel: (value: string) => string;
|
|
23
29
|
export declare const singleItem: (obj: any) => any;
|
|
24
|
-
export declare const
|
|
25
|
-
export declare const
|
|
30
|
+
export declare const parseXml: (xml: string) => Promise<any>;
|
|
31
|
+
export declare const buildXml: (data: object, rootName?: string) => string;
|
package/dist/Core/Utils.js
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
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
|
};
|
|
5
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
15
|
+
exports.buildXml = exports.parseXml = exports.singleItem = exports.strCamel = exports.strStudly = exports.strLcwords = exports.strUcwords = exports.applyMixins = exports.inArray = exports.isIp = exports.isIpv6 = exports.isIpv4 = exports.isFunction = exports.isObject = exports.isNumber = exports.isArray = exports.isString = exports.makeSignature = exports.randomString = exports.parseQueryString = exports.buildQueryString = exports.getTimestamp = exports.md5File = exports.createHmac = exports.createHash = exports.merge = void 0;
|
|
7
16
|
const crypto_1 = __importDefault(require("crypto"));
|
|
8
17
|
const qs_1 = __importDefault(require("qs"));
|
|
18
|
+
const xml2js_1 = __importDefault(require("xml2js"));
|
|
19
|
+
const stream_1 = __importDefault(require("stream"));
|
|
20
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
21
|
const merge = (target, source) => {
|
|
10
22
|
if (exports.isObject(source)) {
|
|
11
23
|
if (source.constructor !== Object) {
|
|
@@ -43,6 +55,31 @@ const createHmac = function (str, key, type = 'sha256') {
|
|
|
43
55
|
return crypto_1.default.createHmac(type, key).update(str).digest('hex');
|
|
44
56
|
};
|
|
45
57
|
exports.createHmac = createHmac;
|
|
58
|
+
/**
|
|
59
|
+
* 计算文件的 md5 值
|
|
60
|
+
* @param path 文件路径或文件可读流
|
|
61
|
+
*/
|
|
62
|
+
const md5File = function (path) {
|
|
63
|
+
return new Promise((reslove, reject) => {
|
|
64
|
+
let stream;
|
|
65
|
+
if (exports.isString(path)) {
|
|
66
|
+
stream = fs_1.default.createReadStream(path);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
stream = new stream_1.default.PassThrough();
|
|
70
|
+
path.pipe(stream);
|
|
71
|
+
}
|
|
72
|
+
let md5sum = crypto_1.default.createHash('md5');
|
|
73
|
+
stream.on('data', function (chunk) {
|
|
74
|
+
md5sum.update(chunk);
|
|
75
|
+
});
|
|
76
|
+
stream.on('end', function () {
|
|
77
|
+
let str = md5sum.digest('hex').toUpperCase();
|
|
78
|
+
reslove(str);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
exports.md5File = md5File;
|
|
46
83
|
const getTimestamp = function (datetime = null) {
|
|
47
84
|
let time;
|
|
48
85
|
try {
|
|
@@ -208,22 +245,26 @@ const singleItem = function (obj) {
|
|
|
208
245
|
return obj;
|
|
209
246
|
};
|
|
210
247
|
exports.singleItem = singleItem;
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
248
|
+
const parseXml = function (xml) {
|
|
249
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
let res = yield xml2js_1.default.parseStringPromise(xml);
|
|
251
|
+
res = exports.singleItem(res);
|
|
252
|
+
if (res['xml'])
|
|
253
|
+
res = res['xml'];
|
|
254
|
+
return res;
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
exports.parseXml = parseXml;
|
|
258
|
+
const buildXml = function (data, rootName = 'xml') {
|
|
259
|
+
let XmlBuilder = new xml2js_1.default.Builder({
|
|
260
|
+
cdata: true,
|
|
261
|
+
rootName,
|
|
262
|
+
renderOpts: {
|
|
263
|
+
pretty: false,
|
|
264
|
+
indent: '',
|
|
265
|
+
newline: '',
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
return XmlBuilder.buildObject(data);
|
|
269
|
+
};
|
|
270
|
+
exports.buildXml = buildXml;
|