Skip to content

Commit 293b87b

Browse files
committed
Fix Device Metadata migration used for Device Tracking if an aliased userId was used.
1 parent 83605cb commit 293b87b

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/actions/CredentialStoreCognitoActions.kt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,26 @@ internal object CredentialStoreCognitoActions : CredentialStoreActions {
3636
legacyCredentialStore.deleteCredential()
3737
}
3838

39-
// migrate device data
40-
val lastAuthUserId = legacyCredentialStore.retrieveLastAuthUserId()
41-
lastAuthUserId?.let {
42-
val deviceMetaData = legacyCredentialStore.retrieveDeviceMetadata(lastAuthUserId)
39+
/*
40+
Migrate Device Metadata
41+
1. We first need to get the list of userIds that contain device metadata on the device.
42+
2. For each userId, we check to see if the current credential store has device metadata for that user.
43+
3. If the current user does not have device metadata in the current store, migrate from legacy.
44+
This is a possibility because of a bug where we were previously attempting to migrate using an aliased
45+
userId lookup. This situation would happen if a user migrated, signed out, then signed back in. Upon
46+
signing back in, they would be granted new device metadata. Since that new metadata is what is
47+
associated with the refresh token, we do not want to overwrite it.
48+
4. If the current user has device metadata in the current credential store, do not migrate from legacy.
49+
5. Upon migration completion, we delete the legacy device metadata.
50+
*/
51+
legacyCredentialStore.retrieveDeviceMetadataUserIdList().forEach { userId ->
52+
val deviceMetaData = legacyCredentialStore.retrieveDeviceMetadata(userId)
4353
if (deviceMetaData != DeviceMetadata.Empty) {
44-
credentialStore.saveDeviceMetadata(lastAuthUserId, deviceMetaData)
45-
legacyCredentialStore.deleteDeviceKeyCredential(lastAuthUserId)
54+
credentialStore.retrieveDeviceMetadata(userId)
55+
if (credentialStore.retrieveDeviceMetadata(userId) == DeviceMetadata.Empty) {
56+
credentialStore.saveDeviceMetadata(userId, deviceMetaData)
57+
}
58+
legacyCredentialStore.deleteDeviceKeyCredential(userId)
4659
}
4760
}
4861

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/data/AWSCognitoLegacyCredentialStore.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.amplifyframework.statemachine.codegen.data.DeviceMetadata
2929
import com.amplifyframework.statemachine.codegen.data.FederatedToken
3030
import com.amplifyframework.statemachine.codegen.data.SignInMethod
3131
import com.amplifyframework.statemachine.codegen.data.SignedInData
32+
import java.io.File
3233
import java.time.Instant
3334
import java.time.temporal.ChronoUnit
3435
import java.util.Date
@@ -74,6 +75,7 @@ internal class AWSCognitoLegacyCredentialStore(
7475
const val TOKEN_KEY = "token"
7576
}
7677

78+
private val userDeviceDetailsCacheKeyPrefix = "$APP_DEVICE_INFO_CACHE.${authConfiguration.userPool?.poolId}."
7779
private val userDeviceDetailsCacheKey = "$APP_DEVICE_INFO_CACHE.${authConfiguration.userPool?.poolId}.%s"
7880

7981
private val idAndCredentialsKeyValue: KeyValueRepository by lazy {
@@ -229,6 +231,22 @@ internal class AWSCognitoLegacyCredentialStore(
229231
)
230232
}
231233

234+
/*
235+
During migration away from the legacy credential store, we need to find all shared preference files that store
236+
device metadata. These filenames contain the real userId (not aliased) for the tracked device metadata.
237+
*/
238+
fun retrieveDeviceMetadataUserIdList(): List<String> {
239+
return try {
240+
val sharedPrefsSuffix = ".xml"
241+
File(context.dataDir, "shared_prefs").listFiles { _, filename ->
242+
filename.startsWith(userDeviceDetailsCacheKeyPrefix) && filename.endsWith(sharedPrefsSuffix)
243+
}?.map { it.name.substringAfter(userDeviceDetailsCacheKeyPrefix).substringBefore(sharedPrefsSuffix) }
244+
?.filter { it.isNotBlank() } ?: emptyList()
245+
} catch (e: Exception) {
246+
return emptyList()
247+
}
248+
}
249+
232250
@Synchronized
233251
override fun retrieveDeviceMetadata(username: String): DeviceMetadata {
234252
val deviceDetailsCacheKey = String.format(userDeviceDetailsCacheKey, username)

0 commit comments

Comments
 (0)