Exclude tracker credentials in backups
Cette révision appartient à :
Parent
72024aa44a
révision
730f3a6e52
6 fichiers modifiés avec 52 ajouts et 16 suppressions
|
@ -22,7 +22,7 @@ android {
|
|||
defaultConfig {
|
||||
applicationId = "eu.kanade.tachiyomi"
|
||||
|
||||
versionCode = 106
|
||||
versionCode = 107
|
||||
versionName = "0.14.6"
|
||||
|
||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||
|
|
|
@ -2,6 +2,7 @@ package eu.kanade.domain.track.service
|
|||
|
||||
import eu.kanade.tachiyomi.data.track.Tracker
|
||||
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
||||
import tachiyomi.core.preference.Preference
|
||||
import tachiyomi.core.preference.PreferenceStore
|
||||
|
||||
class TrackPreferences(
|
||||
|
@ -24,10 +25,10 @@ class TrackPreferences(
|
|||
fun autoUpdateTrack() = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true)
|
||||
|
||||
companion object {
|
||||
fun trackUsername(syncId: Long) = "pref_mangasync_username_$syncId"
|
||||
fun trackUsername(syncId: Long) = Preference.privateKey("pref_mangasync_username_$syncId")
|
||||
|
||||
private fun trackPassword(syncId: Long) = "pref_mangasync_password_$syncId"
|
||||
private fun trackPassword(syncId: Long) = Preference.privateKey("pref_mangasync_password_$syncId")
|
||||
|
||||
private fun trackToken(syncId: Long) = "track_token_$syncId"
|
||||
private fun trackToken(syncId: Long) = Preference.privateKey("track_token_$syncId")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.util.system.DeviceUtil
|
|||
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.system.workManager
|
||||
import tachiyomi.core.preference.Preference
|
||||
import tachiyomi.core.preference.PreferenceStore
|
||||
import tachiyomi.core.preference.TriState
|
||||
import tachiyomi.core.preference.getAndSet
|
||||
|
@ -381,6 +382,19 @@ object Migrations {
|
|||
uiPreferences.relativeTime().set(false)
|
||||
}
|
||||
}
|
||||
if (oldVersion < 107) {
|
||||
preferenceStore.getAll()
|
||||
.filter { it.key.startsWith("pref_mangasync_") || it.key.startsWith("track_token_") }
|
||||
.forEach { (key, value) ->
|
||||
if (value is String) {
|
||||
preferenceStore
|
||||
.getString(Preference.privateKey(key))
|
||||
.set(value)
|
||||
|
||||
preferenceStore.getString(key).delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import logcat.LogPriority
|
|||
import okio.buffer
|
||||
import okio.gzip
|
||||
import okio.sink
|
||||
import tachiyomi.core.preference.Preference
|
||||
import tachiyomi.core.preference.PreferenceStore
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import tachiyomi.data.DatabaseHandler
|
||||
|
@ -235,19 +236,21 @@ class BackupManager(
|
|||
private fun backupAppPreferences(flags: Int): List<BackupPreference> {
|
||||
if (flags and BACKUP_APP_PREFS_MASK != BACKUP_APP_PREFS) return emptyList()
|
||||
|
||||
return preferenceStore.getAll().mapNotNull { (key, value) ->
|
||||
when (value) {
|
||||
is Int -> BackupPreference(key, IntPreferenceValue(value))
|
||||
is Long -> BackupPreference(key, LongPreferenceValue(value))
|
||||
is Float -> BackupPreference(key, FloatPreferenceValue(value))
|
||||
is String -> BackupPreference(key, StringPreferenceValue(value))
|
||||
is Boolean -> BackupPreference(key, BooleanPreferenceValue(value))
|
||||
is Set<*> -> (value as? Set<String>)?.let {
|
||||
BackupPreference(key, StringSetPreferenceValue(it))
|
||||
return preferenceStore.getAll()
|
||||
.filterKeys { !Preference.isPrivate(it) }
|
||||
.mapNotNull { (key, value) ->
|
||||
when (value) {
|
||||
is Int -> BackupPreference(key, IntPreferenceValue(value))
|
||||
is Long -> BackupPreference(key, LongPreferenceValue(value))
|
||||
is Float -> BackupPreference(key, FloatPreferenceValue(value))
|
||||
is String -> BackupPreference(key, StringPreferenceValue(value))
|
||||
is Boolean -> BackupPreference(key, BooleanPreferenceValue(value))
|
||||
is Set<*> -> (value as? Set<String>)?.let {
|
||||
BackupPreference(key, StringSetPreferenceValue(it))
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal suspend fun restoreExistingManga(manga: Manga, dbManga: Mangas): Manga {
|
||||
|
|
|
@ -21,6 +21,24 @@ interface Preference<T> {
|
|||
fun changes(): Flow<T>
|
||||
|
||||
fun stateIn(scope: CoroutineScope): StateFlow<T>
|
||||
|
||||
val isPrivate: Boolean
|
||||
get() = key().startsWith(PRIVATE_PREFIX)
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* A preference that should not be exposed in places like backups.
|
||||
*/
|
||||
fun isPrivate(key: String): Boolean {
|
||||
return key.startsWith(PRIVATE_PREFIX)
|
||||
}
|
||||
|
||||
fun privateKey(key: String): String {
|
||||
return "${PRIVATE_PREFIX}$key"
|
||||
}
|
||||
|
||||
private const val PRIVATE_PREFIX = "__PRIVATE_"
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T, R : T> Preference<T>.getAndSet(crossinline block: (T) -> R) = set(
|
||||
|
|
|
@ -504,7 +504,7 @@
|
|||
<string name="restoring_backup">Restoring backup</string>
|
||||
<string name="restoring_backup_error">Restoring backup failed</string>
|
||||
<string name="restoring_backup_canceled">Canceled restore</string>
|
||||
<string name="backup_info">You should keep copies of backups in other places as well.</string>
|
||||
<string name="backup_info">You should keep copies of backups in other places as well. Backups may contain sensitive data including any stored passwords; be careful if sharing.</string>
|
||||
|
||||
<!-- Sync section -->
|
||||
<string name="syncing_library">Syncing library</string>
|
||||
|
|
Référencer dans un nouveau ticket