@neteasecloudmusicapienhanced/api 4.31.0 → 4.32.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/module/radio_sport_get.js +9 -0
- package/module/register_anonimous.js +2 -1
- package/module/sati_resource_list.js +11 -0
- package/module/sati_resource_list_more.js +13 -0
- package/module/sati_resource_sub.js +10 -0
- package/module/sati_resource_sub_list.js +7 -0
- package/module/sati_tag_list.js +7 -0
- package/module/sati_timescene_resources_get.js +13 -0
- package/module/song_creators.js +9 -0
- package/package.json +1 -1
- package/public/api.html +29 -0
- package/public/docs/home.md +107 -0
- package/public/eapi_decrypt.html +44 -6
- package/server.js +30 -11
- package/util/crypto.js +27 -9
- package/util/request.js +21 -22
|
@@ -2,6 +2,7 @@ const CryptoJS = require('crypto-js')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const ID_XOR_KEY_1 = '3go8&$8*3*3h0k(2)2'
|
|
5
|
+
const logger = require('../util/logger.js')
|
|
5
6
|
|
|
6
7
|
const createOption = require('../util/option.js')
|
|
7
8
|
const { generateDeviceId } = require('../util/index')
|
|
@@ -23,7 +24,7 @@ function cloudmusic_dll_encode_id(some_id) {
|
|
|
23
24
|
|
|
24
25
|
module.exports = async (query, request) => {
|
|
25
26
|
const deviceId = generateDeviceId()
|
|
26
|
-
|
|
27
|
+
logger.info(`Successfully registered anonimous token, deviceId: ${deviceId}`)
|
|
27
28
|
global.deviceId = deviceId
|
|
28
29
|
const encodedId = CryptoJS.enc.Base64.stringify(
|
|
29
30
|
CryptoJS.enc.Utf8.parse(
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// 助眠解压 - 获取标签下资源列表
|
|
2
|
+
|
|
3
|
+
const createOption = require('../util/option.js')
|
|
4
|
+
module.exports = (query, request) => {
|
|
5
|
+
const data = {
|
|
6
|
+
tag: query.tag,
|
|
7
|
+
firstQuery: false,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return request(`/api/voice/sati/resource/list`, data, createOption(query))
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// 助眠解压 - 特定时间场景下的推荐资源
|
|
2
|
+
|
|
3
|
+
const createOption = require('../util/option.js')
|
|
4
|
+
module.exports = (query, request) => {
|
|
5
|
+
const data = {
|
|
6
|
+
firstQuery: false,
|
|
7
|
+
}
|
|
8
|
+
return request(
|
|
9
|
+
`/api/voice/sati/timescene/resources/get`,
|
|
10
|
+
data,
|
|
11
|
+
createOption(query),
|
|
12
|
+
)
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neteasecloudmusicapienhanced/api",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.32.0",
|
|
4
4
|
"description": "全网最全的网易云音乐API接口 || A revival project for NeteaseCloudMusicApi Node.js Services (Half Refactor & Enhanced) || 网易云音乐 API 备份 + 增强 || 本项目自原版v4.28.0版本后开始自行维护",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "nodemon app.js",
|
package/public/api.html
CHANGED
|
@@ -188,6 +188,35 @@
|
|
|
188
188
|
document.getElementById('result').value = 'Request failed: ' + error.message;
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
+
|
|
192
|
+
(function fillFromQuery() {
|
|
193
|
+
const params = new URLSearchParams(window.location.search);
|
|
194
|
+
if (!params.toString()) return;
|
|
195
|
+
const uri = params.get('uri');
|
|
196
|
+
const crypto = params.get('crypto');
|
|
197
|
+
const dataParam = params.get('data');
|
|
198
|
+
if (uri) {
|
|
199
|
+
document.getElementById('uri').value = uri;
|
|
200
|
+
}
|
|
201
|
+
if (crypto) {
|
|
202
|
+
const cryptoSelect = document.getElementById('crypto');
|
|
203
|
+
if ([...cryptoSelect.options].some((opt) => opt.value === crypto)) {
|
|
204
|
+
cryptoSelect.value = crypto;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (dataParam) {
|
|
208
|
+
const decoded = dataParam;
|
|
209
|
+
try {
|
|
210
|
+
document.getElementById('data').value = JSON.stringify(
|
|
211
|
+
JSON.parse(decoded),
|
|
212
|
+
null,
|
|
213
|
+
2,
|
|
214
|
+
);
|
|
215
|
+
} catch (error) {
|
|
216
|
+
document.getElementById('data').value = decoded;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
})();
|
|
191
220
|
</script>
|
|
192
221
|
</body>
|
|
193
222
|
</html>
|
package/public/docs/home.md
CHANGED
|
@@ -209,6 +209,12 @@ $ sudo docker build . -t netease-music-api
|
|
|
209
209
|
$ sudo docker run -d -p 3000:3000 netease-music-api
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
+
## 调试工具
|
|
213
|
+
|
|
214
|
+
- `eapi` 请求参数或返回内容可在 `/eapi_decrypt.html` 里解析
|
|
215
|
+
- 请求参数模式下, 解密结果可直接带到 `/api.html` 继续调试
|
|
216
|
+
- 需要返回值加密时, 可传 `e_r=1`, `weapi` 和 `eapi` 都支持
|
|
217
|
+
|
|
212
218
|
## 接口文档
|
|
213
219
|
|
|
214
220
|
### 调用前须知
|
|
@@ -5031,6 +5037,21 @@ let data = encodeURIComponent(
|
|
|
5031
5037
|
|
|
5032
5038
|
**调用例子:** `/vip/sign/info`
|
|
5033
5039
|
|
|
5040
|
+
### 广播电台 - 收藏/取消收藏电台
|
|
5041
|
+
|
|
5042
|
+
说明: 登录后调用此接口, 传入电台 id, 可收藏或取消收藏广播电台
|
|
5043
|
+
|
|
5044
|
+
**必选参数:**
|
|
5045
|
+
|
|
5046
|
+
`id`: 电台 id
|
|
5047
|
+
|
|
5048
|
+
`t`: 操作类型, `1` 为收藏, 其余值为取消收藏
|
|
5049
|
+
|
|
5050
|
+
**接口地址:** `/broadcast/sub`
|
|
5051
|
+
|
|
5052
|
+
**调用例子:** `/broadcast/sub?id=5&t=1`
|
|
5053
|
+
|
|
5054
|
+
|
|
5034
5055
|
### 用户的创建歌单列表
|
|
5035
5056
|
|
|
5036
5057
|
说明 : 调用此接口, 传入用户id, 获取用户的创建歌单列表
|
|
@@ -5209,6 +5230,92 @@ let data = encodeURIComponent(
|
|
|
5209
5230
|
|
|
5210
5231
|
**调用例子:** `/dj/difm/playing/tracks/list?source=0&channelId=1012`
|
|
5211
5232
|
|
|
5233
|
+
### 助眠解压 - 特定时间场景下的推荐资源
|
|
5234
|
+
|
|
5235
|
+
说明: 调用此接口, 获取特定时间场景下的推荐资源
|
|
5236
|
+
|
|
5237
|
+
**接口地址:** `/sati/timescene/resources/get`
|
|
5238
|
+
|
|
5239
|
+
**调用例子:** `/sati/timescene/resources/get`
|
|
5240
|
+
|
|
5241
|
+
### 助眠解压 - 标签列表
|
|
5242
|
+
|
|
5243
|
+
说明: 调用此接口, 获取标签列表
|
|
5244
|
+
|
|
5245
|
+
**接口地址:** `/sati/tag/list`
|
|
5246
|
+
|
|
5247
|
+
**调用例子:** `/sati/tag/list`
|
|
5248
|
+
|
|
5249
|
+
### 助眠解压 - 获取标签下资源列表
|
|
5250
|
+
|
|
5251
|
+
说明: 调用此接口, 获取标签下资源列表; 接口返回的`trackId`可以用于请求`/song/url/v1`接口,用于获取声音的下载地址
|
|
5252
|
+
|
|
5253
|
+
**必选参数 :**
|
|
5254
|
+
|
|
5255
|
+
`tag`: 标签, 由标签列表接口得到
|
|
5256
|
+
|
|
5257
|
+
**接口地址:** `/sati/resource/list`
|
|
5258
|
+
|
|
5259
|
+
**调用例子:** `/sati/resource/list?tag=naturalMusic`
|
|
5260
|
+
|
|
5261
|
+
### 助眠解压 - 查看同类推荐
|
|
5262
|
+
|
|
5263
|
+
说明: 调用此接口, 查看同类推荐
|
|
5264
|
+
|
|
5265
|
+
**必选参数 :**
|
|
5266
|
+
|
|
5267
|
+
`id`: id, `/sati/tag/list`接口返回的`trackId`
|
|
5268
|
+
|
|
5269
|
+
**接口地址:** `/sati/resource/list/more`
|
|
5270
|
+
|
|
5271
|
+
**调用例子:** `/sati/resource/list/more?id=167003`
|
|
5272
|
+
|
|
5273
|
+
### 助眠解压 - 收藏列表
|
|
5274
|
+
|
|
5275
|
+
说明: 调用此接口, 获取收藏列表
|
|
5276
|
+
|
|
5277
|
+
**接口地址:** `/sati/resource/sub/list`
|
|
5278
|
+
|
|
5279
|
+
**调用例子:** `/sati/resource/sub/list`
|
|
5280
|
+
|
|
5281
|
+
### 助眠解压 - 收藏
|
|
5282
|
+
|
|
5283
|
+
说明: 调用此接口, 收藏声音
|
|
5284
|
+
|
|
5285
|
+
**必选参数 :**
|
|
5286
|
+
|
|
5287
|
+
`id`: id, `/sati/tag/list`接口返回的`trackId`
|
|
5288
|
+
|
|
5289
|
+
**可选参数 :**
|
|
5290
|
+
|
|
5291
|
+
`cancel`: 是否取消收藏, 默认不取消
|
|
5292
|
+
|
|
5293
|
+
**接口地址:** `/sati/resource/sub`
|
|
5294
|
+
|
|
5295
|
+
**调用例子:** `/sati/resource/sub?id=167003`
|
|
5296
|
+
|
|
5297
|
+
### 跑步漫游
|
|
5298
|
+
|
|
5299
|
+
说明: 调用此接口,获取跑步漫游的歌曲信息
|
|
5300
|
+
|
|
5301
|
+
**必选参数:**
|
|
5302
|
+
|
|
5303
|
+
`bpm`: 步频
|
|
5304
|
+
|
|
5305
|
+
**接口地址:** `/radio/sport/get`
|
|
5306
|
+
|
|
5307
|
+
**调用例子:** `/radio/sport/get?bpm=50`
|
|
5308
|
+
|
|
5309
|
+
### 歌曲创作者信息
|
|
5310
|
+
|
|
5311
|
+
说明 : 调用此接口, 传入音乐 id 可获得对应音乐的创作者信息
|
|
5312
|
+
|
|
5313
|
+
**必选参数 :** `id`: 音乐 id
|
|
5314
|
+
|
|
5315
|
+
**接口地址 :** `/song/creators`
|
|
5316
|
+
|
|
5317
|
+
**调用例子 :** `/song/creators?id=33894312`
|
|
5318
|
+
|
|
5212
5319
|
## 离线访问此文档
|
|
5213
5320
|
|
|
5214
5321
|
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
|
package/public/eapi_decrypt.html
CHANGED
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
transition: background 0.2s ease;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
button + button {
|
|
100
|
+
margin-left: 12px;
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
button:hover {
|
|
100
104
|
background: #555;
|
|
101
105
|
}
|
|
@@ -166,6 +170,7 @@
|
|
|
166
170
|
</div>
|
|
167
171
|
|
|
168
172
|
<button @click="decrypt">解密</button>
|
|
173
|
+
<button @click="sendToApi" :disabled="!canSend" :class="[{ 'opacity-50 cursor-not-allowed pointer-events-none': !canSend },]">填入 API 调试</button>
|
|
169
174
|
|
|
170
175
|
<div class="result-section">
|
|
171
176
|
<label>解密结果:</label>
|
|
@@ -194,12 +199,29 @@
|
|
|
194
199
|
mounted() {
|
|
195
200
|
this.decrypt()
|
|
196
201
|
},
|
|
202
|
+
computed: {
|
|
203
|
+
isRequestMode() {
|
|
204
|
+
return this.isReq === true || this.isReq === 'true'
|
|
205
|
+
},
|
|
206
|
+
canSend() {
|
|
207
|
+
if (!this.isRequestMode) return false
|
|
208
|
+
if (!this.result || this.result === '{}' || this.result === 'null') return false
|
|
209
|
+
try {
|
|
210
|
+
JSON.parse(this.result)
|
|
211
|
+
return true
|
|
212
|
+
} catch (error) {
|
|
213
|
+
return false
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
},
|
|
197
217
|
methods: {
|
|
198
|
-
formatResult(
|
|
218
|
+
formatResult(value) {
|
|
219
|
+
if (value == null || value === '') return ''
|
|
199
220
|
try {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
221
|
+
const parsed = typeof value === 'string' ? JSON.parse(value) : value
|
|
222
|
+
return JSON.stringify(parsed, null, 2)
|
|
223
|
+
} catch (error) {
|
|
224
|
+
return String(value)
|
|
203
225
|
}
|
|
204
226
|
},
|
|
205
227
|
async decrypt() {
|
|
@@ -215,9 +237,25 @@
|
|
|
215
237
|
console.log(res.data);
|
|
216
238
|
} catch (error) {
|
|
217
239
|
console.error(error)
|
|
218
|
-
alert(error?.response?.data?.message || '
|
|
240
|
+
alert(error?.response?.data?.message || '解密失败,数据格式错误')
|
|
219
241
|
}
|
|
220
|
-
}
|
|
242
|
+
},
|
|
243
|
+
sendToApi() {
|
|
244
|
+
if (!this.canSend) return
|
|
245
|
+
const payload = JSON.parse(this.result)
|
|
246
|
+
const params = new URLSearchParams()
|
|
247
|
+
params.set('uri', payload.uri || payload.url || payload.path || '')
|
|
248
|
+
params.set('crypto', 'eapi')
|
|
249
|
+
const data =
|
|
250
|
+
payload.params ||
|
|
251
|
+
payload.data ||
|
|
252
|
+
payload.body ||
|
|
253
|
+
payload.payload ||
|
|
254
|
+
payload.request ||
|
|
255
|
+
{}
|
|
256
|
+
params.set('data', JSON.stringify(data))
|
|
257
|
+
window.open(`/api.html?${params.toString()}`, '_blank')
|
|
258
|
+
},
|
|
221
259
|
}
|
|
222
260
|
})
|
|
223
261
|
app.mount('#app')
|
package/server.js
CHANGED
|
@@ -156,6 +156,29 @@ function getCorsAllowOrigin(allowOrigins, requestOrigin) {
|
|
|
156
156
|
return null
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
function createConsoleSpinner(message = '启动中') {
|
|
160
|
+
if (!process.stdout.isTTY) {
|
|
161
|
+
return {
|
|
162
|
+
stop() {},
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
|
167
|
+
let index = 0
|
|
168
|
+
process.stdout.write(`${frames[index]} ${message}...`)
|
|
169
|
+
const timer = setInterval(() => {
|
|
170
|
+
index = (index + 1) % frames.length
|
|
171
|
+
process.stdout.write(`\r${frames[index]} ${message}...`)
|
|
172
|
+
}, 80)
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
stop() {
|
|
176
|
+
clearInterval(timer)
|
|
177
|
+
process.stdout.write(`\r✔ ${message} 完成。\n`)
|
|
178
|
+
},
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
159
182
|
/**
|
|
160
183
|
* Construct the server of NCM API.
|
|
161
184
|
*
|
|
@@ -387,6 +410,8 @@ async function serveNcmApi(options) {
|
|
|
387
410
|
const port = Number(options.port || process.env.PORT || '3000')
|
|
388
411
|
const host = options.host || process.env.HOST || ''
|
|
389
412
|
|
|
413
|
+
const spinner = createConsoleSpinner('服务启动中')
|
|
414
|
+
|
|
390
415
|
const checkVersionSubmission =
|
|
391
416
|
options.checkVersion &&
|
|
392
417
|
checkVersion().then(({ npmVersion, ourVersion, status }) => {
|
|
@@ -403,21 +428,15 @@ async function serveNcmApi(options) {
|
|
|
403
428
|
constructServerSubmission,
|
|
404
429
|
])
|
|
405
430
|
|
|
431
|
+
spinner.stop()
|
|
432
|
+
|
|
406
433
|
/** @type {import('express').Express & ExpressExtension} */
|
|
407
434
|
const appExt = app
|
|
408
435
|
appExt.server = app.listen(port, host, () => {
|
|
409
436
|
console.log(`
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
| . \` | | | |\\/| |
|
|
414
|
-
| |\\ | |____| | | |
|
|
415
|
-
|_| \\_|\\_____|_| |_|
|
|
416
|
-
`)
|
|
417
|
-
console.log(`
|
|
418
|
-
╔═╗╔═╗╦ ╔═╗╔╗╔╦ ╦╔═╗╔╗╔╔═╗╔═╗╔╦╗
|
|
419
|
-
╠═╣╠═╝║ ║╣ ║║║╠═╣╠═╣║║║║ ║╣ ║║
|
|
420
|
-
╩ ╩╩ ╩ ╚═╝╝╚╝╩ ╩╩ ╩╝╚╝╚═╝╚═╝═╩╝
|
|
437
|
+
╔═╗╔═╗╦ ╔═╗╔╗╔╦ ╦╔═╗╔╗╔╔═╗╔═╗╔╦╗
|
|
438
|
+
╠═╣╠═╝║ ║╣ ║║║╠═╣╠═╣║║║║ ║╣ ║║
|
|
439
|
+
╩ ╩╩ ╩ ╚═╝╝╚╝╩ ╩╩ ╩╝╚╝╚═╝╚═╝═╩╝
|
|
421
440
|
`)
|
|
422
441
|
logger.info(`
|
|
423
442
|
- Server started successfully @ http://${host ? host : 'localhost'}:${port}
|
package/util/crypto.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const CryptoJS = require('crypto-js')
|
|
2
2
|
const forge = require('node-forge')
|
|
3
|
+
const zlib = require('zlib')
|
|
3
4
|
const iv = '0102030405060708'
|
|
4
5
|
const presetKey = '0CoJUm6Qyw8W8jud'
|
|
5
6
|
const linuxapiKey = 'rFgB&h#%2?^eDg:Q'
|
|
@@ -44,7 +45,7 @@ const aesDecrypt = (ciphertext, key, iv, format = 'base64') => {
|
|
|
44
45
|
},
|
|
45
46
|
)
|
|
46
47
|
}
|
|
47
|
-
return bytes
|
|
48
|
+
return bytes
|
|
48
49
|
}
|
|
49
50
|
const rsaEncrypt = (str, key) => {
|
|
50
51
|
const forgePublicKey = forge.pki.publicKeyFromPem(key)
|
|
@@ -85,20 +86,37 @@ const eapi = (url, object) => {
|
|
|
85
86
|
params: aesEncrypt(data, 'ecb', eapiKey, '', 'hex'),
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
const eapiResDecrypt = (encryptedParams) => {
|
|
89
|
+
const eapiResDecrypt = (encryptedParams, aeapi = false) => {
|
|
89
90
|
// 使用aesDecrypt解密参数
|
|
90
91
|
try {
|
|
91
|
-
const
|
|
92
|
-
|
|
92
|
+
const decrypted = aesDecrypt(encryptedParams, eapiKey, '', 'hex') // WordArray
|
|
93
|
+
|
|
94
|
+
if (aeapi) {
|
|
95
|
+
// 带压缩的解密:先转 Base64 再解压
|
|
96
|
+
const decryptedBuffer = Buffer.from(
|
|
97
|
+
decrypted.toString(CryptoJS.enc.Base64),
|
|
98
|
+
'base64',
|
|
99
|
+
)
|
|
100
|
+
const decompressed = zlib.gunzipSync(decryptedBuffer)
|
|
101
|
+
return JSON.parse(decompressed.toString())
|
|
102
|
+
} else {
|
|
103
|
+
// 普通解密:直接转 UTF-8 字符串
|
|
104
|
+
return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8))
|
|
105
|
+
}
|
|
93
106
|
} catch (error) {
|
|
94
|
-
console.log(
|
|
107
|
+
console.log(`eapiResDecrypt error:`, error)
|
|
95
108
|
return null
|
|
96
109
|
}
|
|
97
110
|
}
|
|
98
111
|
const eapiReqDecrypt = (encryptedParams) => {
|
|
99
|
-
// 使用aesDecrypt解密参数
|
|
100
|
-
const decryptedData = aesDecrypt(
|
|
101
|
-
|
|
112
|
+
// 使用 aesDecrypt 解密参数
|
|
113
|
+
const decryptedData = aesDecrypt(
|
|
114
|
+
encryptedParams,
|
|
115
|
+
eapiKey,
|
|
116
|
+
'',
|
|
117
|
+
'hex',
|
|
118
|
+
).toString(CryptoJS.enc.Utf8)
|
|
119
|
+
// 使用正则表达式解析出 URL 和数据
|
|
102
120
|
const match = decryptedData.match(/(.*?)-36cd479b6b5-(.*?)-36cd479b6b5-(.*)/)
|
|
103
121
|
if (match) {
|
|
104
122
|
const url = match[1]
|
|
@@ -106,7 +124,7 @@ const eapiReqDecrypt = (encryptedParams) => {
|
|
|
106
124
|
return { url, data }
|
|
107
125
|
}
|
|
108
126
|
|
|
109
|
-
// 如果没有匹配到,返回null
|
|
127
|
+
// 如果没有匹配到,返回 null
|
|
110
128
|
return null
|
|
111
129
|
}
|
|
112
130
|
const decrypt = (cipher) => {
|
package/util/request.js
CHANGED
|
@@ -3,7 +3,6 @@ const encrypt = require('./crypto')
|
|
|
3
3
|
const CryptoJS = require('crypto-js')
|
|
4
4
|
const { default: axios } = require('axios')
|
|
5
5
|
const { PacProxyAgent } = require('pac-proxy-agent')
|
|
6
|
-
const logger = require('./logger')
|
|
7
6
|
const http = require('http')
|
|
8
7
|
const https = require('https')
|
|
9
8
|
const tunnel = require('tunnel')
|
|
@@ -160,10 +159,8 @@ const createRequest = (uri, data, options) => {
|
|
|
160
159
|
return new Promise((resolve, reject) => {
|
|
161
160
|
// 变量声明和初始化
|
|
162
161
|
const headers = options.headers ? { ...options.headers } : {}
|
|
163
|
-
const ip =
|
|
164
|
-
|
|
165
|
-
options.ip ||
|
|
166
|
-
(options.randomCNIP ? generateRandomChineseIP() : '')
|
|
162
|
+
const ip = options.realIP || options.ip || ''
|
|
163
|
+
|
|
167
164
|
// IP头设置
|
|
168
165
|
if (ip) {
|
|
169
166
|
headers['X-Real-IP'] = ip
|
|
@@ -191,6 +188,13 @@ const createRequest = (uri, data, options) => {
|
|
|
191
188
|
|
|
192
189
|
const answer = { status: 500, body: {}, cookie: [] }
|
|
193
190
|
|
|
191
|
+
data.e_r = toBoolean(
|
|
192
|
+
options.e_r !== undefined
|
|
193
|
+
? options.e_r
|
|
194
|
+
: data.e_r !== undefined
|
|
195
|
+
? data.e_r
|
|
196
|
+
: ENCRYPT_RESPONSE,
|
|
197
|
+
)
|
|
194
198
|
// 根据加密方式处理
|
|
195
199
|
switch (crypto) {
|
|
196
200
|
case 'weapi':
|
|
@@ -242,13 +246,7 @@ const createRequest = (uri, data, options) => {
|
|
|
242
246
|
if (crypto === 'eapi') {
|
|
243
247
|
// headers['x-aeapi'] = true // 服务器会使用gzip压缩返回值
|
|
244
248
|
data.header = header
|
|
245
|
-
|
|
246
|
-
options.e_r !== undefined
|
|
247
|
-
? options.e_r
|
|
248
|
-
: data.e_r !== undefined
|
|
249
|
-
? data.e_r
|
|
250
|
-
: ENCRYPT_RESPONSE,
|
|
251
|
-
)
|
|
249
|
+
|
|
252
250
|
encryptData = encrypt.eapi(uri, data)
|
|
253
251
|
url = (options.domain || API_DOMAIN) + '/eapi/' + uri.substr(5)
|
|
254
252
|
} else if (crypto === 'api') {
|
|
@@ -258,10 +256,10 @@ const createRequest = (uri, data, options) => {
|
|
|
258
256
|
break
|
|
259
257
|
|
|
260
258
|
default:
|
|
261
|
-
|
|
259
|
+
console.log('[ERR]', 'Unknown Crypto:', crypto)
|
|
262
260
|
break
|
|
263
261
|
}
|
|
264
|
-
//
|
|
262
|
+
// console.log(url);
|
|
265
263
|
// settings创建
|
|
266
264
|
let settings = {
|
|
267
265
|
method: 'POST',
|
|
@@ -272,8 +270,9 @@ const createRequest = (uri, data, options) => {
|
|
|
272
270
|
httpsAgent: createHttpsAgent(),
|
|
273
271
|
}
|
|
274
272
|
|
|
275
|
-
//
|
|
276
|
-
|
|
273
|
+
// 使用返回值加密
|
|
274
|
+
const use_e_r = (crypto === 'eapi' || crypto === 'weapi') && data.e_r
|
|
275
|
+
if (use_e_r) {
|
|
277
276
|
settings.encoding = null
|
|
278
277
|
settings.responseType = 'arraybuffer'
|
|
279
278
|
}
|
|
@@ -303,16 +302,16 @@ const createRequest = (uri, data, options) => {
|
|
|
303
302
|
settings.httpAgent = agent
|
|
304
303
|
settings.proxy = false
|
|
305
304
|
} else {
|
|
306
|
-
|
|
305
|
+
console.error('代理配置无效,不使用代理')
|
|
307
306
|
}
|
|
308
307
|
} catch (e) {
|
|
309
|
-
|
|
308
|
+
console.error('代理URL解析失败:', e.message)
|
|
310
309
|
}
|
|
311
310
|
}
|
|
312
311
|
} else {
|
|
313
312
|
settings.proxy = false
|
|
314
313
|
}
|
|
315
|
-
//
|
|
314
|
+
// console.log(settings.headers);
|
|
316
315
|
axios(settings)
|
|
317
316
|
.then((res) => {
|
|
318
317
|
const body = res.data
|
|
@@ -321,7 +320,7 @@ const createRequest = (uri, data, options) => {
|
|
|
321
320
|
)
|
|
322
321
|
|
|
323
322
|
try {
|
|
324
|
-
if (
|
|
323
|
+
if (use_e_r) {
|
|
325
324
|
answer.body = encrypt.eapiResDecrypt(
|
|
326
325
|
body.toString('hex').toUpperCase(),
|
|
327
326
|
headers['x-aeapi'],
|
|
@@ -352,14 +351,14 @@ const createRequest = (uri, data, options) => {
|
|
|
352
351
|
if (answer.status === 200) {
|
|
353
352
|
resolve(answer)
|
|
354
353
|
} else {
|
|
355
|
-
|
|
354
|
+
console.log('[ERR]', answer)
|
|
356
355
|
reject(answer)
|
|
357
356
|
}
|
|
358
357
|
})
|
|
359
358
|
.catch((err) => {
|
|
360
359
|
answer.status = 502
|
|
361
360
|
answer.body = { code: 502, msg: err.message || err }
|
|
362
|
-
|
|
361
|
+
console.log('[ERR]', answer)
|
|
363
362
|
reject(answer)
|
|
364
363
|
})
|
|
365
364
|
})
|