Remove koreader sync server address from settings (#1807)

Should have been done with 4dbd9d70d2
This commit is contained in:
schroda
2025-12-06 18:38:45 +01:00
committed by GitHub
parent 39cae6cc2d
commit 3b36ec550d
4 changed files with 71 additions and 31 deletions

View File

@@ -688,12 +688,22 @@ class ServerConfig(
defaultValue = "suwayomi-server-api",
)
val koreaderSyncServerUrl: MutableStateFlow<String> by StringSetting(
@Deprecated("Moved to preference store. User is supposed to use a login/logout mutation")
val koreaderSyncServerUrl: MutableStateFlow<String> by MigratedConfigValue(
protoNumber = 59,
group = SettingGroup.KOREADER_SYNC,
privacySafe = true,
defaultValue = "https://sync.koreader.rocks/",
description = "KOReader Sync Server URL. Public alternative: https://kosync.ak-team.com:3042/",
deprecated = SettingsRegistry.SettingDeprecated(
replaceWith = "MOVE TO PREFERENCES",
message = "Moved to preference store. User is supposed to use a login/logout mutation",
migrateConfig = { value, config ->
val koreaderPreferences = application.getSharedPreferences("koreader_sync", Context.MODE_PRIVATE)
koreaderPreferences.edit().putString("server_address", value.unwrapped() as? String).apply()
config
}
),
)
@Deprecated("Moved to preference store. User is supposed to use a login/logout mutation")

View File

@@ -19,6 +19,7 @@ import java.util.concurrent.CompletableFuture
class KoreaderSyncMutation {
data class ConnectKoSyncAccountInput(
val clientMutationId: String? = null,
val serverAddress: String,
val username: String,
val password: String,
)
@@ -26,7 +27,7 @@ class KoreaderSyncMutation {
@RequireAuth
fun connectKoSyncAccount(input: ConnectKoSyncAccountInput): CompletableFuture<KoSyncConnectPayload> =
future {
val (message, status) = KoreaderSyncService.connect(input.username, input.password)
val (message, status) = KoreaderSyncService.connect(input.serverAddress, input.username, input.password)
KoSyncConnectPayload(
clientMutationId = input.clientMutationId,
@@ -45,7 +46,7 @@ class KoreaderSyncMutation {
KoreaderSyncService.logout()
LogoutKoSyncAccountPayload(
clientMutationId = input.clientMutationId,
status = KoSyncStatusPayload(isLoggedIn = false, username = null),
status = KoSyncStatusPayload(isLoggedIn = false, serverAddress = null, username = null),
)
}

View File

@@ -2,6 +2,7 @@ package suwayomi.tachidesk.graphql.types
data class KoSyncStatusPayload(
val isLoggedIn: Boolean,
val serverAddress: String?,
val username: String?,
)

View File

@@ -34,6 +34,7 @@ import kotlin.math.abs
object KoreaderSyncService {
private val preferences = Injekt.get<Application>().getSharedPreferences("koreader_sync", Context.MODE_PRIVATE)
private const val SERVER_ADDRESS_KEY = "server_address"
private const val USERNAME_KEY = "username"
private const val USERKEY_KEY = "user_key"
private const val DEVICE_ID_KEY = "client_id"
@@ -179,6 +180,7 @@ object KoreaderSyncService {
}
private suspend fun register(
serverAddress: String,
username: String,
userkey: String,
): AuthResult {
@@ -188,7 +190,7 @@ object KoreaderSyncService {
put("password", userkey)
}
val request =
buildRequest("${serverConfig.koreaderSyncServerUrl.value.removeSuffix("/")}/users/create") {
buildRequest("${serverAddress.removeSuffix("/")}/users/create") {
post(payload.toString().toRequestBody("application/json".toMediaType()))
}
@@ -216,11 +218,12 @@ object KoreaderSyncService {
}
private suspend fun authorize(
serverAddress: String,
username: String,
userkey: String,
): AuthResult {
val request =
buildRequest("${serverConfig.koreaderSyncServerUrl.value.removeSuffix("/")}/users/auth") {
buildRequest("${serverAddress.removeSuffix("/")}/users/auth") {
get()
addHeader("x-auth-user", username)
addHeader("x-auth-key", userkey)
@@ -241,61 +244,88 @@ object KoreaderSyncService {
}
}
private fun getCredentials(): Pair<String, String> {
private fun getCredentials(): Triple<String, String, String> {
val serverAddress = preferences.getString(SERVER_ADDRESS_KEY, "https://sync.koreader.rocks/")!!
val username = preferences.getString(USERNAME_KEY, "")!!
val userkey = preferences.getString(USERKEY_KEY, "")!!
return Pair(username, userkey)
return Triple(serverAddress, username, userkey)
}
private fun setCredentials(
serverAddress: String,
username: String,
userkey: String,
) {
preferences
.edit()
.putString(SERVER_ADDRESS_KEY, serverAddress)
.putString(USERNAME_KEY, username)
.putString(USERKEY_KEY, userkey)
.apply()
}
private fun clearCredentials() {
preferences.edit().clear().apply()
}
suspend fun connect(
serverAddress: String,
username: String,
password: String,
): ConnectResult {
val userkey = Hash.md5(password)
val authResult = authorize(username, userkey)
val authResult = authorize(serverAddress, username, userkey)
if (authResult.success) {
setCredentials(username, userkey)
return ConnectResult("Login successful.", KoSyncStatusPayload(isLoggedIn = true, username = username))
setCredentials(serverAddress, username, userkey)
return ConnectResult(
"Login successful.",
KoSyncStatusPayload(isLoggedIn = true, serverAddress = serverAddress, username = username),
)
}
if (authResult.isUserNotFoundError) {
logger.info { "[KOSYNC CONNECT] Authorization failed, attempting to register new user." }
val registerResult = register(username, userkey)
val registerResult = register(serverAddress, username, userkey)
return if (registerResult.success) {
setCredentials(username, userkey)
ConnectResult("Registration successful.", KoSyncStatusPayload(isLoggedIn = true, username = username))
setCredentials(serverAddress, username, userkey)
ConnectResult(
"Registration successful.",
KoSyncStatusPayload(isLoggedIn = true, serverAddress = serverAddress, username = username),
)
} else {
ConnectResult(registerResult.message ?: "Registration failed.", KoSyncStatusPayload(isLoggedIn = false, username = null))
ConnectResult(
registerResult.message ?: "Registration failed.",
KoSyncStatusPayload(isLoggedIn = false, serverAddress = null, username = null),
)
}
}
return ConnectResult(authResult.message ?: "Authentication failed.", KoSyncStatusPayload(isLoggedIn = false, username = null))
return ConnectResult(
authResult.message ?: "Authentication failed.",
KoSyncStatusPayload(isLoggedIn = false, serverAddress = null, username = null),
)
}
suspend fun logout() {
setCredentials("", "")
fun logout() {
clearCredentials()
}
suspend fun getStatus(): KoSyncStatusPayload {
val (username, userkey) = getCredentials()
val (serverAddress, username, userkey) = getCredentials()
if (username.isBlank() || userkey.isBlank()) {
return KoSyncStatusPayload(isLoggedIn = false, username = null)
return KoSyncStatusPayload(isLoggedIn = false, serverAddress = null, username = null)
}
val authResult = authorize(serverAddress, username, userkey)
return if (authResult.success) {
KoSyncStatusPayload(isLoggedIn = true, serverAddress = serverAddress, username = username)
} else {
KoSyncStatusPayload(isLoggedIn = false, serverAddress = null, username = null)
}
val authResult = authorize(username, userkey)
return KoSyncStatusPayload(isLoggedIn = authResult.success, username = if (authResult.success) username else null)
}
suspend fun pushProgress(chapterId: Int) {
@@ -309,8 +339,8 @@ object KoreaderSyncService {
return
}
val (username, userkey) = getCredentials()
if (username.isBlank() || userkey.isBlank()) return
val (serverAddress, username, userkey) = getCredentials()
if (serverAddress.isBlank() || username.isBlank() || userkey.isBlank()) return
val chapterHash = getOrGenerateChapterHash(chapterId)
if (chapterHash.isNullOrBlank()) {
@@ -350,7 +380,7 @@ object KoreaderSyncService {
val requestBody = json.encodeToString(KoreaderProgressPayload.serializer(), payload)
val request =
buildRequest("${serverConfig.koreaderSyncServerUrl.value.removeSuffix("/")}/syncs/progress") {
buildRequest("${serverAddress.removeSuffix("/")}/syncs/progress") {
put(requestBody.toRequestBody("application/json".toMediaType()))
addHeader("x-auth-user", username)
addHeader("x-auth-key", userkey)
@@ -383,8 +413,8 @@ object KoreaderSyncService {
return null
}
val (username, userkey) = getCredentials()
if (username.isBlank() || userkey.isBlank()) return null
val (serverAddress, username, userkey) = getCredentials()
if (serverAddress.isBlank() || username.isBlank() || userkey.isBlank()) return null
val chapterHash = getOrGenerateChapterHash(chapterId)
if (chapterHash.isNullOrBlank()) {
@@ -394,7 +424,7 @@ object KoreaderSyncService {
try {
val request =
buildRequest("${serverConfig.koreaderSyncServerUrl.value.removeSuffix("/")}/syncs/progress/$chapterHash") {
buildRequest("${serverAddress.removeSuffix("/")}/syncs/progress/$chapterHash") {
get()
addHeader("x-auth-user", username)
addHeader("x-auth-key", userkey)
@@ -434,9 +464,7 @@ object KoreaderSyncService {
}
val localPercentage =
if (localProgress?.pageCount ?: 0 >
0
) {
if ((localProgress?.pageCount ?: 0) > 0) {
(localProgress!!.lastPageRead + 1).toFloat() / localProgress.pageCount
} else {
0f