crextractor 1.2.0 → 1.3.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/README.md +22 -13
- package/bin/cli.js +1 -1
- package/crextractor.d.ts +17 -3
- package/crextractor.js +11 -9
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
# Crextractor
|
|
2
2
|
|
|
3
|
-
Utility for extracting credentials from the Crunchyroll Android app
|
|
3
|
+
Utility for extracting credentials from the Crunchyroll Android app (both TV and mobile versions).
|
|
4
|
+
|
|
5
|
+
The [credentials](https://github.com/vitalygashkov/crextractor/blob/main/credentials.tv.json) are [automatically](https://github.com/vitalygashkov/crextractor/actions/workflows/extract.yml) updated once a week (if there are any changes).
|
|
4
6
|
|
|
5
7
|
## Prerequisites
|
|
6
8
|
|
|
7
9
|
- [Node.js](https://nodejs.org/en)
|
|
8
10
|
- [jadx](https://github.com/skylot/jadx)
|
|
9
11
|
|
|
10
|
-
##
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
### Library
|
|
11
15
|
|
|
12
16
|
```bash
|
|
13
17
|
npm i crextractor
|
|
14
18
|
```
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
### Fetching already extracted secrets
|
|
20
|
+
#### Fetch ready credentials from this GitHub repository
|
|
19
21
|
|
|
20
22
|
```js
|
|
23
|
+
import { pull } from 'crextractor';
|
|
24
|
+
|
|
21
25
|
async function main() {
|
|
22
|
-
const
|
|
23
|
-
const data = await fetch(url).then((response) => response.json());
|
|
26
|
+
const credentials = await pull('tv');
|
|
24
27
|
|
|
25
|
-
// You can use the extracted
|
|
28
|
+
// You can use the extracted credentials to obtain access tokens for Crunchyroll APIs
|
|
26
29
|
const response = await fetch('https://beta-api.crunchyroll.com/auth/v1/token', {
|
|
27
30
|
headers: {
|
|
28
|
-
Authorization:
|
|
31
|
+
Authorization: credentials.authorization, // Ready HTTP header in the format `Basic <encoded>`, can be used to access some Crunchyroll APIs
|
|
29
32
|
'User-Agent': 'Crunchyroll/ANDROIDTV/3.42.1_22267 (Android 16; en-US; sdk_gphone64_x86_64)',
|
|
30
33
|
// ...
|
|
31
34
|
},
|
|
@@ -37,17 +40,23 @@ async function main() {
|
|
|
37
40
|
}
|
|
38
41
|
```
|
|
39
42
|
|
|
40
|
-
####
|
|
43
|
+
#### Extract credentials from the latest APK using jadx
|
|
41
44
|
|
|
42
45
|
```js
|
|
43
46
|
import { extract } from 'crextractor';
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
async function main() {
|
|
49
|
+
const { id, secret, encoded, authorization } = await extract();
|
|
50
|
+
// id - Crunchyroll app ID
|
|
51
|
+
// secret - Crunchyroll app secret
|
|
52
|
+
// encoded - Base64 encoded `id:secret` string
|
|
53
|
+
// authorization - ready HTTP header in the format `Basic <encoded>`, can be used to access some Crunchyroll APIs
|
|
46
54
|
|
|
47
|
-
// Do something with the extracted
|
|
55
|
+
// Do something with the extracted credentials
|
|
56
|
+
}
|
|
48
57
|
```
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
### Command-line interface
|
|
51
60
|
|
|
52
61
|
```bash
|
|
53
62
|
npx crextractor --target mobile --output ./credentials.mobile.json
|
package/bin/cli.js
CHANGED
package/crextractor.d.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type CrunchyrollAppCredentials = {
|
|
2
2
|
// Crunchyroll app ID
|
|
3
3
|
id: string;
|
|
4
4
|
// Crunchyroll app secret
|
|
5
5
|
secret: string;
|
|
6
6
|
// Base64 encoded `id:secret` string
|
|
7
7
|
encoded: string;
|
|
8
|
-
// HTTP header
|
|
8
|
+
// Ready HTTP header in the format `Basic <encoded>`, can be used to access some Crunchyroll APIs
|
|
9
9
|
authorization: string;
|
|
10
|
-
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Extract credentials from the Crunchyroll Android APK using jadx.
|
|
14
|
+
*/
|
|
15
|
+
export function extract(options?: {
|
|
16
|
+
target?: 'mobile' | 'tv';
|
|
17
|
+
output?: string;
|
|
18
|
+
cleanup?: boolean;
|
|
19
|
+
}): Promise<CrunchyrollAppCredentials>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Fetch ready credentials from the GitHub repository.
|
|
23
|
+
*/
|
|
24
|
+
export function pull(options?: { target: 'mobile' | 'tv' }): Promise<CrunchyrollAppCredentials>;
|
package/crextractor.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
const { execSync } = require('node:child_process');
|
|
2
2
|
const { join } = require('node:path');
|
|
3
3
|
const { readdir, readFile, writeFile, rm } = require('node:fs/promises');
|
|
4
|
-
const { download } = require('molnia');
|
|
5
4
|
const { existsSync } = require('node:fs');
|
|
5
|
+
const { download } = require('molnia');
|
|
6
6
|
|
|
7
7
|
const downloadMobileApk = async () => {
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const html = await page.text();
|
|
11
|
-
const route = '/r2' + html.split('/r2')[1]?.split('"')[0];
|
|
12
|
-
const url = `https://apkcombo.com${route}`;
|
|
13
|
-
const filepath = join(process.cwd(), 'crunchyroll.xapk');
|
|
8
|
+
const url = 'https://api.qqaoop.com/v11/apps/com.crunchyroll.crunchyroid/download?userId=1';
|
|
9
|
+
const filepath = join(process.cwd(), 'crunchyroll.apk');
|
|
14
10
|
await download(url, {
|
|
15
11
|
output: filepath,
|
|
16
12
|
onError: (error) => console.error(error),
|
|
@@ -100,7 +96,7 @@ const parseVersion = async (decompiledDir) => {
|
|
|
100
96
|
}
|
|
101
97
|
};
|
|
102
98
|
|
|
103
|
-
const extract = async ({ target, output, cleanup = false } = {}) => {
|
|
99
|
+
const extract = async ({ target = 'mobile', output, cleanup = false } = {}) => {
|
|
104
100
|
console.log('Downloading APK...');
|
|
105
101
|
const apkPath = target === 'tv' ? await downloadTvApk() : await downloadMobileApk();
|
|
106
102
|
|
|
@@ -132,4 +128,10 @@ const extract = async ({ target, output, cleanup = false } = {}) => {
|
|
|
132
128
|
return { version, id, secret, encoded, authorization };
|
|
133
129
|
};
|
|
134
130
|
|
|
135
|
-
|
|
131
|
+
const pull = async ({ target = 'mobile' } = {}) => {
|
|
132
|
+
const url = `https://raw.githubusercontent.com/vitalygashkov/crextractor/refs/heads/main/credentials.${target}.json`;
|
|
133
|
+
const credentials = await fetch(url).then((response) => response.json());
|
|
134
|
+
return credentials;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
module.exports = { extract, pull };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crextractor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Utility for extracting credentials from the Crunchyroll Android app",
|
|
5
5
|
"main": "crextractor.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
"type": "commonjs",
|
|
16
16
|
"scripts": {
|
|
17
17
|
"start": "node bin/cli.js",
|
|
18
|
+
"extract:mobile": "node bin/cli.js --target mobile --output ./credentials.mobile.json",
|
|
19
|
+
"extract:tv": "node bin/cli.js --target tv --output ./credentials.tv.json",
|
|
18
20
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
19
21
|
},
|
|
20
22
|
"keywords": [
|