qqmusic-api-enhanced 1.0.1 → 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.
- package/main.js +3 -2
- package/main.ts +3 -0
- package/module/login_qr_check.js +80 -40
- package/module/login_qr_check.ts +85 -42
- package/module/login_qr_create.js +9 -1
- package/module/login_qr_create.ts +9 -1
- package/module/login_refresh.js +18 -4
- package/module/login_refresh.ts +20 -4
- package/module/login_status.js +25 -16
- package/module/login_status.ts +28 -19
- package/module/user_detail.js +27 -4
- package/module/user_detail.ts +30 -4
- package/module/user_vip_info.d.ts +4 -1
- package/module/user_vip_info.js +164 -22
- package/module/user_vip_info.ts +163 -25
- package/package.json +1 -1
- package/util/mobile_qr_session.d.ts +2 -0
- package/util/mobile_qr_session.js +63 -16
- package/util/mobile_qr_session.ts +74 -21
- package/util/option.d.ts +2 -0
- package/util/option.js +33 -18
- package/util/option.ts +34 -20
- package/util/request.js +15 -1
- package/util/request.ts +13 -1
package/main.js
CHANGED
|
@@ -13,7 +13,7 @@ import song_detail_fn from "./module/song_detail.js";
|
|
|
13
13
|
import song_url_fn from "./module/song_url.js";
|
|
14
14
|
import user_detail_fn from "./module/user_detail.js";
|
|
15
15
|
import user_playlist_fn from "./module/user_playlist.js";
|
|
16
|
-
import user_vip_info_fn, { deriveVipInfo, } from "./module/user_vip_info.js";
|
|
16
|
+
import user_vip_info_fn, { deriveVipInfo, parseVipFromIcons, } from "./module/user_vip_info.js";
|
|
17
17
|
import { cookieToJson, cookieToString, parseSetCookie } from "./util/cookie.js";
|
|
18
18
|
import { getGtk, getGuid, getSearchId, hash33, qrcDecrypt } from "./util/crypto.js";
|
|
19
19
|
import { request, requestCgi, requestRaw } from "./util/request.js";
|
|
@@ -34,7 +34,7 @@ export const song_url = (query = {}) => song_url_fn(query, request);
|
|
|
34
34
|
export const user_detail = (query = {}) => user_detail_fn(query, request);
|
|
35
35
|
export const user_playlist = (query = {}) => user_playlist_fn(query, request);
|
|
36
36
|
export const user_vip_info = (query = {}) => user_vip_info_fn(query, request);
|
|
37
|
-
export { request, requestCgi, requestRaw, zzcSign, qrcDecrypt, hash33, getGtk, getGuid, getSearchId, cookieToJson, cookieToString, parseSetCookie, deriveVipInfo, };
|
|
37
|
+
export { request, requestCgi, requestRaw, zzcSign, qrcDecrypt, hash33, getGtk, getGuid, getSearchId, cookieToJson, cookieToString, parseSetCookie, deriveVipInfo, parseVipFromIcons, };
|
|
38
38
|
const api = {
|
|
39
39
|
artist_detail,
|
|
40
40
|
artist_songs,
|
|
@@ -53,6 +53,7 @@ const api = {
|
|
|
53
53
|
user_playlist,
|
|
54
54
|
user_vip_info,
|
|
55
55
|
deriveVipInfo,
|
|
56
|
+
parseVipFromIcons,
|
|
56
57
|
request,
|
|
57
58
|
requestCgi,
|
|
58
59
|
requestRaw,
|
package/main.ts
CHANGED
|
@@ -18,6 +18,7 @@ import user_detail_fn from "./module/user_detail.js";
|
|
|
18
18
|
import user_playlist_fn from "./module/user_playlist.js";
|
|
19
19
|
import user_vip_info_fn, {
|
|
20
20
|
deriveVipInfo,
|
|
21
|
+
parseVipFromIcons,
|
|
21
22
|
type NormalizedVipInfo,
|
|
22
23
|
} from "./module/user_vip_info.js";
|
|
23
24
|
|
|
@@ -88,6 +89,7 @@ export {
|
|
|
88
89
|
cookieToString,
|
|
89
90
|
parseSetCookie,
|
|
90
91
|
deriveVipInfo,
|
|
92
|
+
parseVipFromIcons,
|
|
91
93
|
type ApiResponse,
|
|
92
94
|
type NormalizedVipInfo,
|
|
93
95
|
type NormalizedLoginAccount,
|
|
@@ -112,6 +114,7 @@ const api = {
|
|
|
112
114
|
user_playlist,
|
|
113
115
|
user_vip_info,
|
|
114
116
|
deriveVipInfo,
|
|
117
|
+
parseVipFromIcons,
|
|
115
118
|
request,
|
|
116
119
|
requestCgi,
|
|
117
120
|
requestRaw,
|
package/module/login_qr_check.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { request, requestCgi } from "../util/request.js";
|
|
2
2
|
import { getGtk, getGuid } from "../util/crypto.js";
|
|
3
3
|
import { cookieToString, parseSetCookie } from "../util/cookie.js";
|
|
4
|
+
import { getMobileSession, registerMobileSession } from "../util/mobile_qr_session.js";
|
|
4
5
|
/**
|
|
5
6
|
* 轮询检查二维码登录状态.
|
|
6
7
|
*
|
|
@@ -147,65 +148,104 @@ export default async function login_qr_check(query = {}, req = request) {
|
|
|
147
148
|
body: { code: 400, message: "缺少必要参数 qrcodeID" },
|
|
148
149
|
};
|
|
149
150
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
// 1. 确保后台 MQTT 会话已启动
|
|
152
|
+
let session = getMobileSession(qrcodeID);
|
|
153
|
+
if (!session) {
|
|
154
|
+
try {
|
|
155
|
+
registerMobileSession(qrcodeID);
|
|
156
|
+
}
|
|
157
|
+
catch { }
|
|
158
|
+
session = getMobileSession(qrcodeID);
|
|
159
|
+
}
|
|
160
|
+
// 2. 优先检查实时会话事件
|
|
161
|
+
if (session && session.code === 200) {
|
|
159
162
|
return {
|
|
160
163
|
status: 200,
|
|
161
|
-
body: {
|
|
164
|
+
body: {
|
|
165
|
+
code: 200,
|
|
166
|
+
message: "登录成功",
|
|
167
|
+
uin: session.uin || "",
|
|
168
|
+
musickey: session.musickey || "",
|
|
169
|
+
nickname: session.nickname || "",
|
|
170
|
+
avatarUrl: session.avatarUrl || "",
|
|
171
|
+
cookieStr: session.cookieStr || "",
|
|
172
|
+
},
|
|
162
173
|
};
|
|
163
174
|
}
|
|
164
|
-
if (code ===
|
|
175
|
+
if (session && session.code === 802) {
|
|
165
176
|
return {
|
|
166
177
|
status: 200,
|
|
167
|
-
body: { code: 802, message: "已扫码,等待确认" },
|
|
178
|
+
body: { code: 802, message: session.message || "已扫码,等待确认" },
|
|
168
179
|
};
|
|
169
180
|
}
|
|
170
|
-
if (code ===
|
|
181
|
+
if (session && session.code === 800) {
|
|
171
182
|
return {
|
|
172
183
|
status: 200,
|
|
173
|
-
body: { code: 800, message: "二维码已过期,请刷新" },
|
|
184
|
+
body: { code: 800, message: session.message || "二维码已过期,请刷新" },
|
|
174
185
|
};
|
|
175
186
|
}
|
|
176
|
-
if (code ===
|
|
177
|
-
const cookies = cgiRes.cookie || [];
|
|
178
|
-
const cookieObj = parseSetCookie(cookies);
|
|
179
|
-
if (cgiBody.musicid && !cookieObj.uin)
|
|
180
|
-
cookieObj.uin = String(cgiBody.musicid);
|
|
181
|
-
if (cgiBody.musickey && !cookieObj.qm_keyst)
|
|
182
|
-
cookieObj.qm_keyst = String(cgiBody.musickey);
|
|
183
|
-
if (cgiBody.musickey && !cookieObj.qqmusic_key)
|
|
184
|
-
cookieObj.qqmusic_key = String(cgiBody.musickey);
|
|
185
|
-
if (cgiBody.openid && !cookieObj.openid)
|
|
186
|
-
cookieObj.openid = String(cgiBody.openid);
|
|
187
|
-
if (cgiBody.refresh_token && !cookieObj.refresh_token)
|
|
188
|
-
cookieObj.refresh_token = String(cgiBody.refresh_token);
|
|
189
|
-
const cookieStr = cookieToString(cookieObj);
|
|
187
|
+
if (session && session.code === 803) {
|
|
190
188
|
return {
|
|
191
189
|
status: 200,
|
|
192
|
-
body: {
|
|
193
|
-
code: 200,
|
|
194
|
-
message: "登录成功",
|
|
195
|
-
uin: cookieObj.uin || String(cgiBody.musicid || ""),
|
|
196
|
-
musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
|
|
197
|
-
cookieStr,
|
|
198
|
-
data: cgiBody,
|
|
199
|
-
},
|
|
200
|
-
cookie: cookies,
|
|
190
|
+
body: { code: 803, message: session.message || "用户取消授权" },
|
|
201
191
|
};
|
|
202
192
|
}
|
|
193
|
+
// 3. 兜底轮询 CheckQRCode CGI 状态
|
|
194
|
+
try {
|
|
195
|
+
const cgiRes = await req("music.login.LoginServer", "CheckQRCode", {
|
|
196
|
+
qrcodeID,
|
|
197
|
+
tmeAppID: "qqmusic",
|
|
198
|
+
}, {
|
|
199
|
+
platform: "android",
|
|
200
|
+
});
|
|
201
|
+
const cgiBody = (cgiRes.body || {});
|
|
202
|
+
const code = cgiBody.code !== undefined ? cgiBody.code : cgiBody.ret;
|
|
203
|
+
if (code === 40001) {
|
|
204
|
+
return {
|
|
205
|
+
status: 200,
|
|
206
|
+
body: { code: 802, message: "已扫码,等待确认" },
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (code === 40002) {
|
|
210
|
+
return {
|
|
211
|
+
status: 200,
|
|
212
|
+
body: { code: 800, message: "二维码已过期,请刷新" },
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (code === 0) {
|
|
216
|
+
const cookies = cgiRes.cookie || [];
|
|
217
|
+
const cookieObj = parseSetCookie(cookies);
|
|
218
|
+
if (cgiBody.musicid && !cookieObj.uin)
|
|
219
|
+
cookieObj.uin = String(cgiBody.musicid);
|
|
220
|
+
if (cgiBody.musickey && !cookieObj.qm_keyst)
|
|
221
|
+
cookieObj.qm_keyst = String(cgiBody.musickey);
|
|
222
|
+
if (cgiBody.musickey && !cookieObj.qqmusic_key)
|
|
223
|
+
cookieObj.qqmusic_key = String(cgiBody.musickey);
|
|
224
|
+
if (cgiBody.openid && !cookieObj.openid)
|
|
225
|
+
cookieObj.openid = String(cgiBody.openid);
|
|
226
|
+
if (cgiBody.refresh_token && !cookieObj.refresh_token)
|
|
227
|
+
cookieObj.refresh_token = String(cgiBody.refresh_token);
|
|
228
|
+
const cookieStr = cookieToString(cookieObj);
|
|
229
|
+
return {
|
|
230
|
+
status: 200,
|
|
231
|
+
body: {
|
|
232
|
+
code: 200,
|
|
233
|
+
message: "登录成功",
|
|
234
|
+
uin: cookieObj.uin || String(cgiBody.musicid || ""),
|
|
235
|
+
musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
|
|
236
|
+
cookieStr,
|
|
237
|
+
data: cgiBody,
|
|
238
|
+
},
|
|
239
|
+
cookie: cookies,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
catch { }
|
|
203
244
|
return {
|
|
204
245
|
status: 200,
|
|
205
246
|
body: {
|
|
206
|
-
code: 801,
|
|
207
|
-
message:
|
|
208
|
-
data: cgiBody,
|
|
247
|
+
code: session?.code || 801,
|
|
248
|
+
message: session?.message || "等待 QQ 音乐 App 扫码",
|
|
209
249
|
},
|
|
210
250
|
};
|
|
211
251
|
}
|
package/module/login_qr_check.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { request, requestCgi, type ApiResponse } from "../util/request.js";
|
|
2
2
|
import { getGtk, getGuid } from "../util/crypto.js";
|
|
3
3
|
import { cookieToString, parseSetCookie } from "../util/cookie.js";
|
|
4
|
+
import { getMobileSession, registerMobileSession } from "../util/mobile_qr_session.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* 轮询检查二维码登录状态.
|
|
@@ -191,69 +192,111 @@ export default async function login_qr_check(
|
|
|
191
192
|
};
|
|
192
193
|
}
|
|
193
194
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
{
|
|
198
|
-
qrcodeID
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
platform: "android",
|
|
203
|
-
}
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
const cgiBody = (cgiRes.body || {}) as any;
|
|
207
|
-
const code = cgiBody.code;
|
|
195
|
+
// 1. 确保后台 MQTT 会话已启动
|
|
196
|
+
let session = getMobileSession(qrcodeID);
|
|
197
|
+
if (!session) {
|
|
198
|
+
try {
|
|
199
|
+
registerMobileSession(qrcodeID);
|
|
200
|
+
} catch {}
|
|
201
|
+
session = getMobileSession(qrcodeID);
|
|
202
|
+
}
|
|
208
203
|
|
|
209
|
-
|
|
204
|
+
// 2. 优先检查实时会话事件
|
|
205
|
+
if (session && session.code === 200) {
|
|
210
206
|
return {
|
|
211
207
|
status: 200,
|
|
212
|
-
body: {
|
|
208
|
+
body: {
|
|
209
|
+
code: 200,
|
|
210
|
+
message: "登录成功",
|
|
211
|
+
uin: session.uin || "",
|
|
212
|
+
musickey: session.musickey || "",
|
|
213
|
+
nickname: session.nickname || "",
|
|
214
|
+
avatarUrl: session.avatarUrl || "",
|
|
215
|
+
cookieStr: session.cookieStr || "",
|
|
216
|
+
},
|
|
213
217
|
};
|
|
214
218
|
}
|
|
215
|
-
|
|
219
|
+
|
|
220
|
+
if (session && session.code === 802) {
|
|
216
221
|
return {
|
|
217
222
|
status: 200,
|
|
218
|
-
body: { code: 802, message: "已扫码,等待确认" },
|
|
223
|
+
body: { code: 802, message: session.message || "已扫码,等待确认" },
|
|
219
224
|
};
|
|
220
225
|
}
|
|
221
|
-
|
|
226
|
+
|
|
227
|
+
if (session && session.code === 800) {
|
|
222
228
|
return {
|
|
223
229
|
status: 200,
|
|
224
|
-
body: { code: 800, message: "二维码已过期,请刷新" },
|
|
230
|
+
body: { code: 800, message: session.message || "二维码已过期,请刷新" },
|
|
225
231
|
};
|
|
226
232
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const cookieObj = parseSetCookie(cookies);
|
|
230
|
-
if (cgiBody.musicid && !cookieObj.uin) cookieObj.uin = String(cgiBody.musicid);
|
|
231
|
-
if (cgiBody.musickey && !cookieObj.qm_keyst) cookieObj.qm_keyst = String(cgiBody.musickey);
|
|
232
|
-
if (cgiBody.musickey && !cookieObj.qqmusic_key) cookieObj.qqmusic_key = String(cgiBody.musickey);
|
|
233
|
-
if (cgiBody.openid && !cookieObj.openid) cookieObj.openid = String(cgiBody.openid);
|
|
234
|
-
if (cgiBody.refresh_token && !cookieObj.refresh_token) cookieObj.refresh_token = String(cgiBody.refresh_token);
|
|
235
|
-
|
|
236
|
-
const cookieStr = cookieToString(cookieObj);
|
|
233
|
+
|
|
234
|
+
if (session && session.code === 803) {
|
|
237
235
|
return {
|
|
238
236
|
status: 200,
|
|
239
|
-
body: {
|
|
240
|
-
code: 200,
|
|
241
|
-
message: "登录成功",
|
|
242
|
-
uin: cookieObj.uin || String(cgiBody.musicid || ""),
|
|
243
|
-
musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
|
|
244
|
-
cookieStr,
|
|
245
|
-
data: cgiBody,
|
|
246
|
-
},
|
|
247
|
-
cookie: cookies,
|
|
237
|
+
body: { code: 803, message: session.message || "用户取消授权" },
|
|
248
238
|
};
|
|
249
239
|
}
|
|
250
240
|
|
|
241
|
+
// 3. 兜底轮询 CheckQRCode CGI 状态
|
|
242
|
+
try {
|
|
243
|
+
const cgiRes = await req(
|
|
244
|
+
"music.login.LoginServer",
|
|
245
|
+
"CheckQRCode",
|
|
246
|
+
{
|
|
247
|
+
qrcodeID,
|
|
248
|
+
tmeAppID: "qqmusic",
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
platform: "android",
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const cgiBody = (cgiRes.body || {}) as any;
|
|
256
|
+
const code = cgiBody.code !== undefined ? cgiBody.code : cgiBody.ret;
|
|
257
|
+
|
|
258
|
+
if (code === 40001) {
|
|
259
|
+
return {
|
|
260
|
+
status: 200,
|
|
261
|
+
body: { code: 802, message: "已扫码,等待确认" },
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
if (code === 40002) {
|
|
265
|
+
return {
|
|
266
|
+
status: 200,
|
|
267
|
+
body: { code: 800, message: "二维码已过期,请刷新" },
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
if (code === 0) {
|
|
271
|
+
const cookies = cgiRes.cookie || [];
|
|
272
|
+
const cookieObj = parseSetCookie(cookies);
|
|
273
|
+
if (cgiBody.musicid && !cookieObj.uin) cookieObj.uin = String(cgiBody.musicid);
|
|
274
|
+
if (cgiBody.musickey && !cookieObj.qm_keyst) cookieObj.qm_keyst = String(cgiBody.musickey);
|
|
275
|
+
if (cgiBody.musickey && !cookieObj.qqmusic_key) cookieObj.qqmusic_key = String(cgiBody.musickey);
|
|
276
|
+
if (cgiBody.openid && !cookieObj.openid) cookieObj.openid = String(cgiBody.openid);
|
|
277
|
+
if (cgiBody.refresh_token && !cookieObj.refresh_token) cookieObj.refresh_token = String(cgiBody.refresh_token);
|
|
278
|
+
|
|
279
|
+
const cookieStr = cookieToString(cookieObj);
|
|
280
|
+
return {
|
|
281
|
+
status: 200,
|
|
282
|
+
body: {
|
|
283
|
+
code: 200,
|
|
284
|
+
message: "登录成功",
|
|
285
|
+
uin: cookieObj.uin || String(cgiBody.musicid || ""),
|
|
286
|
+
musickey: cookieObj.qm_keyst || String(cgiBody.musickey || ""),
|
|
287
|
+
cookieStr,
|
|
288
|
+
data: cgiBody,
|
|
289
|
+
},
|
|
290
|
+
cookie: cookies,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
} catch {}
|
|
294
|
+
|
|
251
295
|
return {
|
|
252
296
|
status: 200,
|
|
253
297
|
body: {
|
|
254
|
-
code: 801,
|
|
255
|
-
message:
|
|
256
|
-
data: cgiBody,
|
|
298
|
+
code: session?.code || 801,
|
|
299
|
+
message: session?.message || "等待 QQ 音乐 App 扫码",
|
|
257
300
|
},
|
|
258
301
|
};
|
|
259
302
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { request } from "../util/request.js";
|
|
2
2
|
import { hash33 } from "../util/crypto.js";
|
|
3
3
|
import { parseSetCookie } from "../util/cookie.js";
|
|
4
|
+
import { registerMobileSession } from "../util/mobile_qr_session.js";
|
|
4
5
|
/**
|
|
5
6
|
* 获取登录二维码 (QQ / 微信 / 移动端App).
|
|
6
7
|
*
|
|
@@ -78,13 +79,20 @@ export default async function login_qr_create(query = {}, req = request) {
|
|
|
78
79
|
const cgiRes = await req("music.login.LoginServer", "CreateQRCode", {
|
|
79
80
|
tmeAppID: "qqmusic",
|
|
80
81
|
}, { platform: "android" });
|
|
82
|
+
const qrcodeID = cgiRes.body?.qrcodeID;
|
|
83
|
+
if (qrcodeID) {
|
|
84
|
+
try {
|
|
85
|
+
registerMobileSession(qrcodeID);
|
|
86
|
+
}
|
|
87
|
+
catch { }
|
|
88
|
+
}
|
|
81
89
|
return {
|
|
82
90
|
status: cgiRes.status,
|
|
83
91
|
body: {
|
|
84
92
|
code: 200,
|
|
85
93
|
type: "mobile",
|
|
86
94
|
qrcode: cgiRes.body?.qrcode,
|
|
87
|
-
qrcodeID
|
|
95
|
+
qrcodeID,
|
|
88
96
|
},
|
|
89
97
|
cookie: cgiRes.cookie,
|
|
90
98
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { request, type ApiResponse } from "../util/request.js";
|
|
2
2
|
import { hash33 } from "../util/crypto.js";
|
|
3
3
|
import { parseSetCookie } from "../util/cookie.js";
|
|
4
|
+
import { registerMobileSession } from "../util/mobile_qr_session.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* 获取登录二维码 (QQ / 微信 / 移动端App).
|
|
@@ -99,13 +100,20 @@ export default async function login_qr_create(
|
|
|
99
100
|
{ platform: "android" }
|
|
100
101
|
);
|
|
101
102
|
|
|
103
|
+
const qrcodeID = cgiRes.body?.qrcodeID;
|
|
104
|
+
if (qrcodeID) {
|
|
105
|
+
try {
|
|
106
|
+
registerMobileSession(qrcodeID);
|
|
107
|
+
} catch {}
|
|
108
|
+
}
|
|
109
|
+
|
|
102
110
|
return {
|
|
103
111
|
status: cgiRes.status,
|
|
104
112
|
body: {
|
|
105
113
|
code: 200,
|
|
106
114
|
type: "mobile",
|
|
107
115
|
qrcode: cgiRes.body?.qrcode,
|
|
108
|
-
qrcodeID
|
|
116
|
+
qrcodeID,
|
|
109
117
|
},
|
|
110
118
|
cookie: cgiRes.cookie,
|
|
111
119
|
};
|
package/module/login_refresh.js
CHANGED
|
@@ -11,10 +11,12 @@ export default async function login_refresh(query = {}, req = request) {
|
|
|
11
11
|
const cookieObj = cookieToJson(query.cookie);
|
|
12
12
|
const uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.wxuin || "0";
|
|
13
13
|
const musickey = cookieObj.qm_keyst || cookieObj.qqmusic_key || "";
|
|
14
|
+
const loginType = cookieObj.tmeLoginType || (musickey.startsWith("W_X") ? "1" : "2");
|
|
14
15
|
const param = {
|
|
15
16
|
openid: query.openid || cookieObj.openid || "",
|
|
16
17
|
refresh_token: query.refresh_token || cookieObj.refresh_token || "",
|
|
17
18
|
refresh_key: query.refresh_key || cookieObj.refresh_key || "",
|
|
19
|
+
access_token: cookieObj.access_token || "",
|
|
18
20
|
musicid: Number(uin) || 0,
|
|
19
21
|
str_musicid: uin,
|
|
20
22
|
musickey,
|
|
@@ -22,16 +24,28 @@ export default async function login_refresh(query = {}, req = request) {
|
|
|
22
24
|
};
|
|
23
25
|
const cgiRes = await req("music.login.LoginServer", "Login", param, {
|
|
24
26
|
cookie: query.cookie,
|
|
25
|
-
platform: "
|
|
27
|
+
platform: "android",
|
|
28
|
+
comm: { tmeLoginType: Number(loginType) || 2 },
|
|
26
29
|
});
|
|
27
30
|
const resBody = (cgiRes.body || {});
|
|
28
31
|
const newCookies = parseSetCookie(cgiRes.cookie || []);
|
|
29
32
|
const mergedCookies = { ...cookieObj, ...newCookies };
|
|
30
|
-
if (resBody.musickey
|
|
33
|
+
if (resBody.musickey) {
|
|
31
34
|
mergedCookies.qm_keyst = resBody.musickey;
|
|
32
|
-
}
|
|
33
|
-
if (resBody.musickey && !mergedCookies.qqmusic_key) {
|
|
34
35
|
mergedCookies.qqmusic_key = resBody.musickey;
|
|
36
|
+
mergedCookies.musickey = resBody.musickey;
|
|
37
|
+
}
|
|
38
|
+
if (resBody.musicid) {
|
|
39
|
+
mergedCookies.uin = String(resBody.musicid);
|
|
40
|
+
mergedCookies.qqmusic_uin = String(resBody.musicid);
|
|
41
|
+
mergedCookies.musicid = String(resBody.musicid);
|
|
42
|
+
}
|
|
43
|
+
if (resBody.encryptUin) {
|
|
44
|
+
mergedCookies.euin = resBody.encryptUin;
|
|
45
|
+
mergedCookies.encryptUin = resBody.encryptUin;
|
|
46
|
+
}
|
|
47
|
+
if (resBody.refresh_token) {
|
|
48
|
+
mergedCookies.refresh_token = resBody.refresh_token;
|
|
35
49
|
}
|
|
36
50
|
const cookieStr = cookieToString(mergedCookies);
|
|
37
51
|
return {
|
package/module/login_refresh.ts
CHANGED
|
@@ -21,10 +21,13 @@ export default async function login_refresh(
|
|
|
21
21
|
const uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.wxuin || "0";
|
|
22
22
|
const musickey = cookieObj.qm_keyst || cookieObj.qqmusic_key || "";
|
|
23
23
|
|
|
24
|
+
const loginType = cookieObj.tmeLoginType || (musickey.startsWith("W_X") ? "1" : "2");
|
|
25
|
+
|
|
24
26
|
const param = {
|
|
25
27
|
openid: query.openid || cookieObj.openid || "",
|
|
26
28
|
refresh_token: query.refresh_token || cookieObj.refresh_token || "",
|
|
27
29
|
refresh_key: query.refresh_key || cookieObj.refresh_key || "",
|
|
30
|
+
access_token: cookieObj.access_token || "",
|
|
28
31
|
musicid: Number(uin) || 0,
|
|
29
32
|
str_musicid: uin,
|
|
30
33
|
musickey,
|
|
@@ -37,18 +40,31 @@ export default async function login_refresh(
|
|
|
37
40
|
param,
|
|
38
41
|
{
|
|
39
42
|
cookie: query.cookie,
|
|
40
|
-
platform: "
|
|
43
|
+
platform: "android",
|
|
44
|
+
comm: { tmeLoginType: Number(loginType) || 2 },
|
|
41
45
|
}
|
|
42
46
|
);
|
|
43
47
|
|
|
44
48
|
const resBody = (cgiRes.body || {}) as any;
|
|
45
49
|
const newCookies = parseSetCookie(cgiRes.cookie || []);
|
|
46
50
|
const mergedCookies = { ...cookieObj, ...newCookies };
|
|
47
|
-
|
|
51
|
+
|
|
52
|
+
if (resBody.musickey) {
|
|
48
53
|
mergedCookies.qm_keyst = resBody.musickey;
|
|
49
|
-
}
|
|
50
|
-
if (resBody.musickey && !mergedCookies.qqmusic_key) {
|
|
51
54
|
mergedCookies.qqmusic_key = resBody.musickey;
|
|
55
|
+
mergedCookies.musickey = resBody.musickey;
|
|
56
|
+
}
|
|
57
|
+
if (resBody.musicid) {
|
|
58
|
+
mergedCookies.uin = String(resBody.musicid);
|
|
59
|
+
mergedCookies.qqmusic_uin = String(resBody.musicid);
|
|
60
|
+
mergedCookies.musicid = String(resBody.musicid);
|
|
61
|
+
}
|
|
62
|
+
if (resBody.encryptUin) {
|
|
63
|
+
mergedCookies.euin = resBody.encryptUin;
|
|
64
|
+
mergedCookies.encryptUin = resBody.encryptUin;
|
|
65
|
+
}
|
|
66
|
+
if (resBody.refresh_token) {
|
|
67
|
+
mergedCookies.refresh_token = resBody.refresh_token;
|
|
52
68
|
}
|
|
53
69
|
const cookieStr = cookieToString(mergedCookies);
|
|
54
70
|
|
package/module/login_status.js
CHANGED
|
@@ -9,14 +9,20 @@ import user_vip_info_fn from "./user_vip_info.js";
|
|
|
9
9
|
*/
|
|
10
10
|
export default async function login_status(query = {}, req = request) {
|
|
11
11
|
const cookieObj = cookieToJson(query.cookie);
|
|
12
|
-
let uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.wxuin || "";
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
let uin = cookieObj.uin || cookieObj.qqmusic_uin || cookieObj.musicid || cookieObj.wxuin || "";
|
|
13
|
+
const musickey = cookieObj.qm_keyst || cookieObj.qqmusic_key || cookieObj.musickey || "";
|
|
14
|
+
let cgiRes = { status: 200, body: {} };
|
|
15
|
+
try {
|
|
16
|
+
cgiRes = await req("music.UserInfo.userInfoServer", "GetLoginUserInfo", {}, {
|
|
17
|
+
cookie: query.cookie,
|
|
18
|
+
platform: "android",
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch { }
|
|
17
22
|
const data = (cgiRes.body || {});
|
|
18
23
|
const userData = data.user || data.userInfo || data;
|
|
19
|
-
|
|
24
|
+
let isLogin = (data.code === 0 || (data.code === undefined && Boolean(userData.uin || userData.encryptUin))) &&
|
|
25
|
+
Boolean(userData.uin || userData.encryptUin || uin);
|
|
20
26
|
if (userData.uin) {
|
|
21
27
|
uin = String(userData.uin).trim();
|
|
22
28
|
}
|
|
@@ -25,15 +31,18 @@ export default async function login_status(query = {}, req = request) {
|
|
|
25
31
|
}
|
|
26
32
|
let nickname = userData.nick || userData.nickname || "";
|
|
27
33
|
let avatarUrl = userData.headurl || userData.avatar;
|
|
28
|
-
//
|
|
29
|
-
if (
|
|
34
|
+
// 若基本信息不全,只要有 uin,调用 user_detail 补全真实昵称与高清头像
|
|
35
|
+
if (uin && (!nickname || !avatarUrl)) {
|
|
30
36
|
try {
|
|
31
37
|
const detailRes = await user_detail_fn({ uin, cookie: query.cookie }, req);
|
|
32
|
-
const
|
|
33
|
-
if (
|
|
34
|
-
nickname =
|
|
35
|
-
if (
|
|
36
|
-
avatarUrl =
|
|
38
|
+
const detailData = detailRes.body?.data || {};
|
|
39
|
+
if (detailData.nick && !nickname)
|
|
40
|
+
nickname = detailData.nick;
|
|
41
|
+
if (detailData.headurl && !avatarUrl)
|
|
42
|
+
avatarUrl = detailData.headurl;
|
|
43
|
+
if (detailData.nick && Boolean(musickey || uin)) {
|
|
44
|
+
isLogin = true;
|
|
45
|
+
}
|
|
37
46
|
}
|
|
38
47
|
catch { }
|
|
39
48
|
}
|
|
@@ -42,9 +51,9 @@ export default async function login_status(query = {}, req = request) {
|
|
|
42
51
|
}
|
|
43
52
|
// 补全 VIP 会员信息
|
|
44
53
|
let vip = { vipStatus: "nonVip" };
|
|
45
|
-
if (isLogin) {
|
|
54
|
+
if (isLogin || uin) {
|
|
46
55
|
try {
|
|
47
|
-
const vipRes = await user_vip_info_fn({ cookie: query.cookie }, req);
|
|
56
|
+
const vipRes = await user_vip_info_fn({ cookie: query.cookie, uin }, req);
|
|
48
57
|
vip = vipRes.body.vip;
|
|
49
58
|
}
|
|
50
59
|
catch {
|
|
@@ -62,7 +71,7 @@ export default async function login_status(query = {}, req = request) {
|
|
|
62
71
|
vipExpireTime: vip.vipExpireTime,
|
|
63
72
|
};
|
|
64
73
|
return {
|
|
65
|
-
status: cgiRes.status,
|
|
74
|
+
status: cgiRes.status || 200,
|
|
66
75
|
body: {
|
|
67
76
|
code: isLogin ? 200 : 301,
|
|
68
77
|
isLogin,
|