@@ -13,6 +13,7 @@ struct AWSCognitoAuthCredentialStore {
13
13
14
14
// Credential store constants
15
15
private let service = " com.amplify.awsCognitoAuthPlugin "
16
+ private let sharedService = " com.amplify.awsCognitoAuthPluginShared "
16
17
private let sessionKey = " session "
17
18
private let deviceMetadataKey = " deviceMetadata "
18
19
private let deviceASFKey = " deviceASF "
@@ -25,14 +26,40 @@ struct AWSCognitoAuthCredentialStore {
25
26
private var isKeychainConfiguredKey : String {
26
27
" \( userDefaultsNameSpace) .isKeychainConfigured "
27
28
}
29
+ /// This UserDefaults Key is use to retrieve the stored access group to determine
30
+ /// which access group the migration should happen from
31
+ /// If none is found, the unshared service is used for migration and all items
32
+ /// under that service are queried
33
+ private var accessGroupKey : String {
34
+ " \( userDefaultsNameSpace) .accessGroup "
35
+ }
28
36
29
37
private let authConfiguration : AuthConfiguration
30
38
private let keychain : KeychainStoreBehavior
31
39
private let userDefaults = UserDefaults . standard
40
+ private let accessGroup : String ?
32
41
33
- init ( authConfiguration: AuthConfiguration , accessGroup: String ? = nil ) {
42
+ init (
43
+ authConfiguration: AuthConfiguration ,
44
+ accessGroup: String ? = nil ,
45
+ migrateKeychainItemsOfUserSession: Bool = false
46
+ ) {
34
47
self . authConfiguration = authConfiguration
35
- self . keychain = KeychainStore ( service: service, accessGroup: accessGroup)
48
+ self . accessGroup = accessGroup
49
+ if let accessGroup {
50
+ self . keychain = KeychainStore ( service: sharedService, accessGroup: accessGroup)
51
+ } else {
52
+ self . keychain = KeychainStore ( service: service)
53
+ }
54
+
55
+ let oldAccessGroup = retrieveStoredAccessGroup ( )
56
+ if migrateKeychainItemsOfUserSession {
57
+ try ? migrateKeychainItemsToAccessGroup ( )
58
+ } else if oldAccessGroup == nil && oldAccessGroup != accessGroup {
59
+ try ? KeychainStore ( service: service) . _removeAll ( )
60
+ }
61
+
62
+ saveStoredAccessGroup ( )
36
63
37
64
if !userDefaults. bool ( forKey: isKeychainConfiguredKey) {
38
65
try ? clearAllCredentials ( )
@@ -181,6 +208,39 @@ extension AWSCognitoAuthCredentialStore: AmplifyAuthCredentialStoreBehavior {
181
208
private func clearAllCredentials( ) throws {
182
209
try keychain. _removeAll ( )
183
210
}
211
+
212
+ private func retrieveStoredAccessGroup( ) -> String ? {
213
+ return userDefaults. string ( forKey: accessGroupKey)
214
+ }
215
+
216
+ private func saveStoredAccessGroup( ) {
217
+ if let accessGroup {
218
+ userDefaults. set ( accessGroup, forKey: accessGroupKey)
219
+ } else {
220
+ userDefaults. removeObject ( forKey: accessGroupKey)
221
+ }
222
+ }
223
+
224
+ private func migrateKeychainItemsToAccessGroup( ) throws {
225
+ let oldAccessGroup = retrieveStoredAccessGroup ( )
226
+
227
+ if oldAccessGroup == accessGroup {
228
+ log. info ( " [AWSCognitoAuthCredentialStore] Stored access group is the same as current access group, aborting migration " )
229
+ return
230
+ }
231
+
232
+ let oldService = oldAccessGroup != nil ? sharedService : service
233
+ let newService = accessGroup != nil ? sharedService : service
234
+
235
+ do {
236
+ try KeychainStoreMigrator ( oldService: oldService, newService: newService, oldAccessGroup: oldAccessGroup, newAccessGroup: accessGroup) . migrate ( )
237
+ } catch {
238
+ log. error ( " [AWSCognitoAuthCredentialStore] Migration has failed " )
239
+ return
240
+ }
241
+
242
+ log. verbose ( " [AWSCognitoAuthCredentialStore] Migration of keychain items from old access group to new access group successful " )
243
+ }
184
244
185
245
}
186
246
@@ -204,3 +264,5 @@ private extension AWSCognitoAuthCredentialStore {
204
264
}
205
265
206
266
}
267
+
268
+ extension AWSCognitoAuthCredentialStore : DefaultLogger { }
0 commit comments