From af20a8442d47fc9a6d580bb866932d1b866c66f0 Mon Sep 17 00:00:00 2001 From: Ryan Tobin Date: Mon, 11 Mar 2024 11:59:25 -0700 Subject: [PATCH] Updated Privacy Manifests and some unit tests Summary: Updated Privacy Manifests and some unit tests Reviewed By: jjiang10 Differential Revision: D54685662 fbshipit-source-id: 4bf55d2e21adefe61677f97ea22ede0297e3de70 --- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 4 +- .../Internal/FBSDKAppEventsUtility.m | 14 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m | 7 +- .../FBSDKCoreKit/FBSDKInternalUtility.m | 7 +- .../FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m | 5 +- .../FBSDKDomainConfigurationManager.m | 6 +- .../FBSDKServerConfiguration.m | 1 + .../FBSDKCoreKit/PrivacyInfo.xcprivacy | 12 ++ FBSDKCoreKit/FBSDKCoreKit/Settings.swift | 10 + .../DomainHandlerTests.swift | 4 +- .../GraphRequestConnectionTests.swift | 8 +- .../FBSDKCoreKitTests/GraphRequestTests.swift | 10 +- .../AppEvents/AppEventsUtilityTests.swift | 172 ++++++++++++++++++ .../SKAdNetworkReporterTests.swift | 13 +- .../SKAdNetworkReporterTestsV2.swift | 19 +- .../FBSDKCoreKit_Basics/PrivacyInfo.xcprivacy | 15 +- Package.swift | 22 ++- .../Resources/PrivacyInfo.xcprivacy | 21 +++ Sources/FacebookBasics/Exports.swift | 11 ++ .../Resources/PrivacyInfo.xcprivacy | 34 ++++ .../Resources/PrivacyInfo.xcprivacy | 63 +++++++ 21 files changed, 407 insertions(+), 51 deletions(-) create mode 100644 Sources/FacebookAEM/Resources/PrivacyInfo.xcprivacy create mode 100644 Sources/FacebookBasics/Exports.swift create mode 100644 Sources/FacebookBasics/Resources/PrivacyInfo.xcprivacy create mode 100644 Sources/FacebookCore/Resources/PrivacyInfo.xcprivacy diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index a585f884b5..83881ad193 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -1478,7 +1478,9 @@ - (void)validateConfiguration { [self validateConfiguration]; - accessToken = accessToken ?: FBSDKAccessToken.currentAccessToken; + if (accessToken == nil && (![[FBSDKDomainHandler sharedInstance] isDomainHandlingEnabled] || self.settings.isAdvertiserTrackingEnabled)) { + accessToken = FBSDKAccessToken.currentAccessToken; + } // Rules for how we use the attribution ID / advertiser ID for an 'custom_audience_third_party_id' Graph API request // 1) if the OS tells us that the user has Limited Ad Tracking, then just don't send, and return a nil in the token. diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m index 7bb5fbd966..6a00419a3f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m @@ -373,26 +373,30 @@ - (BOOL)validateIdentifier:(nullable NSString *)identifier } // Given a candidate token (which may be nil), find the real token to string to use. -// Precedence: 1) provided token, 2) current token, 3) app | client token, 4) fully anonymous session. +// Precedence: 1) provided token, 2) current token only if ATE is true, 3) app | client token, 4) fully anonymous session. - (nullable NSString *)tokenStringToUseFor:(nullable FBSDKAccessToken *)token loggingOverrideAppID:(nullable NSString *)loggingOverrideAppID { - if (!token) { + if (!token && (![[FBSDKDomainHandler sharedInstance] isDomainHandlingEnabled] || self.settings.isAdvertiserTrackingEnabled)) { token = FBSDKAccessToken.currentAccessToken; } + if (token && token.isExpired) { + token = nil; + } + NSString *appID = loggingOverrideAppID ?: token.appID ?: self.settings.appID; NSString *tokenString = token.tokenString; NSString *clientTokenString = self.settings.clientToken; - if (![appID isEqualToString:token.appID]) { + if (!token || ![appID isEqualToString:token.appID]) { // If there's a logging override app id present // then we don't want to use the client token since the client token // is intended to match up with the primary app id // and AppEvents doesn't require a client token. - if (clientTokenString && loggingOverrideAppID) { + if (clientTokenString && loggingOverrideAppID && loggingOverrideAppID != self.settings.appID && loggingOverrideAppID != token.appID) { tokenString = nil; - } else if (clientTokenString && appID && ([appID isEqualToString:token.appID] || token == nil)) { + } else if (clientTokenString && appID && (token == nil || [appID isEqualToString:token.appID])) { tokenString = [NSString stringWithFormat:@"%@|%@", appID, clientTokenString]; } else if (appID) { tokenString = nil; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m index 0610be6150..4895621efd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m @@ -279,9 +279,10 @@ + (BOOL)supportsSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { NSString *appID = [decoder decodeObjectOfClass:NSString.class forKey:FBSDK_ACCESSTOKEN_APPID_KEY]; - NSSet *declinedPermissions = [decoder decodeObjectOfClass:NSSet.class forKey:FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY]; - NSSet *expiredPermissions = [decoder decodeObjectOfClass:NSSet.class forKey:FBSDK_ACCESSTOKEN_EXPIREDPERMISSIONS_KEY]; - NSSet *permissions = [decoder decodeObjectOfClass:NSSet.class forKey:FBSDK_ACCESSTOKEN_PERMISSIONS_KEY]; + NSSet *classes = [NSSet setWithArray:@[NSSet.class, NSString.class]]; + NSSet *declinedPermissions = [decoder decodeObjectOfClasses:classes forKey:FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY]; + NSSet *expiredPermissions = [decoder decodeObjectOfClasses:classes forKey:FBSDK_ACCESSTOKEN_EXPIREDPERMISSIONS_KEY]; + NSSet *permissions = [decoder decodeObjectOfClasses:classes forKey:FBSDK_ACCESSTOKEN_PERMISSIONS_KEY]; NSString *tokenString = [decoder decodeObjectOfClass:NSString.class forKey:FBSDK_ACCESSTOKEN_TOKENSTRING_KEY]; NSString *userID = [decoder decodeObjectOfClass:NSString.class forKey:FBSDK_ACCESSTOKEN_USERID_KEY]; NSDate *refreshDate = [decoder decodeObjectOfClass:NSDate.class forKey:FBSDK_ACCESSTOKEN_REFRESHDATE_KEY]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKInternalUtility.m index f36e201f84..91979f73f1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKInternalUtility.m @@ -496,7 +496,12 @@ - (void)detectFatalTrackingDomainsConfig @"Frameworks/FBSDKCoreKit_Basics.framework", @"Frameworks/FBAEMKit.framework", @"Frameworks/FBSDKLoginKit.framework", - @"Frameworks/FBSDKShareKit.framework"]; + @"Frameworks/FBSDKShareKit.framework", + @"Facebook_FacebookAEM.bundle", + @"Facebook_FacebookBasics.bundle", + @"Facebook_FacebookCore.bundle", + @"Facebook_FacebookLogin.bundle", + @"Facebook_FacebookShare.bundle"]; for (NSString *subdirectory in subdirectories) { NSString *subdir = [subdirectory isKindOfClass:[NSNull class]] ? nil: subdirectory; NSArray *privacyInfoUrls = [[NSBundle mainBundle] URLsForResourcesWithExtension:@"xcprivacy" subdirectory:subdir]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m index 323f4dac08..f619e62475 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m @@ -362,13 +362,14 @@ - (BOOL)hasAttachments + (BOOL)isForFetchingDomainConfiguration:(id)request { NSString *appID = self.class.settings.appID; - if (![request.graphPath isEqualToString:appID]) { + NSString *expectedGraphPath = [NSString stringWithFormat:@"%@/%@", appID, kDomainConfigurationDomainInfoField]; + if (![request.graphPath isEqualToString:expectedGraphPath]) { return NO; } if (![request.HTTPMethod isEqualToString:FBSDKHTTPMethodGET]) { return NO; } - if (!request.parameters || ![[request.parameters objectForKey:@"fields"] isEqualToString:kDomainConfigurationDomainInfoField]) { + if (!request.parameters || ![[request.parameters objectForKey:@"fields"] isEqualToString:@""]) { return NO; } return YES; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/DomainHandler/FBSDKDomainConfigurationManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/DomainHandler/FBSDKDomainConfigurationManager.m index 3be8e6137d..e12ebd0124 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/DomainHandler/FBSDKDomainConfigurationManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/DomainHandler/FBSDKDomainConfigurationManager.m @@ -168,9 +168,9 @@ - (void)processLoadRequestResponse:(id)result error:(nullable NSError *)error - (id)requestToLoadDomainConfiguration:(NSString *)appID { - NSDictionary *parameters = @{ @"fields" : DOMAIN_CONFIGURATION_DOMAIN_INFO_FIELD }; - - return [self.graphRequestFactory createGraphRequestWithGraphPath:appID + NSDictionary *parameters = @{ @"fields" : @"" }; + NSString *graphPath = [NSString stringWithFormat:@"%@/%@", appID, DOMAIN_CONFIGURATION_DOMAIN_INFO_FIELD]; + return [self.graphRequestFactory createGraphRequestWithGraphPath:graphPath parameters:parameters tokenString:nil HTTPMethod:nil diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m index 6a20830d76..214eec4c7e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m @@ -261,6 +261,7 @@ - (instancetype)initWithCoder:(NSCoder *)decoder [NSDictionary class], NSString.class, NSArray.class, + NSNumber.class, nil]; NSArray *> *eventBindings = [decoder decodeObjectOfClasses:eventBindingsClasses forKey:FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS]; NSSet *dictionaryClasses = [NSSet setWithObjects: diff --git a/FBSDKCoreKit/FBSDKCoreKit/PrivacyInfo.xcprivacy b/FBSDKCoreKit/FBSDKCoreKit/PrivacyInfo.xcprivacy index 864c47fd71..36c7a8712c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/PrivacyInfo.xcprivacy +++ b/FBSDKCoreKit/FBSDKCoreKit/PrivacyInfo.xcprivacy @@ -15,6 +15,18 @@ NSPrivacyCollectedDataTypes + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeOtherDataTypes + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAnalytics + + NSPrivacyCollectedDataType NSPrivacyCollectedDataTypeCrashData diff --git a/FBSDKCoreKit/FBSDKCoreKit/Settings.swift b/FBSDKCoreKit/FBSDKCoreKit/Settings.swift index 30617d155f..271cf6ccb6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Settings.swift +++ b/FBSDKCoreKit/FBSDKCoreKit/Settings.swift @@ -354,6 +354,16 @@ public final class Settings: NSObject, SettingsProtocol, SettingsLogging, _Clien */ public var isAdvertiserTrackingEnabled: Bool { get { advertisingTrackingStatus == .allowed } + + @available( + *, + deprecated, + message: """ + The setAdvertiserTrackingEnabled flag is not used for FBSDK v17+ on iOS 17+ \ + as the FBSDK v17+ now relies on ATTrackingManager.trackingAuthorizationStatus \ + to accurately represent ATT permission for users of your app. + """ + ) set(isNewlyAllowed) { if _DomainHandler.sharedInstance().isDomainHandlingEnabled() { // swiftlint:disable:next line_length diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/DomainHandlerTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/DomainHandlerTests.swift index f501090a5d..397a3cecfd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/DomainHandlerTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/DomainHandlerTests.swift @@ -99,8 +99,8 @@ final class DomainHandlerTests: XCTestCase { XCTFail("Should have an app id") return } - let parameters = ["fields": "server_domain_infos"] - let domainConfigRequest = GraphRequest(graphPath: appID, parameters: parameters, httpMethod: .get) + let parameters = ["fields": ""] + let domainConfigRequest = GraphRequest(graphPath: "\(appID)/server_domain_infos", parameters: parameters, httpMethod: .get) let urlPrefix = _DomainHandler.sharedInstance().getURLPrefix( forSingleRequest: domainConfigRequest, isAdvertiserTrackingEnabled: true diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestConnectionTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestConnectionTests.swift index cf91841207..dbf18cd44b 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestConnectionTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestConnectionTests.swift @@ -800,8 +800,8 @@ final class GraphRequestConnectionTests: XCTestCase, GraphRequestConnectionDeleg return } GraphRequestConnection.resetDidFetchDomainConfiguration() - let parameters = ["fields": "server_domain_infos"] - let domainConfigRequest = GraphRequest(graphPath: appID, parameters: parameters, httpMethod: .get) + let parameters = ["fields": ""] + let domainConfigRequest = GraphRequest(graphPath: "\(appID)/server_domain_infos", parameters: parameters, httpMethod: .get) connection.add(domainConfigRequest) { _, _, _ in } connection.start() XCTAssertEqual( @@ -2054,8 +2054,8 @@ final class GraphRequestConnectionTests: XCTestCase, GraphRequestConnectionDeleg } func testShouldPiggyBackDomainConfigurationRequest() { - let parameters = ["fields": "server_domain_infos"] - let domainConfigRequest = GraphRequest(graphPath: appID, parameters: parameters, httpMethod: .get) + let parameters = ["fields": ""] + let domainConfigRequest = GraphRequest(graphPath: "\(appID)/server_domain_infos", parameters: parameters, httpMethod: .get) connection.add(domainConfigRequest) { _, _, _ in } if #available(iOS 14.5, *) { XCTAssertFalse( diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestTests.swift index 13c65a68db..3396f696fa 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestTests.swift @@ -461,9 +461,9 @@ final class GraphRequestTests: XCTestCase { XCTFail("Should have an app id") return } - let parameters = ["fields": "server_domain_infos"] + let parameters = ["fields": ""] let domainConfigRequest1 = graphRequestFactory.createGraphRequest( - withGraphPath: appID, + withGraphPath: "\(appID)/server_domain_infos", parameters: parameters, tokenString: nil, httpMethod: nil, @@ -474,7 +474,7 @@ final class GraphRequestTests: XCTestCase { "Request is for fetching the domain configuration" ) - let domainConfigRequest2 = GraphRequest(graphPath: appID, parameters: parameters, httpMethod: .get) + let domainConfigRequest2 = GraphRequest(graphPath: "\(appID)/server_domain_infos", parameters: parameters, httpMethod: .get) XCTAssertTrue( GraphRequest.isForFetchingDomainConfiguration(request: domainConfigRequest2), "Request is for fetching the domain configuration" @@ -505,8 +505,8 @@ final class GraphRequestTests: XCTestCase { ) let failingRequest5 = GraphRequest( - graphPath: appID, - parameters: ["fields": "server_domain_infos,test_field,name,app_events_feature_bitmask"], + graphPath: "\(appID)/server_domain_infos", + parameters: ["fields": "test_field,name,app_events_feature_bitmask"], httpMethod: .get ) XCTAssertFalse( diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AppEventsUtilityTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AppEventsUtilityTests.swift index 94ab6693b2..12dfe3c917 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AppEventsUtilityTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AppEventsUtilityTests.swift @@ -586,6 +586,7 @@ final class AppEventsUtilityTests: XCTestCase { } func testTokenStringWithAccessTokenWithoutAppIdWithClientToken() { + settings.isAdvertiserTrackingEnabled = true AccessToken.current = SampleAccessTokens.validToken settings.appID = nil settings.clientToken = "toktok" @@ -598,7 +599,29 @@ final class AppEventsUtilityTests: XCTestCase { ) } + func testTokenStringWithAccessTokenWithoutAppIdWithClientTokenAdvertiserTrackingDisabled() { + settings.isAdvertiserTrackingEnabled = false + AccessToken.current = SampleAccessTokens.validToken + settings.appID = nil + settings.clientToken = "toktok" + let tokenString = appEventsUtility.tokenStringToUse(for: nil, loggingOverrideAppID: nil) + + if _DomainHandler.sharedInstance().isDomainHandlingEnabled() { + XCTAssertNil( + tokenString, + "tokenString should be nil" + ) + } else { + XCTAssertEqual( + tokenString, + SampleAccessTokens.validToken.tokenString, + "Should use the current access token" + ) + } + } + func testTokenStringWithAccessTokenWithoutAppIdWithoutClientToken() { + settings.isAdvertiserTrackingEnabled = true AccessToken.current = SampleAccessTokens.validToken settings.appID = nil settings.clientToken = nil @@ -613,7 +636,28 @@ final class AppEventsUtilityTests: XCTestCase { ) } + func testTokenStringWithAccessTokenWithoutAppIdWithoutClientTokenAdvertiserTrackingDisabled() { + settings.isAdvertiserTrackingEnabled = false + AccessToken.current = SampleAccessTokens.validToken + settings.appID = nil + settings.clientToken = nil + let tokenString = appEventsUtility.tokenStringToUse(for: nil, loggingOverrideAppID: nil) + if _DomainHandler.sharedInstance().isDomainHandlingEnabled() { + XCTAssertNil( + tokenString, + "tokenString should be nil" + ) + } else { + XCTAssertEqual( + tokenString, + SampleAccessTokens.validToken.tokenString, + "Should use the current access token" + ) + } + } + func testTokenStringWithAccessTokenWithAppIdWithoutClientToken() { + settings.isAdvertiserTrackingEnabled = true AccessToken.current = SampleAccessTokens.validToken settings.appID = "456" settings.clientToken = nil @@ -628,7 +672,28 @@ final class AppEventsUtilityTests: XCTestCase { ) } + func testTokenStringWithAccessTokenWithAppIdWithoutClientTokenAdvertiserTrackingDisabled() { + settings.isAdvertiserTrackingEnabled = false + AccessToken.current = SampleAccessTokens.validToken + settings.appID = "456" + settings.clientToken = nil + let tokenString = appEventsUtility.tokenStringToUse(for: nil, loggingOverrideAppID: nil) + if _DomainHandler.sharedInstance().isDomainHandlingEnabled() { + XCTAssertNil( + tokenString, + "tokenString should be nil" + ) + } else { + XCTAssertEqual( + tokenString, + SampleAccessTokens.validToken.tokenString, + "Should use the current access token" + ) + } + } + func testTokenStringWithAccessTokenWithAppIdWithClientToken() { + settings.isAdvertiserTrackingEnabled = true AccessToken.current = SampleAccessTokens.validToken settings.appID = "456" settings.clientToken = "toktok" @@ -640,6 +705,27 @@ final class AppEventsUtilityTests: XCTestCase { ) } + func testTokenStringWithAccessTokenWithAppIdWithClientTokenAdvertiserTrackingDisabled() { + settings.isAdvertiserTrackingEnabled = false + AccessToken.current = SampleAccessTokens.validToken + settings.appID = "456" + settings.clientToken = "toktok" + let tokenString = appEventsUtility.tokenStringToUse(for: nil, loggingOverrideAppID: nil) + if _DomainHandler.sharedInstance().isDomainHandlingEnabled() { + XCTAssertEqual( + tokenString, + "456|toktok", + "Should default to the client token" + ) + } else { + XCTAssertEqual( + tokenString, + SampleAccessTokens.validToken.tokenString, + "Should use the current access token" + ) + } + } + func testTokenStringWithoutAccessTokenWithoutAppIdWithoutClientTokenWithLoggingAppID() { AccessToken.current = nil settings.appID = nil @@ -729,6 +815,7 @@ final class AppEventsUtilityTests: XCTestCase { } func testTokenStringWithAccessTokenWithAppIdWithClientTokenWithLoggingAppIDMatching() { + settings.isAdvertiserTrackingEnabled = true AccessToken.current = SampleAccessTokens.validToken settings.appID = "456" settings.clientToken = "toktok" @@ -746,6 +833,91 @@ final class AppEventsUtilityTests: XCTestCase { ) } + func testTokenStringWithAccessTokenWithAppIdWithClientTokenWithLoggingAppIDMatchingAdvertiserTrackingDisabled() { + settings.isAdvertiserTrackingEnabled = false + AccessToken.current = SampleAccessTokens.validToken + settings.appID = "appID123" + settings.clientToken = "toktok" + let tokenString = appEventsUtility.tokenStringToUse( + for: nil, + loggingOverrideAppID: "appID123" + ) + if _DomainHandler.sharedInstance().isDomainHandlingEnabled() { + XCTAssertEqual( + tokenString, + "appID123|toktok", + "Should default to the client token" + ) + } else { + XCTAssertEqual( + tokenString, + SampleAccessTokens.validToken.tokenString, + "Should use the current access token" + ) + } + } + + func testTokenStringWithAccessTokenWithAppIdWithClientTokenWithLoggingAppIDMatchingAdvertiserTrackingDisabled2() { + settings.isAdvertiserTrackingEnabled = false + AccessToken.current = SampleAccessTokens.validToken + settings.appID = "456" + settings.clientToken = "toktok" + let tokenString = appEventsUtility.tokenStringToUse( + for: nil, + loggingOverrideAppID: "456" + ) + if _DomainHandler.sharedInstance().isDomainHandlingEnabled() { + XCTAssertEqual( + tokenString, + "456|toktok", + "Should default to the client token" + ) + } else { + XCTAssertNil( + tokenString, + "tokenString should be nil" + ) + } + } + + func testExpiredTokenAdvertiserTrackingEnabled() { + settings.isAdvertiserTrackingEnabled = true + AccessToken.current = SampleAccessTokens.expiredToken + settings.appID = "456" + settings.clientToken = "toktok" + let tokenString = appEventsUtility.tokenStringToUse(for: nil, loggingOverrideAppID: nil) + XCTAssertEqual( + tokenString, + "456|toktok", + "Should default to the client token" + ) + } + + func testExpiredTokenAdvertiserTrackingDisabled() { + settings.isAdvertiserTrackingEnabled = false + AccessToken.current = SampleAccessTokens.expiredToken + settings.appID = "456" + settings.clientToken = "toktok" + let tokenString = appEventsUtility.tokenStringToUse(for: nil, loggingOverrideAppID: nil) + XCTAssertEqual( + tokenString, + "456|toktok", + "Should default to the client token" + ) + } + + func testTokenWithProvidedTokenString() { + let token = SampleAccessTokens.validToken + let tokenString = appEventsUtility.tokenStringToUse(for: token, loggingOverrideAppID: nil) + XCTAssertEqual(tokenString, token.tokenString) + } + + func testTokenWithProvidedTokenString2() { + let token = SampleAccessTokens.validToken + let tokenString = appEventsUtility.tokenStringToUse(for: token, loggingOverrideAppID: "789") + XCTAssertNil(tokenString) + } + func testDefaultDependencies() { appEventsUtility.reset() XCTAssertNil( diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTests.swift index 9b335b465b..39004eabe9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTests.swift @@ -244,11 +244,9 @@ final class SKAdNetworkReporterTests: XCTestCase { XCTAssertFalse(skAdNetworkReporter.shouldCutoff()) // Case 2: timestamp is already expired - let calendar = Calendar(identifier: .gregorian) - var addComponents = DateComponents() - addComponents.day = -2 + let secondsInPast = 2 * 24 * 60 * 60 + let expiredDate = Date().addingTimeInterval(-TimeInterval(secondsInPast)) - let expiredDate = calendar.date(byAdding: addComponents, to: Date()) userDefaultsSpy.set( expiredDate, forKey: "com.facebook.sdk:FBSDKSettingsInstallTimestamp" @@ -261,11 +259,8 @@ final class SKAdNetworkReporterTests: XCTestCase { func testCutoffWhenTimeBucketIsAvailable() { if #available(iOS 14.0, *) { skAdNetworkReporter.configuration = defaultConfiguration - let today = Date() - let calendar = Calendar(identifier: .gregorian) - var addComponents = DateComponents() - addComponents.day = -2 - let expiredDate = calendar.date(byAdding: addComponents, to: today) + let secondsInPast = 2 * 24 * 60 * 60 + let expiredDate = Date().addingTimeInterval(-TimeInterval(secondsInPast)) userDefaultsSpy.set( expiredDate, forKey: "com.facebook.sdk:FBSDKSettingsInstallTimestamp" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTestsV2.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTestsV2.swift index 950516fdf9..677753fabf 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTestsV2.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/SKAdNetworkReporterTestsV2.swift @@ -277,11 +277,9 @@ final class SKAdNetworkReporterTestsV2: XCTestCase { XCTAssertFalse(skAdNetworkReporter.shouldCutoff()) // Case 2: timestamp is already expired - let calendar = Calendar(identifier: .gregorian) - var addComponents = DateComponents() - addComponents.day = -2 + let secondsInPast = 2 * 24 * 60 * 60 + let expiredDate = Date().addingTimeInterval(-TimeInterval(secondsInPast)) - let expiredDate = calendar.date(byAdding: addComponents, to: Date()) userDefaultsSpy.set( expiredDate, forKey: "com.facebook.sdk:FBSDKSettingsInstallTimestamp" @@ -322,11 +320,8 @@ final class SKAdNetworkReporterTestsV2: XCTestCase { func testUpdateConversionValueWhenShouldCutoff() { skAdNetworkReporter.configuration = defaultConfiguration // For v4, fine conversion value will not be updated for 2nd and 3rd postbacks - let calendar = Calendar(identifier: .gregorian) - var addComponents = DateComponents() - addComponents.day = -4 - - let expiredDate = calendar.date(byAdding: addComponents, to: Date()) + let secondsInPast = 4 * 24 * 60 * 60 + let expiredDate = Date().addingTimeInterval(-TimeInterval(secondsInPast)) userDefaultsSpy.set( expiredDate, forKey: "com.facebook.sdk:FBSDKSettingsInstallTimestamp" @@ -354,11 +349,9 @@ final class SKAdNetworkReporterTestsV2: XCTestCase { func testUpdateCoarseConversionValueWhenShouldNotCutoff() { skAdNetworkReporter.configuration = defaultConfiguration // For v4, coarse conversion value will be updated for all postback windows - let calendar = Calendar(identifier: .gregorian) - var addComponents = DateComponents() - addComponents.day = -20 + let secondsInPast = 20 * 24 * 60 * 60 + let expiredDate = Date().addingTimeInterval(-TimeInterval(secondsInPast)) - let expiredDate = calendar.date(byAdding: addComponents, to: Date()) userDefaultsSpy.set( expiredDate, forKey: "com.facebook.sdk:FBSDKSettingsInstallTimestamp" diff --git a/FBSDKCoreKit_Basics/FBSDKCoreKit_Basics/PrivacyInfo.xcprivacy b/FBSDKCoreKit_Basics/FBSDKCoreKit_Basics/PrivacyInfo.xcprivacy index 6138992435..ea086cf64b 100644 --- a/FBSDKCoreKit_Basics/FBSDKCoreKit_Basics/PrivacyInfo.xcprivacy +++ b/FBSDKCoreKit_Basics/FBSDKCoreKit_Basics/PrivacyInfo.xcprivacy @@ -5,7 +5,20 @@ NSPrivacyTracking NSPrivacyCollectedDataTypes - + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeOtherDataTypes + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAnalytics + + + NSPrivacyAccessedAPITypes diff --git a/Package.swift b/Package.swift index 1727cb48fb..324b7f7051 100644 --- a/Package.swift +++ b/Package.swift @@ -52,6 +52,7 @@ let package = Package( targets: [ // The kernel of the SDK .Prefixed.basics, + .basics, /* The legacy Objective-C implementation that will be converted to Swift. @@ -102,7 +103,7 @@ let package = Package( ) extension Product { - static let basics = library(name: .basics, targets: [.Prefixed.basics]) + static let basics = library(name: .basics, targets: [.basics, .Prefixed.basics]) static let core = library(name: .core, targets: [.core, .Prefixed.core]) static let login = library(name: .login, targets: [.login]) static let share = library(name: .share, targets: [.share, .Prefixed.share]) @@ -137,11 +138,28 @@ extension Target { "https://github.com/facebook/facebook-ios-sdk/releases/download/v16.3.1/\(targetName)-Static_XCFramework.zip" } - static let aem = target(name: .aem, dependencies: [.Prefixed.aem]) + static let basics = target( + name: .basics, + dependencies: [.Prefixed.basics], + resources: [ + .copy("Resources/PrivacyInfo.xcprivacy"), + ] + ) + + static let aem = target( + name: .aem, + dependencies: [.Prefixed.aem], + resources: [ + .copy("Resources/PrivacyInfo.xcprivacy"), + ] + ) static let core = target( name: .core, dependencies: [.aem, .Prefixed.basics, .Prefixed.core], + resources: [ + .copy("Resources/PrivacyInfo.xcprivacy"), + ], linkerSettings: [ .cPlusPlusLibrary, .zLibrary, diff --git a/Sources/FacebookAEM/Resources/PrivacyInfo.xcprivacy b/Sources/FacebookAEM/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..93cac16c23 --- /dev/null +++ b/Sources/FacebookAEM/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,21 @@ + + + + + NSPrivacyTracking + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + + diff --git a/Sources/FacebookBasics/Exports.swift b/Sources/FacebookBasics/Exports.swift new file mode 100644 index 0000000000..8215c5c76d --- /dev/null +++ b/Sources/FacebookBasics/Exports.swift @@ -0,0 +1,11 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if canImport(FBSDKCoreKit_Basics) +@_exported import FBSDKCoreKit_Basics +#endif diff --git a/Sources/FacebookBasics/Resources/PrivacyInfo.xcprivacy b/Sources/FacebookBasics/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..ea086cf64b --- /dev/null +++ b/Sources/FacebookBasics/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,34 @@ + + + + + NSPrivacyTracking + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeOtherDataTypes + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAnalytics + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + + + + diff --git a/Sources/FacebookCore/Resources/PrivacyInfo.xcprivacy b/Sources/FacebookCore/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000000..36c7a8712c --- /dev/null +++ b/Sources/FacebookCore/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,63 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeOtherDataTypes + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAnalytics + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeCrashData + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeDeviceID + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeThirdPartyAdvertising + NSPrivacyCollectedDataTypePurposeAppFunctionality + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + ep1.facebook.com + + +