fix(all/jellyfin): Fix login + small code touch-up (#2323)
This commit is contained in:
@ -1,12 +1,14 @@
|
|||||||
apply plugin: 'com.android.application'
|
plugins {
|
||||||
apply plugin: 'kotlin-android'
|
alias(libs.plugins.android.application)
|
||||||
apply plugin: 'kotlinx-serialization'
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.kotlin.serialization)
|
||||||
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
extName = 'Jellyfin'
|
extName = 'Jellyfin'
|
||||||
pkgNameSuffix = 'all.jellyfin'
|
pkgNameSuffix = 'all.jellyfin'
|
||||||
extClass = '.JellyfinFactory'
|
extClass = '.JellyfinFactory'
|
||||||
extVersionCode = 10
|
extVersionCode = 11
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,3 +65,14 @@ data class LinkData(
|
|||||||
val seriesId: String,
|
val seriesId: String,
|
||||||
val seasonId: String,
|
val seasonId: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class LoginResponse(
|
||||||
|
val AccessToken: String,
|
||||||
|
val SessionInfo: SessionObject,
|
||||||
|
) {
|
||||||
|
@Serializable
|
||||||
|
data class SessionObject(
|
||||||
|
val UserId: String,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -2,37 +2,42 @@ package eu.kanade.tachiyomi.animeextension.all.jellyfin
|
|||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
import eu.kanade.tachiyomi.AppInfo
|
import eu.kanade.tachiyomi.AppInfo
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.put
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import okhttp3.Response
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class JellyfinAuthenticator(
|
class JellyfinAuthenticator(
|
||||||
private val preferences: SharedPreferences,
|
private val preferences: SharedPreferences,
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
private val client: OkHttpClient,
|
private val client: OkHttpClient,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
fun login(username: String, password: String): Pair<String?, String?> {
|
fun login(username: String, password: String): Pair<String?, String?> {
|
||||||
return try {
|
return runCatching {
|
||||||
val authResult = authenticateWithPassword(username, password)
|
val authResult = authenticateWithPassword(username, password)
|
||||||
?: throw Exception()
|
val key = authResult.AccessToken
|
||||||
val key = authResult["AccessToken"]!!.jsonPrimitive.content
|
val userId = authResult.SessionInfo.UserId
|
||||||
val userId = authResult["SessionInfo"]!!.jsonObject["UserId"]!!.jsonPrimitive.content
|
|
||||||
saveLogin(key, userId)
|
saveLogin(key, userId)
|
||||||
Pair(key, userId)
|
Pair(key, userId)
|
||||||
} catch (e: Exception) {
|
}.getOrElse {
|
||||||
|
Log.e(LOG_TAG, it.stackTraceToString())
|
||||||
Pair(null, null)
|
Pair(null, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun authenticateWithPassword(username: String, password: String): JsonObject? {
|
private fun authenticateWithPassword(username: String, password: String): LoginResponse {
|
||||||
var deviceId = getPrefDeviceId()
|
var deviceId = getPrefDeviceId()
|
||||||
if (deviceId.isNullOrEmpty()) {
|
if (deviceId.isNullOrEmpty()) {
|
||||||
deviceId = getRandomString()
|
deviceId = getRandomString()
|
||||||
@ -44,13 +49,15 @@ class JellyfinAuthenticator(
|
|||||||
"X-Emby-Authorization",
|
"X-Emby-Authorization",
|
||||||
"MediaBrowser Client=\"$CLIENT\", Device=\"Android $androidVersion\", DeviceId=\"$deviceId\", Version=\"$aniyomiVersion\"",
|
"MediaBrowser Client=\"$CLIENT\", Device=\"Android $androidVersion\", DeviceId=\"$deviceId\", Version=\"$aniyomiVersion\"",
|
||||||
)
|
)
|
||||||
val body = """
|
val body = json.encodeToString(
|
||||||
{"Username":"$username","Pw":"$password"}
|
buildJsonObject {
|
||||||
""".trimIndent()
|
put("Username", username)
|
||||||
.toRequestBody("application/json".toMediaType())
|
put("Pw", password)
|
||||||
|
},
|
||||||
|
).toRequestBody("application/json; charset=utf-8".toMediaType())
|
||||||
|
|
||||||
val request = POST("$baseUrl/Users/authenticatebyname", headers = authHeader, body = body)
|
val request = POST("$baseUrl/Users/authenticatebyname", headers = authHeader, body = body)
|
||||||
val response = client.newCall(request).execute().body.string()
|
return client.newCall(request).execute().parseAs()
|
||||||
return response?.let { Json.decodeFromString<JsonObject>(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRandomString(): String {
|
private fun getRandomString(): String {
|
||||||
@ -76,7 +83,15 @@ class JellyfinAuthenticator(
|
|||||||
DEVICEID_KEY,
|
DEVICEID_KEY,
|
||||||
value,
|
value,
|
||||||
).apply()
|
).apply()
|
||||||
}
|
|
||||||
|
|
||||||
private const val DEVICEID_KEY = "device_id"
|
private inline fun <reified T> Response.parseAs(transform: (String) -> String = { it }): T {
|
||||||
private const val CLIENT = "Aniyomi"
|
val responseBody = use { transform(it.body.string()) }
|
||||||
|
return json.decodeFromString(responseBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DEVICEID_KEY = "device_id"
|
||||||
|
private const val CLIENT = "Aniyomi"
|
||||||
|
private const val LOG_TAG = "JellyfinAuthenticator"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user