mirror of
https://github.com/anidl/multi-downloader-nx.git
synced 2026-04-21 08:21:56 +00:00
added automatic crunchyroll production basic token fetch
This commit is contained in:
parent
f76de18930
commit
81429bbea5
4 changed files with 4218 additions and 3389 deletions
31
crunchy.ts
31
crunchy.ts
|
|
@ -229,6 +229,26 @@ export default class Crunchy implements ServiceClass {
|
|||
console.info('All required fonts downloaded!');
|
||||
}
|
||||
|
||||
private async productionToken() {
|
||||
const tokenReq = await this.req.getData(api.bundlejs);
|
||||
|
||||
if (!tokenReq.ok || !tokenReq.res) {
|
||||
console.error('Failed to get Production Token!');
|
||||
return { isOk: false, reason: new Error('Failed to get Production Token') };
|
||||
}
|
||||
|
||||
const rawjs = await tokenReq.res.text();
|
||||
|
||||
const tokens = rawjs.match(/prod="([\w-]+:[\w-]+)"/);
|
||||
|
||||
if (!tokens) {
|
||||
console.error('Failed to find Production Token in js!');
|
||||
return { isOk: false, reason: new Error('Failed to find Production Token in js') };
|
||||
}
|
||||
|
||||
return Buffer.from(tokens[1], 'latin1').toString('base64');
|
||||
}
|
||||
|
||||
public async doAuth(data: AuthData): Promise<AuthResponse> {
|
||||
const uuid = randomUUID();
|
||||
const authData = new URLSearchParams({
|
||||
|
|
@ -242,7 +262,7 @@ export default class Crunchy implements ServiceClass {
|
|||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
method: 'POST',
|
||||
headers: api.crunchyAuthHeaderMob,
|
||||
headers: {...api.crunchyAuthHeader, Authorization: `Basic ${await this.productionToken()}`},
|
||||
body: authData
|
||||
};
|
||||
const authReq = await this.req.getData(api.beta_auth, authReqOpts);
|
||||
|
|
@ -270,7 +290,7 @@ export default class Crunchy implements ServiceClass {
|
|||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
method: 'POST',
|
||||
headers: api.crunchyAuthHeaderMob,
|
||||
headers: {...api.crunchyAuthHeader, Authorization: `Basic ${await this.productionToken()}`},
|
||||
body: authData
|
||||
};
|
||||
const authReq = await this.req.getData(api.beta_auth, authReqOpts);
|
||||
|
|
@ -327,7 +347,7 @@ export default class Crunchy implements ServiceClass {
|
|||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
method: 'POST',
|
||||
headers: {...api.crunchyAuthHeaderMob, Cookie: `etp_rt=${refreshToken}`},
|
||||
headers: {...api.crunchyAuthHeader, Authorization: `Basic ${await this.productionToken()}`, Cookie: `etp_rt=${refreshToken}`},
|
||||
body: authData
|
||||
};
|
||||
const authReq = await this.req.getData(api.beta_auth, authReqOpts);
|
||||
|
|
@ -365,11 +385,12 @@ export default class Crunchy implements ServiceClass {
|
|||
//'grant_type': 'etp_rt_cookie',
|
||||
'scope': 'offline_access',
|
||||
'device_id': uuid,
|
||||
'device_type': 'Chrome on Windows'
|
||||
'device_name': 'iPhone',
|
||||
'device_type': 'iPhone 13'
|
||||
}).toString();
|
||||
const authReqOpts: reqModule.Params = {
|
||||
method: 'POST',
|
||||
headers: {...api.crunchyAuthHeaderMob, Cookie: `etp_rt=${this.token.refresh_token}`},
|
||||
headers: {...api.crunchyAuthHeader, Authorization: `Basic ${await this.productionToken()}`, Cookie: `etp_rt=${this.token.refresh_token}`},
|
||||
body: authData
|
||||
};
|
||||
const authReq = await this.req.getData(api.beta_auth, authReqOpts);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const domain = {
|
|||
};
|
||||
|
||||
export type APIType = {
|
||||
bundlejs: string,
|
||||
newani: string,
|
||||
search1: string,
|
||||
search2: string,
|
||||
|
|
@ -25,10 +26,6 @@ export type APIType = {
|
|||
// beta api
|
||||
beta_auth: string
|
||||
defaultUserAgent: string,
|
||||
authBasic: string
|
||||
authBasicMob: string
|
||||
authBasicIOS: string
|
||||
authBasicSwitch: string,
|
||||
beta_profile: string
|
||||
beta_cmsToken: string
|
||||
search: string
|
||||
|
|
@ -37,17 +34,9 @@ export type APIType = {
|
|||
beta_cms: string,
|
||||
drm: string;
|
||||
/**
|
||||
* Web Header
|
||||
* Header
|
||||
*/
|
||||
crunchyAuthHeader: Record<string, string>,
|
||||
/**
|
||||
* Mobile Header
|
||||
*/
|
||||
crunchyAuthHeaderMob: Record<string, string>,
|
||||
/**
|
||||
* Switch Header
|
||||
*/
|
||||
crunchyAuthHeaderSwitch: Record<string, string>,
|
||||
hd_apikey: string,
|
||||
hd_devName: string,
|
||||
hd_appId: string,
|
||||
|
|
@ -62,6 +51,7 @@ export type APIType = {
|
|||
// api urls
|
||||
const api: APIType = {
|
||||
// web
|
||||
bundlejs: 'https://static.crunchyroll.com/vilos-v2/web/vilos/js/bundle.js',
|
||||
newani: `${domain.www}/rss/anime`,
|
||||
search1: `${domain.www}/ajax/?req=RpcApiSearch_GetSearchCandidates`,
|
||||
search2: `${domain.www}/search_page`,
|
||||
|
|
@ -78,10 +68,6 @@ const api: APIType = {
|
|||
beta_auth: `${domain.api_beta}/auth/v1/token`,
|
||||
// This User-Agent bypasses Cloudflare security by the newer Endpoint
|
||||
defaultUserAgent: 'Crunchyroll/4.71.0 (bundle_identifier:com.crunchyroll.iphone; build_number:4052956.474096152) iOS/18.3.2 Gravity/4.71.0',
|
||||
authBasic: 'Basic bm9haWhkZXZtXzZpeWcwYThsMHE6',
|
||||
authBasicMob: 'Basic cHVuaDRoa3FxYzkwMXV5aWlqejc6bE44MEx3T3pzNkxRcDd1RzNEUmNTaVFUR2RUU3dHbzQ=',
|
||||
authBasicIOS: 'Basic eHVuaWh2ZWRidDNtYmlzdWhldnQ6MWtJUzVkeVR2akUwX3JxYUEzWWVBaDBiVVhVbXhXMTE=',
|
||||
authBasicSwitch: 'Basic dC1rZGdwMmg4YzNqdWI4Zm4wZnE6eWZMRGZNZnJZdktYaDRKWFMxTEVJMmNDcXUxdjVXYW4=',
|
||||
beta_profile: `${domain.api_beta}/accounts/v1/me/profile`,
|
||||
beta_cmsToken: `${domain.api_beta}/index/v2`,
|
||||
search: `${domain.api_beta}/content/v2/discover/search`,
|
||||
|
|
@ -91,8 +77,6 @@ const api: APIType = {
|
|||
// beta api
|
||||
drm: `${domain.api_beta}/drm/v1/auth`,
|
||||
crunchyAuthHeader: {},
|
||||
crunchyAuthHeaderMob: {},
|
||||
crunchyAuthHeaderSwitch: {},
|
||||
//hidive API
|
||||
hd_apikey: '508efd7b42d546e19cc24f4d0b414e57e351ca73',
|
||||
hd_devName: 'Android',
|
||||
|
|
@ -107,20 +91,11 @@ const api: APIType = {
|
|||
};
|
||||
|
||||
// set header
|
||||
api.crunchyAuthHeader = {
|
||||
Authorization: api.authBasic,
|
||||
};
|
||||
|
||||
api.crunchyAuthHeaderMob = {
|
||||
Authorization: api.authBasicMob,
|
||||
api.crunchyAuthHeader = {
|
||||
'User-Agent': api.defaultUserAgent,
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
|
||||
};
|
||||
|
||||
api.crunchyAuthHeaderSwitch = {
|
||||
Authorization: api.authBasicSwitch,
|
||||
};
|
||||
|
||||
export {
|
||||
domain, api
|
||||
};
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@
|
|||
"yargs": "^17.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.23.0",
|
||||
"@types/bn.js": "^5.1.6",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/elliptic": "^6.4.18",
|
||||
|
|
|
|||
7542
pnpm-lock.yaml
7542
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue