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()}")
|
||||
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())
|
||||
snackString(context.getString(R.string.error_loading_mal_user_data))
|
||||
}
|
||||
CommentsAPI.fetchAuthToken()
|
||||
true
|
||||
} else {
|
||||
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.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
import com.lagradost.nicehttp.NiceResponse
|
||||
import com.lagradost.nicehttp.Requests
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import kotlinx.serialization.KSerializer
|
||||
|
@ -206,31 +207,63 @@ object CommentsAPI {
|
|||
|
||||
suspend fun fetchAuthToken() {
|
||||
if (authToken != null) return
|
||||
val url = "$address/authenticate"
|
||||
val token = PrefManager.getVal(PrefName.AnilistToken, null as String?) ?: return
|
||||
val body: FormBody = FormBody.Builder()
|
||||
.add("token", token)
|
||||
.build()
|
||||
val request = requestBuilder()
|
||||
val json = try {
|
||||
request.post(url, requestBody = body)
|
||||
} catch (e: IOException) {
|
||||
snackString("Failed to login to comments API")
|
||||
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
|
||||
}
|
||||
if (!json.text.startsWith("{")) return
|
||||
}
|
||||
val url = "$address/authenticate"
|
||||
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()
|
||||
.add("token", token)
|
||||
.build()
|
||||
val request = requestBuilder()
|
||||
return request.post(url, requestBody = body)
|
||||
}
|
||||
|
||||
private fun headerBuilder(): Map<String, String> {
|
||||
|
@ -278,7 +311,11 @@ data class AuthResponse(
|
|||
val authToken: String,
|
||||
@SerialName("user")
|
||||
val user: User
|
||||
)
|
||||
) : java.io.Serializable {
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 1
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class User(
|
||||
|
@ -299,7 +336,11 @@ data class User(
|
|||
val isMod: Boolean? = null,
|
||||
@SerialName("total_votes")
|
||||
val totalVotes: Int,
|
||||
)
|
||||
) : java.io.Serializable {
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 1
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class CommentResponse(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ani.dantotsu.settings.saving
|
||||
|
||||
import android.graphics.Color
|
||||
import ani.dantotsu.connections.comments.AuthResponse
|
||||
import ani.dantotsu.connections.mal.MAL
|
||||
import ani.dantotsu.settings.saving.internal.Location
|
||||
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>())),
|
||||
MakeDefault(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
|
||||
DiscordToken(Pref(Location.Protected, String::class, "")),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue