@sansenjian/qq-music-api 1.0.6 → 2.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.
Files changed (94) hide show
  1. package/.babelrc +2 -2
  2. package/.dockerignore +5 -5
  3. package/.editorconfig +31 -31
  4. package/.eslintrc.json +21 -17
  5. package/.github/FUNDING.yml +12 -12
  6. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  7. package/.github/ISSUE_TEMPLATE/custom.md +24 -24
  8. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  9. package/.github/workflows/publish.yml +26 -0
  10. package/.husky/commit-msg +1 -0
  11. package/.husky/pre-commit +1 -0
  12. package/.prettierignore +1 -1
  13. package/.prettierrc +9 -9
  14. package/CHANGELOG.md +70 -70
  15. package/Dockerfile +18 -18
  16. package/LICENSE +21 -21
  17. package/README.md +218 -177
  18. package/app.js +75 -75
  19. package/commitlint.config.js +20 -20
  20. package/config/user-info.js +42 -42
  21. package/index.js +1 -1
  22. package/middlewares/koa-cors.js +97 -97
  23. package/module/apis/UCommon/UCommon.js +6 -6
  24. package/module/apis/album/getAlbumInfo.js +33 -33
  25. package/module/apis/comments/getComments.js +35 -35
  26. package/module/apis/digitalAlbum/getDigitalAlbumLists.js +34 -34
  27. package/module/apis/downloadQQMusic.js +41 -41
  28. package/module/apis/music/getLyric.js +42 -41
  29. package/module/apis/mv/getMvByTag.js +35 -35
  30. package/module/apis/radio/getRadioLists.js +38 -38
  31. package/module/apis/rank/getTopLists.js +44 -44
  32. package/module/apis/search/getHotKey.js +35 -35
  33. package/module/apis/search/getSearchByKey.js +45 -45
  34. package/module/apis/search/getSmartbox.js +34 -34
  35. package/module/apis/singers/getSimilarSinger.js +36 -36
  36. package/module/apis/singers/getSingerDesc.js +38 -38
  37. package/module/apis/singers/getSingerMv.js +35 -35
  38. package/module/apis/singers/getSingerStarNum.js +36 -36
  39. package/module/apis/songLists/songListCategories.js +33 -33
  40. package/module/apis/songLists/songListDetail.js +38 -38
  41. package/module/apis/songLists/songLists.js +41 -41
  42. package/module/apis/u_common.js +17 -16
  43. package/module/apis/user/checkQQLoginQr.js +125 -86
  44. package/module/apis/user/getQQLoginQr.js +17 -11
  45. package/module/apis/y_common.js +27 -14
  46. package/module/config.js +31 -31
  47. package/module/index.js +82 -82
  48. package/package.json +72 -83
  49. package/public/index.html +47 -47
  50. package/routers/context/batchGetSongInfo.js +59 -59
  51. package/routers/context/batchGetSongLists.js +50 -50
  52. package/routers/context/checkQQLoginQr.js +17 -15
  53. package/routers/context/cookies.js +36 -36
  54. package/routers/context/getAlbumInfo.js +27 -27
  55. package/routers/context/getComments.js +51 -51
  56. package/routers/context/getDigitalAlbumLists.js +14 -14
  57. package/routers/context/getDownloadQQMusic.js +14 -14
  58. package/routers/context/getHotkey.js +14 -14
  59. package/routers/context/getImageUrl.js +34 -34
  60. package/routers/context/getLyric.js +26 -26
  61. package/routers/context/getMusicPlay.js +116 -112
  62. package/routers/context/getMv.js +56 -56
  63. package/routers/context/getMvByTag.js +15 -15
  64. package/routers/context/getMvPlay.js +128 -118
  65. package/routers/context/getNewDisks.js +50 -51
  66. package/routers/context/getQQLoginQr.js +12 -12
  67. package/routers/context/getRadioLists.js +14 -14
  68. package/routers/context/getRanks.js +90 -86
  69. package/routers/context/getRecommend.js +86 -86
  70. package/routers/context/getSearchByKey.js +32 -32
  71. package/routers/context/getSimilarSinger.js +25 -25
  72. package/routers/context/getSingerAlbum.js +52 -52
  73. package/routers/context/getSingerDesc.js +25 -25
  74. package/routers/context/getSingerHotsong.js +52 -52
  75. package/routers/context/getSingerList.js +51 -52
  76. package/routers/context/getSingerMv.js +32 -32
  77. package/routers/context/getSingerStarNum.js +24 -24
  78. package/routers/context/getSmartbox.js +24 -24
  79. package/routers/context/getSongInfo.js +49 -49
  80. package/routers/context/getSongListCategories.js +22 -22
  81. package/routers/context/getSongListDetail.js +25 -25
  82. package/routers/context/getSongLists.js +32 -32
  83. package/routers/context/getTicketInfo.js +45 -45
  84. package/routers/context/getTopLists.js +15 -15
  85. package/routers/context/index.js +74 -74
  86. package/routers/router.js +116 -112
  87. package/scripts/build-images.js +36 -36
  88. package/scripts/commit-push.sh +103 -103
  89. package/util/colors.js +16 -16
  90. package/util/cookie.js +22 -22
  91. package/util/loginUtils.js +28 -23
  92. package/util/lyricParse.js +64 -64
  93. package/util/request.js +57 -57
  94. package/vercel.json +15 -15
@@ -1,36 +1,36 @@
1
- const moment = require('moment');
2
- const y_common = require('../y_common');
3
-
4
- module.exports = ({ method = 'get', params = {}, option = {} }) => {
5
- const data = Object.assign(params, {
6
- format: 'json',
7
- outCharset: 'utf-8',
8
- utf8: 1,
9
- rnd: moment().valueOf(),
10
- });
11
- const options = Object.assign(option, {
12
- params: data,
13
- });
14
- return y_common({
15
- url: '/rsc/fcgi-bin/fcg_order_singer_getnum.fcg',
16
- method,
17
- options,
18
- })
19
- .then(res => {
20
- const response = res.data;
21
- return {
22
- status: 200,
23
- body: {
24
- response,
25
- },
26
- };
27
- })
28
- .catch(error => {
29
- console.log('error', error);
30
- return {
31
- body: {
32
- error,
33
- },
34
- };
35
- });
36
- };
1
+ const dayjs = require('dayjs');
2
+ const y_common = require('../y_common');
3
+
4
+ module.exports = ({ method = 'get', params = {}, option = {} }) => {
5
+ const data = Object.assign(params, {
6
+ format: 'json',
7
+ outCharset: 'utf-8',
8
+ utf8: 1,
9
+ rnd: dayjs().valueOf(),
10
+ });
11
+ const options = Object.assign(option, {
12
+ params: data,
13
+ });
14
+ return y_common({
15
+ url: '/rsc/fcgi-bin/fcg_order_singer_getnum.fcg',
16
+ method,
17
+ options,
18
+ })
19
+ .then(res => {
20
+ const response = res.data;
21
+ return {
22
+ status: 200,
23
+ body: {
24
+ response,
25
+ },
26
+ };
27
+ })
28
+ .catch(error => {
29
+ console.log('error', error);
30
+ return {
31
+ body: {
32
+ error,
33
+ },
34
+ };
35
+ });
36
+ };
@@ -1,33 +1,33 @@
1
- const y_common = require('../y_common');
2
-
3
- module.exports = ({ method = 'get', params = {}, option = {} }) => {
4
- const data = Object.assign(params, {
5
- format: 'json',
6
- outCharset: 'utf-8',
7
- });
8
- const options = Object.assign(option, {
9
- params: data,
10
- });
11
- return y_common({
12
- url: '/splcloud/fcgi-bin/fcg_get_diss_tag_conf.fcg',
13
- method,
14
- options,
15
- })
16
- .then(res => {
17
- const response = res.data;
18
- return {
19
- status: 200,
20
- body: {
21
- response,
22
- },
23
- };
24
- })
25
- .catch(error => {
26
- console.log('error', error);
27
- return {
28
- body: {
29
- error,
30
- },
31
- };
32
- });
33
- };
1
+ const y_common = require('../y_common');
2
+
3
+ module.exports = ({ method = 'get', params = {}, option = {} }) => {
4
+ const data = Object.assign(params, {
5
+ format: 'json',
6
+ outCharset: 'utf-8',
7
+ });
8
+ const options = Object.assign(option, {
9
+ params: data,
10
+ });
11
+ return y_common({
12
+ url: '/splcloud/fcgi-bin/fcg_get_diss_tag_conf.fcg',
13
+ method,
14
+ options,
15
+ })
16
+ .then(res => {
17
+ const response = res.data;
18
+ return {
19
+ status: 200,
20
+ body: {
21
+ response,
22
+ },
23
+ };
24
+ })
25
+ .catch(error => {
26
+ console.log('error', error);
27
+ return {
28
+ body: {
29
+ error,
30
+ },
31
+ };
32
+ });
33
+ };
@@ -1,38 +1,38 @@
1
- const y_common = require('../y_common');
2
-
3
- module.exports = ({ method = 'get', params = {}, option = {} }) => {
4
- const data = Object.assign(params, {
5
- format: 'json',
6
- outCharset: 'utf-8',
7
- type: 1,
8
- json: 1,
9
- utf8: 1,
10
- onlysong: 0,
11
- new_format: 1,
12
- });
13
- const options = Object.assign(option, {
14
- params: data,
15
- });
16
- return y_common({
17
- url: '/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg',
18
- method,
19
- options,
20
- })
21
- .then(res => {
22
- const response = res.data;
23
- return {
24
- status: 200,
25
- body: {
26
- response,
27
- },
28
- };
29
- })
30
- .catch(error => {
31
- console.log('error', error);
32
- return {
33
- body: {
34
- error,
35
- },
36
- };
37
- });
38
- };
1
+ const y_common = require('../y_common');
2
+
3
+ module.exports = ({ method = 'get', params = {}, option = {} }) => {
4
+ const data = Object.assign(params, {
5
+ format: 'json',
6
+ outCharset: 'utf-8',
7
+ type: 1,
8
+ json: 1,
9
+ utf8: 1,
10
+ onlysong: 0,
11
+ new_format: 1,
12
+ });
13
+ const options = Object.assign(option, {
14
+ params: data,
15
+ });
16
+ return y_common({
17
+ url: '/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg',
18
+ method,
19
+ options,
20
+ })
21
+ .then(res => {
22
+ const response = res.data;
23
+ return {
24
+ status: 200,
25
+ body: {
26
+ response,
27
+ },
28
+ };
29
+ })
30
+ .catch(error => {
31
+ console.log('error', error);
32
+ return {
33
+ body: {
34
+ error,
35
+ },
36
+ };
37
+ });
38
+ };
@@ -1,41 +1,41 @@
1
- const y_common = require('../y_common');
2
-
3
- module.exports = ({ method = 'get', params = {}, option = {} }) => {
4
- const data = Object.assign(params, {
5
- format: 'json',
6
- outCharset: 'utf-8',
7
- picmid: 1,
8
- });
9
- const options = Object.assign(option, {
10
- params: data,
11
- });
12
- return y_common({
13
- url: '/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg',
14
- method,
15
- options,
16
- })
17
- .then(res => {
18
- const response = res.data;
19
- if (typeof response === 'string') {
20
- const reg = /^\w+\(({[^()]+})\)$/;
21
- const matches = response.match(reg);
22
- if (matches) {
23
- response = JSON.parse(matches[1]);
24
- }
25
- }
26
- return {
27
- status: 200,
28
- body: {
29
- response,
30
- },
31
- };
32
- })
33
- .catch(error => {
34
- console.log('error', error);
35
- return {
36
- body: {
37
- error,
38
- },
39
- };
40
- });
41
- };
1
+ const y_common = require('../y_common');
2
+
3
+ module.exports = ({ method = 'get', params = {}, option = {} }) => {
4
+ const data = Object.assign(params, {
5
+ format: 'json',
6
+ outCharset: 'utf-8',
7
+ picmid: 1,
8
+ });
9
+ const options = Object.assign(option, {
10
+ params: data,
11
+ });
12
+ return y_common({
13
+ url: '/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg',
14
+ method,
15
+ options,
16
+ })
17
+ .then(res => {
18
+ let response = res.data;
19
+ if (typeof response === 'string') {
20
+ const reg = /^\w+\(({[^()]+})\)$/;
21
+ const matches = response.match(reg);
22
+ if (matches) {
23
+ response = JSON.parse(matches[1]);
24
+ }
25
+ }
26
+ return {
27
+ status: 200,
28
+ body: {
29
+ response,
30
+ },
31
+ };
32
+ })
33
+ .catch(error => {
34
+ console.log('error', error);
35
+ return {
36
+ body: {
37
+ error,
38
+ },
39
+ };
40
+ });
41
+ };
@@ -1,16 +1,17 @@
1
- const request = require('../../util/request');
2
- const config = require('../config');
3
- const userInfoConfig = require('../../config/user-info');
4
-
5
- module.exports = ({ options = {}, method = 'get' }) => {
6
- let opts = Object.assign(options, config.commonParams, {
7
- headers: {
8
- referer: 'https://y.qq.com/portal/player.html',
9
- host: 'u.y.qq.com',
10
- 'content-type': 'application/x-www-form-urlencoded',
11
- 'cookie': userInfoConfig.cookie,
12
- },
13
- });
14
- console.log('https://u.y.qq.com/cgi-bin/musicu.fcg', { opts })
15
- return request('https://u.y.qq.com/cgi-bin/musicu.fcg', method, opts, 'u');
16
- };
1
+ const request = require('../../util/request');
2
+ const config = require('../config');
3
+ const userInfoConfig = require('../../config/user-info');
4
+
5
+ module.exports = ({ options = {}, method = 'get' }) => {
6
+ const opts = Object.assign(options, config.commonParams, {
7
+ headers: {
8
+ referer: 'https://y.qq.com/portal/player.html',
9
+ host: 'u.y.qq.com',
10
+ 'content-type': 'application/x-www-form-urlencoded',
11
+ cookie: userInfoConfig.cookie,
12
+ },
13
+ });
14
+ const logOpts = { ...opts, headers: { ...opts.headers, cookie: '[REDACTED]' } };
15
+ console.log('https://u.y.qq.com/cgi-bin/musicu.fcg', { opts: logOpts });
16
+ return request('https://u.y.qq.com/cgi-bin/musicu.fcg', method, opts, 'u');
17
+ };
@@ -1,86 +1,125 @@
1
- const { getGtk, getGuid } = require('../../../util/loginUtils');
2
- const { refreshData } = require('../../../config/user-info');
3
-
4
- module.exports = async ({ method = 'get', params = {}, option = {} }) => {
5
- const { ptqrtoken, qrsig } = params;
6
- if (!ptqrtoken || !qrsig) return { body: '参数错误' };
7
- const url = `https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fgraph.qq.com%2Foauth2.0%2Flogin_jump&ptqrtoken=${ptqrtoken}&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1711022193435&js_ver=23111510&js_type=1&login_sig=du-YS1h8*0GqVqcrru0pXkpwVg2DYw-DtbFulJ62IgPf6vfiJe*4ONVrYc5hMUNE&pt_uistyle=40&aid=716027609&daid=383&pt_3rd_aid=100497308&&o1vId=3674fc47871e9c407d8838690b355408&pt_js_version=v1.48.1`;
8
- const response = await fetch(url, { headers: { Cookie: `qrsig=${qrsig}` }});
9
- const { data = '' } = await response.text();
10
- let allCookie = [];
11
- const setCookie = cookies => {
12
- allCookie = [...allCookie, ...cookies.map(i => i.split(';')[0]).filter(i => i.split('=')[1])];
13
- };
14
- const refresh = data.includes('已失效')
15
- if (!data.includes('登录成功')) return { status: 200, isOk: false, refresh, message: refresh && '二维码已失效' || '未扫描二维码' };
16
-
17
- // 获取p_skey 与gtk
18
- const checkSigUrl = data.match(/(?:'((?:https?|ftp):\/\/[^\s/$.?#].[^\s]*)')/g)[0].replaceAll('\'', '');
19
- const checkSigRes = await fetch(checkSigUrl, { redirect: 'manual', headers: { Cookie: allCookie.join('; ') } });
20
- const p_skey = checkSigRes.headers.get('Set-Cookie').match(/p_skey=([^;]+)/)[1];
21
- const gtk = getGtk(p_skey);
22
- setCookie(checkSigRes.headers.get('Set-Cookie').split(';, '));
23
-
24
- // authorize
25
- const authorizeUrl = 'https://graph.qq.com/oauth2.0/authorize';
26
- const getAuthorizeData = (gtk) => {
27
- let data = new FormData()
28
- data.append('response_type', 'code')
29
- data.append('client_id', 100497308)
30
- data.append('redirect_uri', 'https://y.qq.com/portal/wx_redirect.html?login_type=1&surl=https://y.qq.com/')
31
- data.append('scope', 'get_user_info,get_app_friends')
32
- data.append('state', 'state')
33
- data.append('switch', '')
34
- data.append('from_ptlogin', 1)
35
- data.append('src', 1)
36
- data.append('update_auth', 1)
37
- data.append('openapi', '1010_1030')
38
- data.append('g_tk', gtk)
39
- data.append('auth_time', new Date)
40
- data.append('ui', getGuid())
41
- return data
42
- };
43
-
44
- const authorizeRes = await fetch(authorizeUrl, {
45
- redirect: 'manual',
46
- method: 'POST',
47
- body: getAuthorizeData(gtk),
48
- headers: {
49
- Cookie: allCookie.join('; ')
50
- }
51
- });
52
- const code = authorizeRes.headers.get('Location').match(/[?&]code=([^&]+)/)[1];
53
-
54
- // login
55
- const getFcgReqData = (g_tk, code) => {
56
- const data = {
57
- comm: {
58
- "g_tk":g_tk,
59
- "platform":"yqq",
60
- "ct":24,
61
- "cv":0
62
- }, req: {
63
- "module":"QQConnectLogin.LoginServer",
64
- "method":"QQLogin",
65
- "param": {
66
- "code":code
67
- }
68
- }
69
- }
70
- return JSON.stringify(data)
71
- };
72
-
73
- const loginUrl = 'https://u.y.qq.com/cgi-bin/musicu.fcg';
74
- const loginRes = await fetch(loginUrl, {
75
- method: 'POST',
76
- body: getFcgReqData(gtk, code),
77
- headers: {
78
- 'Content-Type': 'application/x-www-form-urlencoded',
79
- Cookie: allCookie.join('; ')
80
- }
81
- });
82
- setCookie(loginRes.headers.get('Set-Cookie').split(';, '));
83
- global.userInfo = { ...refreshData(allCookie.join('; ')) }
84
-
85
- return { status: 200, isOk: true, message: '登录成功' };
86
- };
1
+ const { getGtk, getGuid } = require('../../../util/loginUtils');
2
+ const { refreshData } = require('../../../config/user-info');
3
+
4
+ const parseSetCookie = setCookieHeader => {
5
+ if (!setCookieHeader) return [];
6
+ const cookies = [];
7
+ const parts = setCookieHeader.split(/,(?=\s*[a-zA-Z_]+=)/);
8
+ for (const part of parts) {
9
+ const cookiePair = part.split(';')[0].trim();
10
+ if (cookiePair && cookiePair.includes('=') && cookiePair.split('=')[1]) {
11
+ cookies.push(cookiePair);
12
+ }
13
+ }
14
+ return cookies;
15
+ };
16
+
17
+ module.exports = async ({ method = 'get', params = {}, option = {} }) => {
18
+ const { ptqrtoken, qrsig } = params;
19
+ if (!ptqrtoken || !qrsig) return { body: '参数错误' };
20
+ const url = `https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fgraph.qq.com%2Foauth2.0%2Flogin_jump&ptqrtoken=${ptqrtoken}&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1711022193435&js_ver=23111510&js_type=1&login_sig=du-YS1h8*0GqVqcrru0pXkpwVg2DYw-DtbFulJ62IgPf6vfiJe*4ONVrYc5hMUNE&pt_uistyle=40&aid=716027609&daid=383&pt_3rd_aid=100497308&&o1vId=3674fc47871e9c407d8838690b355408&pt_js_version=v1.48.1`;
21
+ const response = await fetch(url, { headers: { Cookie: `qrsig=${qrsig}` } });
22
+ const data = await response.text() || '';
23
+
24
+ const cookieMap = new Map();
25
+ const setCookie = setCookieHeader => {
26
+ const cookies = parseSetCookie(setCookieHeader);
27
+ for (const cookie of cookies) {
28
+ const [name] = cookie.split('=');
29
+ cookieMap.set(name, cookie);
30
+ }
31
+ };
32
+
33
+ setCookie(response.headers.get('Set-Cookie'));
34
+
35
+ const refresh = data.includes('已失效');
36
+ if (!data.includes('登录成功'))
37
+ return { status: 200, isOk: false, refresh, message: (refresh && '二维码已失效') || '未扫描二维码' };
38
+
39
+ const allCookie = () => Array.from(cookieMap.values());
40
+
41
+ const urlMatch = data.match(/(?:'((?:https?|ftp):\/\/[^\s/$.?#].[^\s]*)')/g);
42
+ if (!urlMatch || !urlMatch[0]) {
43
+ return { status: 502, body: { error: 'Failed to extract checkSigUrl from response' } };
44
+ }
45
+ const checkSigUrl = urlMatch[0].replaceAll("'", '');
46
+ const checkSigRes = await fetch(checkSigUrl, { redirect: 'manual', headers: { Cookie: allCookie().join('; ') } });
47
+
48
+ const checkSigCookie = checkSigRes.headers.get('Set-Cookie');
49
+ const pSkeyMatch = checkSigCookie?.match(/p_skey=([^;]+)/);
50
+ if (!pSkeyMatch || !pSkeyMatch[1]) {
51
+ return { status: 502, body: { error: 'Failed to extract p_skey from response' } };
52
+ }
53
+ const p_skey = pSkeyMatch[1];
54
+ const gtk = getGtk(p_skey);
55
+ setCookie(checkSigCookie);
56
+
57
+ const authorizeUrl = 'https://graph.qq.com/oauth2.0/authorize';
58
+ const getAuthorizeData = gtk => {
59
+ const data = new FormData();
60
+ data.append('response_type', 'code');
61
+ data.append('client_id', 100497308);
62
+ data.append('redirect_uri', 'https://y.qq.com/portal/wx_redirect.html?login_type=1&surl=https://y.qq.com/');
63
+ data.append('scope', 'get_user_info,get_app_friends');
64
+ data.append('state', 'state');
65
+ data.append('switch', '');
66
+ data.append('from_ptlogin', 1);
67
+ data.append('src', 1);
68
+ data.append('update_auth', 1);
69
+ data.append('openapi', '1010_1030');
70
+ data.append('g_tk', gtk);
71
+ data.append('auth_time', new Date());
72
+ data.append('ui', getGuid());
73
+ return data;
74
+ };
75
+
76
+ const authorizeRes = await fetch(authorizeUrl, {
77
+ redirect: 'manual',
78
+ method: 'POST',
79
+ body: getAuthorizeData(gtk),
80
+ headers: {
81
+ Cookie: allCookie().join('; '),
82
+ },
83
+ });
84
+ setCookie(authorizeRes.headers.get('Set-Cookie'));
85
+
86
+ const location = authorizeRes.headers.get('Location');
87
+ const codeMatch = location?.match(/[?&]code=([^&]+)/);
88
+ if (!codeMatch || !codeMatch[1]) {
89
+ return { status: 502, body: { error: 'Failed to extract code from authorize response' } };
90
+ }
91
+ const code = codeMatch[1];
92
+
93
+ const getFcgReqData = (g_tk, code) => {
94
+ const data = {
95
+ comm: {
96
+ g_tk,
97
+ platform: 'yqq',
98
+ ct: 24,
99
+ cv: 0,
100
+ },
101
+ req: {
102
+ module: 'QQConnectLogin.LoginServer',
103
+ method: 'QQLogin',
104
+ param: {
105
+ code,
106
+ },
107
+ },
108
+ };
109
+ return JSON.stringify(data);
110
+ };
111
+
112
+ const loginUrl = 'https://u.y.qq.com/cgi-bin/musicu.fcg';
113
+ const loginRes = await fetch(loginUrl, {
114
+ method: 'POST',
115
+ body: getFcgReqData(gtk, code),
116
+ headers: {
117
+ 'Content-Type': 'application/x-www-form-urlencoded',
118
+ Cookie: allCookie().join('; '),
119
+ },
120
+ });
121
+ setCookie(loginRes.headers.get('Set-Cookie'));
122
+ global.userInfo = { ...refreshData(allCookie().join('; ')) };
123
+
124
+ return { status: 200, isOk: true, message: '登录成功' };
125
+ };
@@ -1,11 +1,17 @@
1
- const { hash33 } = require('../../../util/loginUtils');
2
-
3
- module.exports = async ({ method = 'get', params = {}, option = {} }) => {
4
- const url = 'https://ssl.ptlogin2.qq.com/ptqrshow?appid=716027609&e=2&l=M&s=3&d=72&v=4&t=0.9698127522807933&daid=383&pt_3rd_aid=100497308&u1=https%3A%2F%2Fgraph.qq.com%2Foauth2.0%2Flogin_jump';
5
- const response = await fetch(url, { responseType: 'arraybuffer' });
6
- const data = await response.arrayBuffer();
7
- const img = "data:image/png;base64," + (data && Buffer.from(data).toString('base64'));
8
- const qrsig = response.headers.get('Set-Cookie')?.match(/qrsig=([^;]+)/)[1];
9
-
10
- return {status: 200, body: { img, ptqrtoken: hash33(qrsig), qrsig } };
11
- };
1
+ const { hash33 } = require('../../../util/loginUtils');
2
+
3
+ module.exports = async ({ method = 'get', params = {}, option = {} }) => {
4
+ const url =
5
+ 'https://ssl.ptlogin2.qq.com/ptqrshow?appid=716027609&e=2&l=M&s=3&d=72&v=4&t=0.9698127522807933&daid=383&pt_3rd_aid=100497308&u1=https%3A%2F%2Fgraph.qq.com%2Foauth2.0%2Flogin_jump';
6
+ const response = await fetch(url, { responseType: 'arraybuffer' });
7
+ const data = await response.arrayBuffer();
8
+ const img = 'data:image/png;base64,' + (data && Buffer.from(data).toString('base64'));
9
+ const cookieHeader = response.headers.get('Set-Cookie');
10
+ const match = cookieHeader?.match(/qrsig=([^;]+)/);
11
+ if (!match) {
12
+ return { status: 502, body: { error: 'Failed to get qrsig from response' } };
13
+ }
14
+ const qrsig = match[1];
15
+
16
+ return { status: 200, body: { img, ptqrtoken: hash33(qrsig), qrsig } };
17
+ };
@@ -1,14 +1,27 @@
1
- const request = require('../../util/request');
2
- const config = require('../config');
3
-
4
- module.exports = ({ url, method = 'get', options = {}, hasCommonParams = true }) => {
5
- let commonParams = hasCommonParams ? config.commonParams : {};
6
- let opts = Object.assign(options, commonParams, {
7
- headers: {
8
- referer: 'https://c.y.qq.com/',
9
- host: 'c.y.qq.com',
10
- },
11
- });
12
- console.log(url, {opts})
13
- return request(url, method, opts);
14
- };
1
+ const request = require('../../util/request');
2
+ const config = require('../config');
3
+
4
+ module.exports = ({ url, method = 'get', options = {}, hasCommonParams = true }) => {
5
+ const commonParams = hasCommonParams ? config.commonParams : {};
6
+ const opts = Object.assign(options, commonParams, {
7
+ headers: {
8
+ referer: 'https://c.y.qq.com/',
9
+ host: 'c.y.qq.com',
10
+ },
11
+ });
12
+ if (process.env.DEBUG === 'true') {
13
+ const logOpts = { ...opts, headers: { ...opts.headers } };
14
+ const SENSITIVE_HEADER_KEYS = ['cookie', 'authorization', 'proxy-authorization'];
15
+
16
+ if (logOpts.headers) {
17
+ Object.keys(logOpts.headers).forEach(key => {
18
+ if (SENSITIVE_HEADER_KEYS.includes(key.toLowerCase())) {
19
+ logOpts.headers[key] = '[masked]';
20
+ }
21
+ });
22
+ }
23
+
24
+ console.log(url, { opts: logOpts });
25
+ }
26
+ return request(url, method, opts);
27
+ };