feat: token lifetime stored
This commit is contained in:
parent
d5c87c46aa
commit
8a922bd083
4 changed files with 69 additions and 22 deletions
|
@ -111,6 +111,10 @@ class App : MultiDexApplication() {
|
||||||
logger("Novel Extensions: ${novelExtensionManager.installedExtensionsFlow.first()}")
|
logger("Novel Extensions: ${novelExtensionManager.installedExtensionsFlow.first()}")
|
||||||
NovelSources.init(novelExtensionManager.installedExtensionsFlow)
|
NovelSources.init(novelExtensionManager.installedExtensionsFlow)
|
||||||
}
|
}
|
||||||
|
val commentsScope = CoroutineScope(Dispatchers.Default)
|
||||||
|
commentsScope.launch {
|
||||||
|
CommentsAPI.fetchAuthToken()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ suspend fun getUserId(context: Context, block: () -> Unit) {
|
||||||
if (MAL.token != null && !MAL.query.getUserData())
|
if (MAL.token != null && !MAL.query.getUserData())
|
||||||
snackString(context.getString(R.string.error_loading_mal_user_data))
|
snackString(context.getString(R.string.error_loading_mal_user_data))
|
||||||
}
|
}
|
||||||
CommentsAPI.fetchAuthToken()
|
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
snackString(context.getString(R.string.error_loading_anilist_user_data))
|
snackString(context.getString(R.string.error_loading_anilist_user_data))
|
||||||
|
|
|
@ -4,6 +4,7 @@ import ani.dantotsu.connections.anilist.Anilist
|
||||||
import ani.dantotsu.settings.saving.PrefManager
|
import ani.dantotsu.settings.saving.PrefManager
|
||||||
import ani.dantotsu.settings.saving.PrefName
|
import ani.dantotsu.settings.saving.PrefName
|
||||||
import ani.dantotsu.snackString
|
import ani.dantotsu.snackString
|
||||||
|
import com.lagradost.nicehttp.NiceResponse
|
||||||
import com.lagradost.nicehttp.Requests
|
import com.lagradost.nicehttp.Requests
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
@ -206,31 +207,63 @@ object CommentsAPI {
|
||||||
|
|
||||||
suspend fun fetchAuthToken() {
|
suspend fun fetchAuthToken() {
|
||||||
if (authToken != null) return
|
if (authToken != null) return
|
||||||
|
val MAX_RETRIES = 5
|
||||||
|
val tokenLifetime: Long = 1000 * 60 * 60 * 24 * 6 // 6 days
|
||||||
|
val tokenExpiry = PrefManager.getVal<Long>(PrefName.CommentTokenExpiry)
|
||||||
|
if (tokenExpiry < System.currentTimeMillis() + tokenLifetime) {
|
||||||
|
val commentResponse = PrefManager.getNullableVal<AuthResponse>(PrefName.CommentAuthResponse, null)
|
||||||
|
if (commentResponse != null) {
|
||||||
|
authToken = commentResponse.authToken
|
||||||
|
userId = commentResponse.user.id
|
||||||
|
isBanned = commentResponse.user.isBanned ?: false
|
||||||
|
isAdmin = commentResponse.user.isAdmin ?: false
|
||||||
|
isMod = commentResponse.user.isMod ?: false
|
||||||
|
totalVotes = commentResponse.user.totalVotes
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
val url = "$address/authenticate"
|
val url = "$address/authenticate"
|
||||||
val token = PrefManager.getVal(PrefName.AnilistToken, null as String?) ?: return
|
val token = PrefManager.getVal(PrefName.AnilistToken, null as String?) ?: return
|
||||||
|
repeat(MAX_RETRIES) { // Define MAX_RETRIES as a constant
|
||||||
|
try {
|
||||||
|
val json = authRequest(token, url)
|
||||||
|
if (json.code == 200) {
|
||||||
|
if (!json.text.startsWith("{")) throw IOException("Invalid response")
|
||||||
|
val parsed = try {
|
||||||
|
Json.decodeFromString<AuthResponse>(json.text)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
snackString("Failed to login to comments API: ${e.printStackTrace()}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
PrefManager.setVal(PrefName.CommentAuthResponse, parsed)
|
||||||
|
PrefManager.setVal(PrefName.CommentTokenExpiry, System.currentTimeMillis() + tokenLifetime)
|
||||||
|
authToken = parsed.authToken
|
||||||
|
userId = parsed.user.id
|
||||||
|
isBanned = parsed.user.isBanned ?: false
|
||||||
|
isAdmin = parsed.user.isAdmin ?: false
|
||||||
|
isMod = parsed.user.isMod ?: false
|
||||||
|
totalVotes = parsed.user.totalVotes
|
||||||
|
return
|
||||||
|
} else if (json.code != 429) {
|
||||||
|
errorReason(json.code, json.text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
snackString("Failed to login to comments API")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Wait for 1 minute before retrying
|
||||||
|
kotlinx.coroutines.delay(60000)
|
||||||
|
}
|
||||||
|
snackString("Failed to login after multiple attempts")
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun authRequest(token: String, url: String): NiceResponse {
|
||||||
val body: FormBody = FormBody.Builder()
|
val body: FormBody = FormBody.Builder()
|
||||||
.add("token", token)
|
.add("token", token)
|
||||||
.build()
|
.build()
|
||||||
val request = requestBuilder()
|
val request = requestBuilder()
|
||||||
val json = try {
|
return request.post(url, requestBody = body)
|
||||||
request.post(url, requestBody = body)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
snackString("Failed to login to comments API")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!json.text.startsWith("{")) return
|
|
||||||
val parsed = try {
|
|
||||||
Json.decodeFromString<AuthResponse>(json.text)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
snackString("Failed to login to comments API: ${e.printStackTrace()}")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
authToken = parsed.authToken
|
|
||||||
userId = parsed.user.id
|
|
||||||
isBanned = parsed.user.isBanned ?: false
|
|
||||||
isAdmin = parsed.user.isAdmin ?: false
|
|
||||||
isMod = parsed.user.isMod ?: false
|
|
||||||
totalVotes = parsed.user.totalVotes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun headerBuilder(): Map<String, String> {
|
private fun headerBuilder(): Map<String, String> {
|
||||||
|
@ -278,7 +311,11 @@ data class AuthResponse(
|
||||||
val authToken: String,
|
val authToken: String,
|
||||||
@SerialName("user")
|
@SerialName("user")
|
||||||
val user: User
|
val user: User
|
||||||
)
|
) : java.io.Serializable {
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID: Long = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class User(
|
data class User(
|
||||||
|
@ -299,7 +336,11 @@ data class User(
|
||||||
val isMod: Boolean? = null,
|
val isMod: Boolean? = null,
|
||||||
@SerialName("total_votes")
|
@SerialName("total_votes")
|
||||||
val totalVotes: Int,
|
val totalVotes: Int,
|
||||||
)
|
) : java.io.Serializable {
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID: Long = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class CommentResponse(
|
data class CommentResponse(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ani.dantotsu.settings.saving
|
package ani.dantotsu.settings.saving
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import ani.dantotsu.connections.comments.AuthResponse
|
||||||
import ani.dantotsu.connections.mal.MAL
|
import ani.dantotsu.connections.mal.MAL
|
||||||
import ani.dantotsu.settings.saving.internal.Location
|
import ani.dantotsu.settings.saving.internal.Location
|
||||||
import ani.dantotsu.settings.saving.internal.Pref
|
import ani.dantotsu.settings.saving.internal.Pref
|
||||||
|
@ -154,6 +155,8 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
||||||
TagsListNonAdult(Pref(Location.Irrelevant, Set::class, setOf<String>())),
|
TagsListNonAdult(Pref(Location.Irrelevant, Set::class, setOf<String>())),
|
||||||
MakeDefault(Pref(Location.Irrelevant, Boolean::class, true)),
|
MakeDefault(Pref(Location.Irrelevant, Boolean::class, true)),
|
||||||
FirstComment(Pref(Location.Irrelevant, Boolean::class, true)),
|
FirstComment(Pref(Location.Irrelevant, Boolean::class, true)),
|
||||||
|
CommentAuthResponse(Pref(Location.Irrelevant, AuthResponse::class, "")),
|
||||||
|
CommentTokenExpiry(Pref(Location.Irrelevant, Long::class, 0L)),
|
||||||
|
|
||||||
//Protected
|
//Protected
|
||||||
DiscordToken(Pref(Location.Protected, String::class, "")),
|
DiscordToken(Pref(Location.Protected, String::class, "")),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue