Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(providers): gogoanime - key extraction #33

Merged
merged 2 commits into from
Aug 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions src/constants/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ const BaseDefault = {
gogoanime: {
root: "https://gogoanime.gg",
encryptAjaxEndpoint: "https://gogoplay.io/encrypt-ajax.php",
// TODO: refactor to use own extracted keys .. in the meantime, thanks @justfoolingaround!
superSecret:
"https://raw.githubusercontent.com/justfoolingaround/animdl-provider-benchmarks/master/api/gogoanime.json",
},
},
};
Expand Down
37 changes: 17 additions & 20 deletions src/providers/gogoanime/extractors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import { createCipheriv, createDecipheriv } from "crypto";
import cheerio from "cheerio";

import { USER_AGENT, BROWSER_HEADERS } from "@constants/headers";
import ENV_CONFIG from "@constants/environment";
import { GOGO_ROOT, GOGO_BASE_SEARCH } from "@constants/urls";
import utils from "@utils/index";

import {
VideoMetadata,
EpisodeRange,
CryptInput,
RemoteSecrets,
GogoSearchResults,
} from "./types";

Expand All @@ -25,17 +23,16 @@ const {
http: { httpGet },
} = utils;

const Constants = {
algorithm: "aes-256-cbc",
};
const CIPHER = "aes-256-cbc";
const KEYS_RE = /(?:container|videocontent)-(\d+)/gm;

const stripNewlinesAndSpacesToNum: (s: string) => number = compose(
stringToNum,
removeMatchedPattern(/[\n\s]+/)
);

const aesEncrypt = ({ source, key, iv }: CryptInput) => {
const cipher = createCipheriv(Constants.algorithm, key, iv);
const cipher = createCipheriv(CIPHER, key, iv);
let encryptedKey = "";

encryptedKey += cipher.update(source, "binary");
Expand All @@ -45,7 +42,7 @@ const aesEncrypt = ({ source, key, iv }: CryptInput) => {
};

const aesDecrypt = ({ source, key, iv }: CryptInput) => {
const decipher = createDecipheriv(Constants.algorithm, key, iv);
const decipher = createDecipheriv(CIPHER, key, iv);
let decryptedToken = "";
// @ts-ignore
decryptedToken += decipher.update(source, "base64url", "utf-8");
Expand All @@ -67,21 +64,20 @@ const extractAndDecryptSources = async (url: URL | null) => {
const embedId = url.searchParams.get("id");
const $ = cheerio.load(serverPageResponse);
const encryptedSource = $("script[data-name='episode']").data().value;
const parsedSecretResult = safeJSONParse(
await httpGet(ENV_CONFIG.urls.gogoanime.superSecret)
);

if (parsedSecretResult) {
const {
key,
second_key: secondKey,
const [encryption_key, iv, decryption_key] = (
serverPageResponse.match(KEYS_RE) || []
).map((secret) => secret.split("-")[1]);

if (encryption_key && iv && decryption_key) {
const encId = aesEncrypt({
source: embedId as string,
key: encryption_key,
iv,
} = parsedSecretResult as unknown as RemoteSecrets;
});

const encId = aesEncrypt({ source: embedId as string, key, iv });
const decSource = aesDecrypt({
source: encryptedSource as string,
key,
key: encryption_key,
iv,
});

Expand All @@ -99,7 +95,7 @@ const extractAndDecryptSources = async (url: URL | null) => {

return aesDecrypt({
source: parsedEncryptedSources as string,
key: secondKey,
key: decryption_key,
iv,
});
}
Expand All @@ -118,7 +114,8 @@ const detailsEmptyOr404 = (pageHTML: string): boolean => {
const getEntryServerUrl = (pageHTML: string): URL | null => {
const $ = cheerio.load(pageHTML);
const serverUrl = $("#load_anime > div > div > iframe").attr("src");
return serverUrl ? new URL("http:" + serverUrl) : null;

return serverUrl ? new URL(serverUrl) : null;
};

const getSearchResults = async (userAnimeQuery: string, pageNumber = 1) => {
Expand Down
6 changes: 0 additions & 6 deletions src/providers/gogoanime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ export interface CryptInput {
iv: string;
}

export interface RemoteSecrets {
key: string;
second_key: string;
iv: string;
}

interface SearchItem {
id?: string | null;
title?: string | null;
Expand Down
Loading