From a0cb813fc4ca4b1c8cf20ba264de985045cbc7e5 Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 31 Oct 2023 15:06:02 +0500 Subject: [PATCH 1/6] added encrypted prefs --- sdk/build.gradle | 1 + .../preference/BasePreferenceRepository.kt | 7 +------ .../preference/SharedPreferenceRepository.kt | 21 ++++++++++++++++++- .../preference/SitePreferenceRepository.kt | 7 +++++++ 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/sdk/build.gradle b/sdk/build.gradle index f7c7fde78..09ba2f582 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -57,6 +57,7 @@ dependencies { implementation Dependencies.coroutinesCore implementation Dependencies.coroutinesAndroid + implementation 'androidx.security:security-crypto:1.1.0-alpha06' implementation Dependencies.retrofit implementation Dependencies.moshi implementation Dependencies.retrofitMoshiConverter diff --git a/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt b/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt index 514e37108..85402a226 100644 --- a/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt +++ b/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt @@ -9,12 +9,7 @@ import android.content.SharedPreferences internal abstract class BasePreferenceRepository(val context: Context) { abstract val prefsName: String - - internal val prefs: SharedPreferences - get() = context.applicationContext.getSharedPreferences( - prefsName, - Context.MODE_PRIVATE - ) + protected abstract val prefs: SharedPreferences // this would clear the prefs asynchronously open fun clearAll() { diff --git a/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt b/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt index 9defef649..2fb28a965 100644 --- a/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt +++ b/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt @@ -1,6 +1,9 @@ package io.customer.sdk.repository.preference import android.content.Context +import android.content.SharedPreferences +import androidx.security.crypto.EncryptedSharedPreferences +import androidx.security.crypto.MasterKey import io.customer.sdk.Version import io.customer.sdk.data.model.Region import io.customer.sdk.data.store.Client @@ -17,7 +20,23 @@ internal class SharedPreferenceRepositoryImp(context: Context) : SharedPreferenc BasePreferenceRepository(context) { override val prefsName: String by lazy { - "io.customer.sdk.${context.packageName}.PREFERENCE_FILE_KEY" + "io.customer.sdk.SECURE_PREFERENCE_FILE_KEY" + } + + override val prefs: SharedPreferences + + init { + val masterKey = MasterKey.Builder(context) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build() + + prefs = EncryptedSharedPreferences.create( + context, + prefsName, + masterKey, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + ) } override fun saveSettings( diff --git a/sdk/src/main/java/io/customer/sdk/repository/preference/SitePreferenceRepository.kt b/sdk/src/main/java/io/customer/sdk/repository/preference/SitePreferenceRepository.kt index 92f30c7a6..123d5fc0b 100644 --- a/sdk/src/main/java/io/customer/sdk/repository/preference/SitePreferenceRepository.kt +++ b/sdk/src/main/java/io/customer/sdk/repository/preference/SitePreferenceRepository.kt @@ -1,6 +1,7 @@ package io.customer.sdk.repository.preference import android.content.Context +import android.content.SharedPreferences import io.customer.sdk.CustomerIOConfig import io.customer.sdk.extensions.getDate import io.customer.sdk.extensions.putDate @@ -28,6 +29,12 @@ internal class SitePreferenceRepositoryImpl( "io.customer.sdk.${context.packageName}.${config.siteId}" } + override val prefs: SharedPreferences + get() = context.applicationContext.getSharedPreferences( + prefsName, + Context.MODE_PRIVATE + ) + companion object { private const val KEY_IDENTIFIER = "identifier" private const val KEY_DEVICE_TOKEN = "device_token" From 78ddfcfd1da5820e7afd8f9805797519fd3e7bb7 Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 31 Oct 2023 15:06:27 +0500 Subject: [PATCH 2/6] added backup rules --- messagingpush/src/main/AndroidManifest.xml | 2 +- messagingpush/src/main/res/xml/backup_rules.xml | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 messagingpush/src/main/res/xml/backup_rules.xml diff --git a/messagingpush/src/main/AndroidManifest.xml b/messagingpush/src/main/AndroidManifest.xml index 2f4af990f..e3132f963 100644 --- a/messagingpush/src/main/AndroidManifest.xml +++ b/messagingpush/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ - + diff --git a/messagingpush/src/main/res/xml/backup_rules.xml b/messagingpush/src/main/res/xml/backup_rules.xml new file mode 100644 index 000000000..630f26290 --- /dev/null +++ b/messagingpush/src/main/res/xml/backup_rules.xml @@ -0,0 +1,7 @@ + + + + + From 8c3eccc6649826e7cc0d8cc94f90020510c4b5eb Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 31 Oct 2023 16:19:18 +0500 Subject: [PATCH 3/6] update dependency reference --- buildSrc/src/main/kotlin/io.customer/android/Dependencies.kt | 2 ++ buildSrc/src/main/kotlin/io.customer/android/Versions.kt | 3 +++ sdk/build.gradle | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/io.customer/android/Dependencies.kt b/buildSrc/src/main/kotlin/io.customer/android/Dependencies.kt index 44d58abea..0c71b12c1 100644 --- a/buildSrc/src/main/kotlin/io.customer/android/Dependencies.kt +++ b/buildSrc/src/main/kotlin/io.customer/android/Dependencies.kt @@ -3,6 +3,8 @@ package io.customer.android object Dependencies { const val androidGradlePlugin = "com.android.tools.build:gradle:${Versions.ANDROID_GRADLE_PLUGIN}" + const val androidxSecurityCrypto = + "androidx.security:security-crypto:${Versions.ANDROIDX_SECURITY_CRYPTO}" const val androidxTestJunit = "androidx.test.ext:junit:${Versions.ANDROIDX_TEST_JUNIT}" const val androidxTestRunner = "androidx.test:runner:${Versions.ANDROIDX_TEST_RUNNER}" const val androidxTestRules = "androidx.test:rules:${Versions.ANDROIDX_TEST_RULES}" diff --git a/buildSrc/src/main/kotlin/io.customer/android/Versions.kt b/buildSrc/src/main/kotlin/io.customer/android/Versions.kt index 26cad265f..d4ff357a7 100644 --- a/buildSrc/src/main/kotlin/io.customer/android/Versions.kt +++ b/buildSrc/src/main/kotlin/io.customer/android/Versions.kt @@ -2,6 +2,9 @@ package io.customer.android object Versions { internal const val ANDROID_GRADLE_PLUGIN = "7.2.0" + + // Using alpha version as current stable version (1.0.0) has minSdkVersion 23 + internal const val ANDROIDX_SECURITY_CRYPTO = "1.1.0-alpha06" internal const val ANDROIDX_TEST_JUNIT = "1.1.4" internal const val ANDROIDX_TEST_RUNNER = "1.4.0" internal const val ANDROIDX_TEST_RULES = "1.4.0" diff --git a/sdk/build.gradle b/sdk/build.gradle index 09ba2f582..22668c82f 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -57,7 +57,7 @@ dependencies { implementation Dependencies.coroutinesCore implementation Dependencies.coroutinesAndroid - implementation 'androidx.security:security-crypto:1.1.0-alpha06' + implementation Dependencies.androidxSecurityCrypto implementation Dependencies.retrofit implementation Dependencies.moshi implementation Dependencies.retrofitMoshiConverter From 0031499e124c05cc3b05875ccf2fcfd43a85e5df Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 31 Oct 2023 16:20:45 +0500 Subject: [PATCH 4/6] revert access modifier --- .../sdk/repository/preference/BasePreferenceRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt b/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt index 85402a226..706279dd7 100644 --- a/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt +++ b/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt @@ -9,7 +9,7 @@ import android.content.SharedPreferences internal abstract class BasePreferenceRepository(val context: Context) { abstract val prefsName: String - protected abstract val prefs: SharedPreferences + internal abstract val prefs: SharedPreferences // this would clear the prefs asynchronously open fun clearAll() { From 4764f177387dfa7dfaf91b2aaabba235380c174f Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 31 Oct 2023 16:33:21 +0500 Subject: [PATCH 5/6] added comments --- messagingpush/src/main/res/xml/backup_rules.xml | 5 +++-- .../sdk/repository/preference/BasePreferenceRepository.kt | 2 ++ .../repository/preference/SharedPreferenceRepository.kt | 7 ++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/messagingpush/src/main/res/xml/backup_rules.xml b/messagingpush/src/main/res/xml/backup_rules.xml index 630f26290..3a1c4ebcf 100644 --- a/messagingpush/src/main/res/xml/backup_rules.xml +++ b/messagingpush/src/main/res/xml/backup_rules.xml @@ -1,7 +1,8 @@ - + + path="io.customer.sdk.EncryptedConfigCache.xml" /> diff --git a/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt b/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt index 706279dd7..6961342b1 100644 --- a/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt +++ b/sdk/src/main/java/io/customer/sdk/repository/preference/BasePreferenceRepository.kt @@ -9,6 +9,8 @@ import android.content.SharedPreferences internal abstract class BasePreferenceRepository(val context: Context) { abstract val prefsName: String + + // Making this abstract so base class has option to use encrypted shared prefs internal abstract val prefs: SharedPreferences // this would clear the prefs asynchronously diff --git a/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt b/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt index 2fb28a965..31ddc4a12 100644 --- a/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt +++ b/sdk/src/main/java/io/customer/sdk/repository/preference/SharedPreferenceRepository.kt @@ -19,8 +19,13 @@ internal interface SharedPreferenceRepository { internal class SharedPreferenceRepositoryImp(context: Context) : SharedPreferenceRepository, BasePreferenceRepository(context) { + // The file name used for storing shared preferences. + // This preference file should not be included in Auto Backup. + // Upon restoration, the encryption key originally used may no longer be present. + // To prevent this, ensure the file name matches the one excluded in backup_rules.xml. + // Read more: https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences override val prefsName: String by lazy { - "io.customer.sdk.SECURE_PREFERENCE_FILE_KEY" + "io.customer.sdk.EncryptedConfigCache" } override val prefs: SharedPreferences From 9a32ba89a3952469d539635e1427f5a58f8a4f7c Mon Sep 17 00:00:00 2001 From: Rehan Date: Tue, 31 Oct 2023 16:57:57 +0500 Subject: [PATCH 6/6] removed empty line