diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-08-31 23:07:20 +0200 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-08-31 23:07:20 +0200 |
| commit | 22721a013bdd10d5eb395ba18453585f5f3f1f7f (patch) | |
| tree | 5a920e31d6026ed5dc55265e5fd057febccc50e3 /StoneIsland/platforms/ios/Pods/FirebaseInstanceID | |
| parent | d22d51a1ae49680015326857360eb699f31efced (diff) | |
rebuild the ios platform and the plugins
Diffstat (limited to 'StoneIsland/platforms/ios/Pods/FirebaseInstanceID')
76 files changed, 8942 insertions, 0 deletions
diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h new file mode 100644 index 00000000..ac1893fa --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h @@ -0,0 +1,147 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +// The format of the debug code will show in the log as: e.g. +// for code 1000, it will show as I-IID001000. +typedef NS_ENUM(NSInteger, FIRInstanceIDMessageCode) { + // DO NOT USE 2000, 2002. + kFIRInstanceIDMessageCodeFIRApp000 = 1000, // I-IID001000 + kFIRInstanceIDMessageCodeFIRApp001 = 1001, + kFIRInstanceIDMessageCodeFIRApp002 = 1002, + kFIRInstanceIDMessageCodeInternal001 = 2001, + kFIRInstanceIDMessageCodeInternal002 = 2002, + // FIRInstanceID.m + // DO NOT USE 4000. + kFIRInstanceIDMessageCodeInstanceID000 = 3000, + kFIRInstanceIDMessageCodeInstanceID001 = 3001, + kFIRInstanceIDMessageCodeInstanceID002 = 3002, + kFIRInstanceIDMessageCodeInstanceID003 = 3003, + kFIRInstanceIDMessageCodeInstanceID004 = 3004, + kFIRInstanceIDMessageCodeInstanceID005 = 3005, + kFIRInstanceIDMessageCodeInstanceID006 = 3006, + kFIRInstanceIDMessageCodeInstanceID007 = 3007, + kFIRInstanceIDMessageCodeInstanceID008 = 3008, + kFIRInstanceIDMessageCodeInstanceID009 = 3009, + kFIRInstanceIDMessageCodeInstanceID010 = 3010, + kFIRInstanceIDMessageCodeInstanceID011 = 3011, + kFIRInstanceIDMessageCodeInstanceID012 = 3012, + kFIRInstanceIDMessageCodeInstanceID013 = 3013, + kFIRInstanceIDMessageCodeInstanceID014 = 3014, + kFIRInstanceIDMessageCodeInstanceID015 = 3015, + kFIRInstanceIDMessageCodeRefetchingTokenForAPNS = 3016, + kFIRInstanceIDMessageCodeInstanceID017 = 3017, + kFIRInstanceIDMessageCodeInstanceID018 = 3018, + // FIRInstanceIDAuthService.m + kFIRInstanceIDMessageCodeAuthService000 = 5000, + kFIRInstanceIDMessageCodeAuthService001 = 5001, + kFIRInstanceIDMessageCodeAuthService002 = 5002, + kFIRInstanceIDMessageCodeAuthService003 = 5003, + kFIRInstanceIDMessageCodeAuthService004 = 5004, + kFIRInstanceIDMessageCodeAuthServiceCheckinInProgress = 5004, + + // FIRInstanceIDBackupExcludedPlist.m + // Do NOT USE 6003 + kFIRInstanceIDMessageCodeBackupExcludedPlist000 = 6000, + kFIRInstanceIDMessageCodeBackupExcludedPlist001 = 6001, + kFIRInstanceIDMessageCodeBackupExcludedPlist002 = 6002, + // FIRInstanceIDCheckinService.m + kFIRInstanceIDMessageCodeService000 = 7000, + kFIRInstanceIDMessageCodeService001 = 7001, + kFIRInstanceIDMessageCodeService002 = 7002, + kFIRInstanceIDMessageCodeService003 = 7003, + kFIRInstanceIDMessageCodeService004 = 7004, + kFIRInstanceIDMessageCodeService005 = 7005, + kFIRInstanceIDMessageCodeService006 = 7006, + kFIRInstanceIDInvalidNetworkSession = 7007, + kFIRInstanceIDInvalidSettingResponse = 7008, + // FIRInstanceIDCheckinStore.m + // DO NOT USE 8002, 8004 - 8008 + kFIRInstanceIDMessageCodeCheckinStore000 = 8000, + kFIRInstanceIDMessageCodeCheckinStore001 = 8001, + kFIRInstanceIDMessageCodeCheckinStore003 = 8003, + kFIRInstanceIDMessageCodeCheckinStoreCheckinPlistDeleted = 8009, + kFIRInstanceIDMessageCodeCheckinStoreCheckinPlistSaved = 8010, + + // DO NOT USE 9000 - 9006 + + // DO NOT USE 10000 - 10009 + + // DO NOT USE 11000 - 11002 + + // DO NOT USE 12000 - 12014 + + // FIRInstanceIDStore.m + // DO NOT USE 13004, 13005, 13007, 13008, 13010, 13011, 13013, 13014 + kFIRInstanceIDMessageCodeStore000 = 13000, + kFIRInstanceIDMessageCodeStore001 = 13001, + kFIRInstanceIDMessageCodeStore002 = 13002, + kFIRInstanceIDMessageCodeStore003 = 13003, + kFIRInstanceIDMessageCodeStore006 = 13006, + kFIRInstanceIDMessageCodeStore009 = 13009, + kFIRInstanceIDMessageCodeStore012 = 13012, + // FIRInstanceIDTokenManager.m + // DO NOT USE 14002, 14005 + kFIRInstanceIDMessageCodeTokenManager000 = 14000, + kFIRInstanceIDMessageCodeTokenManager001 = 14001, + kFIRInstanceIDMessageCodeTokenManager003 = 14003, + kFIRInstanceIDMessageCodeTokenManager004 = 14004, + kFIRInstanceIDMessageCodeTokenManagerErrorDeletingFCMTokensOnAppReset = 14006, + kFIRInstanceIDMessageCodeTokenManagerDeletedFCMTokensOnAppReset = 14007, + kFIRInstanceIDMessageCodeTokenManagerSavedAppVersion = 14008, + kFIRInstanceIDMessageCodeTokenManagerErrorInvalidatingAllTokens = 14009, + kFIRInstanceIDMessageCodeTokenManagerAPNSChanged = 14010, + kFIRInstanceIDMessageCodeTokenManagerAPNSChangedTokenInvalidated = 14011, + kFIRInstanceIDMessageCodeTokenManagerInvalidateStaleToken = 14012, + // FIRInstanceIDTokenStore.m + // DO NOT USE 15002 - 15013 + kFIRInstanceIDMessageCodeTokenStore000 = 15000, + kFIRInstanceIDMessageCodeTokenStore001 = 15001, + kFIRInstanceIDMessageCodeTokenStoreExceptionUnarchivingTokenInfo = 15015, + + // DO NOT USE 16000, 18004 + + // FIRInstanceIDUtilities.m + kFIRInstanceIDMessageCodeUtilitiesMissingBundleIdentifier = 18000, + kFIRInstanceIDMessageCodeUtilitiesAppEnvironmentUtilNotAvailable = 18001, + kFIRInstanceIDMessageCodeUtilitiesCannotGetHardwareModel = 18002, + kFIRInstanceIDMessageCodeUtilitiesCannotGetSystemVersion = 18003, + // FIRInstanceIDTokenOperation.m + kFIRInstanceIDMessageCodeTokenOperationFailedToSignParams = 19000, + // FIRInstanceIDTokenFetchOperation.m + // DO NOT USE 20004, 20005 + kFIRInstanceIDMessageCodeTokenFetchOperationFetchRequest = 20000, + kFIRInstanceIDMessageCodeTokenFetchOperationRequestError = 20001, + kFIRInstanceIDMessageCodeTokenFetchOperationBadResponse = 20002, + kFIRInstanceIDMessageCodeTokenFetchOperationBadTokenStructure = 20003, + // FIRInstanceIDTokenDeleteOperation.m + kFIRInstanceIDMessageCodeTokenDeleteOperationFetchRequest = 21000, + kFIRInstanceIDMessageCodeTokenDeleteOperationRequestError = 21001, + kFIRInstanceIDMessageCodeTokenDeleteOperationBadResponse = 21002, + // FIRInstanceIDTokenInfo.m + kFIRInstanceIDMessageCodeTokenInfoBadAPNSInfo = 22000, + kFIRInstanceIDMessageCodeTokenInfoFirebaseAppIDChanged = 22001, + kFIRInstanceIDMessageCodeTokenInfoLocaleChanged = 22002, + // FIRInstanceIDKeychain.m + kFIRInstanceIDKeychainReadItemError = 23000, + kFIRInstanceIDKeychainAddItemError = 23001, + kFIRInstanceIDKeychainDeleteItemError = 23002, + kFIRInstanceIDKeychainCreateKeyPairError = 23003, + kFIRInstanceIDKeychainUpdateItemError = 23004, + + // DO NOT USE 24000, 24001 +}; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m new file mode 100644 index 00000000..df8ec8ed --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m @@ -0,0 +1,56 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceID+Private.h" + +#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h" + +#import <FirebaseInstanceID/FIRInstanceID_Private.h> +#import "FIRInstanceIDAuthService.h" +#import "FIRInstanceIDDefines.h" +#import "FIRInstanceIDTokenManager.h" + +@class FIRInstallations; + +@interface FIRInstanceID () + +@property(nonatomic, readonly, strong) FIRInstanceIDTokenManager *tokenManager; + +@end + +@implementation FIRInstanceID (Private) + +// This method just wraps our pre-configured auth service to make the request. +// This method is only needed by first-party users, like Remote Config. +- (void)fetchCheckinInfoWithHandler:(FIRInstanceIDDeviceCheckinCompletion)handler { + [self.tokenManager.authService fetchCheckinInfoWithHandler:handler]; +} + +// TODO(#4486): Delete the method, `self.firebaseInstallationsID` and related +// code for Firebase 7 release. +- (NSString *)appInstanceID:(NSError **)outError { + return self.firebaseInstallationsID; +} + +#pragma mark - Firebase Installations Compatibility + +/// Presence of this method indicates that this version of IID uses FirebaseInstallations under the +/// hood. It is checked by FirebaseInstallations SDK. ++ (BOOL)usesFIS { + return YES; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m new file mode 100644 index 00000000..178a0ce3 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m @@ -0,0 +1,1120 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceID.h" + +#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h" + +#import "FIRInstanceID+Private.h" +#import "FIRInstanceIDAuthService.h" +#import "FIRInstanceIDCheckinPreferences.h" +#import "FIRInstanceIDCombinedHandler.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDDefines.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDStore.h" +#import "FIRInstanceIDTokenInfo.h" +#import "FIRInstanceIDTokenManager.h" +#import "FIRInstanceIDUtilities.h" +#import "FIRInstanceIDVersionUtilities.h" +#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h" +#import "GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h" +#import "GoogleUtilities/UserDefaults/Private/GULUserDefaults.h" +#import "NSError+FIRInstanceID.h" + +// Public constants +NSString *const kFIRInstanceIDScopeFirebaseMessaging = @"fcm"; + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +const NSNotificationName kFIRInstanceIDTokenRefreshNotification = + @"com.firebase.iid.notif.refresh-token"; +#else +NSString *const kFIRInstanceIDTokenRefreshNotification = @"com.firebase.iid.notif.refresh-token"; +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +NSString *const kFIRInstanceIDInvalidNilHandlerError = @"Invalid nil handler."; + +// Private constants +int64_t const kMaxRetryIntervalForDefaultTokenInSeconds = 20 * 60; // 20 minutes +int64_t const kMinRetryIntervalForDefaultTokenInSeconds = 10; // 10 seconds +// we retry only a max 5 times. +// TODO(chliangGoogle): If we still fail we should listen for the network change notification +// since GCM would have started Reachability. We only start retrying after we see a configuration +// change. +NSInteger const kMaxRetryCountForDefaultToken = 5; + +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH +static NSString *const kEntitlementsAPSEnvironmentKey = @"Entitlements.aps-environment"; +#else +static NSString *const kEntitlementsAPSEnvironmentKey = + @"Entitlements.com.apple.developer.aps-environment"; +#endif +static NSString *const kAPSEnvironmentDevelopmentValue = @"development"; +/// FIRMessaging selector that returns the current FIRMessaging auto init +/// enabled flag. +static NSString *const kFIRInstanceIDFCMSelectorAutoInitEnabled = + @"isAutoInitEnabledWithUserDefaults:"; + +static NSString *const kFIRInstanceIDAPNSTokenType = @"APNSTokenType"; +static NSString *const kFIRIIDAppReadyToConfigureSDKNotification = + @"FIRAppReadyToConfigureSDKNotification"; +static NSString *const kFIRIIDAppNameKey = @"FIRAppNameKey"; +static NSString *const kFIRIIDErrorDomain = @"com.firebase.instanceid"; +static NSString *const kFIRIIDServiceInstanceID = @"InstanceID"; + +/** + * The APNS token type for the app. If the token type is set to `UNKNOWN` + * InstanceID will implicitly try to figure out what the actual token type + * is from the provisioning profile. + * This must match FIRMessagingAPNSTokenType in FIRMessaging.h + */ +typedef NS_ENUM(NSInteger, FIRInstanceIDAPNSTokenType) { + /// Unknown token type. + FIRInstanceIDAPNSTokenTypeUnknown, + /// Sandbox token type. + FIRInstanceIDAPNSTokenTypeSandbox, + /// Production token type. + FIRInstanceIDAPNSTokenTypeProd, +} NS_SWIFT_NAME(InstanceIDAPNSTokenType); + +@interface FIRInstanceIDResult () +@property(nonatomic, readwrite, copy) NSString *instanceID; +@property(nonatomic, readwrite, copy) NSString *token; +@end + +@interface FIRInstanceID () + +// FIRApp configuration objects. +@property(nonatomic, readwrite, copy) NSString *fcmSenderID; +@property(nonatomic, readwrite, copy) NSString *firebaseAppID; + +// Raw APNS token data +@property(nonatomic, readwrite, strong) NSData *apnsTokenData; + +@property(nonatomic, readwrite) FIRInstanceIDAPNSTokenType apnsTokenType; +// String-based, internal representation of APNS token +@property(nonatomic, readwrite, copy) NSString *APNSTupleString; +// Token fetched from the server automatically for the default app. +@property(nonatomic, readwrite, copy) NSString *defaultFCMToken; + +@property(nonatomic, readwrite, strong) FIRInstanceIDTokenManager *tokenManager; +@property(nonatomic, readwrite, strong) FIRInstallations *installations; + +// backoff and retry for default token +@property(nonatomic, readwrite, assign) NSInteger retryCountForDefaultToken; +@property(atomic, strong, nullable) + FIRInstanceIDCombinedHandler<NSString *> *defaultTokenFetchHandler; + +/// A cached value of FID. Should be used only for `-[FIRInstanceID appInstanceID:]`. +@property(atomic, copy, nullable) NSString *firebaseInstallationsID; + +@end + +// InstanceID doesn't provide any functionality to other components, +// so it provides a private, empty protocol that it conforms to and use it for registration. + +@protocol FIRInstanceIDInstanceProvider +@end + +@interface FIRInstanceID () <FIRInstanceIDInstanceProvider, FIRLibrary> +@end + +@implementation FIRInstanceIDResult +- (id)copyWithZone:(NSZone *)zone { + FIRInstanceIDResult *result = [[[self class] allocWithZone:zone] init]; + result.instanceID = self.instanceID; + result.token = self.token; + return result; +} +@end + +@implementation FIRInstanceID + +// File static to support InstanceID tests that call [FIRInstanceID instanceID] after +// [FIRInstanceID instanceIDForTests]. +static FIRInstanceID *gInstanceID; + ++ (instancetype)instanceID { + // If the static instance was created, return it. This should only be set in tests and we should + // eventually use proper dependency injection for a better test structure. + if (gInstanceID != nil) { + return gInstanceID; + } + FIRApp *defaultApp = [FIRApp defaultApp]; // Missing configure will be logged here. + FIRInstanceID *instanceID = + (FIRInstanceID *)FIR_COMPONENT(FIRInstanceIDInstanceProvider, defaultApp.container); + return instanceID; +} + +- (instancetype)initPrivately { + self = [super init]; + if (self != nil) { + // Use automatic detection of sandbox, unless otherwise set by developer + _apnsTokenType = FIRInstanceIDAPNSTokenTypeUnknown; + } + return self; +} + ++ (FIRInstanceID *)instanceIDForTests { + gInstanceID = [[FIRInstanceID alloc] initPrivately]; + [gInstanceID start]; + return gInstanceID; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - Tokens + +- (NSString *)token { + if (!self.fcmSenderID.length) { + return nil; + } + + NSString *cachedToken = [self cachedTokenIfAvailable]; + + if (cachedToken) { + return cachedToken; + } else { + // If we've never had a cached default token, we should fetch one because unrelatedly, + // this request will help us determine whether the locally-generated Instance ID keypair is not + // unique, and therefore generate a new one. + [self defaultTokenWithHandler:nil]; + return nil; + } +} + +- (void)instanceIDWithHandler:(FIRInstanceIDResultHandler)handler { + FIRInstanceID_WEAKIFY(self); + [self getIDWithHandler:^(NSString *identity, NSError *error) { + FIRInstanceID_STRONGIFY(self); + // This is in main queue already + if (error) { + if (handler) { + handler(nil, error); + } + return; + } + FIRInstanceIDResult *result = [[FIRInstanceIDResult alloc] init]; + result.instanceID = identity; + NSString *cachedToken = [self cachedTokenIfAvailable]; + if (cachedToken) { + if (handler) { + result.token = cachedToken; + handler(result, nil); + } + // If no handler, simply return since client has generated iid and token. + return; + } + [self defaultTokenWithHandler:^(NSString *_Nullable token, NSError *_Nullable error) { + if (handler) { + if (error) { + handler(nil, error); + return; + } + result.token = token; + handler(result, nil); + } + }]; + }]; +} + +- (NSString *)cachedTokenIfAvailable { + FIRInstanceIDTokenInfo *cachedTokenInfo = + [self.tokenManager cachedTokenInfoWithAuthorizedEntity:self.fcmSenderID + scope:kFIRInstanceIDDefaultTokenScope]; + return cachedTokenInfo.token; +} + +- (void)setDefaultFCMToken:(NSString *)defaultFCMToken { + // Sending this notification out will ensure that FIRMessaging and FIRInstanceID has the updated + // default FCM token. + // Only notify of token refresh if we have a new valid token that's different than before + if ((defaultFCMToken.length && _defaultFCMToken.length && + ![defaultFCMToken isEqualToString:_defaultFCMToken]) || + defaultFCMToken.length != _defaultFCMToken.length) { + NSNotification *tokenRefreshNotification = + [NSNotification notificationWithName:kFIRInstanceIDTokenRefreshNotification + object:[defaultFCMToken copy]]; + [[NSNotificationQueue defaultQueue] enqueueNotification:tokenRefreshNotification + postingStyle:NSPostASAP]; + } + + _defaultFCMToken = defaultFCMToken; +} + +- (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + options:(NSDictionary *)options + handler:(FIRInstanceIDTokenHandler)handler { + if (!handler) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID000, + kFIRInstanceIDInvalidNilHandlerError); + return; + } + + // Add internal options + NSMutableDictionary *tokenOptions = [NSMutableDictionary dictionary]; + if (options.count) { + [tokenOptions addEntriesFromDictionary:options]; + } + + NSString *APNSKey = kFIRInstanceIDTokenOptionsAPNSKey; + NSString *serverTypeKey = kFIRInstanceIDTokenOptionsAPNSIsSandboxKey; + if (tokenOptions[APNSKey] != nil && tokenOptions[serverTypeKey] == nil) { + // APNS key was given, but server type is missing. Supply the server type with automatic + // checking. This can happen when the token is requested from FCM, which does not include a + // server type during its request. + tokenOptions[serverTypeKey] = @([self isSandboxApp]); + } + if (self.firebaseAppID) { + tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID; + } + + // comparing enums to ints directly throws a warning + FIRInstanceIDErrorCode noError = INT_MAX; + FIRInstanceIDErrorCode errorCode = noError; + if (FIRInstanceIDIsValidGCMScope(scope) && !tokenOptions[APNSKey]) { + errorCode = kFIRInstanceIDErrorCodeMissingAPNSToken; + } else if (FIRInstanceIDIsValidGCMScope(scope) && + ![tokenOptions[APNSKey] isKindOfClass:[NSData class]]) { + errorCode = kFIRInstanceIDErrorCodeInvalidRequest; + } else if (![authorizedEntity length]) { + errorCode = kFIRInstanceIDErrorCodeInvalidAuthorizedEntity; + } else if (![scope length]) { + errorCode = kFIRInstanceIDErrorCodeInvalidScope; + } else if (!self.installations) { + errorCode = kFIRInstanceIDErrorCodeInvalidStart; + } + + FIRInstanceIDTokenHandler newHandler = ^(NSString *token, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(token, error); + }); + }; + + if (errorCode != noError) { + newHandler(nil, [NSError errorWithFIRInstanceIDErrorCode:errorCode]); + return; + } + + FIRInstanceID_WEAKIFY(self); + FIRInstanceIDAuthService *authService = self.tokenManager.authService; + [authService fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences, + NSError *error) { + FIRInstanceID_STRONGIFY(self); + if (error) { + newHandler(nil, error); + return; + } + + FIRInstanceID_WEAKIFY(self); + [self.installations installationIDWithCompletion:^(NSString *_Nullable identifier, + NSError *_Nullable error) { + FIRInstanceID_STRONGIFY(self); + + if (error) { + NSError *newError = + [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]; + newHandler(nil, newError); + + } else { + FIRInstanceIDTokenInfo *cachedTokenInfo = + [self.tokenManager cachedTokenInfoWithAuthorizedEntity:authorizedEntity scope:scope]; + if (cachedTokenInfo) { + FIRInstanceIDAPNSInfo *optionsAPNSInfo = + [[FIRInstanceIDAPNSInfo alloc] initWithTokenOptionsDictionary:tokenOptions]; + // Check if APNS Info is changed + if ((!cachedTokenInfo.APNSInfo && !optionsAPNSInfo) || + [cachedTokenInfo.APNSInfo isEqualToAPNSInfo:optionsAPNSInfo]) { + // check if token is fresh + if ([cachedTokenInfo isFreshWithIID:identifier]) { + newHandler(cachedTokenInfo.token, nil); + return; + } + } + } + [self.tokenManager fetchNewTokenWithAuthorizedEntity:[authorizedEntity copy] + scope:[scope copy] + instanceID:identifier + options:tokenOptions + handler:newHandler]; + } + }]; + }]; +} + +- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + handler:(FIRInstanceIDDeleteTokenHandler)handler { + if (!handler) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID001, + kFIRInstanceIDInvalidNilHandlerError); + return; + } + + // comparing enums to ints directly throws a warning + FIRInstanceIDErrorCode noError = INT_MAX; + FIRInstanceIDErrorCode errorCode = noError; + + if (![authorizedEntity length]) { + errorCode = kFIRInstanceIDErrorCodeInvalidAuthorizedEntity; + } else if (![scope length]) { + errorCode = kFIRInstanceIDErrorCodeInvalidScope; + } else if (!self.installations) { + errorCode = kFIRInstanceIDErrorCodeInvalidStart; + } + + FIRInstanceIDDeleteTokenHandler newHandler = ^(NSError *error) { + // If a default token is deleted successfully, reset the defaultFCMToken too. + if (!error && [authorizedEntity isEqualToString:self.fcmSenderID] && + [scope isEqualToString:kFIRInstanceIDDefaultTokenScope]) { + self.defaultFCMToken = nil; + } + dispatch_async(dispatch_get_main_queue(), ^{ + handler(error); + }); + }; + + if (errorCode != noError) { + newHandler([NSError errorWithFIRInstanceIDErrorCode:errorCode]); + return; + } + + FIRInstanceID_WEAKIFY(self); + FIRInstanceIDAuthService *authService = self.tokenManager.authService; + [authService + fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences, NSError *error) { + FIRInstanceID_STRONGIFY(self); + if (error) { + newHandler(error); + return; + } + + FIRInstanceID_WEAKIFY(self); + [self.installations installationIDWithCompletion:^(NSString *_Nullable identifier, + NSError *_Nullable error) { + FIRInstanceID_STRONGIFY(self); + if (error) { + NSError *newError = + [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]; + newHandler(newError); + + } else { + [self.tokenManager deleteTokenWithAuthorizedEntity:authorizedEntity + scope:scope + instanceID:identifier + handler:newHandler]; + } + }]; + }]; +} + +#pragma mark - Identity + +- (void)getIDWithHandler:(FIRInstanceIDHandler)handler { + if (!handler) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID003, + kFIRInstanceIDInvalidNilHandlerError); + return; + } + + FIRInstanceID_WEAKIFY(self); + [self.installations + installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) { + FIRInstanceID_STRONGIFY(self); + // When getID is explicitly called, trigger getToken to make sure token always exists. + // This is to avoid ID conflict (ID is not checked for conflict until we generate a token) + if (identifier) { + [self token]; + } + handler(identifier, error); + }]; +} + +- (void)deleteIDWithHandler:(FIRInstanceIDDeleteHandler)handler { + if (!handler) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID004, + kFIRInstanceIDInvalidNilHandlerError); + return; + } + + void (^callHandlerOnMainThread)(NSError *) = ^(NSError *error) { + if ([NSThread isMainThread]) { + handler(error); + return; + } + dispatch_async(dispatch_get_main_queue(), ^{ + handler(error); + }); + }; + + if (!self.installations) { + FIRInstanceIDErrorCode error = kFIRInstanceIDErrorCodeInvalidStart; + callHandlerOnMainThread([NSError errorWithFIRInstanceIDErrorCode:error]); + return; + } + + FIRInstanceID_WEAKIFY(self); + void (^deleteTokensHandler)(NSError *) = ^void(NSError *error) { + FIRInstanceID_STRONGIFY(self); + if (error) { + callHandlerOnMainThread(error); + return; + } + [self deleteIdentityWithHandler:^(NSError *error) { + callHandlerOnMainThread(error); + }]; + }; + + [self.installations + installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) { + FIRInstanceID_STRONGIFY(self); + if (error) { + NSError *newError = + [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]; + callHandlerOnMainThread(newError); + } else { + [self.tokenManager deleteAllTokensWithInstanceID:identifier handler:deleteTokensHandler]; + } + }]; +} + +- (void)notifyIdentityReset { + [self deleteIdentityWithHandler:nil]; +} + +// Delete all the local cache checkin, IID and token. +- (void)deleteIdentityWithHandler:(FIRInstanceIDDeleteHandler)handler { + // Delete tokens. + [self.tokenManager deleteAllTokensLocallyWithHandler:^(NSError *deleteTokenError) { + // Reset FCM token. + self.defaultFCMToken = nil; + if (deleteTokenError) { + if (handler) { + handler(deleteTokenError); + } + return; + } + + // Delete Instance ID. + [self.installations deleteWithCompletion:^(NSError *_Nullable error) { + if (error) { + if (handler) { + handler(error); + } + return; + } + + [self.tokenManager.authService resetCheckinWithHandler:^(NSError *error) { + if (error) { + if (handler) { + handler(error); + } + return; + } + // Only request new token if FCM auto initialization is + // enabled. + if ([self isFCMAutoInitEnabled]) { + // Deletion succeeds! Requesting new checkin, IID and token. + // TODO(chliangGoogle) see if dispatch_after is necessary + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + [self defaultTokenWithHandler:nil]; + }); + } + if (handler) { + handler(nil); + } + }]; + }]; + }]; +} + +#pragma mark - Checkin + +- (BOOL)tryToLoadValidCheckinInfo { + FIRInstanceIDCheckinPreferences *checkinPreferences = + [self.tokenManager.authService checkinPreferences]; + return [checkinPreferences hasValidCheckinInfo]; +} + +- (NSString *)deviceAuthID { + return [self.tokenManager.authService checkinPreferences].deviceID; +} + +- (NSString *)secretToken { + return [self.tokenManager.authService checkinPreferences].secretToken; +} + +- (NSString *)versionInfo { + return [self.tokenManager.authService checkinPreferences].versionInfo; +} + +#pragma mark - Config + ++ (void)load { + [FIRApp registerInternalLibrary:(Class<FIRLibrary>)self + withName:@"fire-iid" + withVersion:FIRInstanceIDCurrentLibraryVersion()]; +} + ++ (nonnull NSArray<FIRComponent *> *)componentsToRegister { + FIRComponentCreationBlock creationBlock = + ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + // InstanceID only works with the default app. + if (!container.app.isDefaultApp) { + // Only configure for the default FIRApp. + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeFIRApp002, + @"Firebase Instance ID only works with the default app."); + return nil; + } + + // Ensure it's cached so it returns the same instance every time instanceID is called. + *isCacheable = YES; + FIRInstanceID *instanceID = [[FIRInstanceID alloc] initPrivately]; + [instanceID start]; + [instanceID configureInstanceIDWithOptions:container.app.options]; + return instanceID; + }; + FIRComponent *instanceIDProvider = + [FIRComponent componentWithProtocol:@protocol(FIRInstanceIDInstanceProvider) + instantiationTiming:FIRInstantiationTimingEagerInDefaultApp + dependencies:@[] + creationBlock:creationBlock]; + return @[ instanceIDProvider ]; +} + +- (void)configureInstanceIDWithOptions:(FIROptions *)options { + NSString *GCMSenderID = options.GCMSenderID; + if (!GCMSenderID.length) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeFIRApp000, + @"Firebase not set up correctly, nil or empty senderID."); + [NSException raise:kFIRIIDErrorDomain + format:@"Could not configure Firebase InstanceID. GCMSenderID must not be nil or " + @"empty."]; + } + + self.fcmSenderID = GCMSenderID; + self.firebaseAppID = options.googleAppID; + + [self updateFirebaseInstallationID]; + + // FCM generates a FCM token during app start for sending push notification to device. + // This is not needed for app extension except for watch. +#if TARGET_OS_WATCH + [self didCompleteConfigure]; +#else + if (![GULAppEnvironmentUtil isAppExtension]) { + [self didCompleteConfigure]; + } +#endif +} + +// This is used to start any operations when we receive FirebaseSDK setup notification +// from FIRCore. +- (void)didCompleteConfigure { + NSString *cachedToken = [self cachedTokenIfAvailable]; + // When there is a cached token, do the token refresh. + if (cachedToken) { + // Clean up expired tokens by checking the token refresh policy. + [self.installations + installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) { + if ([self.tokenManager checkTokenRefreshPolicyWithIID:identifier]) { + // Default token is expired, fetch default token from server. + [self defaultTokenWithHandler:nil]; + } + // Notify FCM with the default token. + self.defaultFCMToken = [self token]; + }]; + } else if ([self isFCMAutoInitEnabled]) { + // When there is no cached token, must check auto init is enabled. + // If it's disabled, don't initiate token generation/refresh. + // If no cache token and auto init is enabled, fetch a token from server. + [self defaultTokenWithHandler:nil]; + // Notify FCM with the default token. + self.defaultFCMToken = [self token]; + } + // ONLY checkin when auto data collection is turned on. + if ([self isFCMAutoInitEnabled]) { + [self.tokenManager.authService scheduleCheckin:YES]; + } +} + +- (BOOL)isFCMAutoInitEnabled { + Class messagingClass = NSClassFromString(kFIRInstanceIDFCMSDKClassString); + // Firebase Messaging is not installed, auto init should be disabled since it's for FCM. + if (!messagingClass) { + return NO; + } + + // Messaging doesn't have the class method, auto init should be enabled since FCM exists. + SEL autoInitSelector = NSSelectorFromString(kFIRInstanceIDFCMSelectorAutoInitEnabled); + if (![messagingClass respondsToSelector:autoInitSelector]) { + return YES; + } + + // Get the autoInitEnabled class method. + IMP isAutoInitEnabledIMP = [messagingClass methodForSelector:autoInitSelector]; + BOOL(*isAutoInitEnabled) + (Class, SEL, GULUserDefaults *) = (BOOL(*)(id, SEL, GULUserDefaults *))isAutoInitEnabledIMP; + + // Check FCM's isAutoInitEnabled property. + return isAutoInitEnabled(messagingClass, autoInitSelector, + [GULUserDefaults standardUserDefaults]); +} + +// Actually makes InstanceID instantiate both the IID and Token-related subsystems. +- (void)start { + if (![FIRInstanceIDStore hasSubDirectory:kFIRInstanceIDSubDirectoryName]) { + [FIRInstanceIDStore createSubDirectory:kFIRInstanceIDSubDirectoryName]; + } + + [self setupTokenManager]; + self.installations = [FIRInstallations installations]; + [self setupNotificationListeners]; +} + +// Creates the token manager, which is used for fetching, caching, and retrieving tokens. +- (void)setupTokenManager { + self.tokenManager = [[FIRInstanceIDTokenManager alloc] init]; +} + +- (void)setupNotificationListeners { + // To prevent double notifications remove observer from all events during setup. + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center removeObserver:self]; + [center addObserver:self + selector:@selector(notifyIdentityReset) + name:kFIRInstanceIDIdentityInvalidatedNotification + object:nil]; + [center addObserver:self + selector:@selector(notifyAPNSTokenIsSet:) + name:kFIRInstanceIDAPNSTokenNotification + object:nil]; + [self observeFirebaseInstallationIDChanges]; +} + +#pragma mark - Private Helpers +/// Maximum retry count to fetch the default token. ++ (int64_t)maxRetryCountForDefaultToken { + return kMaxRetryCountForDefaultToken; +} + +/// Minimum interval in seconds between retries to fetch the default token. ++ (int64_t)minIntervalForDefaultTokenRetry { + return kMinRetryIntervalForDefaultTokenInSeconds; +} + +/// Maximum retry interval between retries to fetch default token. ++ (int64_t)maxRetryIntervalForDefaultTokenInSeconds { + return kMaxRetryIntervalForDefaultTokenInSeconds; +} + +- (NSInteger)retryIntervalToFetchDefaultToken { + if (self.retryCountForDefaultToken >= [[self class] maxRetryCountForDefaultToken]) { + return (NSInteger)[[self class] maxRetryIntervalForDefaultTokenInSeconds]; + } + // exponential backoff with a fixed initial retry time + // 11s, 22s, 44s, 88s ... + int64_t minInterval = [[self class] minIntervalForDefaultTokenRetry]; + return (NSInteger)MIN( + (1 << self.retryCountForDefaultToken) + minInterval * self.retryCountForDefaultToken, + kMaxRetryIntervalForDefaultTokenInSeconds); +} + +- (void)defaultTokenWithHandler:(nullable FIRInstanceIDTokenHandler)aHandler { + [self defaultTokenWithRetry:NO handler:aHandler]; +} + +/** + * @param retry Indicates if the method is called to perform a retry after a failed attempt. + * If `YES`, then actual token request will be performed even if `self.defaultTokenFetchHandler != + * nil` + */ +- (void)defaultTokenWithRetry:(BOOL)retry handler:(nullable FIRInstanceIDTokenHandler)aHandler { + BOOL shouldPerformRequest = retry || self.defaultTokenFetchHandler == nil; + + if (!self.defaultTokenFetchHandler) { + self.defaultTokenFetchHandler = [[FIRInstanceIDCombinedHandler<NSString *> alloc] init]; + } + + if (aHandler) { + [self.defaultTokenFetchHandler addHandler:aHandler]; + } + + if (!shouldPerformRequest) { + return; + } + + NSDictionary *instanceIDOptions = @{}; + BOOL hasFirebaseMessaging = NSClassFromString(kFIRInstanceIDFCMSDKClassString) != nil; + if (hasFirebaseMessaging && self.apnsTokenData) { + BOOL isSandboxApp = (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeSandbox); + if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) { + isSandboxApp = [self isSandboxApp]; + } + instanceIDOptions = @{ + kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData, + kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp), + }; + } + + FIRInstanceID_WEAKIFY(self); + FIRInstanceIDTokenHandler newHandler = ^void(NSString *token, NSError *error) { + FIRInstanceID_STRONGIFY(self); + + if (error) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID009, + @"Failed to fetch default token %@", error); + + // This notification can be sent multiple times since we can't guarantee success at any point + // of time. + NSNotification *tokenFetchFailNotification = + [NSNotification notificationWithName:kFIRInstanceIDDefaultGCMTokenFailNotification + object:[error copy]]; + [[NSNotificationQueue defaultQueue] enqueueNotification:tokenFetchFailNotification + postingStyle:NSPostASAP]; + + self.retryCountForDefaultToken = (NSInteger)MIN(self.retryCountForDefaultToken + 1, + [[self class] maxRetryCountForDefaultToken]); + + // Do not retry beyond the maximum limit. + if (self.retryCountForDefaultToken < [[self class] maxRetryCountForDefaultToken]) { + NSInteger retryInterval = [self retryIntervalToFetchDefaultToken]; + [self retryGetDefaultTokenAfter:retryInterval]; + } else { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID007, + @"Failed to retrieve the default FCM token after %ld retries", + (long)self.retryCountForDefaultToken); + [self performDefaultTokenHandlerWithToken:nil error:error]; + } + } else { + // If somebody updated IID with APNS token while our initial request did not have it + // set we need to update it on the server. + NSData *deviceTokenInRequest = instanceIDOptions[kFIRInstanceIDTokenOptionsAPNSKey]; + BOOL isSandboxInRequest = + [instanceIDOptions[kFIRInstanceIDTokenOptionsAPNSIsSandboxKey] boolValue]; + // Note that APNSTupleStringInRequest will be nil if deviceTokenInRequest is nil + NSString *APNSTupleStringInRequest = FIRInstanceIDAPNSTupleStringForTokenAndServerType( + deviceTokenInRequest, isSandboxInRequest); + // If the APNs value either remained nil, or was the same non-nil value, the APNs value + // did not change. + BOOL APNSRemainedSameDuringFetch = + (self.APNSTupleString == nil && APNSTupleStringInRequest == nil) || + ([self.APNSTupleString isEqualToString:APNSTupleStringInRequest]); + if (!APNSRemainedSameDuringFetch && hasFirebaseMessaging) { + // APNs value did change mid-fetch, so the token should be re-fetched with the current APNs + // value. + [self retryGetDefaultTokenAfter:0]; + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeRefetchingTokenForAPNS, + @"Received APNS token while fetching default token. " + @"Refetching default token."); + // Do not notify and handle completion handler since this is a retry. + // Simply return. + return; + } else { + FIRInstanceIDLoggerInfo(kFIRInstanceIDMessageCodeInstanceID010, + @"Successfully fetched default token."); + } + // Post the required notifications if somebody is waiting. + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID008, @"Got default token %@", + token); + // Update default FCM token, this method also triggers sending notification if token has + // changed. + self.defaultFCMToken = token; + + [self performDefaultTokenHandlerWithToken:token error:nil]; + } + }; + + [self tokenWithAuthorizedEntity:self.fcmSenderID + scope:kFIRInstanceIDDefaultTokenScope + options:instanceIDOptions + handler:newHandler]; +} + +/** + * + */ +- (void)performDefaultTokenHandlerWithToken:(NSString *)token error:(NSError *)error { + if (!self.defaultTokenFetchHandler) { + return; + } + + [self.defaultTokenFetchHandler combinedHandler](token, error); + self.defaultTokenFetchHandler = nil; +} + +- (void)retryGetDefaultTokenAfter:(NSTimeInterval)retryInterval { + FIRInstanceID_WEAKIFY(self); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(retryInterval * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + FIRInstanceID_STRONGIFY(self); + // Pass nil: no new handlers to be added, currently existing handlers + // will be called + [self defaultTokenWithRetry:YES handler:nil]; + }); +} + +#pragma mark - APNS Token +// This should only be triggered from FCM. +- (void)notifyAPNSTokenIsSet:(NSNotification *)notification { + NSData *token = notification.object; + if (!token || ![token isKindOfClass:[NSData class]]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInternal002, @"Invalid APNS token type %@", + NSStringFromClass([notification.object class])); + return; + } + NSInteger type = [notification.userInfo[kFIRInstanceIDAPNSTokenType] integerValue]; + + // The APNS token is being added, or has changed (rare) + if ([self.apnsTokenData isEqualToData:token]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID011, + @"Trying to reset APNS token to the same value. Will return"); + return; + } + // Use this token type for when we have to automatically fetch tokens in the future + self.apnsTokenType = type; + BOOL isSandboxApp = (type == FIRInstanceIDAPNSTokenTypeSandbox); + if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) { + isSandboxApp = [self isSandboxApp]; + } + self.apnsTokenData = [token copy]; + self.APNSTupleString = FIRInstanceIDAPNSTupleStringForTokenAndServerType(token, isSandboxApp); + + // Pro-actively invalidate the default token, if the APNs change makes it + // invalid. Previously, we invalidated just before fetching the token. + NSArray<FIRInstanceIDTokenInfo *> *invalidatedTokens = + [self.tokenManager updateTokensToAPNSDeviceToken:self.apnsTokenData isSandbox:isSandboxApp]; + + // Re-fetch any invalidated tokens automatically, this time with the current APNs token, so that + // they are up-to-date. + if (invalidatedTokens.count > 0) { + FIRInstanceID_WEAKIFY(self); + + [self.installations + installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) { + FIRInstanceID_STRONGIFY(self); + if (self == nil) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID017, + @"Instance ID shut down during token reset. Aborting"); + return; + } + if (self.apnsTokenData == nil) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID018, + @"apnsTokenData was set to nil during token reset. Aborting"); + return; + } + + NSMutableDictionary *tokenOptions = [@{ + kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData, + kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp) + } mutableCopy]; + if (self.firebaseAppID) { + tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID; + } + + for (FIRInstanceIDTokenInfo *tokenInfo in invalidatedTokens) { + if ([tokenInfo.token isEqualToString:self.defaultFCMToken]) { + // We will perform a special fetch for the default FCM token, so that the delegate + // methods are called. For all others, we will do an internal re-fetch. + [self defaultTokenWithHandler:nil]; + } else { + [self.tokenManager fetchNewTokenWithAuthorizedEntity:tokenInfo.authorizedEntity + scope:tokenInfo.scope + instanceID:identifier + options:tokenOptions + handler:^(NSString *_Nullable token, + NSError *_Nullable error){ + + }]; + } + } + }]; + } +} + +- (BOOL)isSandboxApp { + static BOOL isSandboxApp = YES; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + isSandboxApp = ![self isProductionApp]; + }); + return isSandboxApp; +} + +- (BOOL)isProductionApp { + const BOOL defaultAppTypeProd = YES; + + NSError *error = nil; + if ([GULAppEnvironmentUtil isSimulator]) { + [self logAPNSConfigurationError:@"Running InstanceID on a simulator doesn't have APNS. " + @"Use prod profile by default."]; + return defaultAppTypeProd; + } + + if ([GULAppEnvironmentUtil isFromAppStore]) { + // Apps distributed via AppStore or TestFlight use the Production APNS certificates. + return defaultAppTypeProd; + } +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST + NSString *path = [[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent] + stringByAppendingPathComponent:@"embedded.provisionprofile"]; +#elif TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH + NSString *path = [[[NSBundle mainBundle] bundlePath] + stringByAppendingPathComponent:@"embedded.mobileprovision"]; +#endif + + if ([GULAppEnvironmentUtil isAppStoreReceiptSandbox] && !path.length) { + // Distributed via TestFlight + return defaultAppTypeProd; + } + + NSMutableData *profileData = [NSMutableData dataWithContentsOfFile:path options:0 error:&error]; + + if (!profileData.length || error) { + NSString *errorString = + [NSString stringWithFormat:@"Error while reading embedded mobileprovision %@", error]; + [self logAPNSConfigurationError:errorString]; + return defaultAppTypeProd; + } + + // The "embedded.mobileprovision" sometimes contains characters with value 0, which signals the + // end of a c-string and halts the ASCII parser, or with value > 127, which violates strict 7-bit + // ASCII. Replace any 0s or invalid characters in the input. + uint8_t *profileBytes = (uint8_t *)profileData.bytes; + for (int i = 0; i < profileData.length; i++) { + uint8_t currentByte = profileBytes[i]; + if (!currentByte || currentByte > 127) { + profileBytes[i] = '.'; + } + } + + NSString *embeddedProfile = [[NSString alloc] initWithBytesNoCopy:profileBytes + length:profileData.length + encoding:NSASCIIStringEncoding + freeWhenDone:NO]; + + if (error || !embeddedProfile.length) { + NSString *errorString = + [NSString stringWithFormat:@"Error while reading embedded mobileprovision %@", error]; + [self logAPNSConfigurationError:errorString]; + return defaultAppTypeProd; + } + + NSScanner *scanner = [NSScanner scannerWithString:embeddedProfile]; + NSString *plistContents; + if ([scanner scanUpToString:@"<plist" intoString:nil]) { + if ([scanner scanUpToString:@"</plist>" intoString:&plistContents]) { + plistContents = [plistContents stringByAppendingString:@"</plist>"]; + } + } + + if (!plistContents.length) { + return defaultAppTypeProd; + } + + NSData *data = [plistContents dataUsingEncoding:NSUTF8StringEncoding]; + if (!data.length) { + [self logAPNSConfigurationError:@"Couldn't read plist fetched from embedded mobileprovision"]; + return defaultAppTypeProd; + } + + NSError *plistMapError; + id plistData = [NSPropertyListSerialization propertyListWithData:data + options:NSPropertyListImmutable + format:nil + error:&plistMapError]; + if (plistMapError || ![plistData isKindOfClass:[NSDictionary class]]) { + NSString *errorString = + [NSString stringWithFormat:@"Error while converting assumed plist to dict %@", + plistMapError.localizedDescription]; + [self logAPNSConfigurationError:errorString]; + return defaultAppTypeProd; + } + NSDictionary *plistMap = (NSDictionary *)plistData; + + if ([plistMap valueForKeyPath:@"ProvisionedDevices"]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID012, + @"Provisioning profile has specifically provisioned devices, " + @"most likely a Dev profile."); + } + + NSString *apsEnvironment = [plistMap valueForKeyPath:kEntitlementsAPSEnvironmentKey]; + NSString *debugString __unused = + [NSString stringWithFormat:@"APNS Environment in profile: %@", apsEnvironment]; + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID013, @"%@", debugString); + + // No aps-environment in the profile. + if (!apsEnvironment.length) { + [self logAPNSConfigurationError:@"No aps-environment set. If testing on a device APNS is not " + @"correctly configured. Please recheck your provisioning " + @"profiles. If testing on a simulator this is fine since APNS " + @"doesn't work on the simulator."]; + return defaultAppTypeProd; + } + + if ([apsEnvironment isEqualToString:kAPSEnvironmentDevelopmentValue]) { + return NO; + } + + return defaultAppTypeProd; +} + +/// Log error messages only when Messaging exists in the pod. +- (void)logAPNSConfigurationError:(NSString *)errorString { + BOOL hasFirebaseMessaging = NSClassFromString(kFIRInstanceIDFCMSDKClassString) != nil; + if (hasFirebaseMessaging) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID014, @"%@", errorString); + } else { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID015, @"%@", errorString); + } +} + +#pragma mark - Sync InstanceID + +- (void)updateFirebaseInstallationID { + FIRInstanceID_WEAKIFY(self); + [self.installations + installationIDWithCompletion:^(NSString *_Nullable installationID, NSError *_Nullable error) { + FIRInstanceID_STRONGIFY(self); + self.firebaseInstallationsID = installationID; + }]; +} + +- (void)installationIDDidChangeNotificationReceived:(NSNotification *)notification { + NSString *installationAppID = + notification.userInfo[kFIRInstallationIDDidChangeNotificationAppNameKey]; + if ([installationAppID isKindOfClass:[NSString class]] && + [installationAppID isEqual:self.firebaseAppID]) { + [self updateFirebaseInstallationID]; + } +} + +- (void)observeFirebaseInstallationIDChanges { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:FIRInstallationIDDidChangeNotification + object:nil]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(installationIDDidChangeNotificationReceived:) + name:FIRInstallationIDDidChangeNotification + object:nil]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.h new file mode 100644 index 00000000..92b2469b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.h @@ -0,0 +1,64 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + * Represents an APNS device token and whether its environment is for sandbox. + * It can read from and write to an NSDictionary for simple serialization. + */ +@interface FIRInstanceIDAPNSInfo : NSObject <NSCoding> + +/// The APNs device token, provided by the OS to the application delegate +@property(nonatomic, readonly, strong) NSData *deviceToken; +/// Represents whether or not this is deviceToken is for the sandbox +/// environment, or production. +@property(nonatomic, readonly, getter=isSandbox) BOOL sandbox; + +/** + * Initializes the receiver with an APNs device token, and boolean + * representing whether that token is for the sandbox environment. + * + * @param deviceToken The APNs device token typically provided by the + * operating system. + * @param isSandbox YES if the APNs device token is for the sandbox + * environment, or NO if it is for production. + * @return An instance of FIRInstanceIDAPNSInfo. + */ +- (instancetype)initWithDeviceToken:(NSData *)deviceToken isSandbox:(BOOL)isSandbox; + +/** + * Initializes the receiver from a token options dictionary containing data + * within the `kFIRInstanceIDTokenOptionsAPNSKey` and + * `kFIRInstanceIDTokenOptionsAPNSIsSandboxKey` keys. The token should be an + * NSData blob, and the sandbox value should be an NSNumber + * representing a boolean value. + * + * @param dictionary A dictionary containing values under the keys + * `kFIRInstanceIDTokenOptionsAPNSKey` and + * `kFIRInstanceIDTokenOptionsAPNSIsSandboxKey`. + * @return An instance of FIRInstanceIDAPNSInfo, or nil if the + * dictionary data was invalid or missing. + */ +- (nullable instancetype)initWithTokenOptionsDictionary:(NSDictionary *)dictionary; + +- (BOOL)isEqualToAPNSInfo:(FIRInstanceIDAPNSInfo *)otherInfo; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.m new file mode 100644 index 00000000..d1f9d080 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAPNSInfo.m @@ -0,0 +1,79 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDAPNSInfo.h" + +#import "FIRInstanceIDConstants.h" + +/// The key used to find the APNs device token in an archive. +NSString *const kFIRInstanceIDAPNSInfoTokenKey = @"device_token"; +/// The key used to find the sandbox value in an archive. +NSString *const kFIRInstanceIDAPNSInfoSandboxKey = @"sandbox"; + +@implementation FIRInstanceIDAPNSInfo + +- (instancetype)initWithDeviceToken:(NSData *)deviceToken isSandbox:(BOOL)isSandbox { + self = [super init]; + if (self) { + _deviceToken = [deviceToken copy]; + _sandbox = isSandbox; + } + return self; +} + +- (instancetype)initWithTokenOptionsDictionary:(NSDictionary *)dictionary { + id deviceToken = dictionary[kFIRInstanceIDTokenOptionsAPNSKey]; + if (![deviceToken isKindOfClass:[NSData class]]) { + return nil; + } + + id isSandbox = dictionary[kFIRInstanceIDTokenOptionsAPNSIsSandboxKey]; + if (![isSandbox isKindOfClass:[NSNumber class]]) { + return nil; + } + self = [super init]; + if (self) { + _deviceToken = (NSData *)deviceToken; + _sandbox = ((NSNumber *)isSandbox).boolValue; + } + return self; +} + +#pragma mark - NSCoding + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + id deviceToken = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoTokenKey]; + if (![deviceToken isKindOfClass:[NSData class]]) { + return nil; + } + BOOL isSandbox = [aDecoder decodeBoolForKey:kFIRInstanceIDAPNSInfoSandboxKey]; + return [self initWithDeviceToken:(NSData *)deviceToken isSandbox:isSandbox]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.deviceToken forKey:kFIRInstanceIDAPNSInfoTokenKey]; + [aCoder encodeBool:self.sandbox forKey:kFIRInstanceIDAPNSInfoSandboxKey]; +} + +- (BOOL)isEqualToAPNSInfo:(FIRInstanceIDAPNSInfo *)otherInfo { + if ([super isEqual:otherInfo]) { + return YES; + } + return ([self.deviceToken isEqualToData:otherInfo.deviceToken] && + self.isSandbox == otherInfo.isSandbox); +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h new file mode 100644 index 00000000..8d453b8b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h @@ -0,0 +1,95 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +extern NSString *__nonnull const kFIRInstanceIDKeychainWildcardIdentifier; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Wrapper around storing FCM auth data in iOS keychain. + */ +@interface FIRInstanceIDAuthKeychain : NSObject + +/** + * Designated Initializer. Init a generic `SecClassGenericPassword` keychain with `identifier` + * as the `kSecAttrGeneric`. + * + * @param identifier The generic attribute to be used by the keychain. + * + * @return A Keychain object with `kSecAttrGeneric` attribute set to identifier. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier; + +/** + * Get keychain items matching the given service and account. The service and/or account + * can be a wildcard (`kFIRInstanceIDKeychainWildcardIdentifier`), which case the query + * will include all items matching any services and/or accounts. + * + * @param service The kSecAttrService used to save the password. Can be wildcard. + * @param account The kSecAttrAccount used to save the password. Can be wildcard. + * + * @return An array of |NSData|s matching the provided inputs. + */ +- (NSArray<NSData *> *)itemsMatchingService:(NSString *)service account:(NSString *)account; + +/** + * Get keychain item for a given service and account. + * + * @param service The kSecAttrService used to save the password. + * @param account The kSecAttrAccount used to save the password. + * + * @return A cached keychain item for a given account and service, or nil if it was not + * found or could not be retrieved. + */ +- (NSData *)dataForService:(NSString *)service account:(NSString *)account; + +/** + * Remove the cached items from the keychain matching the service, account and access group. + * In case the items do not exist, YES is returned but with a valid error object with code + * `errSecItemNotFound`. + * + * @param service The kSecAttrService used to save the password. + * @param account The kSecAttrAccount used to save the password. + * @param handler The callback handler which is invoked when the remove operation is complete, with + * an error if there is any. + */ +- (void)removeItemsMatchingService:(NSString *)service + account:(NSString *)account + handler:(nullable void (^)(NSError *error))handler; + +/** + * Set the data for a given service and account. + * We use `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly` which + * prevents backup and restore to iCloud, and works for app extension that can + * execute right after a device is restarted (and not unlocked). + * + * @param data The data to save. + * @param service The `kSecAttrService` used to save the password. + * @param account The `kSecAttrAccount` used to save the password. + * @param handler The callback handler which is invoked when the add operation is complete, + * with an error if there is any. + * + */ +- (void)setData:(NSData *)data + forService:(NSString *)service + account:(NSString *)account + handler:(nullable void (^)(NSError *))handler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m new file mode 100644 index 00000000..dfce2f75 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m @@ -0,0 +1,216 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDAuthKeyChain.h" +#import "FIRInstanceIDKeychain.h" +#import "FIRInstanceIDLogger.h" + +/** + * The error type representing why we couldn't read data from the keychain. + */ +typedef NS_ENUM(int, FIRInstanceIDKeychainErrorType) { + kFIRInstanceIDKeychainErrorBadArguments = -1301, +}; + +NSString *const kFIRInstanceIDKeychainWildcardIdentifier = @"*"; + +@interface FIRInstanceIDAuthKeychain () + +@property(nonatomic, copy) NSString *generic; +// cachedKeychainData is keyed by service and account, the value is an array of NSData. +// It is used to cache the tokens per service, per account, as well as checkin data per service, +// per account inside the keychain. +@property(nonatomic) + NSMutableDictionary<NSString *, NSMutableDictionary<NSString *, NSArray<NSData *> *> *> + *cachedKeychainData; + +@end + +@implementation FIRInstanceIDAuthKeychain + +- (instancetype)initWithIdentifier:(NSString *)identifier { + self = [super init]; + if (self) { + _generic = [identifier copy]; + _cachedKeychainData = [[NSMutableDictionary alloc] init]; + } + return self; +} + ++ (NSMutableDictionary *)keychainQueryForService:(NSString *)service + account:(NSString *)account + generic:(NSString *)generic { + NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword}; + + NSMutableDictionary *finalQuery = [NSMutableDictionary dictionaryWithDictionary:query]; + if ([generic length] && ![kFIRInstanceIDKeychainWildcardIdentifier isEqualToString:generic]) { + finalQuery[(__bridge NSString *)kSecAttrGeneric] = generic; + } + if ([account length] && ![kFIRInstanceIDKeychainWildcardIdentifier isEqualToString:account]) { + finalQuery[(__bridge NSString *)kSecAttrAccount] = account; + } + if ([service length] && ![kFIRInstanceIDKeychainWildcardIdentifier isEqualToString:service]) { + finalQuery[(__bridge NSString *)kSecAttrService] = service; + } + return finalQuery; +} + +- (NSMutableDictionary *)keychainQueryForService:(NSString *)service account:(NSString *)account { + return [[self class] keychainQueryForService:service account:account generic:self.generic]; +} + +- (NSArray<NSData *> *)itemsMatchingService:(NSString *)service account:(NSString *)account { + // If query wildcard service, it asks for all the results, which always query from keychain. + if (![service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] && + ![account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] && + _cachedKeychainData[service][account]) { + // As long as service, account array exist, even it's empty, it means we've queried it before, + // returns the cache value. + return _cachedKeychainData[service][account]; + } + + NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; + NSMutableArray<NSData *> *results; + keychainQuery[(__bridge id)kSecReturnData] = (__bridge id)kCFBooleanTrue; +#if TARGET_OS_IOS || TARGET_OS_TV + keychainQuery[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; + keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + // FIRInstanceIDKeychain should only take a query and return a result, will handle the query here. + NSArray *passwordInfos = + CFBridgingRelease([[FIRInstanceIDKeychain sharedInstance] itemWithQuery:keychainQuery]); +#elif TARGET_OS_OSX || TARGET_OS_WATCH + keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne; + NSData *passwordInfos = + CFBridgingRelease([[FIRInstanceIDKeychain sharedInstance] itemWithQuery:keychainQuery]); +#endif + + if (!passwordInfos) { + // Nothing was found, simply return from this sync block. + // Make sure to label the cache entry empty, signaling that we've queried this entry. + if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] || + [account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { + // Do not update cache if it's wildcard query. + return @[]; + } else if (_cachedKeychainData[service]) { + [_cachedKeychainData[service] setObject:@[] forKey:account]; + } else { + [_cachedKeychainData setObject:[@{account : @[]} mutableCopy] forKey:service]; + } + return @[]; + } + results = [[NSMutableArray alloc] init]; +#if TARGET_OS_IOS || TARGET_OS_TV + NSInteger numPasswords = passwordInfos.count; + for (NSUInteger i = 0; i < numPasswords; i++) { + NSDictionary *passwordInfo = [passwordInfos objectAtIndex:i]; + if (passwordInfo[(__bridge id)kSecValueData]) { + [results addObject:passwordInfo[(__bridge id)kSecValueData]]; + } + } +#elif TARGET_OS_OSX || TARGET_OS_WATCH + [results addObject:passwordInfos]; +#endif + // We query the keychain because it didn't exist in cache, now query is done, update the result in + // the cache. + if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] || + [account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { + // Do not update cache if it's wildcard query. + return [results copy]; + } else if (_cachedKeychainData[service]) { + [_cachedKeychainData[service] setObject:[results copy] forKey:account]; + } else { + NSMutableDictionary *entry = [@{account : [results copy]} mutableCopy]; + [_cachedKeychainData setObject:entry forKey:service]; + } + return [results copy]; +} + +- (NSData *)dataForService:(NSString *)service account:(NSString *)account { + NSArray<NSData *> *items = [self itemsMatchingService:service account:account]; + // If items is nil or empty, nil will be returned. + return items.firstObject; +} + +- (void)removeItemsMatchingService:(NSString *)service + account:(NSString *)account + handler:(void (^)(NSError *error))handler { + if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { + // Delete all keychain items. + _cachedKeychainData = [[NSMutableDictionary alloc] init]; + } else if ([account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { + // Delete all entries under service, + if (_cachedKeychainData[service]) { + _cachedKeychainData[service] = [[NSMutableDictionary alloc] init]; + } + } else if (_cachedKeychainData[service]) { + // We should keep the service/account entry instead of nil so we know + // it's "empty entry" instead of "not query from keychain yet". + [_cachedKeychainData[service] setObject:@[] forKey:account]; + } else { + [_cachedKeychainData setObject:[@{account : @[]} mutableCopy] forKey:service]; + } + NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account]; + [[FIRInstanceIDKeychain sharedInstance] removeItemWithQuery:keychainQuery handler:handler]; +} + +- (void)setData:(NSData *)data + forService:(NSString *)service + account:(NSString *)account + handler:(void (^)(NSError *))handler { + if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] || + [account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) { + if (handler) { + handler([NSError errorWithDomain:kFIRInstanceIDKeychainErrorDomain + code:kFIRInstanceIDKeychainErrorBadArguments + userInfo:nil]); + } + return; + } + [self removeItemsMatchingService:service + account:account + handler:^(NSError *error) { + if (error) { + if (handler) { + handler(error); + } + return; + } + if (data.length > 0) { + NSMutableDictionary *keychainQuery = + [self keychainQueryForService:service account:account]; + keychainQuery[(__bridge id)kSecValueData] = data; + + keychainQuery[(__bridge id)kSecAttrAccessible] = + (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; + [[FIRInstanceIDKeychain sharedInstance] + addItemWithQuery:keychainQuery + handler:handler]; + } + }]; + // Set the cache value. This must happen after removeItemsMatchingService:account:handler was + // called, so the cache value was reset before setting a new value. + if (_cachedKeychainData[service]) { + if (_cachedKeychainData[service][account]) { + _cachedKeychainData[service][account] = @[ data ]; + } else { + [_cachedKeychainData[service] setObject:@[ data ] forKey:account]; + } + } else { + [_cachedKeychainData setObject:[@{account : @[ data ]} mutableCopy] forKey:service]; + } +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.h new file mode 100644 index 00000000..1fb715e7 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.h @@ -0,0 +1,91 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> +#import "FIRInstanceIDCheckinService.h" + +@class FIRInstanceIDCheckinPreferences; +@class FIRInstanceIDStore; + +/** + * FIRInstanceIDAuthService is responsible for retrieving, caching, and supplying checkin info + * for the rest of Instance ID. A checkin can be scheduled, meaning that it will keep retrying the + * checkin request until it is successful. A checkin can also be requested directly, with a + * completion handler. + */ +@interface FIRInstanceIDAuthService : NSObject + +/** + * Used only for testing. In addition to taking a store (for locally caching the checkin info), it + * also takes a checkinService. + */ +- (instancetype)initWithCheckinService:(FIRInstanceIDCheckinService *)checkinService + store:(FIRInstanceIDStore *)store; + +/** + * Initializes the auth service given a store (which provides the local caching of checkin info). + * This initializer will create its own instance of FIRInstanceIDCheckinService. + */ +- (instancetype)initWithStore:(FIRInstanceIDStore *)store; + +#pragma mark - Checkin Service + +/** + * Checks if the current deviceID and secret are valid or not. + * + * @return YES if the checkin credentials are valid else NO. + */ +- (BOOL)hasValidCheckinInfo; + +/** + * Fetch checkin info from the server. This would usually refresh the existing + * checkin credentials for the current app. + * + * @param handler The completion handler to invoke once the checkin info has been + * refreshed. + */ +- (void)fetchCheckinInfoWithHandler:(FIRInstanceIDDeviceCheckinCompletion)handler; + +/** + * Schedule checkin. Will hit the network only if the currently loaded checkin + * preferences are stale. + * + * @param immediately YES if we want it to be scheduled immediately else NO. + */ +- (void)scheduleCheckin:(BOOL)immediately; + +/** + * Returns the checkin preferences currently loaded in memory. The Checkin preferences + * can be either valid or invalid. + * + * @return The checkin preferences loaded in memory. + */ +- (FIRInstanceIDCheckinPreferences *)checkinPreferences; + +/** + * Cancels any ongoing checkin fetch, if any. + */ +- (void)stopCheckinRequest; + +/** + * Resets the checkin information. + * + * @param handler The callback handler which is invoked when checkin reset is complete, + * with an error if there is any. + */ +- (void)resetCheckinWithHandler:(void (^)(NSError *error))handler; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.m new file mode 100644 index 00000000..8c33c440 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthService.m @@ -0,0 +1,302 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDAuthService.h" + +#import "FIRInstanceIDCheckinPreferences+Internal.h" +#import "FIRInstanceIDCheckinPreferences.h" +#import "FIRInstanceIDCheckinPreferences_Private.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDDefines.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDStore.h" +#import "NSError+FIRInstanceID.h" + +// Max time interval between checkin retry in seconds. +static const int64_t kMaxCheckinRetryIntervalInSeconds = 1 << 5; + +@interface FIRInstanceIDAuthService () + +// Used to retrieve and cache the checkin info to disk and Keychain. +@property(nonatomic, readwrite, strong) FIRInstanceIDStore *store; +// Used to perform single checkin fetches. +@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinService *checkinService; +// The current checkin info. It will be compared to what is retrieved to determine whether it is +// different than what is in the cache. +@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinPreferences *checkinPreferences; + +// This array will track multiple handlers waiting for checkin to be performed. When a checkin +// request completes, all the handlers will be notified. +// Changes to the checkinHandlers array should happen in a thread-safe manner. +@property(nonatomic, readonly, strong) + NSMutableArray<FIRInstanceIDDeviceCheckinCompletion> *checkinHandlers; + +// This is set to true if there is a checkin request in-flight. +@property(atomic, readwrite, assign) BOOL isCheckinInProgress; +// This timer is used a perform checkin retries. It is cancellable. +@property(atomic, readwrite, strong) NSTimer *scheduledCheckinTimer; +// The number of times checkin has been retried during a scheduled checkin. +@property(atomic, readwrite, assign) int checkinRetryCount; + +@end + +@implementation FIRInstanceIDAuthService + +- (instancetype)initWithCheckinService:(FIRInstanceIDCheckinService *)checkinService + store:(FIRInstanceIDStore *)store { + self = [super init]; + if (self) { + _store = store; + _checkinPreferences = [_store cachedCheckinPreferences]; + _checkinService = checkinService; + _checkinHandlers = [NSMutableArray array]; + } + return self; +} + +- (void)dealloc { + [_scheduledCheckinTimer invalidate]; +} + +- (instancetype)initWithStore:(FIRInstanceIDStore *)store { + FIRInstanceIDCheckinService *checkinService = [[FIRInstanceIDCheckinService alloc] init]; + return [self initWithCheckinService:checkinService store:store]; +} + +#pragma mark - Schedule Checkin + +- (void)scheduleCheckin:(BOOL)immediately { + // Checkin is still valid, so a remote checkin is not required. + if ([self.checkinPreferences hasValidCheckinInfo]) { + return; + } + + // Checkin is already scheduled, so this (non-immediate) request can be ignored. + if (!immediately && [self.scheduledCheckinTimer isValid]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService000, + @"Checkin sync already scheduled. Will not schedule."); + return; + } + + if (immediately) { + [self performScheduledCheckin]; + } else { + int64_t checkinRetryDuration = [self calculateNextCheckinRetryIntervalInSeconds]; + [self startCheckinTimerWithDuration:(NSTimeInterval)checkinRetryDuration]; + } +} + +- (void)startCheckinTimerWithDuration:(NSTimeInterval)timerDuration { + self.scheduledCheckinTimer = + [NSTimer scheduledTimerWithTimeInterval:timerDuration + target:self + selector:@selector(onScheduledCheckinTimerFired:) + userInfo:nil + repeats:NO]; + // Add some tolerance to the timer, to allow iOS to be more flexible with this timer + self.scheduledCheckinTimer.tolerance = 0.5; +} + +- (void)clearScheduledCheckinTimer { + [self.scheduledCheckinTimer invalidate]; + self.scheduledCheckinTimer = nil; +} + +- (void)onScheduledCheckinTimerFired:(NSTimer *)timer { + [self performScheduledCheckin]; +} + +- (void)performScheduledCheckin { + // No checkin scheduled as of now. + [self clearScheduledCheckinTimer]; + + // Checkin is still valid, so a remote checkin is not required. + if ([self.checkinPreferences hasValidCheckinInfo]) { + return; + } + + FIRInstanceID_WEAKIFY(self); + [self + fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences, NSError *error) { + FIRInstanceID_STRONGIFY(self); + self.checkinRetryCount++; + + if (error) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService001, @"Checkin error %@.", + error); + + dispatch_async(dispatch_get_main_queue(), ^{ + // Schedule another checkin + [self scheduleCheckin:NO]; + }); + + } else { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService002, @"Checkin success."); + } + }]; +} + +- (int64_t)calculateNextCheckinRetryIntervalInSeconds { + // persistent failures can lead to overflow prevent that. + if (self.checkinRetryCount >= 10) { + return kMaxCheckinRetryIntervalInSeconds; + } + return MIN(1 << self.checkinRetryCount, kMaxCheckinRetryIntervalInSeconds); +} + +#pragma mark - Checkin Service + +- (BOOL)hasValidCheckinInfo { + return [self.checkinPreferences hasValidCheckinInfo]; +} + +- (void)fetchCheckinInfoWithHandler:(nonnull FIRInstanceIDDeviceCheckinCompletion)handler { + // Perform any changes to self.checkinHandlers and _isCheckinInProgress in a thread-safe way. + @synchronized(self) { + [self.checkinHandlers addObject:handler]; + + if (_isCheckinInProgress) { + // Nothing more to do until our checkin request is done + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthServiceCheckinInProgress, + @"Checkin is in progress\n"); + return; + } + } + + // Checkin is still valid, so a remote checkin is not required. + if ([self.checkinPreferences hasValidCheckinInfo]) { + [self notifyCheckinHandlersWithCheckin:self.checkinPreferences error:nil]; + return; + } + + @synchronized(self) { + _isCheckinInProgress = YES; + } + [self.checkinService + checkinWithExistingCheckin:self.checkinPreferences + completion:^(FIRInstanceIDCheckinPreferences *checkinPreferences, + NSError *error) { + @synchronized(self) { + self->_isCheckinInProgress = NO; + } + if (error) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService003, + @"Failed to checkin device %@", error); + [self notifyCheckinHandlersWithCheckin:nil error:error]; + return; + } + + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeAuthService004, + @"Successfully got checkin credentials"); + BOOL hasSameCachedPreferences = + [self cachedCheckinMatchesCheckin:checkinPreferences]; + checkinPreferences.hasPreCachedAuthCredentials = hasSameCachedPreferences; + + // Update to the most recent checkin preferences + self.checkinPreferences = checkinPreferences; + + // Save the checkin info to disk + // Keychain might not be accessible, so confirm that checkin preferences can + // be saved + [self.store + saveCheckinPreferences:checkinPreferences + handler:^(NSError *checkinSaveError) { + if (checkinSaveError && !hasSameCachedPreferences) { + // The checkin info was new, but it couldn't be + // written to the Keychain. Delete any stuff that was + // cached in memory. This doesn't delete any + // previously persisted preferences. + FIRInstanceIDLoggerError( + kFIRInstanceIDMessageCodeService004, + @"Unable to save checkin info, resetting " + @"checkin preferences " + "in memory."); + [checkinPreferences reset]; + [self + notifyCheckinHandlersWithCheckin:nil + error: + checkinSaveError]; + } else { + // The checkin is either new, or it was the same (and + // it couldn't be saved). Either way, report that the + // checkin preferences were received successfully. + [self notifyCheckinHandlersWithCheckin: + checkinPreferences + error:nil]; + if (!hasSameCachedPreferences) { + // Checkin is new. + // Notify any listeners that might be waiting for + // checkin to be fetched, such as Firebase + // Messaging (for its MCS connection). + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] + postNotificationName: + kFIRInstanceIDCheckinFetchedNotification + object:nil]; + }); + } + } + }]; + }]; +} + +- (FIRInstanceIDCheckinPreferences *)checkinPreferences { + return _checkinPreferences; +} + +- (void)stopCheckinRequest { + [self.checkinService stopFetching]; +} + +- (void)resetCheckinWithHandler:(void (^)(NSError *error))handler { + [self.store removeCheckinPreferencesWithHandler:^(NSError *error) { + if (!error) { + self.checkinPreferences = nil; + } + if (handler) { + handler(error); + } + }]; +} + +#pragma mark - Private + +/** + * Goes through the current list of checkin handlers and fires them with the same checkin and/or + * error info. The checkin handlers will get cleared after. + */ +- (void)notifyCheckinHandlersWithCheckin:(nullable FIRInstanceIDCheckinPreferences *)checkin + error:(nullable NSError *)error { + @synchronized(self) { + for (FIRInstanceIDDeviceCheckinCompletion handler in self.checkinHandlers) { + handler(checkin, error); + } + [self.checkinHandlers removeAllObjects]; + } +} + +/** + * Given a |checkin|, it will compare it to the current checkinPreferences to see if the + * deviceID and secretToken are the same. + */ +- (BOOL)cachedCheckinMatchesCheckin:(FIRInstanceIDCheckinPreferences *)checkin { + if (self.checkinPreferences && checkin) { + return ([self.checkinPreferences.deviceID isEqualToString:checkin.deviceID] && + [self.checkinPreferences.secretToken isEqualToString:checkin.secretToken]); + } + return NO; +} +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.h new file mode 100644 index 00000000..bccaced8 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.h @@ -0,0 +1,81 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@interface FIRInstanceIDBackupExcludedPlist : NSObject + +/** + * Caches the plist contents in memory so we don't hit the disk each time we want + * to query something in the plist. This is loaded lazily i.e. if you write to the + * plist the contents you want to write will be stored here if the write was + * successful. The other case where it is loaded is if you read the plist contents + * by calling `contentAsDictionary`. + * + * In case you write to the plist and then try to read the file using + * `contentAsDictionary` we would just return the cachedPlistContents since it would + * represent the disk contents. + */ +@property(nonatomic, readonly, strong) NSDictionary *cachedPlistContents; + +/** + * Init a backup excluded plist file. + * + * @param fileName The filename for the plist file. + * @param subDirectory The subdirectory in Application Support to save the plist. + * + * @return Helper which allows to read write data to a backup excluded plist. + */ +- (instancetype)initWithFileName:(NSString *)fileName subDirectory:(NSString *)subDirectory; + +/** + * Write dictionary data to the backup excluded plist file. If the file does not exist + * it would be created before writing to it. + * + * @param dict The data to be written to the plist. + * @param error The error object if any while writing the data. + * + * @return YES if the write was successful else NO. + */ +- (BOOL)writeDictionary:(NSDictionary *)dict error:(NSError **)error; + +/** + * Delete the backup excluded plist created with the above filename. + * + * @param error The error object if any while deleting the file. + * + * @return YES If the delete was successful else NO. + */ +- (BOOL)deleteFile:(NSError **)error; + +/** + * The contents of the plist file. We also store the contents of the file in-memory. + * If the in-memory contents are valid we return the in-memory contents else we read + * the file from disk. + * + * @return A dictionary object that contains the contents of the plist file if the file + * exists else nil. + */ +- (NSDictionary *)contentAsDictionary; + +/** + * Check if the plist exists on the disk or not. + * + * @return YES if the file exists on the disk else NO. + */ +- (BOOL)doesFileExist; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m new file mode 100644 index 00000000..c1085cae --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m @@ -0,0 +1,117 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDBackupExcludedPlist.h" + +#import "FIRInstanceIDLogger.h" + +@interface FIRInstanceIDBackupExcludedPlist () + +@property(nonatomic, readwrite, copy) NSString *fileName; +@property(nonatomic, readwrite, copy) NSString *subDirectoryName; +@property(nonatomic, readwrite, strong) NSDictionary *cachedPlistContents; + +@end + +@implementation FIRInstanceIDBackupExcludedPlist + +- (instancetype)initWithFileName:(NSString *)fileName subDirectory:(NSString *)subDirectory { + self = [super init]; + if (self) { + _fileName = [fileName copy]; + _subDirectoryName = [subDirectory copy]; + } + return self; +} + +- (BOOL)writeDictionary:(NSDictionary *)dict error:(NSError **)error { + NSString *path = [self plistPathInDirectory]; + if (![dict writeToFile:path atomically:YES]) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlist000, + @"Failed to write to %@.plist", self.fileName); + return NO; + } + + // Successfully wrote contents -- change the in-memory contents + self.cachedPlistContents = [dict copy]; + + NSURL *URL = [NSURL fileURLWithPath:path]; + if (error) { + *error = nil; + } + + NSDictionary *preferences = [URL resourceValuesForKeys:@[ NSURLIsExcludedFromBackupKey ] + error:error]; + if ([preferences[NSURLIsExcludedFromBackupKey] boolValue]) { + return YES; + } + + BOOL success = [URL setResourceValue:@(YES) forKey:NSURLIsExcludedFromBackupKey error:error]; + if (!success) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlist001, + @"Error excluding %@ from backup, %@", [URL lastPathComponent], + error ? *error : @""); + } + return success; +} + +- (BOOL)deleteFile:(NSError **)error { + BOOL success = YES; + NSString *path = [self plistPathInDirectory]; + if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { + success = [[NSFileManager defaultManager] removeItemAtPath:path error:error]; + } + // remove the in-memory contents + self.cachedPlistContents = nil; + return success; +} + +- (NSDictionary *)contentAsDictionary { + if (!self.cachedPlistContents) { + NSString *path = [self plistPathInDirectory]; + if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { + self.cachedPlistContents = [[NSDictionary alloc] initWithContentsOfFile:path]; + } + } + return self.cachedPlistContents; +} + +- (BOOL)doesFileExist { + NSString *path = [self plistPathInDirectory]; + return [[NSFileManager defaultManager] fileExistsAtPath:path]; +} + +#pragma mark - Private + +- (NSString *)plistPathInDirectory { + NSArray *directoryPaths; + NSString *plistNameWithExtension = [NSString stringWithFormat:@"%@.plist", self.fileName]; + directoryPaths = + NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES); + NSArray *components = @[ directoryPaths.lastObject, _subDirectoryName, plistNameWithExtension ]; + + return [NSString pathWithComponents:components]; +} + +- (NSSearchPathDirectory)supportedDirectory { +#if TARGET_OS_TV + return NSCachesDirectory; +#else + return NSApplicationSupportDirectory; +#endif +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.h new file mode 100644 index 00000000..d2f286d7 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.h @@ -0,0 +1,64 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <FirebaseInstanceID/FIRInstanceIDCheckinPreferences.h> + +@interface FIRInstanceIDCheckinPreferences (Internal) + +/** + * Parse the checkin auth credentials saved in the Keychain to initialize checkin + * preferences. + * + * @param keychainContent The checkin auth credentials saved in the Keychain. + * + * @return A valid checkin preferences object if the checkin auth credentials in the + * keychain can be parsed successfully else nil. + */ ++ (FIRInstanceIDCheckinPreferences *)preferencesFromKeychainContents:(NSString *)keychainContent; + +/** + * Default initializer for InstanceID checkin preferences. + * + * @param deviceID The deviceID for the app. + * @param secretToken The secret token the app uses to authenticate with the server. + * + * @return A checkin preferences object with given deviceID and secretToken. + */ +- (instancetype)initWithDeviceID:(NSString *)deviceID secretToken:(NSString *)secretToken; + +/** + * Update checkin preferences from the preferences dict persisted as a plist. The dict contains + * all the checkin preferences retrieved from the server except the deviceID and secret which + * are stored in the Keychain. + * + * @param checkinPlistContent The checkin preferences saved in a plist on the disk. + */ +- (void)updateWithCheckinPlistContents:(NSDictionary *)checkinPlistContent; + +/** + * Reset the current checkin preferences object. + */ +- (void)reset; + +/** + * The string that contains the checkin auth credentials i.e. deviceID and secret. This + * needs to be stored in the Keychain. + * + * @return The checkin auth credential string containing the deviceID and secret. + */ +- (NSString *)checkinKeychainContent; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.m new file mode 100644 index 00000000..88cc40a1 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences+Internal.m @@ -0,0 +1,112 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDCheckinPreferences+Internal.h" + +#import "FIRInstanceIDCheckinService.h" +#import "FIRInstanceIDUtilities.h" + +static NSString *const kCheckinKeychainContentSeparatorString = @"|"; + +@interface FIRInstanceIDCheckinPreferences () + +@property(nonatomic, readwrite, copy) NSString *deviceID; +@property(nonatomic, readwrite, copy) NSString *secretToken; +@property(nonatomic, readwrite, copy) NSString *digest; +@property(nonatomic, readwrite, copy) NSString *versionInfo; +@property(nonatomic, readwrite, copy) NSString *deviceDataVersion; + +@property(nonatomic, readwrite, strong) NSMutableDictionary *gServicesData; +@property(nonatomic, readwrite, assign) int64_t lastCheckinTimestampMillis; + +@end + +@implementation FIRInstanceIDCheckinPreferences (Internal) + ++ (FIRInstanceIDCheckinPreferences *)preferencesFromKeychainContents:(NSString *)keychainContent { + NSString *deviceID = [self checkinDeviceIDFromKeychainContent:keychainContent]; + NSString *secret = [self checkinSecretFromKeychainContent:keychainContent]; + if ([deviceID length] && [secret length]) { + return [[FIRInstanceIDCheckinPreferences alloc] initWithDeviceID:deviceID secretToken:secret]; + } else { + return nil; + } +} + +- (instancetype)initWithDeviceID:(NSString *)deviceID secretToken:(NSString *)secretToken { + self = [super init]; + if (self) { + self.deviceID = [deviceID copy]; + self.secretToken = [secretToken copy]; + } + return self; +} + +- (void)reset { + self.deviceID = nil; + self.secretToken = nil; + self.digest = nil; + self.versionInfo = nil; + self.gServicesData = nil; + self.deviceDataVersion = nil; + self.lastCheckinTimestampMillis = 0; +} + +- (void)updateWithCheckinPlistContents:(NSDictionary *)checkinPlistContent { + for (NSString *key in checkinPlistContent) { + if ([kFIRInstanceIDDigestStringKey isEqualToString:key]) { + self.digest = [checkinPlistContent[key] copy]; + } else if ([kFIRInstanceIDVersionInfoStringKey isEqualToString:key]) { + self.versionInfo = [checkinPlistContent[key] copy]; + } else if ([kFIRInstanceIDLastCheckinTimeKey isEqualToString:key]) { + self.lastCheckinTimestampMillis = [checkinPlistContent[key] longLongValue]; + } else if ([kFIRInstanceIDGServicesDictionaryKey isEqualToString:key]) { + self.gServicesData = [checkinPlistContent[key] mutableCopy]; + } else if ([kFIRInstanceIDDeviceDataVersionKey isEqualToString:key]) { + self.deviceDataVersion = [checkinPlistContent[key] copy]; + } + // Otherwise we have some keys we don't care about + } +} + +- (NSString *)checkinKeychainContent { + if ([self.deviceID length] && [self.secretToken length]) { + return [NSString stringWithFormat:@"%@%@%@", self.deviceID, + kCheckinKeychainContentSeparatorString, self.secretToken]; + } else { + return nil; + } +} + ++ (NSString *)checkinDeviceIDFromKeychainContent:(NSString *)keychainContent { + return [self checkinKeychainContent:keychainContent forIndex:0]; +} + ++ (NSString *)checkinSecretFromKeychainContent:(NSString *)keychainContent { + return [self checkinKeychainContent:keychainContent forIndex:1]; +} + ++ (NSString *)checkinKeychainContent:(NSString *)keychainContent forIndex:(int)index { + NSArray *keychainComponents = + [keychainContent componentsSeparatedByString:kCheckinKeychainContentSeparatorString]; + if (index >= 0 && index < 2 && [keychainComponents count] == 2) { + return keychainComponents[index]; + } else { + return nil; + } +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.m new file mode 100644 index 00000000..965f4641 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences.m @@ -0,0 +1,95 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDCheckinPreferences.h" + +#import "FIRInstanceIDCheckinService.h" +#import "FIRInstanceIDUtilities.h" +#import "GoogleUtilities/UserDefaults/Private/GULUserDefaults.h" + +const NSTimeInterval kFIRInstanceIDDefaultCheckinInterval = 7 * 24 * 60 * 60; // 7 days. + +@interface FIRInstanceIDCheckinPreferences () + +@property(nonatomic, readwrite, copy) NSString *deviceID; +@property(nonatomic, readwrite, copy) NSString *secretToken; +@property(nonatomic, readwrite, copy) NSString *digest; +@property(nonatomic, readwrite, copy) NSString *versionInfo; +@property(nonatomic, readwrite, copy) NSString *deviceDataVersion; + +@property(nonatomic, readwrite, strong) NSMutableDictionary *gServicesData; +@property(nonatomic, readwrite, assign) int64_t lastCheckinTimestampMillis; + +// This flag indicates that we have already saved the above deviceID and secret +// to our keychain and hence we don't need to save again. This is helpful since +// on checkin refresh we can avoid writing to the Keychain which can sometimes +// be very buggy. For info check this https://forums.developer.apple.com/thread/4743 +@property(nonatomic, readwrite, assign) BOOL hasPreCachedAuthCredentials; + +@end + +@implementation FIRInstanceIDCheckinPreferences + +- (NSDictionary *)checkinPlistContents { + NSMutableDictionary *checkinPlistContents = [NSMutableDictionary dictionary]; + checkinPlistContents[kFIRInstanceIDDigestStringKey] = self.digest ?: @""; + checkinPlistContents[kFIRInstanceIDVersionInfoStringKey] = self.versionInfo ?: @""; + checkinPlistContents[kFIRInstanceIDDeviceDataVersionKey] = self.deviceDataVersion ?: @""; + checkinPlistContents[kFIRInstanceIDLastCheckinTimeKey] = @(self.lastCheckinTimestampMillis); + checkinPlistContents[kFIRInstanceIDGServicesDictionaryKey] = + [self.gServicesData count] ? self.gServicesData : @{}; + return checkinPlistContents; +} + +- (BOOL)hasCheckinInfo { + return (self.deviceID.length && self.secretToken.length); +} + +- (BOOL)hasValidCheckinInfo { + int64_t currentTimestampInMillis = FIRInstanceIDCurrentTimestampInMilliseconds(); + int64_t timeSinceLastCheckinInMillis = currentTimestampInMillis - self.lastCheckinTimestampMillis; + + BOOL hasCheckinInfo = [self hasCheckinInfo]; + NSString *lastLocale = + [[GULUserDefaults standardUserDefaults] stringForKey:kFIRInstanceIDUserDefaultsKeyLocale]; + // If it's app's first time open and checkin is already fetched and no locale information is + // stored, then checkin info is valid. We should not checkin again because locale is considered + // "changed". + if (hasCheckinInfo && !lastLocale) { + NSString *currentLocale = FIRInstanceIDCurrentLocale(); + [[GULUserDefaults standardUserDefaults] setObject:currentLocale + forKey:kFIRInstanceIDUserDefaultsKeyLocale]; + return YES; + } + + // If locale has changed, checkin info is no longer valid. + // Also update locale information if changed. (Only do it here not in token refresh) + if (FIRInstanceIDHasLocaleChanged()) { + NSString *currentLocale = FIRInstanceIDCurrentLocale(); + [[GULUserDefaults standardUserDefaults] setObject:currentLocale + forKey:kFIRInstanceIDUserDefaultsKeyLocale]; + return NO; + } + + return (hasCheckinInfo && + (timeSinceLastCheckinInMillis / 1000.0 < kFIRInstanceIDDefaultCheckinInterval)); +} + +- (void)setHasPreCachedAuthCredentials:(BOOL)hasPreCachedAuthCredentials { + _hasPreCachedAuthCredentials = hasPreCachedAuthCredentials; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences_Private.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences_Private.h new file mode 100644 index 00000000..9c5850ba --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinPreferences_Private.h @@ -0,0 +1,27 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <FirebaseInstanceID/FIRInstanceIDCheckinPreferences.h> + +/** Checkin refresh interval. **/ +FOUNDATION_EXPORT const NSTimeInterval kFIRInstanceIDDefaultCheckinInterval; + +@interface FIRInstanceIDCheckinPreferences () + +- (BOOL)hasPreCachedAuthCredentials; +- (void)setHasPreCachedAuthCredentials:(BOOL)hasPreCachedAuthCredentials; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.h new file mode 100644 index 00000000..e14b51cb --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.h @@ -0,0 +1,68 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +#import <FirebaseInstanceID/FIRInstanceID+Private.h> +#import "FIRInstanceIDUtilities.h" + +NS_ASSUME_NONNULL_BEGIN + +// keys in Checkin preferences +FOUNDATION_EXPORT NSString *const kFIRInstanceIDDeviceAuthIdKey; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDSecretTokenKey; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDDigestStringKey; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDLastCheckinTimeKey; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDVersionInfoStringKey; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDGServicesDictionaryKey; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDDeviceDataVersionKey; + +@class FIRInstanceIDCheckinPreferences; + +/** + * Register the device with Checkin Service and get back the `authID`, `secret + * token` etc. for the client. Checkin results are cached in the + * `FIRInstanceIDCache` and periodically refreshed to prevent them from being stale. + * Each client needs to register with checkin before registering with InstanceID. + */ +@interface FIRInstanceIDCheckinService : NSObject + +/** + * Execute a device checkin request to obtain an deviceID, secret token, + * gService data. + * + * @param existingCheckin An existing checkin preference object, if available. + * @param completion Completion hander called on success or failure of device checkin. + */ +- (void)checkinWithExistingCheckin:(nullable FIRInstanceIDCheckinPreferences *)existingCheckin + completion:(FIRInstanceIDDeviceCheckinCompletion)completion; + +/** + * This would stop any request that the service made to the checkin backend and also + * release any callback handlers that it holds. + */ +- (void)stopFetching; + +/** + * Set test block for mock testing network requests. + * + * @param block The block to invoke as a mock response from the network. + */ ++ (void)setCheckinTestBlock:(nullable FIRInstanceIDURLRequestTestBlock)block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m new file mode 100644 index 00000000..d3ace54e --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m @@ -0,0 +1,242 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDCheckinService.h" + +#import "FIRInstanceIDCheckinPreferences+Internal.h" +#import "FIRInstanceIDCheckinPreferences_Private.h" +#import "FIRInstanceIDDefines.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDStore.h" +#import "FIRInstanceIDUtilities.h" +#import "NSError+FIRInstanceID.h" + +static NSString *const kDeviceCheckinURL = @"https://device-provisioning.googleapis.com/checkin"; + +// keys in Checkin preferences +NSString *const kFIRInstanceIDDeviceAuthIdKey = @"GMSInstanceIDDeviceAuthIdKey"; +NSString *const kFIRInstanceIDSecretTokenKey = @"GMSInstanceIDSecretTokenKey"; +NSString *const kFIRInstanceIDDigestStringKey = @"GMSInstanceIDDigestKey"; +NSString *const kFIRInstanceIDLastCheckinTimeKey = @"GMSInstanceIDLastCheckinTimestampKey"; +NSString *const kFIRInstanceIDVersionInfoStringKey = @"GMSInstanceIDVersionInfo"; +NSString *const kFIRInstanceIDGServicesDictionaryKey = @"GMSInstanceIDGServicesData"; +NSString *const kFIRInstanceIDDeviceDataVersionKey = @"GMSInstanceIDDeviceDataVersion"; + +static NSUInteger const kCheckinType = 2; // DeviceType IOS in l/w/a/_checkin.proto +static NSUInteger const kCheckinVersion = 2; +static NSUInteger const kFragment = 0; + +static FIRInstanceIDURLRequestTestBlock testBlock; + +@interface FIRInstanceIDCheckinService () + +@property(nonatomic, readwrite, strong) NSURLSession *session; + +@end + +@implementation FIRInstanceIDCheckinService +; + +- (instancetype)init { + self = [super init]; + if (self) { + // Create an URLSession once, even though checkin should happen about once a day + NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; + config.timeoutIntervalForResource = 60.0f; // 1 minute + config.allowsCellularAccess = YES; + _session = [NSURLSession sessionWithConfiguration:config]; + _session.sessionDescription = @"com.google.iid-checkin"; + } + return self; +} + +- (void)dealloc { + testBlock = nil; + [self.session invalidateAndCancel]; +} + +- (void)checkinWithExistingCheckin:(FIRInstanceIDCheckinPreferences *)existingCheckin + completion:(FIRInstanceIDDeviceCheckinCompletion)completion { + if (self.session == nil) { + FIRInstanceIDLoggerError(kFIRInstanceIDInvalidNetworkSession, + @"Inconsistent state: NSURLSession has been invalidated"); + NSError *error = + [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn]; + if (completion) { + completion(nil, error); + } + return; + } + + NSURL *url = [NSURL URLWithString:kDeviceCheckinURL]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + [request setValue:@"application/json" forHTTPHeaderField:@"content-type"]; + NSDictionary *checkinParameters = [self checkinParametersWithExistingCheckin:existingCheckin]; + NSData *checkinData = [NSJSONSerialization dataWithJSONObject:checkinParameters + options:0 + error:nil]; + request.HTTPMethod = @"POST"; + request.HTTPBody = checkinData; + + void (^handler)(NSData *, NSURLResponse *, NSError *) = + ^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService000, + @"Device checkin HTTP fetch error. Error Code: %ld", + (long)error.code); + if (completion) { + completion(nil, error); + } + return; + } + + NSError *serializationError; + NSDictionary *dataResponse = [NSJSONSerialization JSONObjectWithData:data + options:0 + error:&serializationError]; + if (serializationError) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService001, + @"Error serializing json object. Error Code: %ld", + _FIRInstanceID_L(serializationError.code)); + if (completion) { + completion(nil, serializationError); + } + return; + } + + NSString *deviceAuthID = [dataResponse[@"android_id"] stringValue]; + NSString *secretToken = [dataResponse[@"security_token"] stringValue]; + if ([deviceAuthID length] == 0) { + NSError *error = + [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidRequest]; + if (completion) { + completion(nil, error); + } + return; + } + + int64_t lastCheckinTimestampMillis = [dataResponse[@"time_msec"] longLongValue]; + int64_t currentTimestampMillis = FIRInstanceIDCurrentTimestampInMilliseconds(); + // Somehow the server clock gets out of sync with the device clock. + // Reset the last checkin timestamp in case this happens. + if (lastCheckinTimestampMillis > currentTimestampMillis) { + FIRInstanceIDLoggerDebug( + kFIRInstanceIDMessageCodeService002, @"Invalid last checkin timestamp %@ in future.", + [NSDate dateWithTimeIntervalSince1970:lastCheckinTimestampMillis / 1000.0]); + lastCheckinTimestampMillis = currentTimestampMillis; + } + + NSString *deviceDataVersionInfo = dataResponse[@"device_data_version_info"] ?: @""; + NSString *digest = dataResponse[@"digest"] ?: @""; + + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService003, + @"Checkin successful with authId: %@, " + @"digest: %@, " + @"lastCheckinTimestamp: %lld", + deviceAuthID, digest, lastCheckinTimestampMillis); + + NSString *versionInfo = dataResponse[@"version_info"] ?: @""; + NSMutableDictionary *gservicesData = [NSMutableDictionary dictionary]; + + // Read gServices data. + NSArray *flatSettings = dataResponse[@"setting"]; + for (NSDictionary *dict in flatSettings) { + if (dict[@"name"] && dict[@"value"]) { + gservicesData[dict[@"name"]] = dict[@"value"]; + } else { + FIRInstanceIDLoggerDebug(kFIRInstanceIDInvalidSettingResponse, + @"Invalid setting in checkin response: (%@: %@)", + dict[@"name"], dict[@"value"]); + } + } + + FIRInstanceIDCheckinPreferences *checkinPreferences = + [[FIRInstanceIDCheckinPreferences alloc] initWithDeviceID:deviceAuthID + secretToken:secretToken]; + NSDictionary *preferences = @{ + kFIRInstanceIDDigestStringKey : digest, + kFIRInstanceIDVersionInfoStringKey : versionInfo, + kFIRInstanceIDLastCheckinTimeKey : @(lastCheckinTimestampMillis), + kFIRInstanceIDGServicesDictionaryKey : gservicesData, + kFIRInstanceIDDeviceDataVersionKey : deviceDataVersionInfo, + }; + [checkinPreferences updateWithCheckinPlistContents:preferences]; + if (completion) { + completion(checkinPreferences, nil); + } + }; + // Test block + if (testBlock) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService005, + @"Test block set, will not hit the server"); + testBlock(request, handler); + return; + } + + NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:handler]; + [task resume]; +} + +- (void)stopFetching { + [self.session invalidateAndCancel]; + // The session cannot be reused after invalidation. Dispose it to prevent accident reusing. + self.session = nil; +} + +#pragma mark - Private + +- (NSDictionary *)checkinParametersWithExistingCheckin: + (nullable FIRInstanceIDCheckinPreferences *)checkinPreferences { + NSString *deviceModel = FIRInstanceIDDeviceModel(); + NSString *systemVersion = FIRInstanceIDOperatingSystemVersion(); + NSString *osVersion = [NSString stringWithFormat:@"IOS_%@", systemVersion]; + + // Get locale from GCM if GCM exists else use system API. + NSString *locale = FIRInstanceIDCurrentLocale(); + + NSInteger userNumber = 0; // Multi Profile may change this. + NSInteger userSerialNumber = 0; // Multi Profile may change this + + NSString *timeZone = [NSTimeZone localTimeZone].name; + int64_t lastCheckingTimestampMillis = checkinPreferences.lastCheckinTimestampMillis; + + NSDictionary *checkinParameters = @{ + @"checkin" : @{ + @"iosbuild" : @{@"model" : deviceModel, @"os_version" : osVersion}, + @"type" : @(kCheckinType), + @"user_number" : @(userNumber), + @"last_checkin_msec" : @(lastCheckingTimestampMillis), + }, + @"fragment" : @(kFragment), + @"locale" : locale, + @"version" : @(kCheckinVersion), + @"digest" : checkinPreferences.digest ?: @"", + @"time_zone" : timeZone, + @"user_serial_number" : @(userSerialNumber), + @"id" : @([checkinPreferences.deviceID longLongValue]), + @"security_token" : @([checkinPreferences.secretToken longLongValue]), + }; + + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeService006, @"Checkin parameters: %@", + checkinParameters); + return checkinParameters; +} + ++ (void)setCheckinTestBlock:(FIRInstanceIDURLRequestTestBlock)block { + testBlock = [block copy]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.h new file mode 100644 index 00000000..a7307a7d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.h @@ -0,0 +1,96 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@class FIRInstanceIDAuthKeychain; +@class FIRInstanceIDBackupExcludedPlist; +@class FIRInstanceIDCheckinPreferences; + +// These values exposed for testing +extern NSString *const kFIRInstanceIDCheckinKeychainService; + +/** + * Checkin preferences backing store. + */ +@interface FIRInstanceIDCheckinStore : NSObject + +/** + * Designated Initializer. Initialize a checkin store with the given backup excluded + * plist filename. + * + * @param checkinFilename The backup excluded plist filename to persist checkin + * preferences. + * + * @param subDirectoryName Sub-directory in standard directory where we write + * InstanceID plist. + * + * @return Store to persist checkin preferences. + */ +- (instancetype)initWithCheckinPlistFileName:(NSString *)checkinFilename + subDirectoryName:(NSString *)subDirectoryName; + +/** + * Initialize a checkin store with the given backup excluded plist and keychain. + * + * @param plist The backup excluded plist to persist checkin preferences. + * @param keychain The keychain used to persist checkin auth preferences. + * + * @return Store to persist checkin preferences. + */ +- (instancetype)initWithCheckinPlist:(FIRInstanceIDBackupExcludedPlist *)plist + keychain:(FIRInstanceIDAuthKeychain *)keychain; + +/** + * Checks whether the backup excluded checkin preferences are present on the disk or not. + * + * @return YES if the backup excluded checkin plist exists on the disks else NO. + */ +- (BOOL)hasCheckinPlist; + +#pragma mark - Save + +/** + * Save the checkin preferences to backing store. + * + * @param preferences Checkin preferences to save. + * @param handler The callback handler which is invoked when the operation is complete, + * with an error if there is any. + */ +- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences + handler:(void (^)(NSError *error))handler; + +#pragma mark - Delete + +/** + * Remove the cached checkin preferences. + * + * @param handler The callback handler which is invoked when the operation is complete, + * with an error if there is any. + */ +- (void)removeCheckinPreferencesWithHandler:(void (^)(NSError *error))handler; + +#pragma mark - Get + +/** + * Get the cached device secret. If we cannot access it for some reason we + * return the appropriate error object. + * + * @return The cached checkin preferences if present else nil. + */ +- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m new file mode 100644 index 00000000..b3bd3535 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m @@ -0,0 +1,194 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDCheckinStore.h" + +#import "FIRInstanceIDAuthKeyChain.h" +#import "FIRInstanceIDBackupExcludedPlist.h" +#import "FIRInstanceIDCheckinPreferences+Internal.h" +#import "FIRInstanceIDCheckinPreferences_Private.h" +#import "FIRInstanceIDCheckinService.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDUtilities.h" +#import "FIRInstanceIDVersionUtilities.h" +#import "NSError+FIRInstanceID.h" + +static NSString *const kFIRInstanceIDCheckinKeychainGeneric = @"com.google.iid"; + +NSString *const kFIRInstanceIDCheckinKeychainService = @"com.google.iid.checkin"; + +@interface FIRInstanceIDCheckinStore () + +@property(nonatomic, readwrite, strong) FIRInstanceIDBackupExcludedPlist *plist; +@property(nonatomic, readwrite, strong) FIRInstanceIDAuthKeychain *keychain; +// Checkin will store items under +// Keychain account: <app bundle id>, +// Keychain service: |kFIRInstanceIDCheckinKeychainService| +@property(nonatomic, readonly) NSString *bundleIdentifierForKeychainAccount; + +@end + +@implementation FIRInstanceIDCheckinStore + +- (instancetype)initWithCheckinPlistFileName:(NSString *)checkinFilename + subDirectoryName:(NSString *)subDirectoryName { + FIRInstanceIDBackupExcludedPlist *plist = + [[FIRInstanceIDBackupExcludedPlist alloc] initWithFileName:checkinFilename + subDirectory:subDirectoryName]; + + FIRInstanceIDAuthKeychain *keychain = + [[FIRInstanceIDAuthKeychain alloc] initWithIdentifier:kFIRInstanceIDCheckinKeychainGeneric]; + return [self initWithCheckinPlist:plist keychain:keychain]; +} + +- (instancetype)initWithCheckinPlist:(FIRInstanceIDBackupExcludedPlist *)plist + keychain:(FIRInstanceIDAuthKeychain *)keychain { + self = [super init]; + if (self) { + _plist = plist; + _keychain = keychain; + } + return self; +} + +- (BOOL)hasCheckinPlist { + return [self.plist doesFileExist]; +} + +- (NSString *)bundleIdentifierForKeychainAccount { + static NSString *bundleIdentifier; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + bundleIdentifier = FIRInstanceIDAppIdentifier(); + }); + return bundleIdentifier; +} + +- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences + handler:(void (^)(NSError *error))handler { + NSDictionary *checkinPlistContents = [preferences checkinPlistContents]; + NSString *checkinKeychainContent = [preferences checkinKeychainContent]; + + if (![checkinKeychainContent length]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStore000, + @"Failed to get checkin keychain content from memory."); + if (handler) { + handler([NSError + errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn]); + } + return; + } + if (![checkinPlistContents count]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStore001, + @"Failed to get checkin plist contents from memory."); + if (handler) { + handler([NSError + errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn]); + } + return; + } + + // Save all other checkin preferences in a plist + NSError *error; + if (![self.plist writeDictionary:checkinPlistContents error:&error]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStore003, + @"Failed to save checkin plist contents." + @"Will delete auth credentials"); + [self.keychain removeItemsMatchingService:kFIRInstanceIDCheckinKeychainService + account:self.bundleIdentifierForKeychainAccount + handler:nil]; + if (handler) { + handler(error); + } + return; + } + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStoreCheckinPlistSaved, + @"Checkin plist file is saved"); + + // Save the deviceID and secret in the Keychain + if (!preferences.hasPreCachedAuthCredentials) { + NSData *data = [checkinKeychainContent dataUsingEncoding:NSUTF8StringEncoding]; + [self.keychain setData:data + forService:kFIRInstanceIDCheckinKeychainService + account:self.bundleIdentifierForKeychainAccount + handler:^(NSError *error) { + if (error) { + if (handler) { + handler(error); + } + return; + } + if (handler) { + handler(nil); + } + }]; + } else { + handler(nil); + } +} + +- (void)removeCheckinPreferencesWithHandler:(void (^)(NSError *error))handler { + // Delete the checkin preferences plist first to avoid delay. + NSError *deletePlistError; + if (![self.plist deleteFile:&deletePlistError]) { + handler(deletePlistError); + return; + } + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeCheckinStoreCheckinPlistDeleted, + @"Deleted checkin plist file."); + // Remove deviceID and secret from Keychain + [self.keychain removeItemsMatchingService:kFIRInstanceIDCheckinKeychainService + account:self.bundleIdentifierForKeychainAccount + handler:^(NSError *error) { + handler(error); + }]; +} + +- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences { + // Query the keychain for deviceID and secret + NSData *item = [self.keychain dataForService:kFIRInstanceIDCheckinKeychainService + account:self.bundleIdentifierForKeychainAccount]; + + // Check info found in keychain + NSString *checkinKeychainContent = [[NSString alloc] initWithData:item + encoding:NSUTF8StringEncoding]; + FIRInstanceIDCheckinPreferences *checkinPreferences = + [FIRInstanceIDCheckinPreferences preferencesFromKeychainContents:checkinKeychainContent]; + + NSDictionary *checkinPlistContents = [self.plist contentAsDictionary]; + + NSString *plistDeviceAuthID = checkinPlistContents[kFIRInstanceIDDeviceAuthIdKey]; + NSString *plistSecretToken = checkinPlistContents[kFIRInstanceIDSecretTokenKey]; + + // If deviceID and secret not found in the keychain verify that we don't have them in the + // checkin preferences plist. + if (![checkinPreferences.deviceID length] && ![checkinPreferences.secretToken length]) { + if ([plistDeviceAuthID length] && [plistSecretToken length]) { + // Couldn't find checkin credentials in keychain but found them in the plist. + checkinPreferences = + [[FIRInstanceIDCheckinPreferences alloc] initWithDeviceID:plistDeviceAuthID + secretToken:plistSecretToken]; + } else { + // Couldn't find checkin credentials in keychain nor plist + return nil; + } + } + + [checkinPreferences updateWithCheckinPlistContents:checkinPlistContents]; + return checkinPreferences; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCombinedHandler.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCombinedHandler.h new file mode 100644 index 00000000..dcb5429b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCombinedHandler.h @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + * A generic class to combine several handler blocks into a single block in a thread-safe manner + */ +@interface FIRInstanceIDCombinedHandler<ResultType> : NSObject + +- (void)addHandler:(void (^)(ResultType _Nullable result, NSError* _Nullable error))handler; +- (void (^)(ResultType _Nullable result, NSError* _Nullable error))combinedHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCombinedHandler.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCombinedHandler.m new file mode 100644 index 00000000..bc6be6c1 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCombinedHandler.m @@ -0,0 +1,64 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDCombinedHandler.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^FIRInstanseIDHandler)(id _Nullable result, NSError *_Nullable error); + +@interface FIRInstanceIDCombinedHandler <ResultType>() +@property(atomic, readonly, strong) NSMutableArray<FIRInstanseIDHandler> *handlers; +@end + +NS_ASSUME_NONNULL_END + +@implementation FIRInstanceIDCombinedHandler + +- (instancetype)init { + self = [super init]; + if (self) { + _handlers = [NSMutableArray array]; + } + return self; +} + +- (void)addHandler:(FIRInstanseIDHandler)handler { + if (!handler) { + return; + } + + @synchronized(self) { + [self.handlers addObject:handler]; + } +} + +- (FIRInstanseIDHandler)combinedHandler { + FIRInstanseIDHandler combinedHandler = nil; + + @synchronized(self) { + NSArray<FIRInstanseIDHandler> *handlers = [self.handlers copy]; + combinedHandler = ^(id result, NSError *error) { + for (FIRInstanseIDHandler handler in handlers) { + handler(result, error); + } + }; + } + + return combinedHandler; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.h new file mode 100644 index 00000000..501039dc --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.h @@ -0,0 +1,65 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +#pragma mark - Commands + +/** + * Value included in a structured response or GCM message from IID, indicating + * an identity reset. + */ +FOUNDATION_EXPORT NSString *const kFIRInstanceID_CMD_RST; + +#pragma mark - Notifications + +/// Notification used to deliver GCM messages for InstanceID. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDCheckinFetchedNotification; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDAPNSTokenNotification; +FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification; + +FOUNDATION_EXPORT NSString *const kFIRInstanceIDIdentityInvalidatedNotification; + +#pragma mark - Miscellaneous + +/// The scope used to save the IID "*" scope token. This is used for saving the +/// IID auth token that we receive from the server. This feature was never +/// implemented on the server side. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDAllScopeIdentifier; +/// The scope used to save the IID "*" scope token. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultTokenScope; + +/// Subdirectory in search path directory to store InstanceID preferences. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDSubDirectoryName; + +/// The key for APNS token in options dictionary. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenOptionsAPNSKey; + +/// The key for APNS token environment type in options dictionary. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenOptionsAPNSIsSandboxKey; + +/// The key for GMP AppID sent in registration requests. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenOptionsFirebaseAppIDKey; + +/// The key to enable auto-register by swizzling AppDelegate's methods. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDAppDelegateProxyEnabledInfoPlistKey; + +/// The key for InstallationID or InstanceID in token request. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDParamInstanceID; + +/// Error code for missing entitlements in Keychain. iOS Keychain error +/// https://forums.developer.apple.com/thread/4743 +FOUNDATION_EXPORT const int kFIRInstanceIDSecMissingEntitlementErrorCode; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.m new file mode 100644 index 00000000..5eda1712 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDConstants.m @@ -0,0 +1,46 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDConstants.h" + +// Commands +NSString *const kFIRInstanceID_CMD_RST = @"RST"; + +// NOTIFICATIONS +NSString *const kFIRInstanceIDCheckinFetchedNotification = @"com.google.gcm.notif-checkin-fetched"; +NSString *const kFIRInstanceIDAPNSTokenNotification = @"com.firebase.iid.notif.apns-token"; +NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification = + @"com.firebase.iid.notif.fcm-token-fail"; + +NSString *const kFIRInstanceIDIdentityInvalidatedNotification = @"com.google.iid.identity-invalid"; + +// Miscellaneous +NSString *const kFIRInstanceIDAllScopeIdentifier = @"iid-all"; +NSString *const kFIRInstanceIDDefaultTokenScope = @"*"; +NSString *const kFIRInstanceIDSubDirectoryName = @"Google/FirebaseInstanceID"; + +// Registration Options +NSString *const kFIRInstanceIDTokenOptionsAPNSKey = @"apns_token"; +NSString *const kFIRInstanceIDTokenOptionsAPNSIsSandboxKey = @"apns_sandbox"; +NSString *const kFIRInstanceIDTokenOptionsFirebaseAppIDKey = @"gmp_app_id"; +NSString *const kFIRInstanceIDParamInstanceID = @"appid"; + +NSString *const kFIRInstanceIDAppDelegateProxyEnabledInfoPlistKey = + @"FirebaseAppDelegateProxyEnabled"; + +// iOS Keychain error https://forums.developer.apple.com/thread/4743 +// An undocumented error code hence need to be redeclared. +const int kFIRInstanceIDSecMissingEntitlementErrorCode = -34018; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDDefines.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDDefines.h new file mode 100644 index 00000000..ccc25b3d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDDefines.h @@ -0,0 +1,47 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRInstanceIDLib_FIRInstanceIDDefines_h +#define FIRInstanceIDLib_FIRInstanceIDDefines_h + +#define _FIRInstanceID_VERBOSE_LOGGING 1 + +// Verbose Logging +#if (_FIRInstanceID_VERBOSE_LOGGING) +#define FIRInstanceID_DEV_VERBOSE_LOG(...) NSLog(__VA_ARGS__) +#else +#define FIRInstanceID_DEV_VERBOSE_LOG(...) \ + do { \ + } while (0) +#endif // VERBOSE_LOGGING + +// WEAKIFY & STRONGIFY +// Helper macro. +#define _FIRInstanceID_WEAKNAME(VAR) VAR##_weak_ + +#define FIRInstanceID_WEAKIFY(VAR) __weak __typeof__(VAR) _FIRInstanceID_WEAKNAME(VAR) = (VAR); + +#define FIRInstanceID_STRONGIFY(VAR) \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") \ + __strong __typeof__(VAR) VAR = _FIRInstanceID_WEAKNAME(VAR); \ + _Pragma("clang diagnostic pop") + +// Type Conversions (used for NSInteger etc) +#ifndef _FIRInstanceID_L +#define _FIRInstanceID_L(v) (long)(v) +#endif + +#endif diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h new file mode 100644 index 00000000..1c80d8e3 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h @@ -0,0 +1,62 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +/* The Keychain error domain */ +extern NSString *const kFIRInstanceIDKeychainErrorDomain; + +/* + * Wrapping the keychain operations in a serialize queue. This is to avoid keychain operation + * blocking main queue. + */ +@interface FIRInstanceIDKeychain : NSObject + +/** + * FIRInstanceIDKeychain. + * + * @return A shared instance of FIRInstanceIDKeychain. + */ ++ (instancetype)sharedInstance; + +/** + * Get keychain items matching the given a query. + * + * @param keychainQuery The keychain query. + * + * @return An CFTypeRef result matching the provided inputs. + */ +- (CFTypeRef)itemWithQuery:(NSDictionary *)keychainQuery; + +/** + * Remove the cached items from the keychain matching the query. + * + * @param keychainQuery The keychain query. + * @param handler The callback handler which is invoked when the remove operation is + * complete, with an error if there is any. + */ +- (void)removeItemWithQuery:(NSDictionary *)keychainQuery handler:(void (^)(NSError *error))handler; + +/** + * Add the item with a given query. + * + * @param keychainQuery The keychain query. + * @param handler The callback handler which is invoked when the add operation is + * complete, with an error if there is any. + */ +- (void)addItemWithQuery:(NSDictionary *)keychainQuery handler:(void (^)(NSError *))handler; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m new file mode 100644 index 00000000..df1b4f76 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m @@ -0,0 +1,114 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDKeychain.h" + +#import "FIRInstanceIDLogger.h" + +NSString *const kFIRInstanceIDKeychainErrorDomain = @"com.google.iid"; + +@interface FIRInstanceIDKeychain () { + dispatch_queue_t _keychainOperationQueue; +} + +@end + +@implementation FIRInstanceIDKeychain + ++ (instancetype)sharedInstance { + static FIRInstanceIDKeychain *sharedInstance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[FIRInstanceIDKeychain alloc] init]; + }); + return sharedInstance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _keychainOperationQueue = + dispatch_queue_create("com.google.FirebaseInstanceID.Keychain", DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (CFTypeRef)itemWithQuery:(NSDictionary *)keychainQuery { + __block SecKeyRef keyRef = NULL; + dispatch_sync(_keychainOperationQueue, ^{ + OSStatus status = + SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyRef); + + if (status != noErr) { + if (keyRef) { + CFRelease(keyRef); + } + FIRInstanceIDLoggerDebug(kFIRInstanceIDKeychainReadItemError, + @"Info is not found in Keychain. OSStatus: %d. Keychain query: %@", + (int)status, keychainQuery); + } + }); + return keyRef; +} + +- (void)removeItemWithQuery:(NSDictionary *)keychainQuery + handler:(void (^)(NSError *error))handler { + dispatch_async(_keychainOperationQueue, ^{ + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)keychainQuery); + if (status != noErr) { + FIRInstanceIDLoggerDebug( + kFIRInstanceIDKeychainDeleteItemError, + @"Couldn't delete item from Keychain OSStatus: %d with the keychain query %@", + (int)status, keychainQuery); + } + + if (handler) { + NSError *error; + // When item is not found, it should NOT be considered as an error. The operation should + // continue. + if (status != noErr && status != errSecItemNotFound) { + error = [NSError errorWithDomain:kFIRInstanceIDKeychainErrorDomain + code:status + userInfo:nil]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + handler(error); + }); + } + }); +} + +- (void)addItemWithQuery:(NSDictionary *)keychainQuery handler:(void (^)(NSError *))handler { + dispatch_async(_keychainOperationQueue, ^{ + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL); + + if (handler) { + NSError *error; + if (status != noErr) { + FIRInstanceIDLoggerWarning(kFIRInstanceIDKeychainAddItemError, + @"Couldn't add item to Keychain OSStatus: %d", (int)status); + error = [NSError errorWithDomain:kFIRInstanceIDKeychainErrorDomain + code:status + userInfo:nil]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + handler(error); + }); + } + }); +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.h new file mode 100644 index 00000000..ab93976c --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.h @@ -0,0 +1,66 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRIMessageCode.h" + +// The convenience macros are only defined if they haven't already been defined. +#ifndef FIRInstanceIDLoggerInfo + +// Convenience macros that log to the shared GTMLogger instance. These macros +// are how users should typically log to FIRInstanceIDLogger. +#define FIRInstanceIDLoggerDebug(code, ...) \ + [FIRInstanceIDSharedLogger() logFuncDebug:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRInstanceIDLoggerInfo(code, ...) \ + [FIRInstanceIDSharedLogger() logFuncInfo:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRInstanceIDLoggerNotice(code, ...) \ + [FIRInstanceIDSharedLogger() logFuncNotice:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRInstanceIDLoggerWarning(code, ...) \ + [FIRInstanceIDSharedLogger() logFuncWarning:__func__ messageCode:code msg:__VA_ARGS__] +#define FIRInstanceIDLoggerError(code, ...) \ + [FIRInstanceIDSharedLogger() logFuncError:__func__ messageCode:code msg:__VA_ARGS__] + +#endif // !defined(FIRInstanceIDLoggerInfo) + +@interface FIRInstanceIDLogger : NSObject + +- (void)logFuncDebug:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncInfo:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncNotice:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncWarning:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +- (void)logFuncError:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... NS_FORMAT_FUNCTION(3, 4); + +@end + +/** + * Instantiates and/or returns a shared GTMLogger used exclusively + * for InstanceID log messages. + * @return the shared GTMLogger instance + */ +FIRInstanceIDLogger *FIRInstanceIDSharedLogger(void); diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.m new file mode 100644 index 00000000..489939da --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDLogger.m @@ -0,0 +1,92 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDLogger.h" + +#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h" + +// Re-definition of FIRLogger service, as it is not included in :FIRAppHeaders target +NSString *const kFIRInstanceIDLoggerService = @"[Firebase/InstanceID]"; + +@implementation FIRInstanceIDLogger + +#pragma mark - Log Helpers + ++ (NSString *)formatMessageCode:(FIRInstanceIDMessageCode)messageCode { + return [NSString stringWithFormat:@"I-IID%06ld", (long)messageCode]; +} + +- (void)logFuncDebug:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelDebug, kFIRInstanceIDLoggerService, + [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncInfo:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelInfo, kFIRInstanceIDLoggerService, + [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncNotice:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelNotice, kFIRInstanceIDLoggerService, + [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncWarning:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelWarning, kFIRInstanceIDLoggerService, + [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +- (void)logFuncError:(const char *)func + messageCode:(FIRInstanceIDMessageCode)messageCode + msg:(NSString *)fmt, ... { + va_list args; + va_start(args, fmt); + FIRLogBasic(FIRLoggerLevelError, kFIRInstanceIDLoggerService, + [FIRInstanceIDLogger formatMessageCode:messageCode], fmt, args); + va_end(args); +} + +@end + +FIRInstanceIDLogger *FIRInstanceIDSharedLogger() { + static dispatch_once_t onceToken; + static FIRInstanceIDLogger *logger; + dispatch_once(&onceToken, ^{ + logger = [[FIRInstanceIDLogger alloc] init]; + }); + + return logger; +} diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.h new file mode 100644 index 00000000..d1f26348 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.h @@ -0,0 +1,183 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@class FIRInstanceIDBackupExcludedPlist; +@class FIRInstanceIDCheckinPreferences; +@class FIRInstanceIDCheckinStore; +@class FIRInstanceIDTokenInfo; +@class FIRInstanceIDTokenStore; + +@class FIRInstanceIDStore; +@protocol FIRInstanceIDStoreDelegate <NSObject> + +/** + * This is called when the store has decided to invalide its tokens associated with the + * previous checkin credentials. After deleting the tokens locally, it calls this method + * to notify the delegate of the change. If possible, the delegate should use this time + * to request the invalidation of the tokens on the server as well. + */ +- (void)store:(FIRInstanceIDStore *)store + didDeleteFCMScopedTokensForCheckin:(FIRInstanceIDCheckinPreferences *)checkin; + +@end + +/** + * Used to persist the InstanceID tokens. This is also used to cache the Checkin + * credentials. The store also checks for stale entries in the store and + * let's us know if things in the store are stale or not. It does not however + * acts on stale entries in anyway. + */ +@interface FIRInstanceIDStore : NSObject + +/** + * The delegate set in the initializer which is notified of changes in the store. + */ +@property(nonatomic, readonly, weak) NSObject<FIRInstanceIDStoreDelegate> *delegate; + +- (instancetype)init __attribute__((unavailable("Use initWithDelegate: instead."))); + +/** + * Initialize a default store to persist InstanceID tokens and options. + * + * @param delegate The delegate with which to be notified of changes in the store. + * @return Store to persist InstanceID tokens. + */ +- (instancetype)initWithDelegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate; + +/** + * Initialize a store with the token store used to persist tokens, and a checkin store. + * Used for testing. + * + * @param checkinStore Persistent store that persists checkin preferences. + * @param tokenStore Persistent store that persists tokens. + * + * @return Store to persist InstanceID tokens and options. + */ +- (instancetype)initWithCheckinStore:(FIRInstanceIDCheckinStore *)checkinStore + tokenStore:(FIRInstanceIDTokenStore *)tokenStore + delegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate + NS_DESIGNATED_INITIALIZER; + +#pragma mark - Save +/** + * Save the instanceID token info to the store. + * + * @param tokenInfo The token info to store. + * @param handler The callback handler which is invoked when the operation is complete, + * with an error if there is any. + */ +- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo handler:(void (^)(NSError *))handler; + +#pragma mark - Get + +/** + * Get the cached token info. + * + * @param authorizedEntity The authorized entity for which we want the token. + * @param scope The scope for which we want the token. + * + * @return The cached token info if any for the given authorizedEntity and scope else + * returns nil. + */ +- (nullable FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope; +/** + * Return all cached token infos from the Keychain. + * + * @return The cached token infos, if any, that are stored in the Keychain. + */ +- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos; + +#pragma mark - Delete + +/** + * Remove the cached token for a given authorizedEntity and scope. If the token was never + * cached or deleted from the cache before this is a no-op. + * + * @param authorizedEntity The authorizedEntity for the cached token. + * @param scope The scope for the cached token + */ +- (void)removeCachedTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope; + +/** + * Removes all cached tokens from the persistent store. In case deleting the cached tokens + * fails we try to delete the backup excluded plist that stores the tokens. + * + * @param handler The callback handler which is invoked when the operation is complete, + * with an error if there is any. + * + */ +- (void)removeAllCachedTokensWithHandler:(nullable void (^)(NSError *error))handler; + +#pragma mark - Persisting Checkin Preferences + +/** + * Save the checkin preferences + * + * @param preferences Checkin preferences to save. + * @param handler The callback handler which is invoked when the operation is complete, + * with an error if there is any. + */ +- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences + handler:(nullable void (^)(NSError *error))handler; + +/** + * Return the cached checkin preferences. + * + * @return Checkin preferences. + */ +- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences; + +/** + * Remove the cached checkin preferences from the store. + * + * @param handler The callback handler which is invoked when the operation is complete, + * with an error if there is any. + */ +- (void)removeCheckinPreferencesWithHandler:(nullable void (^)(NSError *error))handler; + +#pragma mark - Standard Directory sub-directory + +/** + * Check if supported directory has InstanceID subdirectory + * + * @return YES if the Application Support directory has InstanceID subdirectory else NO. + */ ++ (BOOL)hasSubDirectory:(NSString *)subDirectoryName; + +/** + * Create InstanceID subdirectory in Application support directory. + * + * @return YES if the subdirectory was created successfully else NO. + */ ++ (BOOL)createSubDirectory:(NSString *)subDirectoryName; + +/** + * Removes Application Support subdirectory for InstanceID. + * + * @param error The error object if any while trying to delete the sub-directory. + * + * @return YES if the deletion was successful else NO. + */ ++ (BOOL)removeSubDirectory:(NSString *)subDirectoryName error:(NSError **)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.m new file mode 100644 index 00000000..ba68f968 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDStore.m @@ -0,0 +1,240 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDStore.h" + +#import "FIRInstanceIDCheckinPreferences.h" +#import "FIRInstanceIDCheckinStore.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDTokenStore.h" +#import "FIRInstanceIDVersionUtilities.h" + +// NOTE: These values should be in sync with what InstanceID saves in as. +static NSString *const kCheckinFileName = @"g-checkin"; + +// APNS token (use the old key value i.e. with prefix GMS) +static NSString *const kFIRInstanceIDLibraryVersion = @"GMSInstanceID-version"; + +@interface FIRInstanceIDStore () + +@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinStore *checkinStore; +@property(nonatomic, readwrite, strong) FIRInstanceIDTokenStore *tokenStore; + +@end + +@implementation FIRInstanceIDStore + +- (instancetype)initWithDelegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate { + FIRInstanceIDCheckinStore *checkinStore = [[FIRInstanceIDCheckinStore alloc] + initWithCheckinPlistFileName:kCheckinFileName + subDirectoryName:kFIRInstanceIDSubDirectoryName]; + + FIRInstanceIDTokenStore *tokenStore = [FIRInstanceIDTokenStore defaultStore]; + + return [self initWithCheckinStore:checkinStore tokenStore:tokenStore delegate:delegate]; +} + +- (instancetype)initWithCheckinStore:(FIRInstanceIDCheckinStore *)checkinStore + tokenStore:(FIRInstanceIDTokenStore *)tokenStore + delegate:(NSObject<FIRInstanceIDStoreDelegate> *)delegate { + self = [super init]; + if (self) { + _checkinStore = checkinStore; + _tokenStore = tokenStore; + _delegate = delegate; + [self resetCredentialsIfNeeded]; + } + return self; +} + +#pragma mark - Upgrades + ++ (BOOL)hasSubDirectory:(NSString *)subDirectoryName { + NSString *subDirectoryPath = [self pathForSupportSubDirectory:subDirectoryName]; + BOOL isDirectory; + if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&isDirectory]) { + return NO; + } else if (!isDirectory) { + return NO; + } + return YES; +} + ++ (NSSearchPathDirectory)supportedDirectory { +#if TARGET_OS_TV + return NSCachesDirectory; +#else + return NSApplicationSupportDirectory; +#endif +} + ++ (NSString *)pathForSupportSubDirectory:(NSString *)subDirectoryName { + NSArray *directoryPaths = + NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES); + NSString *dirPath = directoryPaths.lastObject; + NSArray *components = @[ dirPath, subDirectoryName ]; + return [NSString pathWithComponents:components]; +} + ++ (BOOL)createSubDirectory:(NSString *)subDirectoryName { + NSString *subDirectoryPath = [self pathForSupportSubDirectory:subDirectoryName]; + BOOL hasSubDirectory; + + if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&hasSubDirectory]) { + NSError *error; + [[NSFileManager defaultManager] createDirectoryAtPath:subDirectoryPath + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (error) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeStore000, + @"Cannot create directory %@, error: %@", subDirectoryPath, error); + return NO; + } + } else { + if (!hasSubDirectory) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeStore001, + @"Found file instead of directory at %@", subDirectoryPath); + return NO; + } + } + return YES; +} + ++ (BOOL)removeSubDirectory:(NSString *)subDirectoryName error:(NSError **)error { + if ([self hasSubDirectory:subDirectoryName]) { + NSString *subDirectoryPath = [self pathForSupportSubDirectory:subDirectoryName]; + BOOL isDirectory; + if ([[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath + isDirectory:&isDirectory]) { + return [[NSFileManager defaultManager] removeItemAtPath:subDirectoryPath error:error]; + } + } + return YES; +} + +/** + * Reset the keychain preferences if the app had been deleted earlier and then reinstalled. + * Keychain preferences are not cleared in the above scenario so explicitly clear them. + * + * In case of an iCloud backup and restore the Keychain preferences should already be empty + * since the Keychain items are marked with `*BackupThisDeviceOnly`. + */ +- (void)resetCredentialsIfNeeded { + BOOL checkinPlistExists = [self.checkinStore hasCheckinPlist]; + // Checkin info existed in backup excluded plist. Should not be a fresh install. + if (checkinPlistExists) { + return; + } + + // Resets checkin in keychain if a fresh install. + // Keychain can still exist even if app is uninstalled. + FIRInstanceIDCheckinPreferences *oldCheckinPreferences = + [self.checkinStore cachedCheckinPreferences]; + + if (oldCheckinPreferences) { + [self.checkinStore removeCheckinPreferencesWithHandler:^(NSError *error) { + if (!error) { + FIRInstanceIDLoggerDebug( + kFIRInstanceIDMessageCodeStore002, + @"Removed cached checkin preferences from Keychain because this is a fresh install."); + } else { + FIRInstanceIDLoggerError( + kFIRInstanceIDMessageCodeStore003, + @"Couldn't remove cached checkin preferences for a fresh install. Error: %@", error); + } + if (oldCheckinPreferences.deviceID.length && oldCheckinPreferences.secretToken.length) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeStore006, + @"App reset detected. Will delete server registrations."); + // We don't really need to delete old FCM tokens created via IID auth tokens since + // those tokens are already hashed by APNS token as the has so creating a new + // token should automatically delete the old-token. + [self.delegate store:self didDeleteFCMScopedTokensForCheckin:oldCheckinPreferences]; + } else { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeStore009, + @"App reset detected but no valid checkin auth preferences found." + @" Will not delete server registrations."); + } + }]; + } +} + +#pragma mark - Get + +- (FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope { + // TODO(chliangGoogle): If we don't have the token plist we should delete all the tokens from + // the keychain. This is because not having the plist signifies a backup and restore operation. + // In case the keychain has any tokens these would now be stale and therefore should be + // deleted. + if (![authorizedEntity length] || ![scope length]) { + return nil; + } + FIRInstanceIDTokenInfo *info = [self.tokenStore tokenInfoWithAuthorizedEntity:authorizedEntity + scope:scope]; + return info; +} + +- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos { + return [self.tokenStore cachedTokenInfos]; +} + +#pragma mark - Save + +- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo + handler:(void (^)(NSError *error))handler { + [self.tokenStore saveTokenInfo:tokenInfo handler:handler]; +} + +#pragma mark - Delete + +- (void)removeCachedTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope { + if (![authorizedEntity length] || ![scope length]) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeStore012, + @"Will not delete token with invalid entity: %@, scope: %@", + authorizedEntity, scope); + return; + } + [self.tokenStore removeTokenWithAuthorizedEntity:authorizedEntity scope:scope]; +} + +- (void)removeAllCachedTokensWithHandler:(void (^)(NSError *error))handler { + [self.tokenStore removeAllTokensWithHandler:handler]; +} + +#pragma mark - FIRInstanceIDCheckinCache protocol + +- (void)saveCheckinPreferences:(FIRInstanceIDCheckinPreferences *)preferences + handler:(void (^)(NSError *error))handler { + [self.checkinStore saveCheckinPreferences:preferences handler:handler]; +} + +- (FIRInstanceIDCheckinPreferences *)cachedCheckinPreferences { + return [self.checkinStore cachedCheckinPreferences]; +} + +- (void)removeCheckinPreferencesWithHandler:(void (^)(NSError *))handler { + [self.checkinStore removeCheckinPreferencesWithHandler:^(NSError *error) { + if (handler) { + handler(error); + } + }]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h new file mode 100644 index 00000000..b6723fda --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRInstanceIDTokenDeleteOperation : FIRInstanceIDTokenOperation + +- (instancetype)initWithAuthorizedEntity:(nullable NSString *)authorizedEntity + scope:(nullable NSString *)scope + checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences + instanceID:(nullable NSString *)instanceID + action:(FIRInstanceIDTokenAction)action; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m new file mode 100644 index 00000000..64039091 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m @@ -0,0 +1,119 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenDeleteOperation.h" + +#import "FIRInstanceIDCheckinPreferences.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDDefines.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDTokenOperation+Private.h" +#import "FIRInstanceIDUtilities.h" +#import "NSError+FIRInstanceID.h" + +@implementation FIRInstanceIDTokenDeleteOperation + +- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences + instanceID:(NSString *)instanceID + action:(FIRInstanceIDTokenAction)action { + self = [super initWithAction:action + forAuthorizedEntity:authorizedEntity + scope:scope + options:nil + checkinPreferences:checkinPreferences + instanceID:instanceID]; + if (self) { + } + return self; +} + +- (void)performTokenOperation { + NSMutableURLRequest *request = [self tokenRequest]; + + // Build form-encoded body + NSString *deviceAuthID = self.checkinPreferences.deviceID; + NSMutableArray<NSURLQueryItem *> *queryItems = + [FIRInstanceIDTokenOperation standardQueryItemsWithDeviceID:deviceAuthID scope:self.scope]; + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"delete" value:@"true"]]; + if (self.action == FIRInstanceIDTokenActionDeleteTokenAndIID) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"iid-operation" value:@"delete"]]; + } + if (self.authorizedEntity) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"sender" value:self.authorizedEntity]]; + } + // Typically we include our public key-signed url items, but in some cases (like deleting all FCM + // tokens), we don't. + if (self.instanceID.length > 0) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:kFIRInstanceIDParamInstanceID + value:self.instanceID]]; + } + + NSURLComponents *components = [[NSURLComponents alloc] init]; + components.queryItems = queryItems; + NSString *content = components.query; + request.HTTPBody = [content dataUsingEncoding:NSUTF8StringEncoding]; + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenDeleteOperationFetchRequest, + @"Unregister request to %@ content: %@", FIRInstanceIDRegisterServer(), + content); + + FIRInstanceID_WEAKIFY(self); + void (^requestHandler)(NSData *, NSURLResponse *, NSError *) = + ^(NSData *data, NSURLResponse *response, NSError *error) { + FIRInstanceID_STRONGIFY(self); + [self handleResponseWithData:data response:response error:error]; + }; + + // Test block + if (self.testBlock) { + self.testBlock(request, requestHandler); + return; + } + + NSURLSession *session = [FIRInstanceIDTokenOperation sharedURLSession]; + self.dataTask = [session dataTaskWithRequest:request completionHandler:requestHandler]; + [self.dataTask resume]; +} + +- (void)handleResponseWithData:(NSData *)data + response:(NSURLResponse *)response + error:(NSError *)error { + if (error) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenDeleteOperationRequestError, + @"Device unregister HTTP fetch error. Error code: %ld", + _FIRInstanceID_L(error.code)); + [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; + return; + } + + NSString *dataResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (dataResponse.length == 0) { + NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; + [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; + return; + } + + if (![dataResponse hasPrefix:@"deleted="] && ![dataResponse hasPrefix:@"token="]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenDeleteOperationBadResponse, + @"Invalid unregister response %@", response); + NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; + [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; + return; + } + [self finishWithResult:FIRInstanceIDTokenOperationSucceeded token:nil error:nil]; +} +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h new file mode 100644 index 00000000..6fa800ef --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h @@ -0,0 +1,34 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString *const kFIRInstanceIDFirebaseUserAgentKey; + +FOUNDATION_EXPORT NSString *const kFIRInstanceIDFirebaseHeartbeatKey; + +@interface FIRInstanceIDTokenFetchOperation : FIRInstanceIDTokenOperation + +- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + options:(nullable NSDictionary<NSString *, NSString *> *)options + checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences + instanceID:(NSString *)instanceID; + +@end +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m new file mode 100644 index 00000000..96ac2793 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m @@ -0,0 +1,207 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenFetchOperation.h" + +#import "FIRInstanceIDCheckinPreferences.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDDefines.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDTokenOperation+Private.h" +#import "FIRInstanceIDUtilities.h" +#import "NSError+FIRInstanceID.h" + +#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h" + +// We can have a static int since this error should theoretically only +// happen once (for the first time). If it repeats there is something +// else that is wrong. +static int phoneRegistrationErrorRetryCount = 0; +static const int kMaxPhoneRegistrationErrorRetryCount = 10; +NSString *const kFIRInstanceIDFirebaseUserAgentKey = @"X-firebase-client"; +NSString *const kFIRInstanceIDFirebaseHeartbeatKey = @"X-firebase-client-log-type"; +NSString *const kFIRInstanceIDHeartbeatTag = @"fire-iid"; + +@implementation FIRInstanceIDTokenFetchOperation + +- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + options:(nullable NSDictionary<NSString *, NSString *> *)options + checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences + instanceID:(NSString *)instanceID { + self = [super initWithAction:FIRInstanceIDTokenActionFetch + forAuthorizedEntity:authorizedEntity + scope:scope + options:options + checkinPreferences:checkinPreferences + instanceID:instanceID]; + if (self) { + } + return self; +} + +- (void)performTokenOperation { + NSMutableURLRequest *request = [self tokenRequest]; + NSString *checkinVersionInfo = self.checkinPreferences.versionInfo; + [request setValue:checkinVersionInfo forHTTPHeaderField:@"info"]; + [request setValue:[FIRApp firebaseUserAgent] + forHTTPHeaderField:kFIRInstanceIDFirebaseUserAgentKey]; + [request setValue:@([FIRHeartbeatInfo heartbeatCodeForTag:kFIRInstanceIDHeartbeatTag]).stringValue + forHTTPHeaderField:kFIRInstanceIDFirebaseHeartbeatKey]; + + // Build form-encoded body + NSString *deviceAuthID = self.checkinPreferences.deviceID; + NSMutableArray<NSURLQueryItem *> *queryItems = + [[self class] standardQueryItemsWithDeviceID:deviceAuthID scope:self.scope]; + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"sender" value:self.authorizedEntity]]; + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"X-subtype" + value:self.authorizedEntity]]; + + if (self.instanceID.length > 0) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:kFIRInstanceIDParamInstanceID + value:self.instanceID]]; + } + // Create query items from passed-in options + id apnsTokenData = self.options[kFIRInstanceIDTokenOptionsAPNSKey]; + id apnsSandboxValue = self.options[kFIRInstanceIDTokenOptionsAPNSIsSandboxKey]; + if ([apnsTokenData isKindOfClass:[NSData class]] && + [apnsSandboxValue isKindOfClass:[NSNumber class]]) { + NSString *APNSString = FIRInstanceIDAPNSTupleStringForTokenAndServerType( + apnsTokenData, ((NSNumber *)apnsSandboxValue).boolValue); + // The name of the query item happens to be the same as the dictionary key + NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:kFIRInstanceIDTokenOptionsAPNSKey + value:APNSString]; + [queryItems addObject:item]; + } + id firebaseAppID = self.options[kFIRInstanceIDTokenOptionsFirebaseAppIDKey]; + if ([firebaseAppID isKindOfClass:[NSString class]]) { + // The name of the query item happens to be the same as the dictionary key + NSURLQueryItem *item = + [NSURLQueryItem queryItemWithName:kFIRInstanceIDTokenOptionsFirebaseAppIDKey + value:(NSString *)firebaseAppID]; + [queryItems addObject:item]; + } + + NSURLComponents *components = [[NSURLComponents alloc] init]; + components.queryItems = queryItems; + NSString *content = components.query; + request.HTTPBody = [content dataUsingEncoding:NSUTF8StringEncoding]; + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenFetchOperationFetchRequest, + @"Register request to %@ content: %@", FIRInstanceIDRegisterServer(), + content); + + FIRInstanceID_WEAKIFY(self); + void (^requestHandler)(NSData *, NSURLResponse *, NSError *) = + ^(NSData *data, NSURLResponse *response, NSError *error) { + FIRInstanceID_STRONGIFY(self); + [self handleResponseWithData:data response:response error:error]; + }; + + // Test block + if (self.testBlock) { + self.testBlock(request, requestHandler); + return; + } + + NSURLSession *session = [FIRInstanceIDTokenOperation sharedURLSession]; + self.dataTask = [session dataTaskWithRequest:request completionHandler:requestHandler]; + [self.dataTask resume]; +} + +#pragma mark - Request Handling + +- (void)handleResponseWithData:(NSData *)data + response:(NSURLResponse *)response + error:(NSError *)error { + if (error) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenFetchOperationRequestError, + @"Token fetch HTTP error. Error Code: %ld", (long)error.code); + [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; + return; + } + NSString *dataResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + + if (dataResponse.length == 0) { + NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; + [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; + return; + } + NSDictionary *parsedResponse = [self parseFetchTokenResponse:dataResponse]; + + if ([parsedResponse[@"token"] length]) { + [self finishWithResult:FIRInstanceIDTokenOperationSucceeded + token:parsedResponse[@"token"] + error:nil]; + return; + } + + NSString *errorValue = parsedResponse[@"Error"]; + NSError *responseError; + if (errorValue.length) { + NSArray *errorComponents = [errorValue componentsSeparatedByString:@":"]; + // HACK (Kansas replication delay), PHONE_REGISTRATION_ERROR on App + // uninstall and reinstall. + if ([errorComponents containsObject:@"PHONE_REGISTRATION_ERROR"]) { + // Encountered issue http://b/27043795 + // Retry register until successful or another error encountered or a + // certain number of tries are over. + + if (phoneRegistrationErrorRetryCount < kMaxPhoneRegistrationErrorRetryCount) { + const int nextRetryInterval = 1 << phoneRegistrationErrorRetryCount; + FIRInstanceID_WEAKIFY(self); + + dispatch_after( + dispatch_time(DISPATCH_TIME_NOW, (int64_t)(nextRetryInterval * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + FIRInstanceID_STRONGIFY(self); + phoneRegistrationErrorRetryCount++; + [self performTokenOperation]; + }); + return; + } + } else if ([errorComponents containsObject:kFIRInstanceID_CMD_RST]) { + // Server detected the identity we use is no longer valid. + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center postNotificationName:kFIRInstanceIDIdentityInvalidatedNotification object:nil]; + + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInternal001, + @"Identity is invalid. Server request identity reset."); + responseError = + [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidIdentity]; + } + } + if (!responseError) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenFetchOperationBadResponse, + @"Invalid fetch response, expected 'token' or 'Error' key"); + responseError = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown]; + } + [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:responseError]; +} + +// expect a response e.g. "token=<reg id>\nGOOG.ttl=123" +- (NSDictionary *)parseFetchTokenResponse:(NSString *)response { + NSArray *lines = [response componentsSeparatedByString:@"\n"]; + NSMutableDictionary *parsedResponse = [NSMutableDictionary dictionary]; + for (NSString *line in lines) { + NSArray *keyAndValue = [line componentsSeparatedByString:@"="]; + if ([keyAndValue count] > 1) { + parsedResponse[keyAndValue[0]] = keyAndValue[1]; + } + } + return parsedResponse; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h new file mode 100644 index 00000000..3b752a3a --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h @@ -0,0 +1,92 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +#import "FIRInstanceIDAPNSInfo.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Represents an Instance ID token, and all of the relevant information + * associated with it. It can read from and write to an NSDictionary object, for + * simple serialization. + */ +@interface FIRInstanceIDTokenInfo : NSObject <NSCoding> + +/// The authorized entity (also known as Sender ID), associated with the token. +@property(nonatomic, readonly, copy) NSString *authorizedEntity; +/// The scope associated with the token. This is an arbitrary string, typically "*". +@property(nonatomic, readonly, copy) NSString *scope; +/// The token value itself, with which all other properties are associated. +@property(nonatomic, readonly, copy) NSString *token; + +// These properties are nullable because they might not exist for tokens fetched from +// legacy storage formats. + +/// The app version that this token represents. +@property(nonatomic, readonly, copy, nullable) NSString *appVersion; +/// The Firebase app ID (also known as GMP App ID), that this token is associated with. +@property(nonatomic, readonly, copy, nullable) NSString *firebaseAppID; + +/// Tokens may not always be associated with an APNs token, and may be associated after +/// being created. +@property(nonatomic, strong, nullable) FIRInstanceIDAPNSInfo *APNSInfo; +/// The time that this token info was updated. The cache time is writeable, since in +/// some cases the token info may be refreshed from the server. In those situations, +/// the cacheTime would be updated. +@property(nonatomic, copy, nullable) NSDate *cacheTime; + +/** + * Initializes a FIRInstanceIDTokenInfo object with the required parameters. These + * parameters represent all the relevant associated data with a token. + * + * @param authorizedEntity The authorized entity (also known as Sender ID). + * @param scope The scope of the token, typically "*" meaning + * it's a "default scope". + * @param token The token value itself. + * @param appVersion The application version that this token is associated with. + * @param firebaseAppID The Firebase app ID which this token is associated with. + * @return An instance of FIRInstanceIDTokenInfo. + */ +- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + token:(NSString *)token + appVersion:(nullable NSString *)appVersion + firebaseAppID:(nullable NSString *)firebaseAppID; + +/** + * Check whether the token is still fresh based on: + * 1. Last fetch token is within the 7 days. + * 2. Language setting is not changed. + * 3. App version is current. + * 4. GMP App ID is current. + * 5. token is consistent with the current IID. + * 6. APNS info has changed. + * @param IID The app identifiier that is used to check if token is prefixed with. + * @return If token is fresh. + * + */ +- (BOOL)isFreshWithIID:(NSString *)IID; + +/* + * Check whether the token is default token. + */ +- (BOOL)isDefaultToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m new file mode 100644 index 00000000..59b0e924 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m @@ -0,0 +1,212 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenInfo.h" + +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDUtilities.h" + +/** + * @enum Token Info Dictionary Key Constants + * @discussion The keys that are checked when a token info is + * created from a dictionary. The same keys are used + * when decoding/encoding an archive. + */ +/// Specifies a dictonary key whose value represents the authorized entity, or +/// Sender ID for the token. +static NSString *const kFIRInstanceIDAuthorizedEntityKey = @"authorized_entity"; +/// Specifies a dictionary key whose value represents the scope of the token, +/// typically "*". +static NSString *const kFIRInstanceIDScopeKey = @"scope"; +/// Specifies a dictionary key which represents the token value itself. +static NSString *const kFIRInstanceIDTokenKey = @"token"; +/// Specifies a dictionary key which represents the app version associated +/// with the token. +static NSString *const kFIRInstanceIDAppVersionKey = @"app_version"; +/// Specifies a dictionary key which represents the GMP App ID associated with +/// the token. +static NSString *const kFIRInstanceIDFirebaseAppIDKey = @"firebase_app_id"; +/// Specifies a dictionary key representing an archive for a +/// `FIRInstanceIDAPNSInfo` object. +static NSString *const kFIRInstanceIDAPNSInfoKey = @"apns_info"; +/// Specifies a dictionary key representing the "last cached" time for the token. +static NSString *const kFIRInstanceIDCacheTimeKey = @"cache_time"; +/// Default interval that token stays fresh. +const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60; // 7 days. + +@implementation FIRInstanceIDTokenInfo + +- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + token:(NSString *)token + appVersion:(NSString *)appVersion + firebaseAppID:(NSString *)firebaseAppID { + self = [super init]; + if (self) { + _authorizedEntity = [authorizedEntity copy]; + _scope = [scope copy]; + _token = [token copy]; + _appVersion = [appVersion copy]; + _firebaseAppID = [firebaseAppID copy]; + } + return self; +} + +- (BOOL)isFreshWithIID:(NSString *)IID { + // Last fetch token cache time could be null if token is from legacy storage format. Then token is + // considered not fresh and should be refreshed and overwrite with the latest storage format. + if (!IID) { + return NO; + } + if (!_cacheTime) { + return NO; + } + + // Check if it's consistent with IID + if (![self.token hasPrefix:IID]) { + return NO; + } + + // Check if app has just been updated to a new version. + NSString *currentAppVersion = FIRInstanceIDCurrentAppVersion(); + if (!_appVersion || ![_appVersion isEqualToString:currentAppVersion]) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManager004, + @"Invalidating cached token for %@ (%@) due to app version change.", + _authorizedEntity, _scope); + return NO; + } + + // Check if GMP App ID has changed + NSString *currentFirebaseAppID = FIRInstanceIDFirebaseAppID(); + if (!_firebaseAppID || ![_firebaseAppID isEqualToString:currentFirebaseAppID]) { + FIRInstanceIDLoggerDebug( + kFIRInstanceIDMessageCodeTokenInfoFirebaseAppIDChanged, + @"Invalidating cached token due to Firebase App IID change from %@ to %@", _firebaseAppID, + currentFirebaseAppID); + return NO; + } + + // Check whether locale has changed, if yes, token needs to be updated with server for locale + // information. + if (FIRInstanceIDHasLocaleChanged()) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenInfoLocaleChanged, + @"Invalidating cached token due to locale change"); + return NO; + } + + // Locale is not changed, check whether token has been fetched within 7 days. + NSTimeInterval lastFetchTokenTimestamp = [_cacheTime timeIntervalSince1970]; + NSTimeInterval currentTimestamp = FIRInstanceIDCurrentTimestampInSeconds(); + NSTimeInterval timeSinceLastFetchToken = currentTimestamp - lastFetchTokenTimestamp; + return (timeSinceLastFetchToken < kDefaultFetchTokenInterval); +} + +- (BOOL)isDefaultToken { + return [self.scope isEqualToString:kFIRInstanceIDDefaultTokenScope]; +} + +#pragma mark - NSCoding + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + // These value cannot be nil + + id authorizedEntity = [aDecoder decodeObjectForKey:kFIRInstanceIDAuthorizedEntityKey]; + if (![authorizedEntity isKindOfClass:[NSString class]]) { + return nil; + } + + id scope = [aDecoder decodeObjectForKey:kFIRInstanceIDScopeKey]; + if (![scope isKindOfClass:[NSString class]]) { + return nil; + } + + id token = [aDecoder decodeObjectForKey:kFIRInstanceIDTokenKey]; + if (![token isKindOfClass:[NSString class]]) { + return nil; + } + + // These values are nullable, so only fail the decode if the type does not match + + id appVersion = [aDecoder decodeObjectForKey:kFIRInstanceIDAppVersionKey]; + if (appVersion && ![appVersion isKindOfClass:[NSString class]]) { + return nil; + } + + id firebaseAppID = [aDecoder decodeObjectForKey:kFIRInstanceIDFirebaseAppIDKey]; + if (firebaseAppID && ![firebaseAppID isKindOfClass:[NSString class]]) { + return nil; + } + + id rawAPNSInfo = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoKey]; + if (rawAPNSInfo && ![rawAPNSInfo isKindOfClass:[NSData class]]) { + return nil; + } + + FIRInstanceIDAPNSInfo *APNSInfo = nil; + if (rawAPNSInfo) { + // TODO(chliangGoogle: Use the new API and secureCoding protocol. + @try { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + APNSInfo = [NSKeyedUnarchiver unarchiveObjectWithData:rawAPNSInfo]; +#pragma clang diagnostic pop + } @catch (NSException *exception) { + FIRInstanceIDLoggerInfo(kFIRInstanceIDMessageCodeTokenInfoBadAPNSInfo, + @"Could not parse raw APNS Info while parsing archived token info."); + APNSInfo = nil; + } @finally { + } + } + + id cacheTime = [aDecoder decodeObjectForKey:kFIRInstanceIDCacheTimeKey]; + if (cacheTime && ![cacheTime isKindOfClass:[NSDate class]]) { + return nil; + } + + self = [super init]; + if (self) { + _authorizedEntity = authorizedEntity; + _scope = scope; + _token = token; + _appVersion = appVersion; + _firebaseAppID = firebaseAppID; + _APNSInfo = APNSInfo; + _cacheTime = cacheTime; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.authorizedEntity forKey:kFIRInstanceIDAuthorizedEntityKey]; + [aCoder encodeObject:self.scope forKey:kFIRInstanceIDScopeKey]; + [aCoder encodeObject:self.token forKey:kFIRInstanceIDTokenKey]; + [aCoder encodeObject:self.appVersion forKey:kFIRInstanceIDAppVersionKey]; + [aCoder encodeObject:self.firebaseAppID forKey:kFIRInstanceIDFirebaseAppIDKey]; + NSData *rawAPNSInfo; + if (self.APNSInfo) { + // TODO(chliangGoogle: Use the new API and secureCoding protocol. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + rawAPNSInfo = [NSKeyedArchiver archivedDataWithRootObject:self.APNSInfo]; +#pragma clang diagnostic pop + + [aCoder encodeObject:rawAPNSInfo forKey:kFIRInstanceIDAPNSInfoKey]; + } + [aCoder encodeObject:self.cacheTime forKey:kFIRInstanceIDCacheTimeKey]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h new file mode 100644 index 00000000..46e1ac88 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h @@ -0,0 +1,149 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceID.h" + +@class FIRInstanceIDAuthService; +@class FIRInstanceIDCheckinPreferences; +@class FIRInstanceIDTokenInfo; +@class FIRInstanceIDStore; + +typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) { + FIRInstanceIDInvalidTokenReasonNone = 0, // 0 + FIRInstanceIDInvalidTokenReasonAppVersion = (1 << 0), // 0...00001 + FIRInstanceIDInvalidTokenReasonAPNSToken = (1 << 1), // 0...00010 +}; + +/** + * Manager for the InstanceID token requests i.e `newToken` and `deleteToken`. This + * manages the overall interaction of the `InstanceIDStore`, the token register + * service and the callbacks associated with `GCMInstanceID`. + */ +@interface FIRInstanceIDTokenManager : NSObject + +/// Expose the auth service, so it can be used by others +@property(nonatomic, readonly, strong) FIRInstanceIDAuthService *authService; + +/** + * Fetch new token for the given authorizedEntity and scope. This makes an + * asynchronous request to the InstanceID backend to create a new token for + * the service and returns it. This will replace any old token for the given + * authorizedEntity and scope that has been cached before. + * + * @param authorizedEntity The authorized entity for the token, should not be nil. + * @param scope The scope for the token, should not be nil. + * @param instanceID The unique string identifying the app instance. + * @param options The options to be added to the fetch request. + * @param handler The handler to be invoked once we have the token or the + * fetch request to InstanceID backend results in an error. Also + * since it's a public handler it should always be called + * asynchronously. This should be non-nil. + */ +- (void)fetchNewTokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + instanceID:(NSString *)instanceID + options:(NSDictionary *)options + handler:(FIRInstanceIDTokenHandler)handler; + +/** + * Return the cached token info, if one exists, for the given authorizedEntity and scope. + * + * @param authorizedEntity The authorized entity for the token. + * @param scope The scope for the token. + * + * @return The cached token info, if available, matching the parameters. + */ +- (FIRInstanceIDTokenInfo *)cachedTokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope; + +/** + * Delete the token for the given authorizedEntity and scope. If the token has + * been cached, it will be deleted from the store. It will also make an + * asynchronous request to the InstanceID backend to invalidate the token. + * + * @param authorizedEntity The authorized entity for the token, should not be nil. + * @param scope The scope for the token, should not be nil. + * @param instanceID The unique string identifying the app instance. + * @param handler The handler to be invoked once the delete request to + * InstanceID backend has returned. If the request was + * successful we invoke the handler with a nil error; + * otherwise we call it with an appropriate error. Also since + * it's a public handler it should always be called + * asynchronously. This should be non-nil. + */ +- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + instanceID:(NSString *)instanceID + handler:(FIRInstanceIDDeleteTokenHandler)handler; + +/** + * Deletes all cached tokens from the persistent store. This method should only be triggered + * when InstanceID is deleted + * + * @param instanceID The unique string identifying the app instance. + * @param handler The handler to be invoked once the delete request to InstanceID backend + * has returned. If the request was successful we invoke the handler with + * a nil error; else we pass in an appropriate error. This should be non-nil + * and be called asynchronously. + */ +- (void)deleteAllTokensWithInstanceID:(NSString *)instanceID + handler:(FIRInstanceIDDeleteHandler)handler; + +/** + * Deletes all cached tokens from the persistent store. + * @param handler The callback handler which is invoked when tokens deletion is complete, + * with an error if there is any. + * + */ +- (void)deleteAllTokensLocallyWithHandler:(void (^)(NSError *error))handler; + +/** + * Stop any ongoing token operations. + */ +- (void)stopAllTokenOperations; + +#pragma mark - Invalidating Cached Tokens + +/** + * Invalidate any cached tokens, if the app version has changed since last launch or if the token + * is cached for more than 7 days. + * @param IID The cached instanceID, check if token is prefixed by such IID. + * + * @return Whether we should fetch default token from server. + * + * @discussion This should safely be called prior to any tokens being retrieved from + * the cache or being fetched from the network. + */ +- (BOOL)checkTokenRefreshPolicyWithIID:(NSString *)IID; + +/** + * Upon being provided with different APNs or sandbox, any locally cached tokens + * should be deleted, and the new APNs token should be cached. + * + * @discussion It is possible for this method to be called while token operations are + * in-progress or queued. In this case, the in-flight token operations will have stale + * APNs information. The default token is checked for being out-of-date by Instance ID, + * and re-fetched. Custom tokens are not currently checked. + * + * @param deviceToken The APNS device token, provided by the operating system. + * @param isSandbox YES if the device token is for the sandbox environment, NO otherwise. + * + * @return The array of FIRInstanceIDTokenInfo objects which were invalidated. + */ +- (NSArray<FIRInstanceIDTokenInfo *> *)updateTokensToAPNSDeviceToken:(NSData *)deviceToken + isSandbox:(BOOL)isSandbox; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m new file mode 100644 index 00000000..0ebcfc88 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m @@ -0,0 +1,340 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenManager.h" + +#import "FIRInstanceIDAuthKeyChain.h" +#import "FIRInstanceIDAuthService.h" +#import "FIRInstanceIDCheckinPreferences.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDDefines.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDStore.h" +#import "FIRInstanceIDTokenDeleteOperation.h" +#import "FIRInstanceIDTokenFetchOperation.h" +#import "FIRInstanceIDTokenInfo.h" +#import "FIRInstanceIDTokenOperation.h" +#import "NSError+FIRInstanceID.h" + +@interface FIRInstanceIDTokenManager () <FIRInstanceIDStoreDelegate> + +@property(nonatomic, readwrite, strong) FIRInstanceIDStore *instanceIDStore; +@property(nonatomic, readwrite, strong) FIRInstanceIDAuthService *authService; +@property(nonatomic, readonly, strong) NSOperationQueue *tokenOperations; + +@property(nonatomic, readwrite, strong) FIRInstanceIDAPNSInfo *currentAPNSInfo; + +@end + +@implementation FIRInstanceIDTokenManager + +- (instancetype)init { + self = [super init]; + if (self) { + _instanceIDStore = [[FIRInstanceIDStore alloc] initWithDelegate:self]; + _authService = [[FIRInstanceIDAuthService alloc] initWithStore:_instanceIDStore]; + [self configureTokenOperations]; + } + return self; +} + +- (void)dealloc { + [self stopAllTokenOperations]; +} + +- (void)configureTokenOperations { + _tokenOperations = [[NSOperationQueue alloc] init]; + _tokenOperations.name = @"com.google.iid-token-operations"; + // For now, restrict the operations to be serial, because in some cases (like if the + // authorized entity and scope are the same), order matters. + // If we have to deal with several different token requests simultaneously, it would be a good + // idea to add some better intelligence around this (performing unrelated token operations + // simultaneously, etc.). + _tokenOperations.maxConcurrentOperationCount = 1; + if ([_tokenOperations respondsToSelector:@selector(qualityOfService)]) { + _tokenOperations.qualityOfService = NSOperationQualityOfServiceUtility; + } +} + +- (void)fetchNewTokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + instanceID:(NSString *)instanceID + options:(NSDictionary *)options + handler:(FIRInstanceIDTokenHandler)handler { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManager000, + @"Fetch new token for authorizedEntity: %@, scope: %@", authorizedEntity, + scope); + FIRInstanceIDTokenFetchOperation *operation = + [self createFetchOperationWithAuthorizedEntity:authorizedEntity + scope:scope + options:options + instanceID:instanceID]; + FIRInstanceID_WEAKIFY(self); + FIRInstanceIDTokenOperationCompletion completion = + ^(FIRInstanceIDTokenOperationResult result, NSString *_Nullable token, + NSError *_Nullable error) { + FIRInstanceID_STRONGIFY(self); + if (error) { + handler(nil, error); + return; + } + NSString *firebaseAppID = options[kFIRInstanceIDTokenOptionsFirebaseAppIDKey]; + FIRInstanceIDTokenInfo *tokenInfo = [[FIRInstanceIDTokenInfo alloc] + initWithAuthorizedEntity:authorizedEntity + scope:scope + token:token + appVersion:FIRInstanceIDCurrentAppVersion() + firebaseAppID:firebaseAppID]; + tokenInfo.APNSInfo = [[FIRInstanceIDAPNSInfo alloc] initWithTokenOptionsDictionary:options]; + + [self.instanceIDStore + saveTokenInfo:tokenInfo + handler:^(NSError *error) { + if (!error) { + // Do not send the token back in case the save was unsuccessful. Since with + // the new asychronous fetch mechanism this can lead to infinite loops, for + // example, we will return a valid token even though we weren't able to store + // it in our cache. The first token will lead to a onTokenRefresh callback + // wherein the user again calls `getToken` but since we weren't able to save + // it we won't hit the cache but hit the server again leading to an infinite + // loop. + FIRInstanceIDLoggerDebug( + kFIRInstanceIDMessageCodeTokenManager001, + @"Token fetch successful, token: %@, authorizedEntity: %@, scope:%@", + token, authorizedEntity, scope); + + if (handler) { + handler(token, nil); + } + } else { + if (handler) { + handler(nil, error); + } + } + }]; + }; + // Add completion handler, and ensure it's called on the main queue + [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, + NSString *_Nullable token, NSError *_Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(result, token, error); + }); + }]; + [self.tokenOperations addOperation:operation]; +} + +- (FIRInstanceIDTokenInfo *)cachedTokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope { + return [self.instanceIDStore tokenInfoWithAuthorizedEntity:authorizedEntity scope:scope]; +} + +- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + instanceID:(NSString *)instanceID + handler:(FIRInstanceIDDeleteTokenHandler)handler { + if ([self.instanceIDStore tokenInfoWithAuthorizedEntity:authorizedEntity scope:scope]) { + [self.instanceIDStore removeCachedTokenWithAuthorizedEntity:authorizedEntity scope:scope]; + } + // Does not matter if we cannot find it in the cache. Still make an effort to unregister + // from the server. + FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences; + FIRInstanceIDTokenDeleteOperation *operation = + [self createDeleteOperationWithAuthorizedEntity:authorizedEntity + scope:scope + checkinPreferences:checkinPreferences + instanceID:instanceID + action:FIRInstanceIDTokenActionDeleteToken]; + + if (handler) { + [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, + NSString *_Nullable token, NSError *_Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(error); + }); + }]; + } + [self.tokenOperations addOperation:operation]; +} + +- (void)deleteAllTokensWithInstanceID:(NSString *)instanceID + handler:(FIRInstanceIDDeleteHandler)handler { + // delete all tokens + FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences; + if (!checkinPreferences) { + // The checkin is already deleted. No need to trigger the token delete operation as client no + // longer has the checkin information for server to delete. + dispatch_async(dispatch_get_main_queue(), ^{ + handler(nil); + }); + return; + } + FIRInstanceIDTokenDeleteOperation *operation = + [self createDeleteOperationWithAuthorizedEntity:kFIRInstanceIDKeychainWildcardIdentifier + scope:kFIRInstanceIDKeychainWildcardIdentifier + checkinPreferences:checkinPreferences + instanceID:instanceID + action:FIRInstanceIDTokenActionDeleteTokenAndIID]; + if (handler) { + [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, + NSString *_Nullable token, NSError *_Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(error); + }); + }]; + } + [self.tokenOperations addOperation:operation]; +} + +- (void)deleteAllTokensLocallyWithHandler:(void (^)(NSError *error))handler { + [self.instanceIDStore removeAllCachedTokensWithHandler:handler]; +} + +- (void)stopAllTokenOperations { + [self.authService stopCheckinRequest]; + [self.tokenOperations cancelAllOperations]; +} + +#pragma mark - FIRInstanceIDStoreDelegate + +- (void)store:(FIRInstanceIDStore *)store + didDeleteFCMScopedTokensForCheckin:(FIRInstanceIDCheckinPreferences *)checkin { + // Make a best effort try to delete the old client related state on the FCM server. This is + // required to delete old pubusb registrations which weren't cleared when the app was deleted. + // + // This is only a one time effort. If this call fails the client would still receive duplicate + // pubsub notifications if he is again subscribed to the same topic. + // + // The client state should be cleared on the server for the provided checkin preferences. + FIRInstanceIDTokenDeleteOperation *operation = + [self createDeleteOperationWithAuthorizedEntity:nil + scope:nil + checkinPreferences:checkin + instanceID:nil + action:FIRInstanceIDTokenActionDeleteToken]; + [operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result, + NSString *_Nullable token, NSError *_Nullable error) { + if (error) { + FIRInstanceIDMessageCode code = + kFIRInstanceIDMessageCodeTokenManagerErrorDeletingFCMTokensOnAppReset; + FIRInstanceIDLoggerDebug(code, @"Failed to delete GCM server registrations on app reset."); + } else { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManagerDeletedFCMTokensOnAppReset, + @"Successfully deleted GCM server registrations on app reset"); + } + }]; + + [self.tokenOperations addOperation:operation]; +} + +#pragma mark - Unit Testing Stub Helpers +// We really have this method so that we can more easily stub it out for unit testing +- (FIRInstanceIDTokenFetchOperation *) + createFetchOperationWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + options:(NSDictionary<NSString *, NSString *> *)options + instanceID:(NSString *)instanceID { + FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences; + FIRInstanceIDTokenFetchOperation *operation = + [[FIRInstanceIDTokenFetchOperation alloc] initWithAuthorizedEntity:authorizedEntity + scope:scope + options:options + checkinPreferences:checkinPreferences + instanceID:instanceID]; + return operation; +} + +// We really have this method so that we can more easily stub it out for unit testing +- (FIRInstanceIDTokenDeleteOperation *) + createDeleteOperationWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences + instanceID:(NSString *)instanceID + action:(FIRInstanceIDTokenAction)action { + FIRInstanceIDTokenDeleteOperation *operation = + [[FIRInstanceIDTokenDeleteOperation alloc] initWithAuthorizedEntity:authorizedEntity + scope:scope + checkinPreferences:checkinPreferences + instanceID:instanceID + action:action]; + return operation; +} + +#pragma mark - Invalidating Cached Tokens +- (BOOL)checkTokenRefreshPolicyWithIID:(NSString *)IID { + // We know at least one cached token exists. + BOOL shouldFetchDefaultToken = NO; + NSArray<FIRInstanceIDTokenInfo *> *tokenInfos = [self.instanceIDStore cachedTokenInfos]; + + NSMutableArray<FIRInstanceIDTokenInfo *> *tokenInfosToDelete = + [NSMutableArray arrayWithCapacity:tokenInfos.count]; + for (FIRInstanceIDTokenInfo *tokenInfo in tokenInfos) { + if ([tokenInfo isFreshWithIID:IID]) { + // Token is fresh and in right format, do nothing + continue; + } + if ([tokenInfo isDefaultToken]) { + // Default token is expired, do not mark for deletion. Fetch directly from server to + // replace the current one. + shouldFetchDefaultToken = YES; + } else { + // Non-default token is expired, mark for deletion. + [tokenInfosToDelete addObject:tokenInfo]; + } + FIRInstanceIDLoggerDebug( + kFIRInstanceIDMessageCodeTokenManagerInvalidateStaleToken, + @"Invalidating cached token for %@ (%@) due to token is no longer fresh.", + tokenInfo.authorizedEntity, tokenInfo.scope); + } + for (FIRInstanceIDTokenInfo *tokenInfoToDelete in tokenInfosToDelete) { + [self.instanceIDStore removeCachedTokenWithAuthorizedEntity:tokenInfoToDelete.authorizedEntity + scope:tokenInfoToDelete.scope]; + } + return shouldFetchDefaultToken; +} + +- (NSArray<FIRInstanceIDTokenInfo *> *)updateTokensToAPNSDeviceToken:(NSData *)deviceToken + isSandbox:(BOOL)isSandbox { + // Each cached IID token that is missing an APNSInfo, or has an APNSInfo associated should be + // checked and invalidated if needed. + FIRInstanceIDAPNSInfo *APNSInfo = [[FIRInstanceIDAPNSInfo alloc] initWithDeviceToken:deviceToken + isSandbox:isSandbox]; + if ([self.currentAPNSInfo isEqualToAPNSInfo:APNSInfo]) { + return @[]; + } + self.currentAPNSInfo = APNSInfo; + + NSArray<FIRInstanceIDTokenInfo *> *tokenInfos = [self.instanceIDStore cachedTokenInfos]; + NSMutableArray<FIRInstanceIDTokenInfo *> *tokenInfosToDelete = + [NSMutableArray arrayWithCapacity:tokenInfos.count]; + for (FIRInstanceIDTokenInfo *cachedTokenInfo in tokenInfos) { + // Check if the cached APNSInfo is nil, or if it is an old APNSInfo. + if (!cachedTokenInfo.APNSInfo || + ![cachedTokenInfo.APNSInfo isEqualToAPNSInfo:self.currentAPNSInfo]) { + // Mark for invalidation. + [tokenInfosToDelete addObject:cachedTokenInfo]; + } + } + for (FIRInstanceIDTokenInfo *tokenInfoToDelete in tokenInfosToDelete) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManagerAPNSChangedTokenInvalidated, + @"Invalidating cached token for %@ (%@) due to APNs token change.", + tokenInfoToDelete.authorizedEntity, tokenInfoToDelete.scope); + [self.instanceIDStore removeCachedTokenWithAuthorizedEntity:tokenInfoToDelete.authorizedEntity + scope:tokenInfoToDelete.scope]; + } + return tokenInfosToDelete; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h new file mode 100644 index 00000000..c430f11f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h @@ -0,0 +1,66 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenOperation.h" + +#import "FIRInstanceIDUtilities.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRInstanceIDTokenOperation (Private) + +@property(atomic, strong) NSURLSessionDataTask *dataTask; +@property(readonly, strong) + NSMutableArray<FIRInstanceIDTokenOperationCompletion> *completionHandlers; + +// For testing only +@property(nonatomic, readwrite, copy) FIRInstanceIDURLRequestTestBlock testBlock; + ++ (NSURLSession *)sharedURLSession; + +#pragma mark - Initialization +- (instancetype)initWithAction:(FIRInstanceIDTokenAction)action + forAuthorizedEntity:(nullable NSString *)authorizedEntity + scope:(NSString *)scope + options:(nullable NSDictionary<NSString *, NSString *> *)options + checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences + instanceID:(NSString *)instanceID; + +#pragma mark - Request Construction ++ (NSMutableArray<NSURLQueryItem *> *)standardQueryItemsWithDeviceID:(NSString *)deviceID + scope:(NSString *)scope; +- (NSMutableURLRequest *)tokenRequest; + +#pragma mark - HTTP Headers +/** + * Given a valid checkin preferences object, it will return a string that can be used + * in the "Authorization" HTTP header to authenticate this request. + * + * @param checkin The valid checkin preferences object, with a deviceID and secretToken. + */ ++ (NSString *)HTTPAuthHeaderFromCheckin:(FIRInstanceIDCheckinPreferences *)checkin; + +#pragma mark - Result +- (void)finishWithResult:(FIRInstanceIDTokenOperationResult)result + token:(nullable NSString *)token + error:(nullable NSError *)error; + +#pragma mark - Methods to override +- (void)performTokenOperation; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h new file mode 100644 index 00000000..fa8ad085 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h @@ -0,0 +1,72 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@class FIRInstanceIDCheckinPreferences; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Represents the action taken on an FCM token. + */ +typedef NS_ENUM(NSInteger, FIRInstanceIDTokenAction) { + FIRInstanceIDTokenActionFetch, + FIRInstanceIDTokenActionDeleteToken, + FIRInstanceIDTokenActionDeleteTokenAndIID, +}; + +/** + * Represents the possible results of a token operation. + */ +typedef NS_ENUM(NSInteger, FIRInstanceIDTokenOperationResult) { + FIRInstanceIDTokenOperationSucceeded, + FIRInstanceIDTokenOperationError, + FIRInstanceIDTokenOperationCancelled, +}; + +/** + * Callback to invoke once the HTTP call to FIRMessaging backend for updating + * subscription finishes. + * + * @param result The result of the operation. + * @param token If the action for fetching a token and the request was successful, this will hold + * the value of the token. Otherwise nil. + * @param error The error which occurred while performing the token operation. This will be nil + * in case the operation was successful, or if the operation was cancelled. + */ +typedef void (^FIRInstanceIDTokenOperationCompletion)(FIRInstanceIDTokenOperationResult result, + NSString *_Nullable token, + NSError *_Nullable error); + +@interface FIRInstanceIDTokenOperation : NSOperation + +@property(nonatomic, readonly) FIRInstanceIDTokenAction action; +@property(nonatomic, readonly, nullable) NSString *authorizedEntity; +@property(nonatomic, readonly, nullable) NSString *scope; +@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *options; +@property(nonatomic, readonly, strong) FIRInstanceIDCheckinPreferences *checkinPreferences; +@property(nonatomic, readonly, strong) NSString *instanceID; + +@property(nonatomic, readonly) FIRInstanceIDTokenOperationResult result; + +- (instancetype)init NS_UNAVAILABLE; + +- (void)addCompletionHandler:(FIRInstanceIDTokenOperationCompletion)handler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m new file mode 100644 index 00000000..e5d725a7 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m @@ -0,0 +1,249 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenOperation.h" + +#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h" + +#import "FIRInstanceIDCheckinPreferences.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDUtilities.h" +#import "NSError+FIRInstanceID.h" + +static const NSInteger kFIRInstanceIDPlatformVersionIOS = 2; + +// Scope parameter that defines the service using the token +static NSString *const kFIRInstanceIDParamScope = @"X-scope"; +// Defines the SDK version +static NSString *const kFIRInstanceIDParamFCMLibVersion = @"X-cliv"; + +@interface FIRInstanceIDTokenOperation () { + BOOL _isFinished; + BOOL _isExecuting; +} + +@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinPreferences *checkinPreferences; +@property(nonatomic, readwrite, strong) NSString *instanceID; + +@property(atomic, strong) NSURLSessionDataTask *dataTask; +@property(readonly, strong) + NSMutableArray<FIRInstanceIDTokenOperationCompletion> *completionHandlers; + +@property(atomic, strong, nullable) NSString *FISAuthToken; + +// For testing only +@property(nonatomic, readwrite, copy) FIRInstanceIDURLRequestTestBlock testBlock; + +@end + +@implementation FIRInstanceIDTokenOperation + ++ (NSURLSession *)sharedURLSession { + static NSURLSession *tokenOperationSharedSession; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; + config.timeoutIntervalForResource = 60.0f; // 1 minute + tokenOperationSharedSession = [NSURLSession sessionWithConfiguration:config]; + tokenOperationSharedSession.sessionDescription = @"com.google.iid.tokens.session"; + }); + return tokenOperationSharedSession; +} + +- (instancetype)initWithAction:(FIRInstanceIDTokenAction)action + forAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + options:(NSDictionary<NSString *, NSString *> *)options + checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences + instanceID:(NSString *)instanceID { + self = [super init]; + if (self) { + _action = action; + _authorizedEntity = [authorizedEntity copy]; + _scope = [scope copy]; + _options = [options copy]; + _checkinPreferences = checkinPreferences; + _instanceID = instanceID; + _completionHandlers = [NSMutableArray array]; + + _isExecuting = NO; + _isFinished = NO; + } + return self; +} + +- (void)dealloc { + _testBlock = nil; + _authorizedEntity = nil; + _scope = nil; + _options = nil; + _checkinPreferences = nil; + _instanceID = nil; + [_completionHandlers removeAllObjects]; + _completionHandlers = nil; +} + +- (void)addCompletionHandler:(FIRInstanceIDTokenOperationCompletion)handler { + [self.completionHandlers addObject:handler]; +} + +- (BOOL)isAsynchronous { + return YES; +} + +- (BOOL)isExecuting { + return _isExecuting; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _isExecuting = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (BOOL)isFinished { + return _isFinished; +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _isFinished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)start { + if (self.isCancelled) { + [self finishWithResult:FIRInstanceIDTokenOperationCancelled token:nil error:nil]; + return; + } + + // Quickly validate whether or not the operation has all it needs to begin + BOOL checkinfoAvailable = [self.checkinPreferences hasCheckinInfo]; + if (!checkinfoAvailable) { + FIRInstanceIDErrorCode errorCode = kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn; + [self finishWithResult:FIRInstanceIDTokenOperationError + token:nil + error:[NSError errorWithFIRInstanceIDErrorCode:errorCode]]; + return; + } + + [self setExecuting:YES]; + + [[FIRInstallations installations] + authTokenWithCompletion:^(FIRInstallationsAuthTokenResult *_Nullable tokenResult, + NSError *_Nullable error) { + if (tokenResult.authToken.length > 0) { + self.FISAuthToken = tokenResult.authToken; + [self performTokenOperation]; + } else { + [self finishWithResult:FIRInstanceIDTokenOperationError token:nil error:error]; + } + }]; +} + +- (void)finishWithResult:(FIRInstanceIDTokenOperationResult)result + token:(nullable NSString *)token + error:(nullable NSError *)error { + // Add a check to prevent this finish from being called more than once. + if (self.isFinished) { + return; + } + self.dataTask = nil; + _result = result; + // TODO(chliangGoogle): Call these in the main thread? + for (FIRInstanceIDTokenOperationCompletion completionHandler in self.completionHandlers) { + completionHandler(result, token, error); + } + + [self setExecuting:NO]; + [self setFinished:YES]; +} + +- (void)cancel { + [super cancel]; + [self.dataTask cancel]; + [self finishWithResult:FIRInstanceIDTokenOperationCancelled token:nil error:nil]; +} + +- (void)performTokenOperation { +} + +- (NSMutableURLRequest *)tokenRequest { + NSString *authHeader = + [FIRInstanceIDTokenOperation HTTPAuthHeaderFromCheckin:self.checkinPreferences]; + return [[self class] requestWithAuthHeader:authHeader FISAuthToken:self.FISAuthToken]; +} + +#pragma mark - Request Construction ++ (NSMutableURLRequest *)requestWithAuthHeader:(NSString *)authHeaderString + FISAuthToken:(NSString *)FISAuthToken { + NSURL *url = [NSURL URLWithString:FIRInstanceIDRegisterServer()]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + + // Add HTTP headers + [request setValue:authHeaderString forHTTPHeaderField:@"Authorization"]; + [request setValue:FIRInstanceIDAppIdentifier() forHTTPHeaderField:@"app"]; + if (FISAuthToken) { + [request setValue:FISAuthToken forHTTPHeaderField:@"x-goog-firebase-installations-auth"]; + } + request.HTTPMethod = @"POST"; + return request; +} + ++ (NSMutableArray<NSURLQueryItem *> *)standardQueryItemsWithDeviceID:(NSString *)deviceID + scope:(NSString *)scope { + NSMutableArray<NSURLQueryItem *> *queryItems = [NSMutableArray arrayWithCapacity:8]; + + // E.g. X-osv=10.2.1 + NSString *systemVersion = FIRInstanceIDOperatingSystemVersion(); + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"X-osv" value:systemVersion]]; + // E.g. device= + if (deviceID) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"device" value:deviceID]]; + } + // E.g. X-scope=fcm + if (scope) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:kFIRInstanceIDParamScope value:scope]]; + } + // E.g. plat=2 + NSString *platform = [NSString stringWithFormat:@"%ld", (long)kFIRInstanceIDPlatformVersionIOS]; + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"plat" value:platform]]; + // E.g. app=com.myapp.foo + NSString *appIdentifier = FIRInstanceIDAppIdentifier(); + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"app" value:appIdentifier]]; + // E.g. app_ver=1.5 + NSString *appVersion = FIRInstanceIDCurrentAppVersion(); + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"app_ver" value:appVersion]]; + // E.g. X-cliv=fiid-1.2.3 + NSString *fcmLibraryVersion = + [NSString stringWithFormat:@"fiid-%@", FIRInstanceIDCurrentGCMVersion()]; + if (fcmLibraryVersion.length) { + NSURLQueryItem *gcmLibVersion = + [NSURLQueryItem queryItemWithName:kFIRInstanceIDParamFCMLibVersion value:fcmLibraryVersion]; + [queryItems addObject:gcmLibVersion]; + } + + return queryItems; +} + +#pragma mark - HTTP Header + ++ (NSString *)HTTPAuthHeaderFromCheckin:(FIRInstanceIDCheckinPreferences *)checkin { + NSString *deviceID = checkin.deviceID; + NSString *secret = checkin.secretToken; + return [NSString stringWithFormat:@"AidLogin %@:%@", deviceID, secret]; +} +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.h new file mode 100644 index 00000000..861c87b9 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.h @@ -0,0 +1,106 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@class FIRInstanceIDAPNSInfo; +@class FIRInstanceIDAuthKeychain; +@class FIRInstanceIDTokenInfo; + +/** + * This class is responsible for retrieving and saving `FIRInstanceIDTokenInfo` objects from the + * keychain. The keychain keys that are used are: + * Account: <Main App Bundle ID> (e.g. com.mycompany.myapp) + * Service: <Sender ID>:<Scope> (e.g. 1234567890:*) + */ +@interface FIRInstanceIDTokenStore : NSObject + +NS_ASSUME_NONNULL_BEGIN + +/** + * Create a default InstanceID token store. Uses a valid Keychain object as it's + * persistent backing store. + * + * @return A valid token store object. + */ ++ (instancetype)defaultStore; + +- (instancetype)init __attribute__((unavailable("Use -initWithKeychain: instead."))); + +/** + * Initialize a token store object with a Keychain object. Used for testing. + * + * @param keychain The Keychain object to use as the backing store for tokens. + * + * @return A valid token store object with the given Keychain as backing store. + */ +- (instancetype)initWithKeychain:(FIRInstanceIDAuthKeychain *)keychain; + +#pragma mark - Get + +/** + * Get the cached token from the Keychain. + * + * @param authorizedEntity The authorized entity for the token. + * @param scope The scope for the token. + * + * @return The cached token info if any for the given authorizedEntity and scope else + * nil. + */ +- (nullable FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope; + +/** + * Return all cached token infos from the Keychain. + * + * @return The cached token infos, if any, that are stored in the Keychain. + */ +- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos; + +#pragma mark - Save + +/** + * Save the instanceID token info to the persistent store. + * + * @param tokenInfo The token info to store. + * @param handler The callback handler which is invoked when token saving is complete, + * with an error if there is any. + */ +- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo + handler:(nullable void (^)(NSError *))handler; + +#pragma mark - Delete + +/** + * Remove the cached token from Keychain. + * + * @param authorizedEntity The authorized entity for the token. + * @param scope The scope for the token. + * + */ +- (void)removeTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope; + +/** + * Remove all the cached tokens from the Keychain. + * @param handler The callback handler which is invoked when tokens deletion is complete, + * with an error if there is any. + * + */ +- (void)removeAllTokensWithHandler:(nullable void (^)(NSError *))handler; + +NS_ASSUME_NONNULL_END + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.m new file mode 100644 index 00000000..f97f9321 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenStore.m @@ -0,0 +1,143 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDTokenStore.h" + +#import "FIRInstanceIDAuthKeyChain.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDLogger.h" +#import "FIRInstanceIDTokenInfo.h" +#import "FIRInstanceIDUtilities.h" + +static NSString *const kFIRInstanceIDTokenKeychainId = @"com.google.iid-tokens"; + +@interface FIRInstanceIDTokenStore () + +@property(nonatomic, readwrite, strong) FIRInstanceIDAuthKeychain *keychain; + +@end + +@implementation FIRInstanceIDTokenStore + ++ (instancetype)defaultStore { + FIRInstanceIDAuthKeychain *tokenKeychain = + [[FIRInstanceIDAuthKeychain alloc] initWithIdentifier:kFIRInstanceIDTokenKeychainId]; + return [[FIRInstanceIDTokenStore alloc] initWithKeychain:tokenKeychain]; +} + +- (instancetype)initWithKeychain:(FIRInstanceIDAuthKeychain *)keychain { + self = [super init]; + if (self) { + _keychain = keychain; + } + return self; +} + +#pragma mark - Get + ++ (NSString *)serviceKeyForAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope { + return [NSString stringWithFormat:@"%@:%@", authorizedEntity, scope]; +} + +- (nullable FIRInstanceIDTokenInfo *)tokenInfoWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope { + NSString *account = FIRInstanceIDAppIdentifier(); + NSString *service = [[self class] serviceKeyForAuthorizedEntity:authorizedEntity scope:scope]; + NSData *item = [self.keychain dataForService:service account:account]; + if (!item) { + return nil; + } + // Token infos created from legacy storage don't have appVersion, firebaseAppID, or APNSInfo. + FIRInstanceIDTokenInfo *tokenInfo = [[self class] tokenInfoFromKeychainItem:item]; + return tokenInfo; +} + +- (NSArray<FIRInstanceIDTokenInfo *> *)cachedTokenInfos { + NSString *account = FIRInstanceIDAppIdentifier(); + NSArray<NSData *> *items = + [self.keychain itemsMatchingService:kFIRInstanceIDKeychainWildcardIdentifier account:account]; + NSMutableArray<FIRInstanceIDTokenInfo *> *tokenInfos = + [NSMutableArray arrayWithCapacity:items.count]; + for (NSData *item in items) { + FIRInstanceIDTokenInfo *tokenInfo = [[self class] tokenInfoFromKeychainItem:item]; + if (tokenInfo) { + [tokenInfos addObject:tokenInfo]; + } + } + return tokenInfos; +} + ++ (nullable FIRInstanceIDTokenInfo *)tokenInfoFromKeychainItem:(NSData *)item { + // Check if it is saved as an archived FIRInstanceIDTokenInfo, otherwise return nil. + FIRInstanceIDTokenInfo *tokenInfo = nil; + // NOTE: Passing in nil to unarchiveObjectWithData will result in an iOS error logged + // in the console on iOS 10 and below. Avoid by checking item.data's existence. + if (item) { + // TODO(chliangGoogle: Use the new API and secureCoding protocol. + @try { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + tokenInfo = [NSKeyedUnarchiver unarchiveObjectWithData:item]; +#pragma clang diagnostic pop + + } @catch (NSException *exception) { + FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenStoreExceptionUnarchivingTokenInfo, + @"Unable to parse token info from Keychain item; item was in an " + @"invalid format"); + tokenInfo = nil; + } @finally { + } + } + return tokenInfo; +} + +#pragma mark - Save +// Token Infos will be saved under these Keychain keys: +// Account: <Main App Bundle ID> (e.g. com.mycompany.myapp) +// Service: <Sender ID>:<Scope> (e.g. 1234567890:*) +- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo + handler:(void (^)(NSError *))handler { // Keep the cachetime up-to-date. + tokenInfo.cacheTime = [NSDate date]; + // Always write to the Keychain, so that the cacheTime is up-to-date. + NSData *tokenInfoData; + // TODO(chliangGoogle: Use the new API and secureCoding protocol. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + tokenInfoData = [NSKeyedArchiver archivedDataWithRootObject:tokenInfo]; +#pragma clang diagnostic pop + NSString *account = FIRInstanceIDAppIdentifier(); + NSString *service = [[self class] serviceKeyForAuthorizedEntity:tokenInfo.authorizedEntity + scope:tokenInfo.scope]; + [self.keychain setData:tokenInfoData forService:service account:account handler:handler]; +} + +#pragma mark - Delete + +- (void)removeTokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity + scope:(nonnull NSString *)scope { + NSString *account = FIRInstanceIDAppIdentifier(); + NSString *service = [[self class] serviceKeyForAuthorizedEntity:authorizedEntity scope:scope]; + [self.keychain removeItemsMatchingService:service account:account handler:nil]; +} + +- (void)removeAllTokensWithHandler:(void (^)(NSError *error))handler { + NSString *account = FIRInstanceIDAppIdentifier(); + [self.keychain removeItemsMatchingService:kFIRInstanceIDKeychainWildcardIdentifier + account:account + handler:handler]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.h new file mode 100644 index 00000000..da6ebad3 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.h @@ -0,0 +1,85 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +/// FIRMessaging Class that responds to the FIRMessaging SDK version selector. +/// Verify at runtime if the class exists and implements the required method. +FOUNDATION_EXPORT NSString *const kFIRInstanceIDFCMSDKClassString; + +/// locale key stored in GULUserDefaults +FOUNDATION_EXPORT NSString *const kFIRInstanceIDUserDefaultsKeyLocale; + +#pragma mark - Test Blocks + +/** + * Response block for mock registration requests made during tests. + * + * @param data The data as returned by the mock request. + * @param response The response as returned by the mock request. + * @param error The error if any as returned by the mock request. + */ +typedef void (^FIRInstanceIDURLRequestTestResponseBlock)(NSData *data, + NSURLResponse *response, + NSError *error); + +/** + * Test block to mock registration requests response. + * + * @param request The request to mock response for. + * @param response The response block for the mocked request. + */ +typedef void (^FIRInstanceIDURLRequestTestBlock)(NSURLRequest *request, + FIRInstanceIDURLRequestTestResponseBlock response); + +#pragma mark - URL Helpers + +FOUNDATION_EXPORT NSString *FIRInstanceIDRegisterServer(void); + +#pragma mark - Time + +FOUNDATION_EXPORT int64_t FIRInstanceIDCurrentTimestampInSeconds(void); +FOUNDATION_EXPORT int64_t FIRInstanceIDCurrentTimestampInMilliseconds(void); + +#pragma mark - App Info + +FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentAppVersion(void); +FOUNDATION_EXPORT NSString *FIRInstanceIDAppIdentifier(void); +FOUNDATION_EXPORT NSString *FIRInstanceIDFirebaseAppID(void); + +#pragma mark - Device Info + +FOUNDATION_EXPORT NSString *FIRInstanceIDDeviceModel(void); +FOUNDATION_EXPORT NSString *FIRInstanceIDOperatingSystemVersion(void); +FOUNDATION_EXPORT BOOL FIRInstanceIDHasLocaleChanged(void); + +#pragma mark - Helpers + +FOUNDATION_EXPORT BOOL FIRInstanceIDIsValidGCMScope(NSString *scope); +FOUNDATION_EXPORT NSString *FIRInstanceIDStringForAPNSDeviceToken(NSData *deviceToken); +FOUNDATION_EXPORT NSString *FIRInstanceIDAPNSTupleStringForTokenAndServerType(NSData *deviceToken, + BOOL isSandbox); + +#pragma mark - GCM Helpers +/// Returns the current GCM version if GCM library is found else returns nil. +FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentGCMVersion(void); + +/// Returns the current locale. If GCM is present it queries GCM for a +/// Context Manager specific locale. Otherwise, it returns the system's first +/// preferred language (which may be set independently from locale). If the +/// system returns no preferred languages, this method returns the most common +/// language for the user's given locale. Guaranteed to return a nonnull value. +FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentLocale(void); diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.m new file mode 100644 index 00000000..25d1b972 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDUtilities.m @@ -0,0 +1,208 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDUtilities.h" + +#if TARGET_OS_IOS || TARGET_OS_TV +#import <UIKit/UIKit.h> +#endif +#import <sys/utsname.h> + +#import "FIRInstanceID.h" +#import "FIRInstanceIDConstants.h" +#import "FIRInstanceIDLogger.h" +#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h" +#import "GoogleUtilities/UserDefaults/Private/GULUserDefaults.h" + +// Convert the macro to a string +#define STR_EXPAND(x) #x +#define STR(x) STR_EXPAND(x) + +static NSString *const kFIRInstanceIDAPNSSandboxPrefix = @"s_"; +static NSString *const kFIRInstanceIDAPNSProdPrefix = @"p_"; + +/// FIRMessaging Class that responds to the FIRMessaging SDK version selector. +/// Verify at runtime if the class exists and implements the required method. +NSString *const kFIRInstanceIDFCMSDKClassString = @"FIRMessaging"; + +/// FIRMessaging selector that returns the current FIRMessaging library version. +static NSString *const kFIRInstanceIDFCMSDKVersionSelectorString = @"FIRMessagingSDKVersion"; + +/// FIRMessaging selector that returns the current device locale. +static NSString *const kFIRInstanceIDFCMSDKLocaleSelectorString = @"FIRMessagingSDKCurrentLocale"; + +NSString *const kFIRInstanceIDUserDefaultsKeyLocale = + @"com.firebase.instanceid.user_defaults.locale"; // locale key stored in GULUserDefaults + +/// Static values which will be populated once retrieved using +/// |FIRInstanceIDRetrieveEnvironmentInfoFromFirebaseCore|. +static NSString *operatingSystemVersion; +static NSString *hardwareDeviceModel; + +#pragma mark - URL Helpers + +NSString *FIRInstanceIDRegisterServer() { + return @"https://fcmtoken.googleapis.com/register"; +} + +#pragma mark - Time + +int64_t FIRInstanceIDCurrentTimestampInSeconds() { + return (int64_t)[[NSDate date] timeIntervalSince1970]; +} + +int64_t FIRInstanceIDCurrentTimestampInMilliseconds() { + return (int64_t)(FIRInstanceIDCurrentTimestampInSeconds() * 1000.0); +} + +#pragma mark - App Info + +NSString *FIRInstanceIDCurrentAppVersion() { + NSString *version = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"]; + if (![version length]) { + return @""; + } + return version; +} + +NSString *FIRInstanceIDBundleIDByRemovingLastPartFrom(NSString *bundleID) { + NSString *bundleIDComponentsSeparator = @"."; + + NSMutableArray<NSString *> *bundleIDComponents = + [[bundleID componentsSeparatedByString:bundleIDComponentsSeparator] mutableCopy]; + [bundleIDComponents removeLastObject]; + + return [bundleIDComponents componentsJoinedByString:bundleIDComponentsSeparator]; +} + +NSString *FIRInstanceIDAppIdentifier() { + NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier]; + if (!bundleID.length) { + FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeUtilitiesMissingBundleIdentifier, + @"The mainBundle's bundleIdentifier returned '%@'. Bundle identifier " + @"expected to be non-empty.", + bundleID); + return @""; + } +#if TARGET_OS_WATCH + return FIRInstanceIDBundleIDByRemovingLastPartFrom(bundleID); +#endif + return bundleID; +} + +NSString *FIRInstanceIDFirebaseAppID() { + return [FIROptions defaultOptions].googleAppID; +} + +#pragma mark - Device Info +// Get the device model from Firebase Core's App Environment Util +NSString *FIRInstanceIDDeviceModel() { + static dispatch_once_t once; + dispatch_once(&once, ^{ + struct utsname systemInfo; + if (uname(&systemInfo) == 0) { + hardwareDeviceModel = [NSString stringWithUTF8String:systemInfo.machine]; + } + }); + return hardwareDeviceModel; +} + +// Get the system version from Firebase Core's App Environment Util +NSString *FIRInstanceIDOperatingSystemVersion() { +#if TARGET_OS_IOS || TARGET_OS_TV + return [UIDevice currentDevice].systemVersion; +#elif TARGET_OS_OSX || TARGET_OS_WATCH + return [NSProcessInfo processInfo].operatingSystemVersionString; +#endif +} + +BOOL FIRInstanceIDHasLocaleChanged() { + NSString *lastLocale = + [[GULUserDefaults standardUserDefaults] stringForKey:kFIRInstanceIDUserDefaultsKeyLocale]; + NSString *currentLocale = FIRInstanceIDCurrentLocale(); + if (lastLocale) { + if ([currentLocale isEqualToString:lastLocale]) { + return NO; + } + } + return YES; +} + +#pragma mark - Helpers + +BOOL FIRInstanceIDIsValidGCMScope(NSString *scope) { + return [scope compare:kFIRInstanceIDScopeFirebaseMessaging + options:NSCaseInsensitiveSearch] == NSOrderedSame; +} + +NSString *FIRInstanceIDStringForAPNSDeviceToken(NSData *deviceToken) { + NSMutableString *APNSToken = [NSMutableString string]; + unsigned char *bytes = (unsigned char *)[deviceToken bytes]; + for (int i = 0; i < (int)deviceToken.length; i++) { + [APNSToken appendFormat:@"%02x", bytes[i]]; + } + return APNSToken; +} + +NSString *FIRInstanceIDAPNSTupleStringForTokenAndServerType(NSData *deviceToken, BOOL isSandbox) { + if (deviceToken == nil) { + // A nil deviceToken leads to an invalid tuple string, so return nil. + return nil; + } + NSString *prefix = isSandbox ? kFIRInstanceIDAPNSSandboxPrefix : kFIRInstanceIDAPNSProdPrefix; + NSString *APNSString = FIRInstanceIDStringForAPNSDeviceToken(deviceToken); + NSString *APNSTupleString = [NSString stringWithFormat:@"%@%@", prefix, APNSString]; + + return APNSTupleString; +} + +#pragma mark - GCM Helpers + +NSString *FIRInstanceIDCurrentGCMVersion() { + Class versionClass = NSClassFromString(kFIRInstanceIDFCMSDKClassString); + SEL versionSelector = NSSelectorFromString(kFIRInstanceIDFCMSDKVersionSelectorString); + if ([versionClass respondsToSelector:versionSelector]) { + IMP getVersionIMP = [versionClass methodForSelector:versionSelector]; + NSString *(*getVersion)(id, SEL) = (void *)getVersionIMP; + return getVersion(versionClass, versionSelector); + } + return nil; +} + +NSString *FIRInstanceIDCurrentLocale() { + Class localeClass = NSClassFromString(kFIRInstanceIDFCMSDKClassString); + SEL localeSelector = NSSelectorFromString(kFIRInstanceIDFCMSDKLocaleSelectorString); + + if ([localeClass respondsToSelector:localeSelector]) { + IMP getLocaleIMP = [localeClass methodForSelector:localeSelector]; + NSString *(*getLocale)(id, SEL) = (void *)getLocaleIMP; + NSString *fcmLocale = getLocale(localeClass, localeSelector); + if (fcmLocale != nil) { + return fcmLocale; + } + } + + NSString *systemLanguage = [[NSLocale preferredLanguages] firstObject]; + if (systemLanguage != nil) { + return systemLanguage; + } + + if (@available(macOS 10.12, iOS 10.0, *)) { + return [NSLocale currentLocale].languageCode; + } else { + return nil; + } +} diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.h new file mode 100644 index 00000000..ec5a76c5 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.h @@ -0,0 +1,35 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +/** + * Parsing utility for InstanceID Library versions. InstanceID lib follows semantic versioning. + * This provides utilities to parse the library versions to enable features and do + * updates based on appropriate library versions. + * + * Some example semantic versions are 1.0.1, 2.1.0, 2.1.1, 2.2.0-alpha1, 2.2.1-beta1 + */ + +FOUNDATION_EXPORT NSString *FIRInstanceIDCurrentLibraryVersion(void); +/// Returns the current Major version of GCM library. +FOUNDATION_EXPORT int FIRInstanceIDCurrentLibraryVersionMajor(void); +/// Returns the current Minor version of GCM library. +FOUNDATION_EXPORT int FIRInstanceIDCurrentLibraryVersionMinor(void); +/// Returns the current Patch version of GCM library. +FOUNDATION_EXPORT int FIRInstanceIDCurrentLibraryVersionPatch(void); +/// Returns YES if current library version is `beta` else NO. +FOUNDATION_EXPORT BOOL FIRInstanceIDCurrentLibraryVersionIsBeta(void); diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.m new file mode 100644 index 00000000..c2e532a7 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDVersionUtilities.m @@ -0,0 +1,85 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceIDVersionUtilities.h" + +// Convert the macro to a string +#define STR(x) STR_EXPAND(x) +#define STR_EXPAND(x) #x + +static NSString *const kSemanticVersioningSeparator = @"."; +static NSString *const kBetaVersionPrefix = @"-beta"; + +static NSString *libraryVersion; + +static int majorVersion; +static int minorVersion; +static int patchVersion; +static int betaVersion; + +void FIRInstanceIDParseCurrentLibraryVersion() { + static NSArray *allVersions; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableString *daylightVersion = + [NSMutableString stringWithUTF8String:STR(FIRInstanceID_LIB_VERSION)]; + // Parse versions + // major, minor, patch[-beta#] + allVersions = [daylightVersion componentsSeparatedByString:kSemanticVersioningSeparator]; + if (allVersions.count == 3) { + majorVersion = [allVersions[0] intValue]; + minorVersion = [allVersions[1] intValue]; + + // Parse patch and beta versions + NSArray *patchAndBetaVersion = + [allVersions[2] componentsSeparatedByString:kBetaVersionPrefix]; + if (patchAndBetaVersion.count == 2) { + patchVersion = [patchAndBetaVersion[0] intValue]; + betaVersion = [patchAndBetaVersion[1] intValue]; + } else if (patchAndBetaVersion.count == 1) { + patchVersion = [patchAndBetaVersion[0] intValue]; + } + } + + // Copy library version + libraryVersion = [daylightVersion copy]; + }); +} + +NSString *FIRInstanceIDCurrentLibraryVersion() { + FIRInstanceIDParseCurrentLibraryVersion(); + return libraryVersion; +} + +int FIRInstanceIDCurrentLibraryVersionMajor() { + FIRInstanceIDParseCurrentLibraryVersion(); + return majorVersion; +} + +int FIRInstanceIDCurrentLibraryVersionMinor() { + FIRInstanceIDParseCurrentLibraryVersion(); + return minorVersion; +} + +int FIRInstanceIDCurrentLibraryVersionPatch() { + FIRInstanceIDParseCurrentLibraryVersion(); + return patchVersion; +} + +BOOL FIRInstanceIDCurrentLibraryVersionIsBeta() { + FIRInstanceIDParseCurrentLibraryVersion(); + return betaVersion > 0; +} diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.h new file mode 100644 index 00000000..b533dc4a --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.h @@ -0,0 +1,70 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +FOUNDATION_EXPORT NSString *const kFIRInstanceIDDomain; + +typedef NS_ENUM(NSUInteger, FIRInstanceIDErrorCode) { + // Unknown error. + kFIRInstanceIDErrorCodeUnknown = 0, + + // Http related errors. + kFIRInstanceIDErrorCodeAuthentication = 1, + kFIRInstanceIDErrorCodeNoAccess = 2, + kFIRInstanceIDErrorCodeTimeout = 3, + kFIRInstanceIDErrorCodeNetwork = 4, + + // Another operation is in progress. + kFIRInstanceIDErrorCodeOperationInProgress = 5, + + // Failed to perform device check in. + kFIRInstanceIDErrorCodeRegistrarFailedToCheckIn = 6, + + kFIRInstanceIDErrorCodeInvalidRequest = 7, + + // InstanceID generic errors + kFIRInstanceIDErrorCodeMissingDeviceID = 501, + + // InstanceID Token specific errors + kFIRInstanceIDErrorCodeMissingAPNSToken = 1001, + kFIRInstanceIDErrorCodeMissingAPNSServerType = 1002, + kFIRInstanceIDErrorCodeInvalidAuthorizedEntity = 1003, + kFIRInstanceIDErrorCodeInvalidScope = 1004, + kFIRInstanceIDErrorCodeInvalidStart = 1005, + kFIRInstanceIDErrorCodeInvalidKeyPair = 1006, + + // InstanceID Identity specific errors + // Generic InstanceID keypair error + kFIRInstanceIDErrorCodeMissingKeyPair = 2001, + kFIRInstanceIDErrorCodeInvalidKeyPairTags = 2002, + kFIRInstanceIDErrorCodeInvalidKeyPairCreationTime = 2005, + kFIRInstanceIDErrorCodeInvalidIdentity = 2006, + +}; + +@interface NSError (FIRInstanceID) + +@property(nonatomic, readonly) FIRInstanceIDErrorCode instanceIDErrorCode; + ++ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode; + ++ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode + userInfo:(NSDictionary *)userInfo; + ++ (NSError *)FIRInstanceIDErrorMissingCheckin; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.m b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.m new file mode 100644 index 00000000..560a5df0 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/NSError+FIRInstanceID.m @@ -0,0 +1,44 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "NSError+FIRInstanceID.h" + +NSString *const kFIRInstanceIDDomain = @"com.firebase.iid"; + +@implementation NSError (FIRInstanceID) + +- (FIRInstanceIDErrorCode)instanceIDErrorCode { + return (FIRInstanceIDErrorCode)self.code; +} + ++ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode { + return [NSError errorWithFIRInstanceIDErrorCode:errorCode userInfo:nil]; +} + ++ (NSError *)errorWithFIRInstanceIDErrorCode:(FIRInstanceIDErrorCode)errorCode + userInfo:(NSDictionary *)userInfo { + return [NSError errorWithDomain:kFIRInstanceIDDomain code:errorCode userInfo:userInfo]; +} + ++ (NSError *)FIRInstanceIDErrorMissingCheckin { + NSDictionary *userInfo = @{@"msg" : @"Missing device credentials. Retry later."}; + + return [NSError errorWithDomain:kFIRInstanceIDDomain + code:kFIRInstanceIDErrorCodeMissingDeviceID + userInfo:userInfo]; +} + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceID+Private.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceID+Private.h new file mode 100644 index 00000000..632e21bc --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceID+Private.h @@ -0,0 +1,63 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <FirebaseInstanceID/FIRInstanceID.h> +#import <FirebaseInstanceID/FIRInstanceIDCheckinPreferences.h> + +/** + * @related FIRInstanceIDCheckinService + * + * The completion handler invoked once the fetch from Checkin server finishes. + * For successful fetches we returned checkin information by the checkin service + * and `nil` error, else we return the appropriate error object as reported by the + * Checkin Service. + * + * @param checkinPreferences The checkin preferences as fetched from the server. + * @param error The error object which fetching GServices data. + */ +typedef void (^FIRInstanceIDDeviceCheckinCompletion)( + FIRInstanceIDCheckinPreferences *_Nullable checkinPreferences, NSError *_Nullable error); + +/** + * Private API used by Firebase SDK teams by calling in reflection or internal teams. + */ +@interface FIRInstanceID (Private) + +/** + * Fetches checkin info for the app. If the app has valid cached checkin preferences + * they are returned instead of making a network request. + * + * @param handler The completion handler to invoke once the request has completed. + */ +- (void)fetchCheckinInfoWithHandler:(nullable FIRInstanceIDDeviceCheckinCompletion)handler; + +/** + * Get the InstanceID for the app. If an ID was created before and cached + * successfully we will return that ID. If no cached ID exists we create + * a new ID, cache it and return that. + * + * This is a blocking call and should not really be called on the main thread. + * + * @param error The error object that represents the error while trying to + * retrieve the instance id. + * + * @return The InstanceID for the app. + */ +- (nullable NSString *)appInstanceID:(NSError *_Nullable *_Nullable)error + DEPRECATED_MSG_ATTRIBUTE("Please use getID(handler:) for Swift or " + "getIDWithHandler: for Objective-C instead."); + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceIDCheckinPreferences.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceIDCheckinPreferences.h new file mode 100644 index 00000000..be3ec572 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceIDCheckinPreferences.h @@ -0,0 +1,62 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +/** + * The preferences InstanceID loads from checkin server. The deviceID and secret that checkin + * provides is used to authenticate all future requests to the server. Besides the deviceID + * and secret the other information that checkin provides is stored in a plist on the device. + * The deviceID and secret are persisted in the device keychain. + */ +@interface FIRInstanceIDCheckinPreferences : NSObject + +/** + * DeviceID and secretToken are the checkin auth credentials and are stored in the Keychain. + */ +@property(nonatomic, readonly, copy) NSString *deviceID; +@property(nonatomic, readonly, copy) NSString *secretToken; + +/** + * All the other checkin preferences other than deviceID and secret are stored in a plist. + */ +@property(nonatomic, readonly, copy) NSString *deviceDataVersion; +@property(nonatomic, readonly, copy) NSString *digest; +@property(nonatomic, readonly, copy) NSString *versionInfo; +@property(nonatomic, readonly, assign) int64_t lastCheckinTimestampMillis; + +/** + * The content retrieved from checkin server that should be persisted in a plist. This + * doesn't contain the deviceID and secret which are stored in the Keychain since they + * should be more private. + * + * @return The checkin preferences that should be persisted in a plist. + */ +- (NSDictionary *)checkinPlistContents; + +/** + * Return whether checkin info exists, valid or not. + */ +- (BOOL)hasCheckinInfo; + +/** + * Verify if checkin preferences are valid or not. + * + * @return YES if valid checkin preferences else NO. + */ +- (BOOL)hasValidCheckinInfo; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceID_Private.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceID_Private.h new file mode 100644 index 00000000..c343f88d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Private/FIRInstanceID_Private.h @@ -0,0 +1,74 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <FirebaseInstanceID/FIRInstanceID.h> + +NS_ASSUME_NONNULL_BEGIN + +@class FIRInstanceIDCheckinPreferences; +@class FIRInstallations; + +/** + * Private API used by other Firebase SDKs. + */ +@interface FIRInstanceID () + +@property(nonatomic, readonly, strong) NSString *deviceAuthID; +@property(nonatomic, readonly, strong) NSString *secretToken; +@property(nonatomic, readonly, strong) NSString *versionInfo; + +@property(nonatomic, readonly, strong) FIRInstallations *installations; + +/// A cached value of FID. Should be used only for `-[FIRInstanceID appInstanceID:]`. +@property(atomic, readonly, copy, nullable) NSString *firebaseInstallationsID; + +/** + * Private initializer. + */ +- (instancetype)initPrivately; + +/** + * Returns a Firebase Messaging scoped token for the firebase app. + * + * @return Returns the stored token if the device has registered with Firebase Messaging, otherwise + * returns nil. + */ +- (nullable NSString *)token; + +/** + * Verify if valid checkin preferences have been loaded in memory. + * + * @return YES if valid checkin preferences exist in memory else NO. + */ +- (BOOL)hasValidCheckinInfo; + +/** + * Try to load prefetched checkin preferences from the cache. This supports the use case where + * InstanceID library has already obtained a valid checkin and we should be using that. + * + * This should be used as a last gasp effort to retreive any cached checkin preferences before + * hitting the FIRMessaging backend to retrieve new preferences. + * + * Note this is only required because InstanceID and FIRMessaging both require checkin preferences + * which need to be synced with each other. + * + * @return YES if successfully loaded cached checkin preferences into memory else NO. + */ +- (BOOL)tryToLoadValidCheckinInfo; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FIRInstanceID.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FIRInstanceID.h new file mode 100644 index 00000000..0f96d910 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FIRInstanceID.h @@ -0,0 +1,312 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@class FIRInstanceIDResult; +/** + * @memberof FIRInstanceID + * + * The scope to be used when fetching/deleting a token for Firebase Messaging. + */ +FOUNDATION_EXPORT NSString *const kFIRInstanceIDScopeFirebaseMessaging + NS_SWIFT_NAME(InstanceIDScopeFirebaseMessaging); + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +/** + * Called when the system determines that tokens need to be refreshed. + * This method is also called if Instance ID has been reset in which + * case, tokens and FCM topic subscriptions also need to be refreshed. + * + * Instance ID service will throttle the refresh event across all devices + * to control the rate of token updates on application servers. + */ +FOUNDATION_EXPORT const NSNotificationName kFIRInstanceIDTokenRefreshNotification + NS_SWIFT_NAME(InstanceIDTokenRefresh); +#else +/** + * Called when the system determines that tokens need to be refreshed. + * This method is also called if Instance ID has been reset in which + * case, tokens and FCM topic subscriptions also need to be refreshed. + * + * Instance ID service will throttle the refresh event across all devices + * to control the rate of token updates on application servers. + */ +FOUNDATION_EXPORT NSString *const kFIRInstanceIDTokenRefreshNotification + NS_SWIFT_NAME(InstanceIDTokenRefreshNotification); +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +/** + * @related FIRInstanceID + * + * The completion handler invoked when the InstanceID token returns. If + * the call fails we return the appropriate `error code` as described below. + * + * @param token The valid token as returned by InstanceID backend. + * + * @param error The error describing why generating a new token + * failed. See the error codes below for a more detailed + * description. + */ +typedef void (^FIRInstanceIDTokenHandler)(NSString *__nullable token, NSError *__nullable error) + NS_SWIFT_NAME(InstanceIDTokenHandler); + +/** + * @related FIRInstanceID + * + * The completion handler invoked when the InstanceID `deleteToken` returns. If + * the call fails we return the appropriate `error code` as described below + * + * @param error The error describing why deleting the token failed. + * See the error codes below for a more detailed description. + */ +typedef void (^FIRInstanceIDDeleteTokenHandler)(NSError *error) + NS_SWIFT_NAME(InstanceIDDeleteTokenHandler); + +/** + * @related FIRInstanceID + * + * The completion handler invoked when the app identity is created. If the + * identity wasn't created for some reason we return the appropriate error code. + * + * @param identity A valid identity for the app instance, nil if there was an error + * while creating an identity. + * @param error The error if fetching the identity fails else nil. + */ +typedef void (^FIRInstanceIDHandler)(NSString *__nullable identity, NSError *__nullable error) + NS_SWIFT_NAME(InstanceIDHandler); + +/** + * @related FIRInstanceID + * + * The completion handler invoked when the app identity and all the tokens associated + * with it are deleted. Returns a valid error object in case of failure else nil. + * + * @param error The error if deleting the identity and all the tokens associated with + * it fails else nil. + */ +typedef void (^FIRInstanceIDDeleteHandler)(NSError *__nullable error) + NS_SWIFT_NAME(InstanceIDDeleteHandler); + +/** + * @related FIRInstanceID + * + * The completion handler invoked when the app identity and token are fetched. If the + * identity wasn't created for some reason we return the appropriate error code. + * + * @param result The result containing an identity for the app instance and a valid token, + * nil if there was an error while creating the result. + * @param error The error if fetching the identity or token fails else nil. + */ +typedef void (^FIRInstanceIDResultHandler)(FIRInstanceIDResult *__nullable result, + NSError *__nullable error) + NS_SWIFT_NAME(InstanceIDResultHandler); + +/** + * Public errors produced by InstanceID. + */ +typedef NS_ENUM(NSUInteger, FIRInstanceIDError) { + // Http related errors. + + /// Unknown error. + FIRInstanceIDErrorUnknown = 0, + + /// Auth Error -- GCM couldn't validate request from this client. + FIRInstanceIDErrorAuthentication = 1, + + /// NoAccess -- InstanceID service cannot be accessed. + FIRInstanceIDErrorNoAccess = 2, + + /// Timeout -- Request to InstanceID backend timed out. + FIRInstanceIDErrorTimeout = 3, + + /// Network -- No network available to reach the servers. + FIRInstanceIDErrorNetwork = 4, + + /// OperationInProgress -- Another similar operation in progress, + /// bailing this one. + FIRInstanceIDErrorOperationInProgress = 5, + + /// InvalidRequest -- Some parameters of the request were invalid. + FIRInstanceIDErrorInvalidRequest = 7, +} NS_SWIFT_NAME(InstanceIDError); + +/** + * A class contains the results of InstanceID and token query. + */ +NS_SWIFT_NAME(InstanceIDResult) +@interface FIRInstanceIDResult : NSObject <NSCopying> + +/** + * An instanceID uniquely identifies the app instance. + */ +@property(nonatomic, readonly, copy) NSString *instanceID; + +/* + * Returns a Firebase Messaging scoped token for the firebase app. + */ +@property(nonatomic, readonly, copy) NSString *token; + +@end + +/** + * Instance ID provides a unique identifier for each app instance and a mechanism + * to authenticate and authorize actions (for example, sending an FCM message). + * + * Once an InstanceID is generated, the library periodically sends information about the + * application and the device where it's running to the Firebase backend. To stop this. see + * `[FIRInstanceID deleteIDWithHandler:]`. + * + * Instance ID is long lived but, may be reset if the device is not used for + * a long time or the Instance ID service detects a problem. + * If Instance ID is reset, the app will be notified via + * `kFIRInstanceIDTokenRefreshNotification`. + * + * If the Instance ID has become invalid, the app can request a new one and + * send it to the app server. + * To prove ownership of Instance ID and to allow servers to access data or + * services associated with the app, call + * `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. + */ +NS_SWIFT_NAME(InstanceID) +@interface FIRInstanceID : NSObject + +/** + * FIRInstanceID. + * + * @return A shared instance of FIRInstanceID. + */ ++ (instancetype)instanceID NS_SWIFT_NAME(instanceID()); + +/** + * Unavailable. Use +instanceID instead. + */ +- (instancetype)init __attribute__((unavailable("Use +instanceID instead."))); + +#pragma mark - Tokens + +/** + * Returns a result of app instance identifier InstanceID and a Firebase Messaging scoped token. + * param handler The callback handler invoked when an app instanceID and a default token + * are generated and returned. If instanceID and token fetching fail for some + * reason the callback is invoked with nil `result` and the appropriate error. + */ +- (void)instanceIDWithHandler:(FIRInstanceIDResultHandler)handler; + +/** + * Returns a token that authorizes an Entity (example: cloud service) to perform + * an action on behalf of the application identified by Instance ID. + * + * This is similar to an OAuth2 token except, it applies to the + * application instance instead of a user. + * + * This is an asynchronous call. If the token fetching fails for some reason + * we invoke the completion callback with nil `token` and the appropriate + * error. + * + * This generates an Instance ID if it does not exist yet, which starts periodically sending + * information to the Firebase backend (see `[FIRInstanceID getIDWithHandler:]`). + * + * Note, you can only have one `token` or `deleteToken` call for a given + * authorizedEntity and scope at any point of time. Making another such call with the + * same authorizedEntity and scope before the last one finishes will result in an + * error with code `OperationInProgress`. + * + * @see FIRInstanceID deleteTokenWithAuthorizedEntity:scope:handler: + * + * @param authorizedEntity Entity authorized by the token. + * @param scope Action authorized for authorizedEntity. + * @param options The extra options to be sent with your token request. The + * value for the `apns_token` should be the NSData object + * passed to the UIApplicationDelegate's + * `didRegisterForRemoteNotificationsWithDeviceToken` method. + * The value for `apns_sandbox` should be a boolean (or an + * NSNumber representing a BOOL in Objective-C) set to true if + * your app is a debug build, which means that the APNs + * device token is for the sandbox environment. It should be + * set to false otherwise. If the `apns_sandbox` key is not + * provided, an automatically-detected value shall be used. + * @param handler The callback handler which is invoked when the token is + * successfully fetched. In case of success a valid `token` and + * `nil` error are returned. In case of any error the `token` + * is nil and a valid `error` is returned. The valid error + * codes have been documented above. + */ +- (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + options:(nullable NSDictionary *)options + handler:(FIRInstanceIDTokenHandler)handler; + +/** + * Revokes access to a scope (action) for an entity previously + * authorized by `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. + * + * This is an asynchronous call. Call this on the main thread since InstanceID lib + * is not thread safe. In case token deletion fails for some reason we invoke the + * `handler` callback passed in with the appropriate error code. + * + * Note, you can only have one `token` or `deleteToken` call for a given + * authorizedEntity and scope at a point of time. Making another such call with the + * same authorizedEntity and scope before the last one finishes will result in an error + * with code `OperationInProgress`. + * + * @param authorizedEntity Entity that must no longer have access. + * @param scope Action that entity is no longer authorized to perform. + * @param handler The handler that is invoked once the unsubscribe call ends. + * In case of error an appropriate error object is returned + * else error is nil. + */ +- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity + scope:(NSString *)scope + handler:(FIRInstanceIDDeleteTokenHandler)handler; + +#pragma mark - Identity + +/** + * Asynchronously fetch a stable identifier that uniquely identifies the app + * instance. If the identifier has been revoked or has expired, this method will + * return a new identifier. + * + * Once an InstanceID is generated, the library periodically sends information about the + * application and the device where it's running to the Firebase backend. To stop this. see + * `[FIRInstanceID deleteIDWithHandler:]`. + * + * @param handler The handler to invoke once the identifier has been fetched. + * In case of error an appropriate error object is returned else + * a valid identifier is returned and a valid identifier for the + * application instance. + */ +- (void)getIDWithHandler:(FIRInstanceIDHandler)handler NS_SWIFT_NAME(getID(handler:)); + +/** + * Resets Instance ID and revokes all tokens. + * + * This method also triggers a request to fetch a new Instance ID and Firebase Messaging scope + * token. Please listen to kFIRInstanceIDTokenRefreshNotification when the new ID and token are + * ready. + * + * This stops the periodic sending of data to the Firebase backend that began when the Instance ID + * was generated. No more data is sent until another library calls Instance ID internally again + * (like FCM, RemoteConfig or Analytics) or user explicitly calls Instance ID APIs to get an + * Instance ID and token again. + */ +- (void)deleteIDWithHandler:(FIRInstanceIDDeleteHandler)handler NS_SWIFT_NAME(deleteID(handler:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FirebaseInstanceID.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FirebaseInstanceID.h new file mode 100644 index 00000000..78c9ef16 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/Public/FirebaseInstanceID.h @@ -0,0 +1,17 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRInstanceID.h" diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRAppInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRAppInternal.h new file mode 100644 index 00000000..9a0c943d --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRAppInternal.h @@ -0,0 +1,173 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if SWIFT_PACKAGE +// TODO(paulb777): Investigate if there's a common strategy for both Cocoapods and Swift PM. +#import "FIRApp.h" +#else +#import <FirebaseCore/FIRApp.h> +#endif + +// The has_include is a workaround so the old IID needed for the FIS tests can find FIRErrors.h +#if __has_include("FirebaseCore/Sources/Private/FIRErrors.h") +#import "FirebaseCore/Sources/Private/FIRErrors.h" +#else +#import <FirebaseCore/FIRErrors.h> +#endif + +@class FIRComponentContainer; +@protocol FIRLibrary; + +/** + * The internal interface to FIRApp. This is meant for first-party integrators, who need to receive + * FIRApp notifications, log info about the success or failure of their configuration, and access + * other internal functionality of FIRApp. + * + * TODO(b/28296561): Restructure this header. + */ +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRConfigType) { + FIRConfigTypeCore = 1, + FIRConfigTypeSDK = 2, +}; + +extern NSString *const kFIRDefaultAppName; +extern NSString *const kFIRAppReadyToConfigureSDKNotification; +extern NSString *const kFIRAppDeleteNotification; +extern NSString *const kFIRAppIsDefaultAppKey; +extern NSString *const kFIRAppNameKey; +extern NSString *const kFIRGoogleAppIDKey; + +/** + * The format string for the User Defaults key used for storing the data collection enabled flag. + * This includes formatting to append the Firebase App's name. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; + +/** + * The plist key used for storing the data collection enabled flag. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; + +/** + * A notification fired containing diagnostic information when SDK errors occur. + */ +extern NSString *const kFIRAppDiagnosticsNotification; + +/** @var FIRAuthStateDidChangeInternalNotification + @brief The name of the @c NSNotificationCenter notification which is posted when the auth state + changes (e.g. a new token has been produced, a user logs in or out). The object parameter of + the notification is a dictionary possibly containing the key: + @c FIRAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not + contain this key it indicates a sign-out event took place. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotification; + +/** @var FIRAuthStateDidChangeInternalNotificationTokenKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new access token. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; + +/** @var FIRAuthStateDidChangeInternalNotificationAppKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the FIRApp associated with the auth instance. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; + +/** @var FIRAuthStateDidChangeInternalNotificationUIDKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new user's UID (or nil if there is no longer a user signed in). + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; + +@interface FIRApp () + +/** + * A flag indicating if this is the default app (has the default app name). + */ +@property(nonatomic, readonly) BOOL isDefaultApp; + +/* + * The container of interop SDKs for this app. + */ +@property(nonatomic) FIRComponentContainer *container; + +/** + * Creates an error for failing to configure a subspec service. This method is called by each + * FIRApp notification listener. + */ ++ (NSError *)errorForSubspecConfigurationFailureWithDomain:(NSString *)domain + errorCode:(FIRErrorCode)code + service:(NSString *)service + reason:(NSString *)reason; +/** + * Checks if the default app is configured without trying to configure it. + */ ++ (BOOL)isDefaultAppConfigured; + +/** + * Registers a given third-party library with the given version number to be reported for + * analytics. + * + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; + +/** + * Registers a given internal library with the given version number to be reported for + * analytics. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class<FIRLibrary>)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version; + +/** + * A concatenated string representing all the third-party libraries and version numbers. + */ ++ (NSString *)firebaseUserAgent; + +/** + * Used by each SDK to send logs about SDK configuration status to Clearcut. + * + * @note This API is a no-op, please remove calls to it. + */ +- (void)sendLogsWithServiceName:(NSString *)serviceName + version:(NSString *)version + error:(NSError *)error; + +/** + * Can be used by the unit tests in eack SDK to reset FIRApp. This method is thread unsafe. + */ ++ (void)resetApps; + +/** + * Can be used by the unit tests in each SDK to set customized options. + */ +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponent.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponent.h new file mode 100644 index 00000000..cb51ee70 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponent.h @@ -0,0 +1,91 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@class FIRApp; +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides a system to clean up cached instances returned from the component system. +NS_SWIFT_NAME(ComponentLifecycleMaintainer) +@protocol FIRComponentLifecycleMaintainer +/// The associated app will be deleted, clean up any resources as they are about to be deallocated. +- (void)appWillBeDeleted:(FIRApp *)app; +@end + +typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, + BOOL *isCacheable) + NS_SWIFT_NAME(ComponentCreationBlock); + +@class FIRDependency; + +/// Describes the timing of instantiation. Note: new components should default to lazy unless there +/// is a strong reason to be eager. +typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { + FIRInstantiationTimingLazy, + FIRInstantiationTimingAlwaysEager, + FIRInstantiationTimingEagerInDefaultApp +} NS_SWIFT_NAME(InstantiationTiming); + +/// A component that can be used from other Firebase SDKs. +NS_SWIFT_NAME(Component) +@interface FIRComponent : NSObject + +/// The protocol describing functionality provided from the Component. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// The timing of instantiation. +@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; + +/// An array of dependencies for the component. +@property(nonatomic, copy, readonly) NSArray<FIRDependency *> *dependencies; + +/// A block to instantiate an instance of the component with the appropriate dependencies. +@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; + +// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format +// for the next two methods. +// clang-format off + +/// Creates a component with no dependencies that will be lazily initialized. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:creationBlock:)); + +/// Creates a component to be registered with the component container. +/// +/// @param protocol - The protocol describing functionality provided by the component. +/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's +/// a good reason to be instantiated earlier. +/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. +/// @param creationBlock - A block to instantiate the component with a container, and if +/// @return A component that can be registered with the component container. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray<FIRDependency *> *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); + +// clang-format on + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponentContainer.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponentContainer.h new file mode 100644 index 00000000..db2bafef --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponentContainer.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#import <Foundation/Foundation.h> + +// The has_include is a workaround so the old IID needed for the FIS tests can find the headers. +#if __has_include("FirebaseCore/Sources/Private/FIRComponentType.h") +#import "FirebaseCore/Sources/Private/FIRComponentType.h" +#import "FirebaseCore/Sources/Private/FIRLibrary.h" +#else +#import <FirebaseCore/FIRComponentType.h> +#import <FirebaseCore/FIRLibrary.h> +#endif + +NS_ASSUME_NONNULL_BEGIN + +/// A type-safe macro to retrieve a component from a container. This should be used to retrieve +/// components instead of using the container directly. +#define FIR_COMPONENT(type, container) \ + [FIRComponentType<id<type>> instanceForProtocol:@protocol(type) inContainer:container] + +@class FIRApp; + +/// A container that holds different components that are registered via the +/// `registerAsComponentRegistrant:` call. These classes should conform to `FIRComponentRegistrant` +/// in order to properly register components for Core. +NS_SWIFT_NAME(FirebaseComponentContainer) +@interface FIRComponentContainer : NSObject + +/// A weak reference to the app that an instance of the container belongs to. +@property(nonatomic, weak, readonly) FIRApp *app; + +/// Unavailable. Use the `container` property on `FIRApp`. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponentType.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponentType.h new file mode 100644 index 00000000..6f2aca7b --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRComponentType.h @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Do not use directly. A placeholder type in order to provide a macro that will warn users of +/// mis-matched protocols. +NS_SWIFT_NAME(ComponentType) +@interface FIRComponentType<__covariant T> : NSObject + +/// Do not use directly. A factory method to retrieve an instance that provides a specific +/// functionality. ++ (T)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h new file mode 100644 index 00000000..76c0c05f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h @@ -0,0 +1,35 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@class FIRDiagnosticsData; +@class FIROptions; + +NS_ASSUME_NONNULL_BEGIN + +/** Connects FIRCore with the CoreDiagnostics library. */ +@interface FIRCoreDiagnosticsConnector : NSObject + +/** Logs FirebaseCore related data. + * + * @param options The options object containing data to log. + */ ++ (void)logCoreTelemetryWithOptions:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRDependency.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRDependency.h new file mode 100644 index 00000000..46e9b7ea --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRDependency.h @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/// A dependency on a specific protocol's functionality. +NS_SWIFT_NAME(Dependency) +@interface FIRDependency : NSObject + +/// The protocol describing functionality being depended on. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// A flag to specify if the dependency is required or not. +@property(nonatomic, readonly) BOOL isRequired; + +/// Initializes a dependency that is required. Calls `initWithProtocol:isRequired` with `YES` for +/// the required parameter. +/// Creates a required dependency on the specified protocol's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol; + +/// Creates a dependency on the specified protocol's functionality and specify if it's required for +/// the class's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +/// Use `dependencyWithProtocol:isRequired:` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRErrorCode.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRErrorCode.h new file mode 100644 index 00000000..c90d9eec --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRErrorCode.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** Error codes in Firebase error domain. */ +typedef NS_ENUM(NSInteger, FIRErrorCode) { + /** + * Unknown error. + */ + FIRErrorCodeUnknown = 0, + /** + * Loading data from the GoogleService-Info.plist file failed. This is a fatal error and should + * not be ignored. Further calls to the API will fail and/or possibly cause crashes. + */ + FIRErrorCodeInvalidPlistFile = -100, + + /** + * Validating the Google App ID format failed. + */ + FIRErrorCodeInvalidAppID = -101, + + /** + * Error code for failing to configure a specific service. It's deprecated, but + * still used after copybara. + */ + FIRErrorCodeConfigFailed = -114, +}; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRErrors.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRErrors.h new file mode 100644 index 00000000..19e47328 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRErrors.h @@ -0,0 +1,24 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +#include "FIRErrorCode.h" + +extern NSString *const kFirebaseErrorDomain; +extern NSString *const kFirebaseConfigErrorDomain; +extern NSString *const kFirebaseCoreErrorDomain; +extern NSString *const kFirebasePerfErrorDomain; diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h new file mode 100644 index 00000000..bfff73e5 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h @@ -0,0 +1,39 @@ +// Copyright 2019 Google +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRHeartbeatInfo : NSObject + +// Enum representing the different heartbeat codes. +typedef NS_ENUM(NSInteger, FIRHeartbeatInfoCode) { + FIRHeartbeatInfoCodeNone = 0, + FIRHeartbeatInfoCodeSDK = 1, + FIRHeartbeatInfoCodeGlobal = 2, + FIRHeartbeatInfoCodeCombined = 3, +}; + +/** + * Get heartbeat code requred for the sdk. + * @param heartbeatTag String representing the sdk heartbeat tag. + * @return Heartbeat code indicating whether or not an sdk/global heartbeat + * needs to be sent + */ ++ (FIRHeartbeatInfoCode)heartbeatCodeForTag:(NSString *)heartbeatTag; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRLibrary.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRLibrary.h new file mode 100644 index 00000000..e7a9e077 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRLibrary.h @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRLibrary_h +#define FIRLibrary_h + +#import <Foundation/Foundation.h> + +// The has_include is a workaround so the old IID needed for the FIS tests can find the headers. +#if __has_include("FirebaseCore/Sources/Private/FIRComponent.h") +#import "FirebaseCore/Sources/Private/FIRComponent.h" +#else +#import <FirebaseCore/FIRComponent.h> +#endif + +@class FIRApp; + +NS_ASSUME_NONNULL_BEGIN + +/// Provide an interface to register a library for userAgent logging and availability to others. +NS_SWIFT_NAME(Library) +@protocol FIRLibrary + +/// Returns one or more FIRComponents that will be registered in +/// FIRApp and participate in dependency resolution and injection. ++ (NSArray<FIRComponent *> *)componentsToRegister; + +@optional +/// Implement this method if the library needs notifications for lifecycle events. This method is +/// called when the developer calls `FirebaseApp.configure()`. ++ (void)configureWithApp:(FIRApp *)app; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRLibrary_h */ diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRLogger.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRLogger.h new file mode 100644 index 00000000..6fd77844 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIRLogger.h @@ -0,0 +1,156 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +#if SWIFT_PACKAGE +// TODO(paulb777): Investigate if there's a common strategy for both Cocoapods and Swift PM. +#import "FIRLoggerLevel.h" +#else +#import <FirebaseCore/FIRLoggerLevel.h> +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** + * The Firebase services used in Firebase logger. + */ +typedef NSString *const FIRLoggerService; + +extern FIRLoggerService kFIRLoggerABTesting; +extern FIRLoggerService kFIRLoggerAdMob; +extern FIRLoggerService kFIRLoggerAnalytics; +extern FIRLoggerService kFIRLoggerAuth; +extern FIRLoggerService kFIRLoggerCrash; +extern FIRLoggerService kFIRLoggerCore; +extern FIRLoggerService kFIRLoggerMLKit; +extern FIRLoggerService kFIRLoggerPerf; +extern FIRLoggerService kFIRLoggerRemoteConfig; + +/** + * The key used to store the logger's error count. + */ +extern NSString *const kFIRLoggerErrorCountKey; + +/** + * The key used to store the logger's warning count. + */ +extern NSString *const kFIRLoggerWarningCountKey; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Enables or disables Analytics debug mode. + * If set to YES, the logging level for Analytics will be set to FIRLoggerLevelDebug. + * Enabling the debug mode has no effect if the app is running from App Store. + * (required) analytics debug mode flag. + */ +void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); + +/** + * Changes the default logging level of FIRLoggerLevelNotice to a user-specified level. + * The default level cannot be set above FIRLoggerLevelNotice if the app is running from App Store. + * (required) log level (one of the FIRLoggerLevel enum values). + */ +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +/** + * Checks if the specified logger level is loggable given the current settings. + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) whether or not this function is called from the Analytics component. + */ +BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); + +/** + * Logs a message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FIRLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) service name of type FIRLoggerService. + * (required) message code starting with "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * (required) message string which can be a format string. + * (optional) variable arguments list obtained from calling va_start, used when message is a format + * string. + */ +extern void FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + NSString *messageCode, + NSString *message, +// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable +// See: http://stackoverflow.com/q/29095469 +#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX + va_list args_ptr +#else + va_list _Nullable args_ptr +#endif +); + +/** + * The following functions accept the following parameters in order: + * (required) service name of type FIRLoggerService. + * (required) message code starting from "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * See go/firebase-log-proposal for details. + * (required) message string which can be a format string. + * (optional) the list of arguments to substitute into the format string. + * Example usage: + * FIRLogError(kFIRLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +@interface FIRLoggerWrapper : NSObject + +/** + * Objective-C wrapper for FIRLogBasic to allow weak linking to FIRLogger + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) service name of type FIRLoggerService. + * (required) message code starting with "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * (required) message string which can be a format string. + * (optional) variable arguments list obtained from calling va_start, used when message is a format + * string. + */ + ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIROptionsInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIROptionsInternal.h new file mode 100644 index 00000000..acaf4586 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FIROptionsInternal.h @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if SWIFT_PACKAGE +// TODO(paulb777): Investigate if there's a common strategy for both Cocoapods and Swift PM. +#import "FIROptions.h" +#else +#import <FirebaseCore/FIROptions.h> +#endif + +/** + * Keys for the strings in the plist file. + */ +extern NSString *const kFIRAPIKey; +extern NSString *const kFIRTrackingID; +extern NSString *const kFIRGoogleAppID; +extern NSString *const kFIRClientID; +extern NSString *const kFIRGCMSenderID; +extern NSString *const kFIRAndroidClientID; +extern NSString *const kFIRDatabaseURL; +extern NSString *const kFIRStorageBucket; +extern NSString *const kFIRBundleID; +extern NSString *const kFIRProjectID; + +/** + * Keys for the plist file name + */ +extern NSString *const kServiceInfoFileName; + +extern NSString *const kServiceInfoFileType; + +/** + * This header file exposes the initialization of FIROptions to internal use. + */ +@interface FIROptions () + +/** + * resetDefaultOptions and initInternalWithOptionsDictionary: are exposed only for unit tests. + */ ++ (void)resetDefaultOptions; + +/** + * Initializes the options with dictionary. The above strings are the keys of the dictionary. + * This is the designated initializer. + */ +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary; + +/** + * defaultOptions and defaultOptionsDictionary are exposed in order to be used in FIRApp and + * other first party services. + */ ++ (FIROptions *)defaultOptions; + ++ (NSDictionary *)defaultOptionsDictionary; + +/** + * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at + * runtime. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet; + +/** + * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless + * explicitly disabled in GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; + +/** + * Whether or not Analytics Collection was completely disabled. If YES, then + * isAnalyticsCollectionEnabled will be NO. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; + +/** + * The version ID of the client library, e.g. @"1100000". + */ +@property(nonatomic, readonly, copy) NSString *libraryVersionID; + +/** + * The flag indicating whether this object was constructed with the values in the default plist + * file. + */ +@property(nonatomic) BOOL usingOptionsFromDefaultPlist; + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isMeasurementEnabled; + +/** + * Whether or not Analytics was enabled in the developer console. + */ +@property(nonatomic, readonly) BOOL isAnalyticsEnabled; + +/** + * Whether or not SignIn was enabled in the developer console. + */ +@property(nonatomic, readonly) BOOL isSignInEnabled; + +/** + * Whether or not editing is locked. This should occur after FIROptions has been set on a FIRApp. + */ +@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FirebaseCoreInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FirebaseCoreInternal.h new file mode 100644 index 00000000..93af6cb8 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseCore/Sources/Private/FirebaseCoreInternal.h @@ -0,0 +1,31 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// An umbrella header, for any other libraries in this repo to access Firebase Public and Private +// headers. Any package manager complexity should be handled here. + +#if SWIFT_PACKAGE +@import FirebaseCore; +#else +#import <FirebaseCore/FirebaseCore.h> +#endif + +#import "FirebaseCore/Sources/Private/FIRAppInternal.h" +#import "FirebaseCore/Sources/Private/FIRComponent.h" +#import "FirebaseCore/Sources/Private/FIRComponentContainer.h" +#import "FirebaseCore/Sources/Private/FIRDependency.h" +#import "FirebaseCore/Sources/Private/FIRHeartbeatInfo.h" +#import "FirebaseCore/Sources/Private/FIRLibrary.h" +#import "FirebaseCore/Sources/Private/FIRLogger.h" +#import "FirebaseCore/Sources/Private/FIROptionsInternal.h" diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h new file mode 100644 index 00000000..cd40f172 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h @@ -0,0 +1,23 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// An umbrella header, for any other libraries in this repo to access Firebase +// Installations Public headers. Any package manager complexity should be +// handled here. + +#if SWIFT_PACKAGE +@import FirebaseInstallations; +#else +#import <FirebaseInstallations/FirebaseInstallations.h> +#endif diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h new file mode 100644 index 00000000..2fb16226 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULAppEnvironmentUtil.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@interface GULAppEnvironmentUtil : NSObject + +/// Indicates whether the app is from Apple Store or not. Returns NO if the app is on simulator, +/// development environment or sideloaded. ++ (BOOL)isFromAppStore; + +/// Indicates whether the app is a Testflight app. Returns YES if the app has sandbox receipt. +/// Returns NO otherwise. ++ (BOOL)isAppStoreReceiptSandbox; + +/// Indicates whether the app is on simulator or not at runtime depending on the device +/// architecture. ++ (BOOL)isSimulator; + +/// The current device model. Returns an empty string if device model cannot be retrieved. ++ (NSString *)deviceModel; + +/// The current operating system version. Returns an empty string if the system version cannot be +/// retrieved. ++ (NSString *)systemVersion; + +/// Indicates whether it is running inside an extension or an app. ++ (BOOL)isAppExtension; + +/// @return Returns @YES when is run on iOS version greater or equal to 7.0 ++ (BOOL)isIOS7OrHigher DEPRECATED_MSG_ATTRIBUTE( + "Always `YES` because only iOS 8 and higher supported. The method will be removed."); + +@end diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULHeartbeatDateStorage.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULHeartbeatDateStorage.h new file mode 100644 index 00000000..9432dfc0 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULHeartbeatDateStorage.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/// Stores either a date or a dictionary to a specified file. +@interface GULHeartbeatDateStorage : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@property(nonatomic, readonly) NSURL *fileURL; + +/** + * Default initializer. + * @param fileName The name of the file to store the date information. + * exist, it will be created if needed. + */ +- (instancetype)initWithFileName:(NSString *)fileName; + +/** + * Reads the date from the specified file for the given tag. + * @return Returns date if exists, otherwise `nil`. + */ +- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag; + +/** + * Saves the date for the specified tag in the specified file. + * @return YES on success, NO otherwise. + */ +- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULKeychainStorage.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULKeychainStorage.h new file mode 100644 index 00000000..dc01a836 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULKeychainStorage.h @@ -0,0 +1,79 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +@class FBLPromise<ValueType>; + +NS_ASSUME_NONNULL_BEGIN + +/// The class provides a convenient abstraction on top of the iOS Keychain API to save data. +@interface GULKeychainStorage : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** Initializes the keychain storage with Keychain Service name. + * @param service A Keychain Service name that will be used to store and retrieve objects. See also + * `kSecAttrService`. + */ +- (instancetype)initWithService:(NSString *)service; + +/** + * Get an object by key. + * @param key The key. + * @param objectClass The expected object class required by `NSSecureCoding`. + * @param accessGroup The Keychain Access Group. + * + * @return Returns a promise. It is resolved with an object stored by key if exists. It is resolved + * with `nil` when the object not found. It fails on a Keychain error. + */ +- (FBLPromise<id<NSSecureCoding>> *)getObjectForKey:(NSString *)key + objectClass:(Class)objectClass + accessGroup:(nullable NSString *)accessGroup; + +/** + * Saves the given object by the given key. + * @param object The object to store. + * @param key The key to store the object. If there is an existing object by the key, it will be + * overridden. + * @param accessGroup The Keychain Access Group. + * + * @return Returns which is resolved with `[NSNull null]` on success. + */ +- (FBLPromise<NSNull *> *)setObject:(id<NSSecureCoding>)object + forKey:(NSString *)key + accessGroup:(nullable NSString *)accessGroup; + +/** + * Removes the object by the given key. + * @param key The key to store the object. If there is an existing object by the key, it will be + * overridden. + * @param accessGroup The Keychain Access Group. + * + * @return Returns which is resolved with `[NSNull null]` on success. + */ +- (FBLPromise<NSNull *> *)removeObjectForKey:(NSString *)key + accessGroup:(nullable NSString *)accessGroup; + +#if TARGET_OS_OSX +/// If not `nil`, then only this keychain will be used to save and read data (see +/// `kSecMatchSearchList` and `kSecUseKeychain`. It is mostly intended to be used by unit tests. +@property(nonatomic, nullable) SecKeychainRef keychainRef; +#endif // TARGET_OSX + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULKeychainUtils.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULKeychainUtils.h new file mode 100644 index 00000000..de4bef2f --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULKeychainUtils.h @@ -0,0 +1,61 @@ +/* + * Copyright 2019 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString *const kGULKeychainUtilsErrorDomain; + +/// Helper functions to access Keychain. +@interface GULKeychainUtils : NSObject + +/** Fetches a keychain item data matching to the provided query. + * @param query A dictionary with Keychain query parameters. See docs for `SecItemCopyMatching` for + * details. + * @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be + * assigned with an error if there is. + * @returns Data for the first Keychain Item matching the provided query or `nil` if there is not + * such an item (`outError` will be `nil` in this case) or an error occurred. + */ ++ (nullable NSData *)getItemWithQuery:(NSDictionary *)query + error:(NSError *_Nullable *_Nullable)outError; + +/** Stores data to a Keychain Item matching to the provided query. An existing Keychain Item + * matching the query parameters will be updated or a new will be created. + * @param item A Keychain Item data to store. + * @param query A dictionary with Keychain query parameters. See docs for `SecItemAdd` and + * `SecItemUpdate` for details. + * @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be + * assigned with an error if there is. + * @returns `YES` when data was successfully stored, `NO` otherwise. + */ ++ (BOOL)setItem:(NSData *)item + withQuery:(NSDictionary *)query + error:(NSError *_Nullable *_Nullable)outError; + +/** Removes a Keychain Item matching to the provided query. + * @param query A dictionary with Keychain query parameters. See docs for `SecItemDelete` for + * details. + * @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be + * assigned with an error if there is. + * @returns `YES` if the item was removed successfully or doesn't exist, `NO` otherwise. + */ ++ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULSecureCoding.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULSecureCoding.h new file mode 100644 index 00000000..8484b395 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/Environment/Private/GULSecureCoding.h @@ -0,0 +1,36 @@ +// Copyright 2019 Google +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** The class wraps `NSKeyedArchiver` and `NSKeyedUnarchiver` API to provide a unified secure coding + * methods for iOS versions before and after 11. + */ +@interface GULSecureCoding : NSObject + ++ (nullable id)unarchivedObjectOfClasses:(NSSet<Class> *)classes + fromData:(NSData *)data + error:(NSError **)outError; + ++ (nullable id)unarchivedObjectOfClass:(Class)class + fromData:(NSData *)data + error:(NSError **)outError; + ++ (nullable NSData *)archivedDataWithRootObject:(id<NSCoding>)object error:(NSError **)outError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h new file mode 100644 index 00000000..0d047818 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/GoogleUtilities/UserDefaults/Private/GULUserDefaults.h @@ -0,0 +1,110 @@ +// Copyright 2018 Google +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/// A thread-safe user defaults that uses C functions from CFPreferences.h instead of +/// `NSUserDefaults`. This is to avoid sending an `NSNotification` when it's changed from a +/// background thread to avoid crashing. // TODO: Insert radar number here. +@interface GULUserDefaults : NSObject + +/// A shared user defaults similar to +[NSUserDefaults standardUserDefaults] and accesses the same +/// data of the standardUserDefaults. ++ (GULUserDefaults *)standardUserDefaults; + +/// Initializes preferences with a suite name that is the same with the NSUserDefaults' suite name. +/// Both of CFPreferences and NSUserDefaults share the same plist file so their data will exactly +/// the same. +/// +/// @param suiteName The name of the suite of the user defaults. +- (instancetype)initWithSuiteName:(nullable NSString *)suiteName; + +#pragma mark - Getters + +/// Searches the receiver's search list for a default with the key 'defaultName' and return it. If +/// another process has changed defaults in the search list, NSUserDefaults will automatically +/// update to the latest values. If the key in question has been marked as ubiquitous via a Defaults +/// Configuration File, the latest value may not be immediately available, and the registered value +/// will be returned instead. +- (nullable id)objectForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will return nil if the value is not an NSArray. +- (nullable NSArray *)arrayForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will return nil if the value +/// is not an NSDictionary. +- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will convert NSNumber values to their NSString +/// representation. If a non-string non-number value is found, nil will be returned. +- (nullable NSString *)stringForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it converts the returned value to an NSInteger. If the +/// value is an NSNumber, the result of -integerValue will be returned. If the value is an NSString, +/// it will be converted to NSInteger if possible. If the value is a boolean, it will be converted +/// to either 1 for YES or 0 for NO. If the value is absent or can't be converted to an integer, 0 +/// will be returned. +- (NSInteger)integerForKey:(NSString *)defaultName; + +/// Similar to -integerForKey:, except that it returns a float, and boolean values will not be +/// converted. +- (float)floatForKey:(NSString *)defaultName; + +/// Similar to -integerForKey:, except that it returns a double, and boolean values will not be +/// converted. +- (double)doubleForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it converts the returned value to a BOOL. If the value +/// is an NSNumber, NO will be returned if the value is 0, YES otherwise. If the value is an +/// NSString, values of "YES" or "1" will return YES, and values of "NO", "0", or any other string +/// will return NO. If the value is absent or can't be converted to a BOOL, NO will be returned. +- (BOOL)boolForKey:(NSString *)defaultName; + +#pragma mark - Setters + +/// Immediately stores a value (or removes the value if `nil` is passed as the value) for the +/// provided key in the search list entry for the receiver's suite name in the current user and any +/// host, then asynchronously stores the value persistently, where it is made available to other +/// processes. +- (void)setObject:(nullable id)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a float to an NSNumber. +- (void)setFloat:(float)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a double to an +/// NSNumber. +- (void)setDouble:(double)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from an NSInteger to an +/// NSNumber. +- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a BOOL to an NSNumber. +- (void)setBool:(BOOL)value forKey:(NSString *)defaultName; + +#pragma mark - Removing Defaults + +/// Equivalent to -[... setObject:nil forKey:defaultName] +- (void)removeObjectForKey:(NSString *)defaultName; + +#pragma mark - Save data + +/// Blocks the calling thread until all in-progress set operations have completed. +- (void)synchronize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/LICENSE b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/LICENSE new file mode 100644 index 00000000..fcce5066 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Firebase, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/README.md b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/README.md new file mode 100644 index 00000000..1d9f0f67 --- /dev/null +++ b/StoneIsland/platforms/ios/Pods/FirebaseInstanceID/README.md @@ -0,0 +1,298 @@ +[](https://cocoapods.org/pods/Firebase) +[](https://cocoapods.org/pods/Firebase) +[](https://cocoapods.org/pods/Firebase) + +[![Actions Status][gh-abtesting-badge]][gh-actions] +[![Actions Status][gh-auth-badge]][gh-actions] +[![Actions Status][gh-core-badge]][gh-actions] +[![Actions Status][gh-crashlytics-badge]][gh-actions] +[![Actions Status][gh-database-badge]][gh-actions] +[![Actions Status][gh-datatransport-badge]][gh-actions] +[![Actions Status][gh-dynamiclinks-badge]][gh-actions] +[![Actions Status][gh-firebasepod-badge]][gh-actions] +[![Actions Status][gh-firestore-badge]][gh-actions] +[![Actions Status][gh-functions-badge]][gh-actions] +[![Actions Status][gh-inappmessaging-badge]][gh-actions] +[![Actions Status][gh-interop-badge]][gh-actions] +[![Actions Status][gh-messaging-badge]][gh-actions] +[![Actions Status][gh-remoteconfig-badge]][gh-actions] +[![Actions Status][gh-storage-badge]][gh-actions] +[![Actions Status][gh-symbolcollision-badge]][gh-actions] +[![Actions Status][gh-zip-badge]][gh-actions] +[](https://travis-ci.org/firebase/firebase-ios-sdk) + +# Firebase Apple Open Source Development + +This repository contains all Apple platform Firebase SDK source except FirebaseAnalytics, +FirebasePerformance, and FirebaseML. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution are at +[Carthage](Carthage.md). + +### Rome + +Instructions for installing binary frameworks via +[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). + +### Using Firebase from a Framework or a library + +[Using Firebase from a Framework or a library](docs/firebase_in_libraries.md) + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + + * Xcode 10.3 (or later) + * CocoaPods 1.7.2 (or later) + * [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self contained Xcode project. See +[Firestore/README.md](Firestore/README.md). + +### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +### Adding a New Firebase Pod + +See [AddNewPod.md](AddNewPod.md). + +### Managing Headers and Imports + +See [HeadersImports.md](HeadersImports.md). + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh) +before creating a PR. + +Travis will verify that any code changes are done in a style compliant way. Install +`clang-format` and `swiftformat`: + +``` +brew install clang-format +brew install swiftformat +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +#### Viewing Code Coverage (Deprecated) + +First, make sure that [xcov](https://github.com/nakiostudio/xcov) is installed with `gem install xcov`. + +After running the `AllUnitTests_iOS` scheme in Xcode, execute +`xcov --workspace Firebase.xcworkspace --scheme AllUnitTests_iOS --output_directory xcov_output` +at Example/ in the terminal. This will aggregate the coverage, and you can run `open xcov_output/index.html` to see the results. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[the Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid GoogleServices-Info.plist and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](FirebaseStorage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### tvOS, macOS, watchOS and Catalyst +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and work on +tvOS, macOS, watchOS and Catalyst. + +For tvOS, checkout the [Sample](Example/tvOSSample). +For watchOS, currently only Messaging and Storage (and their dependencies) have limited support. Checkout the +[Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that macOS, tvOS, watchOS and Catalyst are not officially supported by Firebase, and this +repository is actively developed primarily for iOS. While we can catch basic unit test issues with +Travis, there may be some changes where the SDK no longer works as expected on macOS, tvOS or watchOS. If you +encounter this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the app +has communicated with our servers". This relies on Analytics and will not work on macOS/tvOS/watchOS/Catalyst. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +To install, add a subset of the following to the Podfile: + +``` +pod 'Firebase/ABTesting' # No watchOS support yet +pod 'Firebase/Auth' # No watchOS support yet +pod 'Firebase/Crashlytics' # No watchOS support yet +pod 'Firebase/Database' # No watchOS support yet +pod 'Firebase/Firestore' # No watchOS support yet +pod 'Firebase/Functions' # No watchOS support yet +pod 'Firebase/Messaging' +pod 'Firebase/RemoteConfig' # No watchOS support yet +pod 'Firebase/Storage' +``` + +#### Additional Catalyst Notes + +* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability` +to Build Settings. +* FirebaseFirestore requires signing the +[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). + +[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions +[gh-abtesting-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/abtesting/badge.svg +[gh-auth-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/auth/badge.svg +[gh-core-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/core/badge.svg +[gh-crashlytics-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/crashlytics/badge.svg +[gh-database-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/database/badge.svg +[gh-datatransport-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/datatransport/badge.svg +[gh-dynamiclinks-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/dynamiclinks/badge.svg +[gh-firebasepod-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firebasepod/badge.svg +[gh-firestore-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/firestore/badge.svg +[gh-functions-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/functions/badge.svg +[gh-inappmessaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/inappmessaging/badge.svg +[gh-interop-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/interop/badge.svg +[gh-messaging-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/messaging/badge.svg +[gh-remoteconfig-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/remoteconfig/badge.svg +[gh-storage-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/storage/badge.svg +[gh-symbolcollision-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/symbolcollision/badge.svg +[gh-zip-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/zip/badge.svg |
