YakshaScans: Fix 403 Error (#6832)

add js challenge interceptor
This commit is contained in:
dngonz 2024-12-29 07:42:02 +01:00 committed by Draff
parent 77debf098e
commit 39ae8f5e73
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
2 changed files with 45 additions and 1 deletions

View File

@ -3,7 +3,7 @@ ext {
extClass = '.YakshaScans' extClass = '.YakshaScans'
themePkg = 'madara' themePkg = 'madara'
baseUrl = 'https://yakshascans.com' baseUrl = 'https://yakshascans.com'
overrideVersionCode = 0 overrideVersionCode = 1
isNsfw = true isNsfw = true
} }

View File

@ -1,8 +1,15 @@
package eu.kanade.tachiyomi.extension.en.yakshascans package eu.kanade.tachiyomi.extension.en.yakshascans
import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.interceptor.rateLimit import eu.kanade.tachiyomi.network.interceptor.rateLimit
import okhttp3.FormBody
import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response
import java.io.IOException
import java.security.MessageDigest
class YakshaScans : Madara( class YakshaScans : Madara(
"YakshaScans", "YakshaScans",
@ -12,8 +19,45 @@ class YakshaScans : Madara(
override val client: OkHttpClient = super.client.newBuilder() override val client: OkHttpClient = super.client.newBuilder()
.rateLimit(1) .rateLimit(1)
.addInterceptor(::jsChallengeInterceptor)
.build() .build()
private fun jsChallengeInterceptor(chain: Interceptor.Chain): Response {
val request = chain.request()
val origRes = chain.proceed(request)
if (origRes.code != 403) return origRes
origRes.close()
// Same delay as the source
Thread.sleep(3000L)
val token = fetchToken(chain).sha256()
val body = FormBody.Builder().add("challenge", token).build()
val challengeReq = POST("$baseUrl/hcdn-cgi/jschallenge-validate", headers, body = body)
val challengeResponse = chain.proceed(challengeReq)
challengeResponse.close()
if (challengeResponse.code != 200) throw IOException("Failed to bypass js challenge!")
return chain.proceed(request)
}
private tailrec fun fetchToken(chain: Interceptor.Chain, attempt: Int = 0): String {
if (attempt > 5) throw IOException("Failed to fetch challenge token!")
val request = GET("$baseUrl/hcdn-cgi/jschallenge", headers)
val res = chain.proceed(request).body.string()
return res.substringAfter("cjs = '").substringBefore("'")
.takeUnless { it == "nil" } ?: fetchToken(chain, attempt + 1)
}
private fun String.sha256(): String {
return MessageDigest
.getInstance("SHA-256")
.digest(toByteArray())
.fold("", { str, it -> str + "%02x".format(it) })
}
override val useNewChapterEndpoint = true override val useNewChapterEndpoint = true
override val mangaDetailsSelectorDescription: String = override val mangaDetailsSelectorDescription: String =