Skip to content

Commit 3409b8f

Browse files
update dependencies
1 parent b653919 commit 3409b8f

1 file changed

Lines changed: 74 additions & 12 deletions

File tree

KuramanimeProvider/src/main/kotlin/com/hexated/KuramanimeProvider.kt

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.hexated
22

3+
import app.cash.quickjs.QuickJs
34
import com.lagradost.cloudstream3.*
45
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
56
import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId
@@ -11,6 +12,7 @@ import com.lagradost.cloudstream3.utils.newExtractorLink
1112
import kotlinx.coroutines.delay
1213
import org.jsoup.Jsoup
1314
import org.jsoup.nodes.Element
15+
import java.net.URI
1416
import java.util.Calendar
1517

1618
class KuramanimeProvider : MainAPI() {
@@ -178,8 +180,8 @@ class KuramanimeProvider : MainAPI() {
178180
}
179181
}
180182

181-
private suspend fun invokeLocalSource(url: String, server: String, headers: Map<String, String>, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
182-
val request = app.post(url, data = mapOf("authorization" to getAuth()), headers = headers, cookies = cookies)
183+
private suspend fun invokeLocalSource(url: String, server: String, headers: Map<String, String>, authScriptUrl: String, refererUrl: String, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
184+
val request = app.post(url, data = mapOf("authorization" to getAuth(authScriptUrl, refererUrl)), headers = headers, cookies = cookies)
183185
delay(2000)
184186
val document = request.document
185187
document.select("video#player > source").map {
@@ -203,6 +205,8 @@ class KuramanimeProvider : MainAPI() {
203205

204206
val token = res.selectFirst("meta[name=csrf-token]")?.attr("content") ?: return false
205207
val dataKps = res.selectFirst("[data-kk]")?.attr("data-kk") ?: return false
208+
val tokenAuthUrl = res.selectFirst("input#tokenAuthJs")?.attr("value")
209+
val authScriptUrl = if (tokenAuthUrl != null) "$mainUrl$tokenAuthUrl" else "$mainUrl/storage/leviathan.js?v=${System.currentTimeMillis()}"
206210

207211
val assets = getAssets(dataKps)
208212
var headers = mapOf(
@@ -223,9 +227,9 @@ class KuramanimeProvider : MainAPI() {
223227
val server = source.attr("value")
224228
val link = "$data?${assets.MIX_PAGE_TOKEN_KEY}=$tokenKey&${assets.MIX_STREAM_SERVER_KEY}=$server"
225229
if (server.contains(Regex("(?i)kuramadrive|archive"))) {
226-
invokeLocalSource(link, server, headers, subtitleCallback, callback)
230+
invokeLocalSource(link, server, headers, authScriptUrl, data, subtitleCallback, callback)
227231
} else {
228-
val request = app.post(link, data = mapOf("authorization" to getAuth()), referer = data, headers = headers, cookies = cookies)
232+
val request = app.post(link, data = mapOf("authorization" to getAuth(authScriptUrl, data)), referer = data, headers = headers, cookies = cookies)
229233
delay(2000)
230234
request.document.select("div.iframe-container iframe").attr("src").let { videoUrl ->
231235
loadExtractor(fixUrl(videoUrl), "$mainUrl/", subtitleCallback, callback)
@@ -247,20 +251,78 @@ class KuramanimeProvider : MainAPI() {
247251
)
248252
}
249253

250-
suspend fun getAuth(): String {
251-
return authorization ?: fetchAuth().also { authorization = it }
254+
suspend fun getAuth(tokenUrl: String, referer: String): String {
255+
return authorization ?: fetchAuth(tokenUrl, referer).also { authorization = it }
252256
}
253257

254-
suspend fun fetchAuth(): String {
255-
val responseText = app.get("$mainUrl/misc/token/refresh-token", cookies = cookies).text
258+
suspend fun fetchAuth(tokenUrl: String, referer: String): String {
259+
val jsReqHeaders = mapOf(
260+
"Accept" to "*/*",
261+
"Referer" to referer,
262+
"X-Requested-With" to "XMLHttpRequest"
263+
)
256264

257-
val token = Regex(""""token"\s*:\s*"([^"]+)"""").find(responseText)?.groupValues?.get(1)
265+
val jsCode = app.get(tokenUrl, headers = jsReqHeaders, cookies = cookies).text
266+
267+
if (jsCode.trim().startsWith("<")) {
268+
throw ErrorLoadingException("Failed: leviathan.js intercepted by Cloudflare. Try disabling your proxy/VPN for a while.")
269+
}
258270

259-
if (token.isNullOrEmpty()) {
260-
throw ErrorLoadingException("Failed: Failed to retrieve token from refresh-token endpoint.")
271+
val host = URI(mainUrl).host
272+
273+
val script = """
274+
var window = this;
275+
var global = this;
276+
var document = { createElement: function() { return {}; } };
277+
var navigator = { userAgent: "Mozilla/5.0" };
278+
var location = { hostname: "$host", href: "$mainUrl" };
279+
280+
var extractedToken = "FAILED_EMPTY";
281+
282+
var fetch = function(reqUrl, options) {
283+
if (options && options.headers && options.headers['Authorization']) {
284+
extractedToken = options.headers['Authorization'];
285+
}
286+
};
287+
288+
var ${'$'} = function(options) {
289+
if (options && options.headers && options.headers['Authorization']) {
290+
extractedToken = options.headers['Authorization'];
291+
}
292+
return { done: function(){ return this; }, fail: function(){ return this; } };
293+
};
294+
${'$'}.ajax = ${'$'};
295+
window.${'$'} = ${'$'};
296+
window.jQuery = ${'$'};
297+
298+
try {
299+
$jsCode
300+
} catch(e) {
301+
extractedToken = "ERROR_EVAL: " + e.message;
302+
}
303+
304+
if (extractedToken === "FAILED_EMPTY") {
305+
for (var key in window) {
306+
if (typeof window[key] === 'function' && key !== 'fetch' && key !== '${'$'}' && key !== 'evaluate') {
307+
try {
308+
window[key]('https://dummy', 'GET', "{}");
309+
} catch(e) {}
310+
}
311+
}
312+
}
313+
314+
extractedToken;
315+
""".trimIndent()
316+
317+
val authHeader = QuickJs.create().use { ctx ->
318+
ctx.evaluate(script) as String?
319+
}
320+
321+
if (authHeader.isNullOrEmpty() || authHeader.startsWith("FAILED") || authHeader.startsWith("ERROR")) {
322+
throw ErrorLoadingException("QuickJs failed to extract token: $authHeader")
261323
}
262324

263-
return token
325+
return authHeader.replace("Bearer ", "", ignoreCase = true).trim()
264326
}
265327

266328
private fun randomId(length: Int = 6): String {

0 commit comments

Comments
 (0)