node-easywechat 3.0.0-beta.5 → 3.0.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 +21 -0
- package/README.md +36 -1
- package/dist/Core/Contracts/RefreshableAccessTokenInterface.d.ts +2 -2
- package/dist/Core/Contracts/RefreshableAccessTokenInterface.js +2 -2
- package/dist/Core/HttpClient/HttpClient.js +3 -1
- package/dist/Core/HttpClient/HttpClientResponse.d.ts +16 -5
- package/dist/Core/HttpClient/HttpClientResponse.js +64 -22
- package/dist/Core/Message.d.ts +0 -127
- package/dist/Core/Mixins/DecryptXmlMessageMixin.js +1 -1
- package/dist/Core/Mixins/ResponseXmlMessageMixin.js +2 -2
- package/dist/Core/Support/PrivateKey.d.ts +20 -0
- package/dist/Core/Support/PrivateKey.js +38 -0
- package/dist/Core/Support/PublicKey.d.ts +14 -0
- package/dist/Core/Support/PublicKey.js +36 -0
- package/dist/Core/Support/RSA.d.ts +2 -2
- package/dist/Core/Support/RSA.js +4 -4
- package/dist/Core/Support/Utils.d.ts +6 -0
- package/dist/Core/Support/Utils.js +15 -1
- package/dist/MiniApp/Application.d.ts +4 -4
- package/dist/MiniApp/Contracts/ApplicationInterface.d.ts +2 -2
- package/dist/OfficialAccount/AccessToken.d.ts +2 -2
- package/dist/OfficialAccount/AccessToken.js +2 -2
- package/dist/OfficialAccount/Application.d.ts +4 -4
- package/dist/OfficialAccount/Contracts/ApplicationInterface.d.ts +2 -2
- package/dist/OfficialAccount/JsApiTicket.js +2 -2
- package/dist/OfficialAccount/Message.d.ts +139 -0
- package/dist/OfficialAccount/Message.js +1 -0
- package/dist/Pay/Application.d.ts +52 -0
- package/dist/Pay/Application.js +96 -0
- package/dist/Pay/Client.d.ts +42 -0
- package/dist/Pay/Client.js +125 -0
- package/dist/Pay/Config.d.ts +5 -0
- package/dist/Pay/Config.js +17 -0
- package/dist/Pay/Contracts/ApplicationInterface.d.ts +50 -0
- package/dist/Pay/Contracts/ApplicationInterface.js +45 -0
- package/dist/Pay/Contracts/MerchantInterface.d.ts +35 -0
- package/dist/Pay/Contracts/MerchantInterface.js +35 -0
- package/dist/Pay/Contracts/ResponseValidatorInterface.d.ts +9 -0
- package/dist/Pay/Contracts/ResponseValidatorInterface.js +10 -0
- package/dist/Pay/LegacySignature.d.ts +12 -0
- package/dist/Pay/LegacySignature.js +59 -0
- package/dist/Pay/Merchant.d.ts +25 -0
- package/dist/Pay/Merchant.js +53 -0
- package/dist/Pay/Message.d.ts +175 -0
- package/dist/Pay/Message.js +24 -0
- package/dist/Pay/Server.d.ts +41 -0
- package/dist/Pay/Server.js +122 -0
- package/dist/Pay/Signature.d.ts +15 -0
- package/dist/Pay/Signature.js +44 -0
- package/dist/Pay/Utils.d.ts +54 -0
- package/dist/Pay/Utils.js +142 -0
- package/dist/Types/global.d.ts +110 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v3.0.0 (2022-07-28)
|
|
5
|
+
|
|
6
|
+
- Feat: 请求后自动解析响应结果,简化获取数据的方式
|
|
7
|
+
- Feat: 新增微信支付模块的公共调用方法
|
|
8
|
+
- Feat: 新增支付模块
|
|
9
|
+
|
|
10
|
+
- Fix: 响应内容解析时排除buffer对象
|
|
11
|
+
- Fix: 修复获取框架版本异常的问题
|
|
12
|
+
- Fix: 修复获取响应对象的字符串数据时异常的问题
|
|
13
|
+
- Fix: 修复测试用例中post等方式模拟请求时异常的问题
|
|
14
|
+
- Fix: 调整微信支付配置项
|
|
15
|
+
- Fix: 修复消息参数提示缺失问题
|
|
16
|
+
- Fix: 调整默认的RSA加密算法中的哈希方式为sha256
|
|
17
|
+
- Fix: 调整默认Message提示的作用域为公众号和小程序
|
|
18
|
+
- Fix: 修复AccessToken对象声明错误的问题
|
|
19
|
+
|
|
20
|
+
- Docs: 增加微信支付相关说明文档
|
|
21
|
+
|
|
4
22
|
## v3.0.0-beta.5 (2022-06-29)
|
|
5
23
|
|
|
6
24
|
- Fix: 修复服务端获取消息异常的问题
|
|
7
25
|
|
|
8
26
|
## v3.0.0-beta.4 (2022-06-24)
|
|
9
27
|
|
|
28
|
+
- Feat: 增加链式添加上传文件的方法
|
|
10
29
|
- Feat: 请求接口数据增加 FormData 实例的支持
|
|
11
30
|
|
|
31
|
+
- Fix: 修复接受微信回调接口验证请求时,返回对象无文件内容的问题
|
|
32
|
+
|
|
12
33
|
## v3.0.0-beta.3 (2022-06-22)
|
|
13
34
|
|
|
14
35
|
- Fix: 修复获取js ticket时无法自动获取access_token的问题
|
package/README.md
CHANGED
|
@@ -37,16 +37,31 @@ let app = new MiniApp({
|
|
|
37
37
|
// 配置项
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
+
// 微信支付
|
|
41
|
+
const { Pay } = require('node-easywechat');
|
|
42
|
+
// 实例化应用
|
|
43
|
+
let app = new Pay({
|
|
44
|
+
// 配置项
|
|
45
|
+
});
|
|
46
|
+
|
|
40
47
|
// ----- 以下为通用的 api 调用方法 -----
|
|
41
48
|
|
|
42
49
|
// 获取 api 调用客户端
|
|
43
50
|
let client = app.getClient();
|
|
44
51
|
|
|
45
52
|
// 请求 api
|
|
53
|
+
// 注意,这里返回的是 HttpClientResponse 对象
|
|
46
54
|
let response = await client.post('/cgi-bin/user/info/updateremark', {
|
|
47
55
|
openid: 'xxxx',
|
|
48
56
|
remark: 'xxxx',
|
|
49
57
|
});
|
|
58
|
+
// 获取具体数据
|
|
59
|
+
let data = response.toObject();
|
|
60
|
+
// 另外还有以下方法:
|
|
61
|
+
// toJson() 转json字符串
|
|
62
|
+
// toString() 转字符串
|
|
63
|
+
// saveAs(filename) 保存为文件
|
|
64
|
+
// toDataUrl() 转base64字符串
|
|
50
65
|
```
|
|
51
66
|
|
|
52
67
|
### 配置项示例
|
|
@@ -103,6 +118,26 @@ let response = await client.post('/cgi-bin/user/info/updateremark', {
|
|
|
103
118
|
}
|
|
104
119
|
```
|
|
105
120
|
|
|
121
|
+
``` js
|
|
122
|
+
// 微信支付配置
|
|
123
|
+
{
|
|
124
|
+
// 商户号
|
|
125
|
+
mch_id: '',
|
|
126
|
+
// 商户证书路径
|
|
127
|
+
certificate: '',
|
|
128
|
+
// 商户证书私钥路径
|
|
129
|
+
private_key: '',
|
|
130
|
+
// 平台证书(v3接口需要)
|
|
131
|
+
// 持路径列表或者PublicKey对象列表或者,以serial_no为key,证书内容或PublicKey对象为value的对象
|
|
132
|
+
// 下载工具:https://github.com/wechatpay-apiv3/CertificateDownloader
|
|
133
|
+
platform_certs: '',
|
|
134
|
+
// v3 API密钥
|
|
135
|
+
secret_key: '',
|
|
136
|
+
// v2 API密钥
|
|
137
|
+
v2_secret_key: '',
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
106
141
|
### 自定义模块(模块替换)使用方法
|
|
107
142
|
|
|
108
143
|
#### 日志模块
|
|
@@ -214,7 +249,7 @@ app.setRequest(request);
|
|
|
214
249
|
### 模块支持情况
|
|
215
250
|
|
|
216
251
|
- [x] 公众号模块
|
|
217
|
-
- [
|
|
252
|
+
- [x] 微信支付
|
|
218
253
|
- [x] 小程序
|
|
219
254
|
- [ ] 开放平台
|
|
220
255
|
- [ ] 企业微信
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import AccessTokenInterface from "./AccessTokenInterface";
|
|
2
|
-
declare abstract class
|
|
2
|
+
declare abstract class RefreshableAccessTokenInterface extends AccessTokenInterface {
|
|
3
3
|
/**
|
|
4
4
|
* 刷新token
|
|
5
5
|
* @returns
|
|
6
6
|
*/
|
|
7
7
|
refresh(): Promise<string>;
|
|
8
8
|
}
|
|
9
|
-
export =
|
|
9
|
+
export = RefreshableAccessTokenInterface;
|
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
const AccessTokenInterface_1 = __importDefault(require("./AccessTokenInterface"));
|
|
15
|
-
class
|
|
15
|
+
class RefreshableAccessTokenInterface extends AccessTokenInterface_1.default {
|
|
16
16
|
/**
|
|
17
17
|
* 刷新token
|
|
18
18
|
* @returns
|
|
@@ -22,4 +22,4 @@ class RefreshableAccessToken extends AccessTokenInterface_1.default {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
;
|
|
25
|
-
module.exports =
|
|
25
|
+
module.exports = RefreshableAccessTokenInterface;
|
|
@@ -102,7 +102,9 @@ class HttpClient {
|
|
|
102
102
|
let usedTime = Date.now() - starttime;
|
|
103
103
|
yield this.logger('after', options, usedTime, response);
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
let resp = new HttpClientResponse_1.default(response, this.failureJudge, this.throwError);
|
|
106
|
+
yield resp.parseContent(this.throwError);
|
|
107
|
+
return resp;
|
|
106
108
|
});
|
|
107
109
|
}
|
|
108
110
|
getInstance() {
|
|
@@ -5,7 +5,20 @@ declare class HttpClientResponse implements HttpClientResponseInterface {
|
|
|
5
5
|
protected response: AxiosResponse;
|
|
6
6
|
protected failureJudge: HttpClientFailureJudgeClosure;
|
|
7
7
|
protected throwError: boolean;
|
|
8
|
+
protected parsedContent: Record<string, any>;
|
|
8
9
|
constructor(response: AxiosResponse, failureJudge?: HttpClientFailureJudgeClosure, throwError?: boolean);
|
|
10
|
+
/**
|
|
11
|
+
* 设置解析后的body内容
|
|
12
|
+
* @param content
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
setParsedContent(content: Record<string, any>): this;
|
|
16
|
+
/**
|
|
17
|
+
* 解析body内容
|
|
18
|
+
* @param throwError
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
parseContent(throwError?: boolean): Promise<void>;
|
|
9
22
|
withThrowError(throwError: boolean): this;
|
|
10
23
|
throwOnFailure(): this;
|
|
11
24
|
quietly(): this;
|
|
@@ -27,21 +40,19 @@ declare class HttpClientResponse implements HttpClientResponseInterface {
|
|
|
27
40
|
isSuccessful(): boolean;
|
|
28
41
|
/**
|
|
29
42
|
* 返回对象格式
|
|
30
|
-
* @param throwError
|
|
31
43
|
* @returns
|
|
32
44
|
*/
|
|
33
|
-
toObject<T = WeixinResponse>(
|
|
45
|
+
toObject<T = WeixinResponse>(): T;
|
|
34
46
|
/**
|
|
35
47
|
* 返回json字符串
|
|
36
|
-
* @param throwError
|
|
37
48
|
* @returns
|
|
38
49
|
*/
|
|
39
|
-
toJson(
|
|
50
|
+
toJson(): string;
|
|
40
51
|
/**
|
|
41
52
|
* 返回字符串
|
|
42
53
|
* @returns
|
|
43
54
|
*/
|
|
44
|
-
toString():
|
|
55
|
+
toString(): string;
|
|
45
56
|
/**
|
|
46
57
|
* 另存为文件
|
|
47
58
|
* @param filename 完整的文件名(含路径)
|
|
@@ -15,10 +15,65 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
15
15
|
const merge_1 = __importDefault(require("merge"));
|
|
16
16
|
const Utils_1 = require("../Support/Utils");
|
|
17
17
|
class HttpClientResponse {
|
|
18
|
-
constructor(response, failureJudge = null, throwError =
|
|
18
|
+
constructor(response, failureJudge = null, throwError = false) {
|
|
19
19
|
this.response = response;
|
|
20
20
|
this.failureJudge = failureJudge;
|
|
21
21
|
this.throwError = throwError;
|
|
22
|
+
this.parsedContent = null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 设置解析后的body内容
|
|
26
|
+
* @param content
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
setParsedContent(content) {
|
|
30
|
+
this.parsedContent = content;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 解析body内容
|
|
35
|
+
* @param throwError
|
|
36
|
+
* @returns
|
|
37
|
+
*/
|
|
38
|
+
parseContent(throwError = false) {
|
|
39
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
throwError = throwError !== null && throwError !== void 0 ? throwError : this.throwError;
|
|
41
|
+
let content = this.response.data;
|
|
42
|
+
if (!content) {
|
|
43
|
+
if (throwError) {
|
|
44
|
+
throw new Error('Response body is empty.');
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (typeof content === 'string') {
|
|
49
|
+
if (this.is('xml') && content.indexOf('<xml>') > -1) {
|
|
50
|
+
this.parsedContent = yield (0, Utils_1.parseXml)(content);
|
|
51
|
+
}
|
|
52
|
+
else if (this.is('json')) {
|
|
53
|
+
try {
|
|
54
|
+
this.parsedContent = JSON.parse(content);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
if (throwError) {
|
|
58
|
+
throw new Error('Fail to parse JSON content.');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (this.is('text')) {
|
|
63
|
+
try {
|
|
64
|
+
this.parsedContent = (0, Utils_1.parseQueryString)(content);
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
if (throwError) {
|
|
68
|
+
throw new Error('Fail to parse QueryString content.');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (!Buffer.isBuffer(content)) {
|
|
74
|
+
this.parsedContent = content;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
22
77
|
}
|
|
23
78
|
withThrowError(throwError) {
|
|
24
79
|
this.throwError = throwError;
|
|
@@ -63,40 +118,25 @@ class HttpClientResponse {
|
|
|
63
118
|
}
|
|
64
119
|
/**
|
|
65
120
|
* 返回对象格式
|
|
66
|
-
* @param throwError
|
|
67
121
|
* @returns
|
|
68
122
|
*/
|
|
69
|
-
toObject(
|
|
70
|
-
return
|
|
71
|
-
throwError = throwError === null ? this.throwError : throwError;
|
|
72
|
-
let content = this.response.data;
|
|
73
|
-
if (!content) {
|
|
74
|
-
throw new Error('Response body is empty.');
|
|
75
|
-
}
|
|
76
|
-
if (typeof content === 'string') {
|
|
77
|
-
if (this.is('xml') && content.indexOf('<xml>') > -1) {
|
|
78
|
-
return (0, Utils_1.parseXml)(content);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return content;
|
|
82
|
-
});
|
|
123
|
+
toObject() {
|
|
124
|
+
return this.parsedContent;
|
|
83
125
|
}
|
|
84
126
|
/**
|
|
85
127
|
* 返回json字符串
|
|
86
|
-
* @param throwError
|
|
87
128
|
* @returns
|
|
88
129
|
*/
|
|
89
|
-
toJson(
|
|
90
|
-
return
|
|
91
|
-
return JSON.stringify(yield this.toObject(throwError));
|
|
92
|
-
});
|
|
130
|
+
toJson() {
|
|
131
|
+
return JSON.stringify(this.toObject());
|
|
93
132
|
}
|
|
94
133
|
/**
|
|
95
134
|
* 返回字符串
|
|
96
135
|
* @returns
|
|
97
136
|
*/
|
|
98
137
|
toString() {
|
|
99
|
-
|
|
138
|
+
let obj = this.getContent();
|
|
139
|
+
return (typeof obj === 'object' && obj !== null) ? JSON.stringify(obj) : String(obj);
|
|
100
140
|
}
|
|
101
141
|
/**
|
|
102
142
|
* 另存为文件
|
|
@@ -126,6 +166,8 @@ class HttpClientResponse {
|
|
|
126
166
|
*/
|
|
127
167
|
is(type) {
|
|
128
168
|
let contentType = this.getHeader('content-type');
|
|
169
|
+
if (!contentType)
|
|
170
|
+
return false;
|
|
129
171
|
let res = false;
|
|
130
172
|
switch (type.toLowerCase()) {
|
|
131
173
|
case 'json':
|
package/dist/Core/Message.d.ts
CHANGED
|
@@ -27,132 +27,5 @@ declare class Message {
|
|
|
27
27
|
toString(): string;
|
|
28
28
|
}
|
|
29
29
|
interface Message extends HasAttributesMixin {
|
|
30
|
-
/**
|
|
31
|
-
* 消息密文,兼容模式、安全模式才有
|
|
32
|
-
*/
|
|
33
|
-
Encrypt?: string;
|
|
34
|
-
/**
|
|
35
|
-
* 开发者微信号
|
|
36
|
-
*/
|
|
37
|
-
ToUserName?: string;
|
|
38
|
-
/**
|
|
39
|
-
* 发送方帐号 OpenId
|
|
40
|
-
*/
|
|
41
|
-
FromUserName?: string;
|
|
42
|
-
/**
|
|
43
|
-
* 消息创建时间
|
|
44
|
-
*/
|
|
45
|
-
CreateTime?: number;
|
|
46
|
-
/**
|
|
47
|
-
* 消息类型,'event':事件,'text':文本,'image':图片,'voice':语音,'video':视频,'shortvideo':小视频,'location':地理位置,'link':链接
|
|
48
|
-
*/
|
|
49
|
-
MsgType?: string;
|
|
50
|
-
/**
|
|
51
|
-
* 消息id,64位整型
|
|
52
|
-
* @scope MsgType='text' | 'image' | 'voice' | 'video' | 'shortvideo' | 'location'
|
|
53
|
-
*/
|
|
54
|
-
MsgId?: string;
|
|
55
|
-
/**
|
|
56
|
-
* 文本消息内容
|
|
57
|
-
* @scope MsgType='text'
|
|
58
|
-
*/
|
|
59
|
-
Content?: string;
|
|
60
|
-
/**
|
|
61
|
-
* 图片链接
|
|
62
|
-
* @scope MsgType='image'
|
|
63
|
-
*/
|
|
64
|
-
PicUrl?: string;
|
|
65
|
-
/**
|
|
66
|
-
* 媒体id,可以调用获取临时素材接口拉取数据
|
|
67
|
-
* @scope MsgType='image' | 'voice'
|
|
68
|
-
*/
|
|
69
|
-
MediaId?: string;
|
|
70
|
-
/**
|
|
71
|
-
* 语音格式,如amr,speex等
|
|
72
|
-
* @scope MsgType='voice'
|
|
73
|
-
*/
|
|
74
|
-
Format?: string;
|
|
75
|
-
/**
|
|
76
|
-
* 语音识别结果,UTF8编码
|
|
77
|
-
* @scope MsgType='voice'
|
|
78
|
-
*/
|
|
79
|
-
Recognition?: string;
|
|
80
|
-
/**
|
|
81
|
-
* 缩略图的媒体id
|
|
82
|
-
* @scope MsgType='video' | 'shortvideo'
|
|
83
|
-
*/
|
|
84
|
-
ThumbMediaId?: string;
|
|
85
|
-
/**
|
|
86
|
-
* 纬度
|
|
87
|
-
* @scope MsgType='location'
|
|
88
|
-
*/
|
|
89
|
-
Location_X?: number;
|
|
90
|
-
/**
|
|
91
|
-
* 经度
|
|
92
|
-
* @scope MsgType='location'
|
|
93
|
-
*/
|
|
94
|
-
Location_Y?: number;
|
|
95
|
-
/**
|
|
96
|
-
* 地图缩放大小
|
|
97
|
-
* @scope MsgType='location'
|
|
98
|
-
*/
|
|
99
|
-
Scale?: number;
|
|
100
|
-
/**
|
|
101
|
-
* 地理位置信息
|
|
102
|
-
* @scope MsgType='location'
|
|
103
|
-
*/
|
|
104
|
-
Label?: number;
|
|
105
|
-
/**
|
|
106
|
-
* 消息标题
|
|
107
|
-
* @scope MsgType='link'
|
|
108
|
-
*/
|
|
109
|
-
Title?: string;
|
|
110
|
-
/**
|
|
111
|
-
* 消息描述
|
|
112
|
-
* @scope MsgType='link'
|
|
113
|
-
*/
|
|
114
|
-
Description?: string;
|
|
115
|
-
/**
|
|
116
|
-
* 消息链接
|
|
117
|
-
* @scope MsgType='link'
|
|
118
|
-
*/
|
|
119
|
-
Url?: string;
|
|
120
|
-
/**
|
|
121
|
-
* 事件类型,subscribe:关注,unsubscribe:取消关注,SCAN:扫描(用户已关注),LOCATION:地理位置;CLICK:自定义菜单事件,VIEW:点击菜单跳转链接
|
|
122
|
-
* @scope MsgType='event'
|
|
123
|
-
*/
|
|
124
|
-
Event?: string;
|
|
125
|
-
/**
|
|
126
|
-
* 事件KEY值
|
|
127
|
-
*
|
|
128
|
-
* Event='subscribe' | 'SCAN'时:qrscene_为前缀,后面为二维码的参数值
|
|
129
|
-
*
|
|
130
|
-
* Event='CLICK'时:自定义菜单接口中KEY值对应
|
|
131
|
-
*
|
|
132
|
-
* Event='VIEW'时:设置的跳转URL
|
|
133
|
-
*
|
|
134
|
-
* @scope MsgType='event' && Event='subscribe' | 'SCAN' | 'CLICK' | 'VIEW'
|
|
135
|
-
*/
|
|
136
|
-
EventKey?: string;
|
|
137
|
-
/**
|
|
138
|
-
* 二维码的ticket,可用来换取二维码图片
|
|
139
|
-
* @scope MsgType='event' && Event='subscribe' | 'SCAN'
|
|
140
|
-
*/
|
|
141
|
-
Ticket?: string;
|
|
142
|
-
/**
|
|
143
|
-
* 纬度
|
|
144
|
-
* @scope MsgType='event' && Event='LOCATION'
|
|
145
|
-
*/
|
|
146
|
-
Latitude?: number;
|
|
147
|
-
/**
|
|
148
|
-
* 经度
|
|
149
|
-
* @scope MsgType='event' && Event='LOCATION'
|
|
150
|
-
*/
|
|
151
|
-
Longitude?: number;
|
|
152
|
-
/**
|
|
153
|
-
* 位置精度
|
|
154
|
-
* @scope MsgType='event' && Event='LOCATION'
|
|
155
|
-
*/
|
|
156
|
-
Precision?: number;
|
|
157
30
|
}
|
|
158
31
|
export = Message;
|
|
@@ -16,7 +16,7 @@ class DecryptXmlMessageMixin {
|
|
|
16
16
|
*/
|
|
17
17
|
decryptMessage(message, encryptor, signature, timestamp, nonce) {
|
|
18
18
|
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
-
let ciphertext = message
|
|
19
|
+
let ciphertext = message['Encrypt'];
|
|
20
20
|
this.validateSignature(encryptor.getToken(), ciphertext, signature, timestamp, nonce);
|
|
21
21
|
let attributes = yield (0, Utils_1.parseXml)(encryptor.decrypt(ciphertext, signature, nonce, timestamp));
|
|
22
22
|
message.merge(attributes);
|
|
@@ -25,8 +25,8 @@ class ResponseXmlMessageMixin {
|
|
|
25
25
|
return new Response_1.default(200, {}, 'success');
|
|
26
26
|
}
|
|
27
27
|
let attributes = merge_1.default.recursive({
|
|
28
|
-
ToUserName: message
|
|
29
|
-
FromUserName: message
|
|
28
|
+
ToUserName: message['FromUserName'],
|
|
29
|
+
FromUserName: message['ToUserName'],
|
|
30
30
|
CreateTime: (0, Utils_1.getTimestamp)(),
|
|
31
31
|
}, yield this.normalizeResponse(response));
|
|
32
32
|
return this.createXmlResponse(attributes, encryptor);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare class PrivateKey {
|
|
2
|
+
protected key: string;
|
|
3
|
+
protected passphrase?: string;
|
|
4
|
+
constructor(key: string, passphrase?: string);
|
|
5
|
+
/**
|
|
6
|
+
* 获取私钥
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
getKey(): string;
|
|
10
|
+
/**
|
|
11
|
+
* 获取密码
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
getPassphrase(): string;
|
|
15
|
+
/**
|
|
16
|
+
* 转为字符串
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
toString(): string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
exports.PrivateKey = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
class PrivateKey {
|
|
9
|
+
constructor(key, passphrase) {
|
|
10
|
+
this.key = key;
|
|
11
|
+
this.passphrase = passphrase;
|
|
12
|
+
if (fs_1.default.existsSync(key)) {
|
|
13
|
+
this.key = fs_1.default.readFileSync(key, 'utf8') || '';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 获取私钥
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
getKey() {
|
|
21
|
+
return this.key;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 获取密码
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
getPassphrase() {
|
|
28
|
+
return this.passphrase;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 转为字符串
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
34
|
+
toString() {
|
|
35
|
+
return this.getKey();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.PrivateKey = PrivateKey;
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
exports.PublicKey = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
class PublicKey {
|
|
10
|
+
constructor(certificate) {
|
|
11
|
+
this.certificate = certificate;
|
|
12
|
+
if (fs_1.default.existsSync(certificate)) {
|
|
13
|
+
this.certificate = fs_1.default.readFileSync(certificate, 'utf8') || '';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 获取公钥的序列号
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
getSerialNo() {
|
|
21
|
+
try {
|
|
22
|
+
return new crypto_1.X509Certificate(this.certificate).serialNumber;
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
throw new Error('Read the $certificate failed, please check it whether or nor correct');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 转为字符串
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
toString() {
|
|
33
|
+
return this.certificate;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.PublicKey = PublicKey;
|
|
@@ -23,7 +23,7 @@ declare class RSA {
|
|
|
23
23
|
* 加密
|
|
24
24
|
* @param plaintext 待加密文本
|
|
25
25
|
* @param encoding 编码,默认:'base64'
|
|
26
|
-
* @param hashType 哈希方式,默认:'
|
|
26
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
27
27
|
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
28
28
|
* @returns
|
|
29
29
|
*/
|
|
@@ -32,7 +32,7 @@ declare class RSA {
|
|
|
32
32
|
* 解密
|
|
33
33
|
* @param ciphertext 待解密文本
|
|
34
34
|
* @param encoding 编码,默认:'base64'
|
|
35
|
-
* @param hashType 哈希方式,默认:'
|
|
35
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
36
36
|
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
37
37
|
* @returns
|
|
38
38
|
*/
|
package/dist/Core/Support/RSA.js
CHANGED
|
@@ -34,11 +34,11 @@ class RSA {
|
|
|
34
34
|
* 加密
|
|
35
35
|
* @param plaintext 待加密文本
|
|
36
36
|
* @param encoding 编码,默认:'base64'
|
|
37
|
-
* @param hashType 哈希方式,默认:'
|
|
37
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
38
38
|
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
39
39
|
* @returns
|
|
40
40
|
*/
|
|
41
|
-
encrypt(plaintext, encoding = 'base64', hashType = '
|
|
41
|
+
encrypt(plaintext, encoding = 'base64', hashType = 'sha256', padding = crypto_1.default.constants.RSA_PKCS1_OAEP_PADDING) {
|
|
42
42
|
let encryptedData = crypto_1.default.publicEncrypt({
|
|
43
43
|
key: this.publicKey,
|
|
44
44
|
padding,
|
|
@@ -50,11 +50,11 @@ class RSA {
|
|
|
50
50
|
* 解密
|
|
51
51
|
* @param ciphertext 待解密文本
|
|
52
52
|
* @param encoding 编码,默认:'base64'
|
|
53
|
-
* @param hashType 哈希方式,默认:'
|
|
53
|
+
* @param hashType 哈希方式,默认:'sha256'
|
|
54
54
|
* @param padding 补位方式,默认:crypto.constants.RSA_PKCS1_OAEP_PADDING
|
|
55
55
|
* @returns
|
|
56
56
|
*/
|
|
57
|
-
decrypt(ciphertext, encoding = 'base64', hashType = '
|
|
57
|
+
decrypt(ciphertext, encoding = 'base64', hashType = 'sha256', padding = crypto_1.default.constants.RSA_PKCS1_OAEP_PADDING) {
|
|
58
58
|
let decryptedData = crypto_1.default.privateDecrypt({
|
|
59
59
|
key: this.privateKey,
|
|
60
60
|
padding,
|
|
@@ -93,3 +93,9 @@ export declare const parseXml: (xml: string) => Promise<Record<string, any>>;
|
|
|
93
93
|
* @returns
|
|
94
94
|
*/
|
|
95
95
|
export declare const buildXml: (data: Record<string, any>, rootName?: string) => string;
|
|
96
|
+
/**
|
|
97
|
+
* 创建UserAgent
|
|
98
|
+
* @param appends 可选,附加的字符串列表
|
|
99
|
+
* @returns
|
|
100
|
+
*/
|
|
101
|
+
export declare const createUserAgent: (appends?: string[]) => string;
|
|
@@ -12,12 +12,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.buildXml = exports.parseXml = exports.singleItem = exports.strSnake = exports.strCamel = exports.strStudly = exports.strLcwords = exports.strUcwords = exports.rtrim = exports.ltrim = exports.trim = 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 = void 0;
|
|
15
|
+
exports.createUserAgent = exports.buildXml = exports.parseXml = exports.singleItem = exports.strSnake = exports.strCamel = exports.strStudly = exports.strLcwords = exports.strUcwords = exports.rtrim = exports.ltrim = exports.trim = 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 = void 0;
|
|
16
16
|
const crypto_1 = __importDefault(require("crypto"));
|
|
17
17
|
const qs_1 = __importDefault(require("qs"));
|
|
18
18
|
const xml2js_1 = __importDefault(require("xml2js"));
|
|
19
19
|
const stream_1 = __importDefault(require("stream"));
|
|
20
20
|
const fs_1 = __importDefault(require("fs"));
|
|
21
|
+
const axios_1 = __importDefault(require("axios"));
|
|
21
22
|
const createHash = function (str, type = 'sha1') {
|
|
22
23
|
return crypto_1.default.createHash(type).update(str).digest('hex');
|
|
23
24
|
};
|
|
@@ -321,3 +322,16 @@ const buildXml = function (data, rootName = 'xml') {
|
|
|
321
322
|
return XmlBuilder.buildObject(data).replace('<?xml version="1.0"?>', '');
|
|
322
323
|
};
|
|
323
324
|
exports.buildXml = buildXml;
|
|
325
|
+
/**
|
|
326
|
+
* 创建UserAgent
|
|
327
|
+
* @param appends 可选,附加的字符串列表
|
|
328
|
+
* @returns
|
|
329
|
+
*/
|
|
330
|
+
const createUserAgent = function (appends = []) {
|
|
331
|
+
let values = [];
|
|
332
|
+
values.push(`node-easywechat/${require('../../../package.json').version}`);
|
|
333
|
+
values.push(`axios/${axios_1.default.VERSION}`);
|
|
334
|
+
values = values.concat(appends);
|
|
335
|
+
return values.join(' ');
|
|
336
|
+
};
|
|
337
|
+
exports.createUserAgent = createUserAgent;
|