yz-yuki-plugin 2.0.4-3 → 2.0.4-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/CHANGELOG.md +1 -0
- package/lib/components/dynamic/Account.js +1 -2
- package/lib/components/dynamic/Content.js +1 -2
- package/lib/components/dynamic/Footer.js +1 -2
- package/lib/components/dynamic/ForwardContent.js +1 -2
- package/lib/models/bilibili/bilibili.get.web.data.js +4 -1
- package/lib/models/bilibili/bilibili.models.d.ts +6 -0
- package/lib/models/bilibili/bilibili.models.js +43 -16
- package/lib/models/bilibili/bilibili.ticket.d.ts +12 -0
- package/lib/models/bilibili/bilibili.ticket.js +59 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -34,6 +34,5 @@ const Footer = ({ data }) => {
|
|
|
34
34
|
React.createElement("span", { className: "italic" }, yukiPluginVersion))),
|
|
35
35
|
React.createElement("img", { src: data.urlImgData, alt: "\u4E8C\u7EF4\u7801", className: "qr-code" }))));
|
|
36
36
|
};
|
|
37
|
-
var Footer$1 = Footer;
|
|
38
37
|
|
|
39
|
-
export { Footer
|
|
38
|
+
export { Footer as default };
|
|
@@ -13,6 +13,5 @@ const ForwardContent = ({ data }) => (React.createElement(React.Fragment, null,
|
|
|
13
13
|
React.createElement("div", { className: "orig-container", id: "orig-container" },
|
|
14
14
|
React.createElement(Account, { data: data }),
|
|
15
15
|
React.createElement(Content, { data: data })))));
|
|
16
|
-
var ForwardContent$1 = ForwardContent;
|
|
17
16
|
|
|
18
|
-
export { ForwardContent
|
|
17
|
+
export { ForwardContent as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import lodash from 'lodash';
|
|
3
3
|
import { BiliApi } from './bilibili.api.js';
|
|
4
|
-
import { readSyncCookie, readSavedCookieItems, readSavedCookieOtherItems } from './bilibili.models.js';
|
|
4
|
+
import { readSyncCookie, cookieWithBiliTicket, readSavedCookieItems, readSavedCookieOtherItems } from './bilibili.models.js';
|
|
5
5
|
import { getWbiSign } from './bilibili.wbi.js';
|
|
6
6
|
|
|
7
7
|
class BiliGetWebData {
|
|
@@ -11,6 +11,7 @@ class BiliGetWebData {
|
|
|
11
11
|
async getBiliDynamicListDataByUid(uid) {
|
|
12
12
|
const url = BiliApi.BILIBIL_API.biliDynamicInfoList;
|
|
13
13
|
let { cookie } = await readSyncCookie();
|
|
14
|
+
cookie = await cookieWithBiliTicket(cookie);
|
|
14
15
|
const data = {
|
|
15
16
|
offset: '',
|
|
16
17
|
host_mid: uid,
|
|
@@ -40,6 +41,7 @@ class BiliGetWebData {
|
|
|
40
41
|
async getBilibiUserInfoByUid(uid) {
|
|
41
42
|
const url = BiliApi.BILIBIL_API.biliSpaceUserInfoWbi;
|
|
42
43
|
let { cookie } = await readSyncCookie();
|
|
44
|
+
cookie = await cookieWithBiliTicket(cookie);
|
|
43
45
|
const data = {
|
|
44
46
|
mid: uid,
|
|
45
47
|
jsonp: 'jsonp',
|
|
@@ -62,6 +64,7 @@ class BiliGetWebData {
|
|
|
62
64
|
async searchBiliUserInfoByKeyword(keyword) {
|
|
63
65
|
const url = BiliApi.BILIBIL_API.biliSearchUpWbi;
|
|
64
66
|
let { cookie } = await readSyncCookie();
|
|
67
|
+
cookie = await cookieWithBiliTicket(cookie);
|
|
65
68
|
const data = {
|
|
66
69
|
keyword: keyword,
|
|
67
70
|
page: 1,
|
|
@@ -55,3 +55,9 @@ export declare function postGateway(cookie: string): Promise<import("axios").Axi
|
|
|
55
55
|
* @param {string} uuid
|
|
56
56
|
*/
|
|
57
57
|
export declare function get_buvid_fp(cookie: string): Promise<string>;
|
|
58
|
+
/**
|
|
59
|
+
* 获取有效bili_ticket并添加到cookie
|
|
60
|
+
* @param {string} cookie
|
|
61
|
+
* @returns {Promise<{ cookie: string; }>} 返回包含最新有效的bili_ticket的cookie
|
|
62
|
+
*/
|
|
63
|
+
export declare function cookieWithBiliTicket(cookie: string): Promise<string>;
|
|
@@ -10,6 +10,7 @@ import { Segment, Bot, Redis } from 'yunzai';
|
|
|
10
10
|
import { renderPage } from '../../utils/image.js';
|
|
11
11
|
import { _paths } from '../../utils/paths.js';
|
|
12
12
|
import { BiliApi } from './bilibili.api.js';
|
|
13
|
+
import { getBiliTicket } from './bilibili.ticket.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* *******************************************************************
|
|
@@ -362,11 +363,11 @@ async function getNewTempCk() {
|
|
|
362
363
|
let newTempCk = `${uuid}${buvid3_buvid4}${b_lsid}`; //${buvid_fp}`;
|
|
363
364
|
await saveTempCk(newTempCk);
|
|
364
365
|
const result = await postGateway(newTempCk);
|
|
365
|
-
const
|
|
366
|
-
if (code !== 0) {
|
|
367
|
-
logger?.
|
|
366
|
+
const data = await result.data; // 解析校验结果
|
|
367
|
+
if (data?.code !== 0) {
|
|
368
|
+
logger?.error(`优纪插件:tempCK,Gateway校验失败:${JSON.stringify(data)}`);
|
|
368
369
|
}
|
|
369
|
-
else if (code === 0) {
|
|
370
|
+
else if (data?.code === 0) {
|
|
370
371
|
logger?.mark(`优纪插件:tempCK,Gateway校验成功:${JSON.stringify(data)}`);
|
|
371
372
|
}
|
|
372
373
|
}
|
|
@@ -526,19 +527,20 @@ async function getPayload(cookie) {
|
|
|
526
527
|
* @returns 返回POST请求的结果
|
|
527
528
|
*/
|
|
528
529
|
async function postGateway(cookie) {
|
|
529
|
-
const
|
|
530
|
+
const data = { payload: await getPayload(cookie) };
|
|
530
531
|
const requestUrl = 'https://api.bilibili.com/x/internal/gaia-gateway/ExClimbWuzhi';
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
532
|
+
const config = {
|
|
533
|
+
headers: lodash.merge({}, BiliApi.BILIBILI_HEADERS, {
|
|
534
|
+
'Cookie': cookie,
|
|
535
|
+
'Content-type': 'application/json;charset=UTF-8',
|
|
536
|
+
}, {
|
|
537
|
+
'Host': 'api.bilibili.com',
|
|
538
|
+
'Origin': 'https://www.bilibili.com',
|
|
539
|
+
'Referer': 'https://www.bilibili.com/',
|
|
540
|
+
})
|
|
541
|
+
};
|
|
540
542
|
try {
|
|
541
|
-
const res = await axios.post(requestUrl,
|
|
543
|
+
const res = await axios.post(requestUrl, data, config);
|
|
542
544
|
return res;
|
|
543
545
|
}
|
|
544
546
|
catch (error) {
|
|
@@ -546,5 +548,30 @@ async function postGateway(cookie) {
|
|
|
546
548
|
throw error;
|
|
547
549
|
}
|
|
548
550
|
}
|
|
551
|
+
/**
|
|
552
|
+
* 获取有效bili_ticket并添加到cookie
|
|
553
|
+
* @param {string} cookie
|
|
554
|
+
* @returns {Promise<{ cookie: string; }>} 返回包含最新有效的bili_ticket的cookie
|
|
555
|
+
*/
|
|
556
|
+
async function cookieWithBiliTicket(cookie) {
|
|
557
|
+
const BiliJctKey = "Yz:yuki:bili:bili_ticket";
|
|
558
|
+
cookie = await readSavedCookieItems(cookie, ['bili_ticket'], true);
|
|
559
|
+
const biliTicket = await Redis.get(BiliJctKey);
|
|
560
|
+
if (!biliTicket) {
|
|
561
|
+
try {
|
|
562
|
+
const csrf = await readSavedCookieItems(cookie, ['bili_jct'], false);
|
|
563
|
+
const { ticket, ttl } = await getBiliTicket(csrf);
|
|
564
|
+
await Redis.set(BiliJctKey, ticket, { EX: ttl });
|
|
565
|
+
return cookie + `;bili_ticket=${ticket};`;
|
|
566
|
+
}
|
|
567
|
+
catch (error) {
|
|
568
|
+
logger?.error(`${error}`);
|
|
569
|
+
return cookie;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
return cookie + `;bili_ticket=${biliTicket};`;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
549
576
|
|
|
550
|
-
export { applyLoginQRCode, checkBiliLogin, exitBiliLogin, genUUID, gen_b_lsid, getNewTempCk, pollLoginQRCode, postGateway, readSavedCookieItems, readSavedCookieOtherItems, readSyncCookie, readTempCk, saveLocalBiliCk, saveLoginCookie, saveTempCk };
|
|
577
|
+
export { applyLoginQRCode, checkBiliLogin, cookieWithBiliTicket, exitBiliLogin, genUUID, gen_b_lsid, getNewTempCk, pollLoginQRCode, postGateway, readSavedCookieItems, readSavedCookieOtherItems, readSyncCookie, readTempCk, saveLocalBiliCk, saveLoginCookie, saveTempCk };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get Bilibili web ticket
|
|
3
|
+
* @param {string | null} csrf CSRF token, can be empty or null, or the cookie's bili_jct value
|
|
4
|
+
* @returns {Promise<{ code: number, ticket: string, created_at: number, ttl: number }>}
|
|
5
|
+
* Promise that resolves to an object containing code, ticket, created_at, and ttl values
|
|
6
|
+
*/
|
|
7
|
+
export declare function getBiliTicket(csrf: string | null): Promise<{
|
|
8
|
+
code?: number;
|
|
9
|
+
ticket?: string;
|
|
10
|
+
created_at?: number;
|
|
11
|
+
ttl?: number;
|
|
12
|
+
}>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createHmac } from 'crypto';
|
|
2
|
+
import { BiliApi } from './bilibili.api.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generate HMAC-SHA256 signature
|
|
6
|
+
* @param {string} key The key string to use for the HMAC-SHA256 hash
|
|
7
|
+
* @param {string} message The message string to hash
|
|
8
|
+
* @returns {string} The HMAC-SHA256 signature as a hex string
|
|
9
|
+
*/
|
|
10
|
+
function hmacSha256(key, message) {
|
|
11
|
+
return createHmac('sha256', key).update(message).digest('hex');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get Bilibili web ticket
|
|
15
|
+
* @param {string | null} csrf CSRF token, can be empty or null, or the cookie's bili_jct value
|
|
16
|
+
* @returns {Promise<{ code: number, ticket: string, created_at: number, ttl: number }>}
|
|
17
|
+
* Promise that resolves to an object containing code, ticket, created_at, and ttl values
|
|
18
|
+
*/
|
|
19
|
+
async function getBiliTicket(csrf) {
|
|
20
|
+
const ts = Math.floor(Date.now() / 1000);
|
|
21
|
+
const hexSign = hmacSha256('XgwSnGZ1p', `ts${ts}`);
|
|
22
|
+
const url = 'https://api.bilibili.com/bapis/bilibili.api.ticket.v1.Ticket/GenWebTicket';
|
|
23
|
+
const params = new URLSearchParams({
|
|
24
|
+
key_id: 'ec02',
|
|
25
|
+
hexsign: hexSign,
|
|
26
|
+
'context[ts]': String(ts),
|
|
27
|
+
csrf: csrf ?? '' // 使用空字符串代替null
|
|
28
|
+
});
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch(`${url}?${params}`, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
'User-Agent': BiliApi.BILIBILI_HEADERS['User-Agent']
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new Error(`get bili_jct HTTP error! status: ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
const data = await response.json();
|
|
40
|
+
if (data.code !== 0) {
|
|
41
|
+
if (data.code === 400) {
|
|
42
|
+
throw new Error(`get bili_jct Parameter error! ${data.message}`);
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Failed to retrieve bili ticket: ${data.message}`);
|
|
45
|
+
}
|
|
46
|
+
// 返回所需的对象结构
|
|
47
|
+
return {
|
|
48
|
+
code: data.code,
|
|
49
|
+
ticket: data.data?.ticket,
|
|
50
|
+
created_at: data.data?.created_at,
|
|
51
|
+
ttl: data.data?.ttl
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw new Error(`Failed to fetch Bilibili ticket: ${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { getBiliTicket };
|