4242#import " FIRAuthKeychain.h"
4343#import " FIRAuthOperationType.h"
4444#import " FIRAuthSettings.h"
45+ #import " FIRAuthStoredUserManager.h"
4546#import " FIRUser_Internal.h"
4647#import " FirebaseAuth.h"
4748#import " FIRAuthBackend.h"
@@ -245,6 +246,11 @@ @interface FIRAuth () <FIRLibrary, FIRComponentLifecycleMaintainer>
245246 */
246247@property (nonatomic , copy , nullable ) NSString *additionalFrameworkMarker;
247248
249+ /* * @property storedUserManager
250+ @brief The stored user manager.
251+ */
252+ @property (nonatomic , strong , nullable ) FIRAuthStoredUserManager *storedUserManager;
253+
248254/* * @fn initWithApp:
249255 @brief Creates a @c FIRAuth instance associated with the provided @c FIRApp instance.
250256 @param app The application to associate the auth instance with.
@@ -390,11 +396,29 @@ - (nullable instancetype)initWithAPIKey:(NSString *)APIKey appName:(NSString *)a
390396 if (keychainServiceName) {
391397 strongSelf->_keychain = [[FIRAuthKeychain alloc ] initWithService: keychainServiceName];
392398 }
393- FIRUser *user;
399+
400+ strongSelf.storedUserManager =
401+ [[FIRAuthStoredUserManager alloc ] initWithServiceName: keychainServiceName];
402+
394403 NSError *error;
395- if ([strongSelf getUser: &user error: &error]) {
396- [strongSelf updateCurrentUser: user byForce: NO savingToDisk: NO error: &error];
397- self->_lastNotifiedUserToken = user.rawAccessToken ;
404+ NSString *storedUserAccessGroup = [strongSelf.storedUserManager getStoredUserAccessGroupWithError: &error];
405+ if (!error) {
406+ if (!storedUserAccessGroup) {
407+ FIRUser *user;
408+ if ([strongSelf getUser: &user error: &error]) {
409+ [strongSelf updateCurrentUser: user byForce: NO savingToDisk: NO error: &error];
410+ self->_lastNotifiedUserToken = user.rawAccessToken ;
411+ } else {
412+ FIRLogError (kFIRLoggerAuth , @" I-AUT000001" ,
413+ @" Error loading saved user when starting up: %@ " , error);
414+ }
415+ } else {
416+ [strongSelf useUserAccessGroup: storedUserAccessGroup error: &error];
417+ if (error) {
418+ FIRLogError (kFIRLoggerAuth , @" I-AUT000001" ,
419+ @" Error loading saved user when starting up: %@ " , error);
420+ }
421+ }
398422 } else {
399423 FIRLogError (kFIRLoggerAuth , @" I-AUT000001" ,
400424 @" Error loading saved user when starting up: %@ " , error);
@@ -1855,26 +1879,40 @@ - (BOOL)updateCurrentUser:(nullable FIRUser *)user
18551879/* * @fn saveUser:error:
18561880 @brief Persists user.
18571881 @param user The user to save.
1858- @param error Return value for any error which occurs.
1882+ @param outError Return value for any error which occurs.
18591883 @return @YES on success, @NO otherwise.
18601884 */
18611885- (BOOL )saveUser : (FIRUser *)user
1862- error : (NSError *_Nullable *_Nullable)error {
1886+ error : (NSError *_Nullable *_Nullable)outError {
18631887 BOOL success;
1864- NSString *userKey = [NSString stringWithFormat: kUserKey , _firebaseAppName];
18651888
1866- if (!user) {
1867- success = [_keychain removeDataForKey: userKey error: error];
1889+ if (!self.userAccessGroup ) {
1890+ NSString *userKey = [NSString stringWithFormat: kUserKey , _firebaseAppName];
1891+ if (!user) {
1892+ success = [_keychain removeDataForKey: userKey error: outError];
1893+ } else {
1894+ // Encode the user object.
1895+ NSMutableData *archiveData = [NSMutableData data ];
1896+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc ] initForWritingWithMutableData: archiveData];
1897+ [archiver encodeObject: user forKey: userKey];
1898+ [archiver finishEncoding ];
1899+
1900+ // Save the user object's encoded value.
1901+ success = [_keychain setData: archiveData forKey: userKey error: outError];
1902+ }
18681903 } else {
1869- // Encode the user object.
1870- NSMutableData *archiveData = [NSMutableData data ];
1871- NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc ] initForWritingWithMutableData: archiveData];
1872- [archiver encodeObject: user forKey: userKey];
1873- [archiver finishEncoding ];
1874-
1875- // Save the user object's encoded value.
1876- success = [_keychain setData: archiveData forKey: userKey error: error];
1904+ if (!user) {
1905+ success = [self .storedUserManager removeStoredUserForAccessGroup: self .userAccessGroup
1906+ projectIdentifier: self .app.options.APIKey
1907+ error: outError];
1908+ } else {
1909+ success = [self .storedUserManager setStoredUser: user
1910+ forAccessGroup: self .userAccessGroup
1911+ projectIdentifier: self .app.options.APIKey
1912+ error: outError];
1913+ }
18771914 }
1915+
18781916 return success;
18791917}
18801918
@@ -1887,26 +1925,44 @@ - (BOOL)saveUser:(FIRUser *)user
18871925 */
18881926- (BOOL )getUser : (FIRUser *_Nullable *)outUser
18891927 error : (NSError *_Nullable *_Nullable)error {
1890- NSString *userKey = [NSString stringWithFormat: kUserKey , _firebaseAppName];
1928+ if (!self.userAccessGroup ) {
1929+ NSString *userKey = [NSString stringWithFormat: kUserKey , _firebaseAppName];
18911930
1892- NSError *keychainError;
1893- NSData *encodedUserData = [_keychain dataForKey: userKey error: &keychainError];
1894- if (keychainError) {
1895- if (error) {
1896- *error = keychainError;
1931+ NSError *keychainError;
1932+ NSData *encodedUserData = [_keychain dataForKey: userKey error: &keychainError];
1933+ if (keychainError) {
1934+ if (error) {
1935+ *error = keychainError;
1936+ }
1937+ return NO ;
18971938 }
1898- return NO ;
1899- }
1900- if (!encodedUserData) {
1901- *outUser = nil ;
1939+ if (!encodedUserData) {
1940+ *outUser = nil ;
1941+ return YES ;
1942+ }
1943+ NSKeyedUnarchiver *unarchiver =
1944+ [[NSKeyedUnarchiver alloc ] initForReadingWithData: encodedUserData];
1945+ FIRUser *user = [unarchiver decodeObjectOfClass: [FIRUser class ] forKey: userKey];
1946+ user.auth = self;
1947+ *outUser = user;
1948+
19021949 return YES ;
1950+ } else {
1951+ FIRUser *user = [self .storedUserManager getStoredUserForAccessGroup: self .userAccessGroup
1952+ projectIdentifier: self .app.options.APIKey
1953+ error: error];
1954+ user.auth = self;
1955+ *outUser = user;
1956+ if (user) {
1957+ return YES ;
1958+ } else {
1959+ if (error && *error) {
1960+ return NO ;
1961+ } else {
1962+ return YES ;
1963+ }
1964+ }
19031965 }
1904- NSKeyedUnarchiver *unarchiver =
1905- [[NSKeyedUnarchiver alloc ] initForReadingWithData: encodedUserData];
1906- FIRUser *user = [unarchiver decodeObjectOfClass: [FIRUser class ] forKey: userKey];
1907- user.auth = self;
1908- *outUser = user;
1909- return YES ;
19101966}
19111967
19121968#pragma mark - Interoperability
@@ -2011,6 +2067,58 @@ - (nullable NSString *)getUserID {
20112067 return _currentUser.uid ;
20122068}
20132069
2070+ #pragma mark - Keychain sharing
2071+
2072+ - (BOOL )useUserAccessGroup : (NSString *_Nullable)accessGroup
2073+ error : (NSError *_Nullable *_Nullable)outError {
2074+ BOOL success;
2075+ success = [self .storedUserManager setStoredUserAccessGroup: accessGroup error: outError];
2076+ if (!success) {
2077+ return NO ;
2078+ }
2079+
2080+ FIRUser *user = [self getStoredUserForAccessGroup: accessGroup error: outError];
2081+ if (!user && outError && *outError) {
2082+ return NO ;
2083+ }
2084+ success = [self updateCurrentUser: user byForce: NO savingToDisk: NO error: outError];
2085+ if (!success) {
2086+ return NO ;
2087+ }
2088+
2089+ if (_userAccessGroup == nil && accessGroup != nil ) {
2090+ NSString *userKey = [NSString stringWithFormat: kUserKey , _firebaseAppName];
2091+ [_keychain removeDataForKey: userKey error: outError];
2092+ }
2093+ _userAccessGroup = accessGroup;
2094+ self->_lastNotifiedUserToken = user.rawAccessToken ;
2095+
2096+ return YES ;
2097+ }
2098+
2099+ - (FIRUser *)getStoredUserForAccessGroup : (NSString *_Nullable)accessGroup
2100+ error : (NSError *_Nullable *_Nullable)outError {
2101+ FIRUser *user;
2102+ if (!accessGroup) {
2103+ NSString *userKey = [NSString stringWithFormat: kUserKey , _firebaseAppName];
2104+ NSData *encodedUserData = [_keychain dataForKey: userKey error: outError];
2105+ if (!encodedUserData) {
2106+ return nil ;
2107+ }
2108+
2109+ NSKeyedUnarchiver *unarchiver =
2110+ [[NSKeyedUnarchiver alloc ] initForReadingWithData: encodedUserData];
2111+ user = [unarchiver decodeObjectOfClass: [FIRUser class ] forKey: userKey];
2112+ user.auth = self;
2113+ } else {
2114+ user = [self .storedUserManager getStoredUserForAccessGroup: self .userAccessGroup
2115+ projectIdentifier: self .app.options.APIKey
2116+ error: outError];
2117+ }
2118+
2119+ return user;
2120+ }
2121+
20142122@end
20152123
20162124NS_ASSUME_NONNULL_END
0 commit comments