@yunzhanghu/sdk-nodejs 1.0.3 → 1.0.4

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.
@@ -1,387 +1,377 @@
1
1
  /* eslint-disable no-param-reassign */
2
- import * as crypto from "crypto"
2
+ import * as crypto from 'crypto';
3
3
 
4
- import getInstance from "../common/http"
5
- import YZHSDKHttpException from "./exception/yzhSDKHttpException"
4
+ import getInstance from '../common/http';
5
+ import YZHSDKHttpException from './exception/yzhSDKHttpException';
6
6
 
7
- const clearEncoding = "utf8"
8
- const cipherEncoding = "base64"
7
+ const clearEncoding = 'utf8';
8
+ const cipherEncoding = 'base64';
9
9
 
10
- export type ResponseCallback<TReuslt = any> = (error: null | string, rep: TReuslt) => void
10
+ export type ResponseCallback<TReuslt = any> = (error: null | string, rep: TReuslt) => void;
11
11
 
12
- type ResponseData = any
12
+ type ResponseData = any;
13
13
 
14
14
  export class YZHClient {
15
- public dealer_id: string
16
-
17
- public broker_id: string
18
-
19
- public app_key: string
20
-
21
- public des3_key: string
22
-
23
- public private_key: string
24
-
25
- public yzh_public_key: string
26
-
27
- public sign_type: "rsa" | "sha256"
28
-
29
- public base_url?: string
30
-
31
- public timeout?: number
32
-
33
- /**
34
- * 构造函数参数
35
- * @param {string} dealer_id 平台企业 ID
36
- * @param {string} broker_id 综合服务主体 ID
37
- * @param {string} app_key App Key
38
- * @param {string} des3_key 3DES Key
39
- * @param {string} private_key 平台企业私钥
40
- * @param {string} yzh_public_key 云账户公钥
41
- * @param {string} sign_type 签名算法,支持 RSA、HMAC,枚举分别为 rsa、sha256
42
- * @param {string} base_url 可选,默认为 https://api-service.yunzhanghu.com/
43
- * @param {number} timeout 请求超时时间。可选,默认30*1000ms。0为永不超时。
44
- */
45
- constructor(conf: {
46
- dealer_id: string
47
- broker_id: string
48
- app_key: string
49
- des3_key: string
50
- private_key: string
51
- yzh_public_key: string
52
- sign_type: "rsa" | "sha256"
53
- base_url?: string
54
- timeout?: number
55
- }) {
56
- const { dealer_id, broker_id, app_key, des3_key, private_key, yzh_public_key, sign_type } =
57
- conf || {}
58
- if (
59
- conf &&
60
- dealer_id &&
61
- broker_id &&
62
- app_key &&
63
- des3_key &&
64
- private_key &&
65
- yzh_public_key &&
66
- sign_type
67
- ) {
68
- this.dealer_id = conf.dealer_id
69
- this.broker_id = conf.broker_id
70
- this.app_key = conf.app_key
71
- this.des3_key = conf.des3_key
72
- this.private_key = conf.private_key
73
- this.yzh_public_key = conf.yzh_public_key
74
- this.sign_type = conf.sign_type
75
- this.base_url = conf?.base_url
76
- this.timeout = conf?.timeout
77
- } else {
78
- throw new YZHSDKHttpException(
79
- `实例初始化失败,请检查以下配置是否缺失:\ndealer_id、broker_id、app_key、des3_key、private_key、yzh_public_key、sign_type`
80
- )
81
- }
82
- }
83
-
84
- // 基础请求:进行请求实例生成 Header,动态设置、请求体包装等偏底层操作
85
- private doRequest(method: string, action: string, req: any): Promise<ResponseData> {
86
- const { request_id, ...resReq } = req
87
- // 请求参数加密
88
- const encryptParams = this.generatorRequestParams(resReq)
89
- // 生成请求实例,配置 Header
90
- const instance = getInstance({
91
- request_id: request_id ?? this.mess(),
92
- dealer_id: this.dealer_id,
93
- base_url: this.base_url,
94
- timeout: this.timeout,
95
- })
96
-
97
- // 返回请求实例
98
- const baseInstanceConf = { method, url: action }
99
- let instanceConf
100
- if (method === "get") {
101
- instanceConf = { ...baseInstanceConf, params: encryptParams }
102
- } else {
103
- instanceConf = { ...baseInstanceConf, data: encryptParams }
104
- }
105
- return instance(instanceConf)
106
- }
107
-
108
- // 公共请求:调用封装好的基础请求方法 doRequest,进行发送请求与响应内容处理
109
- async request(
110
- method: string,
111
- action: string,
112
- req?: any,
113
- options?: { encryption: boolean },
114
- cb?: ResponseCallback
115
- ): Promise<ResponseData> {
116
- if (typeof options === "function") {
117
- cb = options
118
- options = {} as any
119
- }
120
- try {
121
- const result = await this.doRequest(method, action, req ?? {})
122
- // 错误码处理 > 验签 > 解密
123
- const responseData = await this.parseResponse(result, options?.encryption)
124
- cb && cb(null, responseData)
125
-
126
- return responseData
127
- } catch (e) {
128
- if (cb) {
129
- cb(e as any, null)
130
- } else {
131
- throw e
132
- }
133
- }
134
- }
135
-
136
- /**
137
- * 请求参数加密
138
- * @param {object} params
139
- * @returns {*} object
140
- */
141
- private generatorRequestParams(params: string) {
142
- try {
143
- const t = Date.now().toString()
144
- const m = this.mess()
145
-
146
- const plaintext = JSON.stringify(params)
147
-
148
- const data = this.encrypt(plaintext)
149
-
150
- const signStr = this.sign(data, m, t)
151
- return {
152
- data,
153
- mess: m,
154
- timestamp: t,
155
- sign: signStr,
156
- sign_type: this.sign_type,
157
- }
158
- } catch (err) {
159
- throw new YZHSDKHttpException(`${err}`)
160
- }
161
- }
162
-
163
- /**
164
- * 生成签名(RSA 签名算法)
165
- * @param {string} data 经过加密后的具体数据
166
- * @param {string} mess 自定义随机字符串,用于签名
167
- * @param {string} timestamp 时间戳,精确到秒
168
- * @returns {string} 签名内容
169
- */
170
- private signRSASHA256 = (data: string, mess: string, timestamp: string) => {
171
- try {
172
- const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`
173
- const sign = crypto.createSign("RSA-SHA256")
174
- sign.update(plaintext)
175
- sign.end()
176
- return sign.sign(this.private_key, cipherEncoding)
177
- } catch (err) {
178
- throw new YZHSDKHttpException(`${err}`)
15
+ public dealer_id: string;
16
+
17
+ public broker_id: string;
18
+
19
+ public app_key: string;
20
+
21
+ public des3_key: string;
22
+
23
+ public private_key: string;
24
+
25
+ public yzh_public_key: string;
26
+
27
+ public sign_type: 'rsa' | 'sha256';
28
+
29
+ public base_url?: string;
30
+
31
+ public timeout?: number;
32
+
33
+ /**
34
+ * 构造函数参数
35
+ * @param {string} dealer_id 平台企业 ID
36
+ * @param {string} broker_id 综合服务主体 ID
37
+ * @param {string} app_key App Key
38
+ * @param {string} des3_key 3DES Key
39
+ * @param {string} private_key 平台企业私钥
40
+ * @param {string} yzh_public_key 云账户公钥
41
+ * @param {string} sign_type 签名算法,支持 RSA、HMAC,枚举分别为 rsa、sha256
42
+ * @param {string} base_url 可选,默认为 https://api-service.yunzhanghu.com/
43
+ * @param {number} timeout 请求超时时间。可选,默认30*1000ms。0为永不超时。
44
+ */
45
+ constructor(conf: {
46
+ dealer_id: string;
47
+ broker_id: string;
48
+ app_key: string;
49
+ des3_key: string;
50
+ private_key: string;
51
+ yzh_public_key: string;
52
+ sign_type: 'rsa' | 'sha256';
53
+ base_url?: string;
54
+ timeout?: number;
55
+ }) {
56
+ const { dealer_id, broker_id, app_key, des3_key, private_key, yzh_public_key, sign_type } = conf || {};
57
+ if (conf && dealer_id && broker_id && app_key && des3_key && private_key && yzh_public_key && sign_type) {
58
+ this.dealer_id = conf.dealer_id;
59
+ this.broker_id = conf.broker_id;
60
+ this.app_key = conf.app_key;
61
+ this.des3_key = conf.des3_key;
62
+ this.private_key = conf.private_key;
63
+ this.yzh_public_key = conf.yzh_public_key;
64
+ this.sign_type = conf.sign_type;
65
+ this.base_url = conf?.base_url;
66
+ this.timeout = conf?.timeout;
67
+ } else {
68
+ throw new YZHSDKHttpException(
69
+ `实例初始化失败,请检查以下配置是否缺失:\ndealer_id、broker_id、app_key、des3_key、private_key、yzh_public_key、sign_type`
70
+ );
71
+ }
179
72
  }
180
- }
181
-
182
- /**
183
- * 生成签名(HMAC 签名算法)
184
- * @param {string} data 经过加密后的具体数据
185
- * @param {string} mess 自定义随机字符串,用于签名
186
- * @param {string} timestamp 时间戳,精确到秒
187
- * @returns {string} 签名内容
188
- */
189
- private signHmacSHA256 = (data: string, mess: string, timestamp: string) => {
190
- try {
191
- const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`
192
- const hmac = crypto.createHmac("sha256", this.app_key)
193
- hmac.update(plaintext)
194
- return hmac.digest("hex")
195
- } catch (err) {
196
- throw new YZHSDKHttpException(`${err}`)
73
+
74
+ // 基础请求:进行请求实例生成 Header,动态设置、请求体包装等偏底层操作
75
+ private doRequest(method: string, action: string, req: any): Promise<ResponseData> {
76
+ const { request_id, ...resReq } = req;
77
+ // 请求参数加密
78
+ const encryptParams = this.generatorRequestParams(resReq);
79
+ // 生成请求实例,配置 Header
80
+ const instance = getInstance({
81
+ request_id: request_id ?? this.mess(),
82
+ dealer_id: this.dealer_id,
83
+ base_url: this.base_url,
84
+ timeout: this.timeout,
85
+ });
86
+
87
+ // 返回请求实例
88
+ const baseInstanceConf = { method, url: action };
89
+ let instanceConf;
90
+ if (method === 'get') {
91
+ instanceConf = { ...baseInstanceConf, params: encryptParams };
92
+ } else {
93
+ instanceConf = { ...baseInstanceConf, data: encryptParams };
94
+ }
95
+ return instance(instanceConf);
197
96
  }
198
- }
199
-
200
- /**
201
- * 生成签名
202
- * @param {string} data 经过加密后的具体数据
203
- * @param {string} mess 自定义随机字符串,用于签名
204
- * @param {string} timestamp 时间戳,精确到秒
205
- * @param {string} sign_type 签名算法,支持 RSA、HMAC,枚举分别为 rsa、sha256
206
- * @returns {string} 签名内容
207
- */
208
- private sign = (data: string, mess: string, timestamp: string) => {
209
- try {
210
- switch (this.sign_type) {
211
- case "rsa": {
212
- return this.signRSASHA256(data, mess, timestamp)
97
+
98
+ // 公共请求:调用封装好的基础请求方法 doRequest,进行发送请求与响应内容处理
99
+ async request(
100
+ method: string,
101
+ action: string,
102
+ req?: any,
103
+ options?: { encryption: boolean },
104
+ cb?: ResponseCallback
105
+ ): Promise<ResponseData> {
106
+ if (typeof options === 'function') {
107
+ cb = options;
108
+ options = {} as any;
213
109
  }
214
- case "sha256": {
215
- return this.signHmacSHA256(data, mess, timestamp)
110
+ try {
111
+ const result = await this.doRequest(method, action, req ?? {});
112
+ // 错误码处理 > 验签 > 解密
113
+ const responseData = await this.parseResponse(result, options?.encryption);
114
+ cb && cb(null, responseData);
115
+
116
+ return responseData;
117
+ } catch (e) {
118
+ if (cb) {
119
+ cb(e as any, null);
120
+ } else {
121
+ throw e;
122
+ }
216
123
  }
217
- default:
218
- throw new YZHSDKHttpException(`sign_type 类型不存在`)
219
- }
220
- } catch (err) {
221
- throw new YZHSDKHttpException(`${err}`)
222
- }
223
- }
224
-
225
- // 自定义随机字符串
226
- // eslint-disable-next-line class-methods-use-this
227
- private mess = () => {
228
- const buf = crypto.randomBytes(16)
229
- const token = buf.toString("hex")
230
- return token.toString()
231
- }
232
-
233
- /**
234
- * 3DES 加密数据
235
- * @param plaintext
236
- * @returns 字符串加密数据
237
- */
238
- private encrypt = (plaintext: string) => {
239
- try {
240
- const iv = this.des3_key.slice(0, 8)
241
- const cipherChunks = []
242
- const cipher = crypto.createCipheriv("des-ede3-cbc", this.des3_key, iv)
243
- cipher.setAutoPadding(true)
244
- cipherChunks.push(cipher.update(plaintext, clearEncoding, cipherEncoding))
245
- cipherChunks.push(cipher.final(cipherEncoding))
246
-
247
- return cipherChunks.join("")
248
- } catch (err) {
249
- throw new YZHSDKHttpException(`${err}`)
250
- }
251
- }
252
-
253
- // 返回处理结果
254
- // eslint-disable-next-line @typescript-eslint/require-await
255
- private async parseResponse(result: ResponseData, encryption?: boolean) {
256
- if (result.status !== 200) {
257
- const yzhError = new YZHSDKHttpException(result.statusText)
258
- yzhError.httpCode = result.status
259
- throw yzhError
260
- } else {
261
- // HTTP Status Code 200
262
- const { data: axiosData } = result
263
- let response = axiosData
264
- // 需解密
265
- if (encryption) {
266
- response = { ...response, data: this.decrypt(response.data) }
267
- }
268
- return response
269
- }
270
- }
271
-
272
- /**
273
- * 3DES 解密数据
274
- * @param ciphertext
275
- * @returns 明文数据
276
- */
277
- decrypt = (ciphertext: string) => {
278
- try {
279
- const iv = this.des3_key.slice(0, 8)
280
- const cipherChunks = []
281
- const decipher = crypto.createDecipheriv("des-ede3-cbc", this.des3_key, iv)
282
- decipher.setAutoPadding(true)
283
- cipherChunks.push(decipher.update(ciphertext, cipherEncoding, clearEncoding))
284
- cipherChunks.push(decipher.final(clearEncoding))
285
- return JSON.parse(cipherChunks.join(""))
286
- } catch (err) {
287
- throw new YZHSDKHttpException(`${err}`)
288
- }
289
- }
290
-
291
- /**
292
- * 验签
293
- * @param {string} data 返回的数据
294
- * @param {string} mess 返回的随机字符串
295
- * @param {string} timestamp 返回的时间戳
296
- * @param {string} sign 返回的签名
297
- * @returns {boolean} true:验签成功;false:验签失败
298
- */
299
- verifyRSASHA256 = (data: string, mess: string, timestamp: string, sign: string) => {
300
- try {
301
- const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`
302
- const verify = crypto.createVerify("RSA-SHA256")
303
- verify.update(plaintext)
304
- return verify.verify(this.yzh_public_key, sign, cipherEncoding)
305
- } catch (err) {
306
- throw new YZHSDKHttpException(`${err}`)
307
- }
308
- }
309
-
310
- verifyHmacSHA256 = (data: string, mess: string, timestamp: string, sign: string) => {
311
- try {
312
- const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`
313
- const hmac = crypto.createHmac("sha256", this.app_key)
314
- hmac.update(plaintext)
315
- return hmac.digest("hex") === sign
316
- } catch (err) {
317
- throw new YZHSDKHttpException(`${err}`)
318
- }
319
- }
320
-
321
- /**
322
- * 文件密码解密
323
- * @param ciphertextbase64
324
- * @returns 解密后的密码
325
- */
326
- filePassWordDecryption = (ciphertextbase64: string) => {
327
- try {
328
- const buff = Buffer.from(ciphertextbase64, "base64")
329
-
330
- const decrypted = crypto.privateDecrypt(
331
- {
332
- key: this.private_key,
333
- padding: crypto.constants.RSA_PKCS1_PADDING,
334
- },
335
- buff
336
- )
337
- return decrypted.toString("utf8")
338
- } catch (err) {
339
- throw new YZHSDKHttpException(`${err}`)
340
124
  }
341
- }
342
-
343
- /**
344
- * 验签+解密
345
- * @param responseData 回调返回对象
346
- * @returns
347
- */
348
- notifyDecoder: (params: {
349
- /** 返回的数据 */
350
- data: string
351
- /** 返回的随机字符串 */
352
- mess: string
353
- /** 返回的时间戳 */
354
- timestamp: string
355
- /** 返回的签名 */
356
- sign: string
357
- }) => {
358
- /** 验签结果 */
359
- result: boolean
360
- /** 解密结果 */
361
- plaintext: object
362
- } = (responseData) => {
363
- const notifyDecoderResult = (data: string, mess: string, timestamp: string, sign: string) => {
364
- const verifyMap = {
365
- rsa: this.verifyRSASHA256,
366
- sha256: this.verifyHmacSHA256,
367
- }
368
- // 验签结果 boolean
369
- const verifyResult = verifyMap[this.sign_type](data, mess, timestamp, sign)
370
- let plaintext = {}
371
- if (verifyResult) {
372
- plaintext = this.decrypt(data)
373
- }
374
- return {
375
- result: verifyResult,
376
- plaintext,
377
- }
125
+
126
+ /**
127
+ * 请求参数加密
128
+ * @param {object} params
129
+ * @returns {*} object
130
+ */
131
+ private generatorRequestParams(params: string) {
132
+ try {
133
+ const t = Date.now().toString();
134
+ const m = this.mess();
135
+
136
+ const plaintext = JSON.stringify(params);
137
+
138
+ const data = this.encrypt(plaintext);
139
+
140
+ const signStr = this.sign(data, m, t);
141
+ return {
142
+ data,
143
+ mess: m,
144
+ timestamp: t,
145
+ sign: signStr,
146
+ sign_type: this.sign_type,
147
+ };
148
+ } catch (err) {
149
+ throw new YZHSDKHttpException(`${err}`);
150
+ }
378
151
  }
379
- const { data, mess, timestamp, sign } = responseData ?? {}
380
- if (data && mess && timestamp && sign) {
381
- return notifyDecoderResult(data, mess, timestamp, sign)
152
+
153
+ /**
154
+ * 生成签名(RSA 签名算法)
155
+ * @param {string} data 经过加密后的具体数据
156
+ * @param {string} mess 自定义随机字符串,用于签名
157
+ * @param {string} timestamp 时间戳,精确到秒
158
+ * @returns {string} 签名内容
159
+ */
160
+ private signRSASHA256 = (data: string, mess: string, timestamp: string) => {
161
+ try {
162
+ const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`;
163
+ const sign = crypto.createSign('RSA-SHA256');
164
+ sign.update(plaintext);
165
+ sign.end();
166
+ return sign.sign(this.private_key, cipherEncoding);
167
+ } catch (err) {
168
+ throw new YZHSDKHttpException(`${err}`);
169
+ }
170
+ };
171
+
172
+ /**
173
+ * 生成签名(HMAC 签名算法)
174
+ * @param {string} data 经过加密后的具体数据
175
+ * @param {string} mess 自定义随机字符串,用于签名
176
+ * @param {string} timestamp 时间戳,精确到秒
177
+ * @returns {string} 签名内容
178
+ */
179
+ private signHmacSHA256 = (data: string, mess: string, timestamp: string) => {
180
+ try {
181
+ const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`;
182
+ const hmac = crypto.createHmac('sha256', this.app_key);
183
+ hmac.update(plaintext);
184
+ return hmac.digest('hex');
185
+ } catch (err) {
186
+ throw new YZHSDKHttpException(`${err}`);
187
+ }
188
+ };
189
+
190
+ /**
191
+ * 生成签名
192
+ * @param {string} data 经过加密后的具体数据
193
+ * @param {string} mess 自定义随机字符串,用于签名
194
+ * @param {string} timestamp 时间戳,精确到秒
195
+ * @param {string} sign_type 签名算法,支持 RSA、HMAC,枚举分别为 rsa、sha256
196
+ * @returns {string} 签名内容
197
+ */
198
+ private sign = (data: string, mess: string, timestamp: string) => {
199
+ try {
200
+ switch (this.sign_type) {
201
+ case 'rsa': {
202
+ return this.signRSASHA256(data, mess, timestamp);
203
+ }
204
+ case 'sha256': {
205
+ return this.signHmacSHA256(data, mess, timestamp);
206
+ }
207
+ default:
208
+ throw new YZHSDKHttpException(`sign_type 类型不存在`);
209
+ }
210
+ } catch (err) {
211
+ throw new YZHSDKHttpException(`${err}`);
212
+ }
213
+ };
214
+
215
+ // 自定义随机字符串
216
+ // eslint-disable-next-line class-methods-use-this
217
+ private mess = () => {
218
+ const buf = crypto.randomBytes(16);
219
+ const token = buf.toString('hex');
220
+ return token.toString();
221
+ };
222
+
223
+ /**
224
+ * 3DES 加密数据
225
+ * @param plaintext
226
+ * @returns 字符串加密数据
227
+ */
228
+ private encrypt = (plaintext: string) => {
229
+ try {
230
+ const iv = this.des3_key.slice(0, 8);
231
+ const cipherChunks = [];
232
+ const cipher = crypto.createCipheriv('des-ede3-cbc', this.des3_key, iv);
233
+ cipher.setAutoPadding(true);
234
+ cipherChunks.push(cipher.update(plaintext, clearEncoding, cipherEncoding));
235
+ cipherChunks.push(cipher.final(cipherEncoding));
236
+
237
+ return cipherChunks.join('');
238
+ } catch (err) {
239
+ throw new YZHSDKHttpException(`${err}`);
240
+ }
241
+ };
242
+
243
+ // 返回处理结果
244
+ // eslint-disable-next-line @typescript-eslint/require-await
245
+ private async parseResponse(result: ResponseData, encryption?: boolean) {
246
+ if (result.status !== 200) {
247
+ const yzhError = new YZHSDKHttpException(result.statusText);
248
+ yzhError.httpCode = result.status;
249
+ throw yzhError;
250
+ } else {
251
+ // HTTP Status Code 200
252
+ const { data: axiosData } = result;
253
+ let response = axiosData;
254
+ // 需解密
255
+ if (encryption) {
256
+ response = { ...response, data: this.decrypt(response.data) };
257
+ }
258
+ return response;
259
+ }
382
260
  }
383
- return { result: false, plaintext: "" }
384
- }
261
+
262
+ /**
263
+ * 3DES 解密数据
264
+ * @param ciphertext
265
+ * @returns 明文数据
266
+ */
267
+ decrypt = (ciphertext: string) => {
268
+ try {
269
+ const iv = this.des3_key.slice(0, 8);
270
+ const cipherChunks = [];
271
+ const decipher = crypto.createDecipheriv('des-ede3-cbc', this.des3_key, iv);
272
+ decipher.setAutoPadding(true);
273
+ cipherChunks.push(decipher.update(ciphertext, cipherEncoding, clearEncoding));
274
+ cipherChunks.push(decipher.final(clearEncoding));
275
+ return JSON.parse(cipherChunks.join(''));
276
+ } catch (err) {
277
+ throw new YZHSDKHttpException(`${err}`);
278
+ }
279
+ };
280
+
281
+ /**
282
+ * 验签
283
+ * @param {string} data 返回的数据
284
+ * @param {string} mess 返回的随机字符串
285
+ * @param {string} timestamp 返回的时间戳
286
+ * @param {string} sign 返回的签名
287
+ * @returns {boolean} true:验签成功;false:验签失败
288
+ */
289
+ verifyRSASHA256 = (data: string, mess: string, timestamp: string, sign: string) => {
290
+ try {
291
+ const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`;
292
+ const verify = crypto.createVerify('RSA-SHA256');
293
+ verify.update(plaintext);
294
+ return verify.verify(this.yzh_public_key, sign, cipherEncoding);
295
+ } catch (err) {
296
+ throw new YZHSDKHttpException(`${err}`);
297
+ }
298
+ };
299
+
300
+ verifyHmacSHA256 = (data: string, mess: string, timestamp: string, sign: string) => {
301
+ try {
302
+ const plaintext = `data=${data}&mess=${mess}&timestamp=${timestamp}&key=${this.app_key}`;
303
+ const hmac = crypto.createHmac('sha256', this.app_key);
304
+ hmac.update(plaintext);
305
+ return hmac.digest('hex') === sign;
306
+ } catch (err) {
307
+ throw new YZHSDKHttpException(`${err}`);
308
+ }
309
+ };
310
+
311
+ /**
312
+ * 文件密码解密
313
+ * @param ciphertextbase64
314
+ * @returns 解密后的密码
315
+ */
316
+ filePassWordDecryption = (ciphertextbase64: string) => {
317
+ try {
318
+ const buff = Buffer.from(ciphertextbase64, 'base64');
319
+
320
+ const decrypted = crypto.privateDecrypt(
321
+ {
322
+ key: this.private_key,
323
+ padding: crypto.constants.RSA_PKCS1_PADDING,
324
+ },
325
+ buff
326
+ );
327
+ return decrypted.toString('utf8');
328
+ } catch (err) {
329
+ throw new YZHSDKHttpException(`${err}`);
330
+ }
331
+ };
332
+
333
+ /**
334
+ * 验签+解密
335
+ * @param responseData 回调返回对象
336
+ * @returns
337
+ */
338
+ notifyDecoder: (params: {
339
+ /** 返回的数据 */
340
+ data: string;
341
+ /** 返回的随机字符串 */
342
+ mess: string;
343
+ /** 返回的时间戳 */
344
+ timestamp: string;
345
+ /** 返回的签名 */
346
+ sign: string;
347
+ }) => {
348
+ /** 验签结果 */
349
+ result: boolean;
350
+ /** 解密结果 */
351
+ plaintext: object;
352
+ } = responseData => {
353
+ const notifyDecoderResult = (data: string, mess: string, timestamp: string, sign: string) => {
354
+ const verifyMap = {
355
+ rsa: this.verifyRSASHA256,
356
+ sha256: this.verifyHmacSHA256,
357
+ };
358
+ // 验签结果 boolean
359
+ const verifyResult = verifyMap[this.sign_type](data, mess, timestamp, sign);
360
+ let plaintext = {};
361
+ if (verifyResult) {
362
+ plaintext = this.decrypt(data);
363
+ }
364
+ return {
365
+ result: verifyResult,
366
+ plaintext,
367
+ };
368
+ };
369
+ const { data, mess, timestamp, sign } = responseData ?? {};
370
+ if (data && mess && timestamp && sign) {
371
+ return notifyDecoderResult(data, mess, timestamp, sign);
372
+ }
373
+ return { result: false, plaintext: '' };
374
+ };
385
375
  }
386
376
 
387
- export default YZHClient
377
+ export default YZHClient;