diff --git a/IdentityCore/IdentityCore.xcodeproj/project.pbxproj b/IdentityCore/IdentityCore.xcodeproj/project.pbxproj index b29954f22..8564d8e3f 100644 --- a/IdentityCore/IdentityCore.xcodeproj/project.pbxproj +++ b/IdentityCore/IdentityCore.xcodeproj/project.pbxproj @@ -148,6 +148,8 @@ 232C658C2138BED1002A41FE /* MSIDAADAuthorityMetadataResponseSerializerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 232C658B2138BED0002A41FE /* MSIDAADAuthorityMetadataResponseSerializerTests.m */; }; 232C658D2138BED1002A41FE /* MSIDAADAuthorityMetadataResponseSerializerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 232C658B2138BED0002A41FE /* MSIDAADAuthorityMetadataResponseSerializerTests.m */; }; 23368C0326436E4100374103 /* MSIDRequestParameters+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 23368C0226436E4100374103 /* MSIDRequestParameters+Internal.h */; }; + 233827912BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 233827902BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m */; }; + 233827922BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 233827902BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m */; }; 2338ECCB208A675D00809B9E /* MSIDAADRequestErrorHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 2338ECC8208A675D00809B9E /* MSIDAADRequestErrorHandler.m */; }; 2338ECCC208A675D00809B9E /* MSIDAADRequestErrorHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 2338ECC8208A675D00809B9E /* MSIDAADRequestErrorHandler.m */; }; 2338ECCD208A675D00809B9E /* MSIDHttpRequestErrorHandling.h in Headers */ = {isa = PBXBuildFile; fileRef = 2338ECC9208A675D00809B9E /* MSIDHttpRequestErrorHandling.h */; }; @@ -191,6 +193,10 @@ 23419F83239B36F500EA78C5 /* MSIDAccountIdentifierTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 23419F81239B36F500EA78C5 /* MSIDAccountIdentifierTests.m */; }; 234858DF20490EF8004FBC3C /* MSIDDefaultTokenCacheIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 965981041FF4C9B400E31CDE /* MSIDDefaultTokenCacheIntegrationTests.m */; }; 2348C313221B4EFF00498D56 /* MSIDBasicContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 2323A6C42217AD4A00727088 /* MSIDBasicContext.m */; }; + 234A0BE02BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 234A0BDF2BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m */; }; + 234A0BE12BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 234A0BDF2BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m */; }; + 234A0BE32BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 234A0BE22BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m */; }; + 234A0BE42BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 234A0BE22BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m */; }; 234DE5832A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 234DE5812A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.h */; }; 234DE5842A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 234DE5822A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.m */; }; 234DE5852A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 234DE5822A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.m */; }; @@ -2060,6 +2066,7 @@ 232C65872138BDC5002A41FE /* MSIDAADAuthorityMetadataResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDAADAuthorityMetadataResponse.m; sourceTree = ""; }; 232C658B2138BED0002A41FE /* MSIDAADAuthorityMetadataResponseSerializerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDAADAuthorityMetadataResponseSerializerTests.m; sourceTree = ""; }; 23368C0226436E4100374103 /* MSIDRequestParameters+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MSIDRequestParameters+Internal.h"; sourceTree = ""; }; + 233827902BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDBrowserNativeMessageGetTokenResponseTests.m; sourceTree = ""; }; 2338ECC8208A675D00809B9E /* MSIDAADRequestErrorHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSIDAADRequestErrorHandler.m; sourceTree = ""; }; 2338ECC9208A675D00809B9E /* MSIDHttpRequestErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSIDHttpRequestErrorHandling.h; sourceTree = ""; }; 2338ECCA208A675D00809B9E /* MSIDAADRequestErrorHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSIDAADRequestErrorHandler.h; sourceTree = ""; }; @@ -2089,6 +2096,8 @@ 23419F7B239B0D1C00EA78C5 /* MSIDAuthorityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDAuthorityTests.m; sourceTree = ""; }; 23419F7E239B33E400EA78C5 /* MSIDAADV2TokenResponseTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDAADV2TokenResponseTests.m; sourceTree = ""; }; 23419F81239B36F500EA78C5 /* MSIDAccountIdentifierTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDAccountIdentifierTests.m; sourceTree = ""; }; + 234A0BDF2BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDBrowserNativeMessageSignOutResponseTests.m; sourceTree = ""; }; + 234A0BE22BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDBrowserNativeMessageSignOutRequestTests.m; sourceTree = ""; }; 234DE5812A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSIDBrowserNativeMessageRequest.h; sourceTree = ""; }; 234DE5822A9456F600E244B3 /* MSIDBrowserNativeMessageRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSIDBrowserNativeMessageRequest.m; sourceTree = ""; }; 2352AF302AA7C7B700FA2253 /* MSIDBrowserNativeMessageGetTokenResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSIDBrowserNativeMessageGetTokenResponse.h; sourceTree = ""; }; @@ -5612,6 +5621,9 @@ B431B5252AF05B3F0020CD3D /* MSIDBrokerOperationPasskeyCredentialRequestTests.m */, B431B5282AF05C890020CD3D /* MSIDBrokerOperationGetPasskeyAssertionResponseTests.m */, B431B52B2AF19E230020CD3D /* MSIDBrokerOperationGetPasskeyCredentialResponseTests.m */, + 233827902BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m */, + 234A0BDF2BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m */, + 234A0BE22BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m */, 586DE2A72BC884600082137F /* MSIDAuthenticationSchemeSshCertTest.m */, ); path = tests; @@ -6796,6 +6808,7 @@ B2936F7920ABF8310050C585 /* MSIDLegacyAccessTokenTests.m in Sources */, 60747FF62354F04F00C5308F /* MSIDBrokerOperationGetAccountsRequestTests.m in Sources */, 586CD77E293FD77100550710 /* MSIDRequestControllerFactoryTests.m in Sources */, + 233827912BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m in Sources */, 238EF086209161830035ABE6 /* MSIDAADJsonResponsePreprocessorTests.m in Sources */, B20657C61FC9265800412B7D /* MSIDTelemetryExtensionsTests.m in Sources */, B2BE924F21A24A5300F5AB8C /* MSIDSilentControllerIntegrationTests.m in Sources */, @@ -6837,6 +6850,7 @@ 963553BF20CA7C52005235E5 /* MSIDSystemWebviewControllerTests.m in Sources */, 963CFAF320AD817600BDA25F /* MSIDWebviewAuthorizationTests.m in Sources */, B2525C752330623E006FBA4B /* MSIDMainThreadUtilTests.m in Sources */, + 234A0BE32BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m in Sources */, 2338ECDA208A7CBD00809B9E /* MSIDAADRequestErrorHandlerTests.m in Sources */, 23CA0C4A220A3B6900768729 /* MSIDPKeyAuthHandlerTests.m in Sources */, 80B6BF3C2480A3E30031BFE8 /* MSIDWorkPlaceJoinUtilTests.m in Sources */, @@ -6870,6 +6884,7 @@ B2DD4B4020A934170047A66E /* MSIDCredentialTypeTests.m in Sources */, 580E254E271A1815003D1795 /* MSIDBrokerOperationGetSsoCookiesResponseTests.m in Sources */, B2C708DF219BC67F00D917B8 /* MSIDDefaultSilentTokenRequestTests.m in Sources */, + 234A0BE02BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m in Sources */, B210F4501FDDF5D2005A8F76 /* MSIDClientInfoTests.m in Sources */, 6080B9A523886DD9009B1322 /* MSIDBrokerOperationGetDeviceInfoRequestTests.m in Sources */, B431B5292AF05C890020CD3D /* MSIDBrokerOperationGetPasskeyAssertionResponseTests.m in Sources */, @@ -7324,6 +7339,7 @@ B2DD5B9C20475E780084313F /* MSIDBaseTokenTests.m in Sources */, 239DF9C420E04BC9002D428B /* MSIDADFSAuthorityTests.m in Sources */, B431B5422AF1C6C10020CD3D /* MSIDSSOExtensionPasskeyCredentialRequestMock.m in Sources */, + 233827922BC8C40C0079C82F /* MSIDBrowserNativeMessageGetTokenResponseTests.m in Sources */, 23419F6123974C0D00EA78C5 /* MSIDBrokerOperationTokenRequestTests.m in Sources */, 236CB13F2A609A1B005A6F5F /* MSIDBrokerOperationBrowserNativeMessageRequestTests.m in Sources */, B2807FFF204CB25E00944D89 /* MSIDTokenResponseTests.m in Sources */, @@ -7335,6 +7351,7 @@ B20657C71FC9265800412B7D /* MSIDTelemetryExtensionsTests.m in Sources */, 239DF9C720E04ECF002D428B /* MSIDAuthorityIntegrationTests.m in Sources */, B2E7698F206096A7000F3F2B /* MSIDTelemetryCacheEventTests.m in Sources */, + 234A0BE12BCDC4B900AFBBAA /* MSIDBrowserNativeMessageSignOutResponseTests.m in Sources */, 23419F7D239B0D1C00EA78C5 /* MSIDAuthorityTests.m in Sources */, E733EE0D25C0A50A00ACB79A /* MSIDThumbprintCalculatorTests.m in Sources */, 234858DF20490EF8004FBC3C /* MSIDDefaultTokenCacheIntegrationTests.m in Sources */, @@ -7350,6 +7367,7 @@ 728D9E492824A323001D990F /* MSIDPkeyAuthHelperTests.m in Sources */, 589BDB1E2718CD7D00BF3799 /* MSIDBrokerOperationGetSsoCookiesRequestTests.m in Sources */, B26A0B9A2072BABE006BD95A /* MSIDAADV2Oauth2FactoryTests.m in Sources */, + 234A0BE42BCDCCB100AFBBAA /* MSIDBrowserNativeMessageSignOutRequestTests.m in Sources */, B287C4CF26A132FA004303F1 /* MSIDSSOExtensionRequestDelegateTests.m in Sources */, 60BF06052051F9A200DE7C1C /* MSIDTelemetryTestDispatcher.m in Sources */, 23CAB3912A60ACB50066CFA2 /* MSIDBrokerOperationBrowserNativeMessageResponseTests.m in Sources */, diff --git a/IdentityCore/src/MSIDBrokerConstants.h b/IdentityCore/src/MSIDBrokerConstants.h index 08bc01f2b..d18468a74 100644 --- a/IdentityCore/src/MSIDBrokerConstants.h +++ b/IdentityCore/src/MSIDBrokerConstants.h @@ -92,7 +92,7 @@ extern NSString * _Nonnull const MSID_BROKER_REQUEST_SENT_TIMESTAMP; extern NSString * _Nonnull const MSID_BROKER_ACCOUNT_HOME_TENANT_ID; extern NSString * _Nonnull const MSID_CLIENT_SKU_KEY; extern NSString * _Nonnull const MSID_SKIP_VALIDATE_RESULT_ACCOUNT_KEY; -extern NSString * _Nonnull const JIT_TROUBLESHOOTING_HOST; +extern NSString * _Nonnull const MSID_JIT_TROUBLESHOOTING_HOST; extern NSString * _Nonnull const MSID_IS_CALLER_MANAGED_KEY; extern NSString * _Nonnull const MSID_BROKER_PREFERRED_AUTH_CONFIGURATION_KEY; extern NSString * _Nonnull const MSID_BROKER_SDM_WPJ_ATTEMPTED; diff --git a/IdentityCore/src/MSIDBrokerConstants.m b/IdentityCore/src/MSIDBrokerConstants.m index 6ea9bfe7f..f32ec3d8d 100644 --- a/IdentityCore/src/MSIDBrokerConstants.m +++ b/IdentityCore/src/MSIDBrokerConstants.m @@ -91,7 +91,7 @@ NSString *const MSID_PRIMARY_REGISTRATION_CLOUD = @"primary_registration_metadata_cloud_host"; NSString *const MSID_PRIMARY_REGISTRATION_CERTIFICATE_THUMBPRINT = @"primary_registration_metadata_certificate_thumbprint"; NSString *const MSID_PLATFORM_SSO_STATUS_KEY = @"platform_sso_status"; -NSString *const JIT_TROUBLESHOOTING_HOST = @"jit_troubleshooting"; +NSString *const MSID_JIT_TROUBLESHOOTING_HOST = @"jit_troubleshooting"; NSString *const MSID_IS_CALLER_MANAGED_KEY = @"isCallerAppManaged"; NSString *const MSID_BROKER_SDM_WPJ_ATTEMPTED = @"sdm_reg_attempted"; NSString *const MSID_FORCE_REFRESH_KEY = @"force_refresh"; diff --git a/IdentityCore/src/MSIDConstants.h b/IdentityCore/src/MSIDConstants.h index 039633f29..c5651b0a8 100644 --- a/IdentityCore/src/MSIDConstants.h +++ b/IdentityCore/src/MSIDConstants.h @@ -114,6 +114,7 @@ typedef void (^MSIDPasskeyCredentialRequestCompletionBlock)(MSIDPasskeyCredentia extern NSString * _Nonnull const MSID_PLATFORM_KEY;//The SDK platform. iOS or OSX extern NSString * _Nonnull const MSID_SOURCE_PLATFORM_KEY;//The source SDK platform. iOS or OSX +extern NSString * _Nonnull const MSID_PLATFORM_SEQUENCE_KEY; extern NSString * _Nonnull const MSID_VERSION_KEY; extern NSString * _Nonnull const MSID_CPU_KEY;//E.g. ARM64 extern NSString * _Nonnull const MSID_OS_VER_KEY;//iOS/OSX version @@ -161,4 +162,13 @@ extern NSString * _Nonnull const MSID_CLIENT_SKU_ADAL_IOS; extern NSString * _Nonnull const MSID_BROWSER_NATIVE_MESSAGE_ACCOUNT_ID_KEY; +typedef NS_ENUM(NSInteger, MSIDPlatformSequenceIndex) +{ + MSIDPlatformSequenceIndexSrc = 0, + MSIDPlatformSequenceIndexMsalRuntime = 1, + MSIDPlatformSequenceIndexBrowserExt = 2, + MSIDPlatformSequenceIndexBrowserCore = 3, + MSIDPlatformSequenceIndexLast = MSIDPlatformSequenceIndexBrowserCore, +}; + #define METHODANDLINE [NSString stringWithFormat:@"%s [Line %d]", __PRETTY_FUNCTION__, __LINE__] diff --git a/IdentityCore/src/MSIDConstants.m b/IdentityCore/src/MSIDConstants.m index ba8917804..431b406f5 100644 --- a/IdentityCore/src/MSIDConstants.m +++ b/IdentityCore/src/MSIDConstants.m @@ -25,6 +25,7 @@ NSString *const MSID_PLATFORM_KEY = @"x-client-SKU"; NSString *const MSID_SOURCE_PLATFORM_KEY = @"x-client-src-SKU"; +NSString *const MSID_PLATFORM_SEQUENCE_KEY = @"x-client-xtra-sku"; NSString *const MSID_VERSION_KEY = @"x-client-Ver"; NSString *const MSID_CPU_KEY = @"x-client-CPU"; NSString *const MSID_OS_VER_KEY = @"x-client-OS"; diff --git a/IdentityCore/src/MSIDError.h b/IdentityCore/src/MSIDError.h index f5d0d5f5f..1b97648ba 100644 --- a/IdentityCore/src/MSIDError.h +++ b/IdentityCore/src/MSIDError.h @@ -325,6 +325,9 @@ typedef NS_ENUM(NSInteger, MSIDErrorCode) // In PSSO, KeyId stored in passkey provider storage does not match NGC key, needs to configure and retry MSIDErrorPSSOKeyIdMismatch = -51838, + // JIT - Error Handling config invalid or not found + MSIDErrorJITErrorHandlingConfigNotFound = -51839, + // Throttling errors MSIDErrorThrottleCacheNoRecord = -51900, MSIDErrorThrottleCacheInvalidSignature = -51901, diff --git a/IdentityCore/src/MSIDError.m b/IdentityCore/src/MSIDError.m index 3c6265667..83183c789 100644 --- a/IdentityCore/src/MSIDError.m +++ b/IdentityCore/src/MSIDError.m @@ -197,6 +197,7 @@ MSIDErrorCode MSIDErrorCodeForOAuthErrorWithSubErrorCode(NSString *oauthError, M @(MSIDErrorJITTroubleshootingAcquireToken), @(MSIDErrorDeviceNotPSSORegistered), @(MSIDErrorPSSOKeyIdMismatch), + @(MSIDErrorJITErrorHandlingConfigNotFound), ], MSIDOAuthErrorDomain : @[// Server Errors @@ -397,6 +398,9 @@ void MSIDFillAndLogError(NSError **error, MSIDErrorCode errorCode, NSString *err return @"MSIDErrorJITTroubleshootingResultUnknown"; case MSIDErrorJITTroubleshootingAcquireToken: return @"MSIDErrorJITTroubleshootingAcquireToken"; + case MSIDErrorJITErrorHandlingConfigNotFound: + return @"MSIDErrorJITErrorHandlingConfigNotFound"; + // PSSO errors case MSIDErrorDeviceNotPSSORegistered: return @"MSIDErrorDeviceNotPSSORegistered"; case MSIDErrorPSSOKeyIdMismatch: diff --git a/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.h b/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.h index d4e45eadb..3a06a8256 100644 --- a/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.h +++ b/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.h @@ -37,6 +37,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, nullable) NSString *clientAppName; @property (nonatomic) MSIDClientSDKType clientSDK; @property (nonatomic) BOOL clientBrokerKeyCapabilityNotSupported; +@property (nonatomic, nullable) NSString *platformSequence; + (BOOL)fillRequest:(MSIDBrokerOperationRequest *)request keychainAccessGroup:(nullable NSString *)keychainAccessGroup diff --git a/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.m b/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.m index a29ba53a1..7aeb8267e 100644 --- a/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.m +++ b/IdentityCore/src/broker_operation/request/MSIDBrokerOperationRequest.m @@ -80,6 +80,8 @@ - (instancetype)initWithJSONDictionary:(NSDictionary *)json error:(NSError **)er NSString *sdkTypeString = [json msidStringObjectForKey:MSID_BROKER_CLIENT_SDK_KEY]; _clientSDK = MSIDClientSDKTypeFromString(sdkTypeString); + + _platformSequence = [json msidStringObjectForKey:MSID_PLATFORM_SEQUENCE_KEY]; } return self; @@ -120,6 +122,8 @@ - (NSDictionary *)jsonDictionary NSString *sdkTypeString = MSIDClientSDKTypeToString(self.clientSDK); json[MSID_BROKER_CLIENT_SDK_KEY] = sdkTypeString; + + json[MSID_PLATFORM_SEQUENCE_KEY] = self.platformSequence; return json; } diff --git a/IdentityCore/src/broker_operation/response/browser_native_message_response/MSIDBrowserNativeMessageGetTokenResponse.m b/IdentityCore/src/broker_operation/response/browser_native_message_response/MSIDBrowserNativeMessageGetTokenResponse.m index f1536b9e4..02caa6b31 100644 --- a/IdentityCore/src/broker_operation/response/browser_native_message_response/MSIDBrowserNativeMessageGetTokenResponse.m +++ b/IdentityCore/src/broker_operation/response/browser_native_message_response/MSIDBrowserNativeMessageGetTokenResponse.m @@ -77,6 +77,11 @@ - (NSDictionary *)jsonDictionary response[@"account"] = accountJson; response[@"state"] = self.state; + __auto_type propertiesJson = [NSMutableDictionary new]; + // TODO: once ests follow the latest protocol, this should be removed. Account ID should be read from accountJson. + propertiesJson[@"UPN"] = tokenResponse.idTokenObj.username; + response[@"properties"] = propertiesJson; + return response; } diff --git a/IdentityCore/src/parameters/MSIDRequestParameters.h b/IdentityCore/src/parameters/MSIDRequestParameters.h index 88bbf2acd..b7931a106 100644 --- a/IdentityCore/src/parameters/MSIDRequestParameters.h +++ b/IdentityCore/src/parameters/MSIDRequestParameters.h @@ -57,6 +57,10 @@ @property (nonatomic) NSString *clientSku; @property (nonatomic) BOOL skipValidateResultAccount; @property (nonatomic) BOOL forceRefresh; +@property (nonatomic) BOOL bypassRedirectURIValidation; + +// Telemetry metadata +@property (nonatomic) NSString *platformSequence; // Additional body parameters that will be appended to all token requests @property (nonatomic) NSDictionary *extraTokenRequestParameters; diff --git a/IdentityCore/src/parameters/MSIDRequestParameters.m b/IdentityCore/src/parameters/MSIDRequestParameters.m index 012424452..5e9c566bb 100644 --- a/IdentityCore/src/parameters/MSIDRequestParameters.m +++ b/IdentityCore/src/parameters/MSIDRequestParameters.m @@ -332,7 +332,7 @@ - (BOOL)validateParametersWithError:(NSError **)error return NO; } - if (!self.redirectUri) + if (!self.redirectUri && !self.bypassRedirectURIValidation) { MSIDFillAndLogError(error, MSIDErrorInvalidDeveloperParameter, @"Missing redirectUri parameter", self.correlationId); return NO; @@ -387,6 +387,7 @@ - (instancetype)copyWithZone:(NSZone*)zone parameters->_clientCapabilities = [_clientCapabilities copyWithZone:zone]; parameters->_msidConfiguration = [_msidConfiguration copyWithZone:zone]; parameters->_keychainAccessGroup = [_keychainAccessGroup copyWithZone:zone]; + parameters->_platformSequence = [_platformSequence copyWithZone:zone]; return parameters; } diff --git a/IdentityCore/src/requests/broker/MSIDBrokerTokenRequest.m b/IdentityCore/src/requests/broker/MSIDBrokerTokenRequest.m index 59e4aee96..95b13e459 100644 --- a/IdentityCore/src/requests/broker/MSIDBrokerTokenRequest.m +++ b/IdentityCore/src/requests/broker/MSIDBrokerTokenRequest.m @@ -191,6 +191,7 @@ - (NSDictionary *)defaultPayloadContents:(NSError **)error [queryDictionary msidSetNonEmptyString:self.requestParameters.clientSku forKey:MSID_CLIENT_SKU_KEY]; [queryDictionary msidSetNonEmptyString:self.requestParameters.skipValidateResultAccount ? @"YES" : @"NO" forKey:MSID_SKIP_VALIDATE_RESULT_ACCOUNT_KEY]; + [queryDictionary msidSetNonEmptyString:self.requestParameters.platformSequence forKey:MSID_PLATFORM_SEQUENCE_KEY]; return queryDictionary; } @@ -222,6 +223,7 @@ - (NSDictionary *)defaultResumeDictionaryContents [resumeDictionary msidSetNonEmptyString:self.requestParameters.clientSku forKey:MSID_CLIENT_SKU_KEY]; [resumeDictionary msidSetNonEmptyString:self.requestParameters.skipValidateResultAccount ? @"YES" : @"NO" forKey:MSID_SKIP_VALIDATE_RESULT_ACCOUNT_KEY]; + [resumeDictionary msidSetNonEmptyString:self.requestParameters.platformSequence forKey:MSID_PLATFORM_SEQUENCE_KEY]; return resumeDictionary; } diff --git a/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.h b/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.h index 1ee2ac677..27270d2c0 100644 --- a/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.h +++ b/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.h @@ -27,4 +27,6 @@ - (NSDictionary *)msidParsedClientTelemetry; ++ (NSString *)msidUpdatePlatformSequenceParamWithSrcName:(NSString *)name srcVersion:(NSString *)version sequence:(NSString *)sequence; + @end diff --git a/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.m b/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.m index 97a0f8fe6..670f41a57 100644 --- a/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.m +++ b/IdentityCore/src/util/NSString+MSIDTelemetryExtensions.m @@ -24,6 +24,7 @@ #import "NSString+MSIDTelemetryExtensions.h" #import "MSIDTelemetryEventStrings.h" #import "MSIDVersion.h" +#import "MSIDConstants.h" #define MSID_CLIENT_TELEMETRY_VERSION_NUMBER @"1" @@ -73,4 +74,51 @@ - (NSDictionary *)msidParsedClientTelemetry return telemetryDict; } ++ (NSString *)msidUpdatePlatformSequenceParamWithSrcName:(NSString *)name srcVersion:(NSString *)version sequence:(NSString *)sequence +{ + static NSString *const kDelimeter = @","; + + NSMutableArray *sequenceItems; + if ([NSString msidIsStringNilOrBlank:sequence]) + { + // Init array of empty items. + sequenceItems = [NSMutableArray new]; + for (NSInteger key= 0; key <= MSIDPlatformSequenceIndexLast; key++) + { + [sequenceItems addObject:@""]; + } + } + else + { + sequenceItems = [[sequence componentsSeparatedByString:kDelimeter] mutableCopy]; + } + + // Validate count. + if (sequenceItems.count <= MSIDPlatformSequenceIndexLast) + { + MSID_LOG_WITH_CTX(MSIDLogLevelError,nil, @"Failed to add platform sequence param: sequence count %lu is invalid.", (unsigned long)sequenceItems.count); + return sequence; + } + + // Validate name. + if ([NSString msidIsStringNilOrBlank:name]) + { + MSID_LOG_WITH_CTX(MSIDLogLevelWarning,nil, @"Failed to add platform sequence param: name is empty/nil."); + return sequence; + } + + // Validate version. + if ([NSString msidIsStringNilOrBlank:version]) + { + MSID_LOG_WITH_CTX(MSIDLogLevelWarning,nil, @"Failed to add platform sequence param: version is empty/nil."); + return sequence; + } + + sequenceItems[MSIDPlatformSequenceIndexSrc] = [NSString stringWithFormat:@"%@|%@", name, version]; + + NSString *resultSequence = [sequenceItems componentsJoinedByString:kDelimeter]; + + return resultSequence; +} + @end diff --git a/IdentityCore/src/webview/response/MSIDJITTroubleshootingResponse.m b/IdentityCore/src/webview/response/MSIDJITTroubleshootingResponse.m index 6d6ca6985..d09d66a8a 100644 --- a/IdentityCore/src/webview/response/MSIDJITTroubleshootingResponse.m +++ b/IdentityCore/src/webview/response/MSIDJITTroubleshootingResponse.m @@ -73,7 +73,7 @@ - (BOOL)isJITRetryResponse:(NSURL *)url - (BOOL)isJITTroubleshootingResponse:(NSURL *)url { if (!url) return NO; - return ([@"msauth" caseInsensitiveCompare:url.scheme] == NSOrderedSame && [JIT_TROUBLESHOOTING_HOST caseInsensitiveCompare:url.host] == NSOrderedSame); + return ([@"msauth" caseInsensitiveCompare:url.scheme] == NSOrderedSame && [MSID_JIT_TROUBLESHOOTING_HOST caseInsensitiveCompare:url.host] == NSOrderedSame); } - (NSError *)getErrorFromResponseWithContext:(id )context diff --git a/IdentityCore/tests/MSIDBrowserNativeMessageGetTokenResponseTests.m b/IdentityCore/tests/MSIDBrowserNativeMessageGetTokenResponseTests.m new file mode 100644 index 000000000..4da688a71 --- /dev/null +++ b/IdentityCore/tests/MSIDBrowserNativeMessageGetTokenResponseTests.m @@ -0,0 +1,101 @@ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +#import +#import "MSIDBrowserNativeMessageGetTokenResponse.h" +#import "MSIDBrokerOperationTokenResponse.h" +#import "MSIDAADV2TokenResponse.h" +#import "MSIDTestIdTokenUtil.h" +#import "MSIDTokenResponse.h" +#import "MSIDTestIdentifiers.h" + +@interface MSIDTokenResponseMock : MSIDTokenResponse + +@property (nonatomic) NSDictionary *responseJson; + +@end + +@implementation MSIDTokenResponseMock + +- (NSDictionary *)jsonDictionary +{ + return self.responseJson; +} + +@end + +@interface MSIDBrowserNativeMessageGetTokenResponseTests : XCTestCase + +@end + +@implementation MSIDBrowserNativeMessageGetTokenResponseTests + +- (void)testResponseType_shouldBeGenericResponse +{ + // We don't use this operation directly, it is wrapped by "BrokerOperationBrowserNativeMessage" operation, so we don't care about response type and return generic response. + XCTAssertEqualObjects(@"operation_generic_response", [MSIDBrowserNativeMessageGetTokenResponse responseType]); +} + +- (void)testJsonDictionary_whenNoResposne_shouldReturnNil +{ + __auto_type tokenResponse = [[MSIDBrokerOperationTokenResponse alloc] initWithDeviceInfo:nil]; + __auto_type response = [[MSIDBrowserNativeMessageGetTokenResponse alloc] initWithTokenResponse:tokenResponse]; + + XCTAssertNil([response jsonDictionary]); +} + +- (void)testJsonDictionary_whenPayloadExist_shouldBeCorrect +{ + NSString *idToken = [MSIDTestIdTokenUtil idTokenWithPreferredUsername:DEFAULT_TEST_ID_TOKEN_USERNAME + subject:DEFAULT_TEST_ID_TOKEN_SUBJECT]; + + NSDictionary *jsonInput = @{@"id_token": idToken}; + + MSIDTokenResponseMock *tokenResponseMock = [[MSIDTokenResponseMock alloc] initWithJSONDictionary:jsonInput error:nil]; + tokenResponseMock.responseJson = @{@"some_key": @"some_value"}; + + __auto_type operationTokenResponse = [[MSIDBrokerOperationTokenResponse alloc] initWithDeviceInfo:nil]; + operationTokenResponse.tokenResponse = tokenResponseMock; + + __auto_type response = [[MSIDBrowserNativeMessageGetTokenResponse alloc] initWithTokenResponse:operationTokenResponse]; + response.state = @"1234"; + + __auto_type expectedJson = @{ + @"account": @{ + @"id": tokenResponseMock.accountIdentifier, + @"userName": tokenResponseMock.idTokenObj.username + }, + @"properties": @{ + @"UPN": tokenResponseMock.idTokenObj.username + }, + @"state": @"1234", + @"some_key": @"some_value" + }; + + XCTAssertNotNil([response jsonDictionary]); + XCTAssertEqualObjects(expectedJson, [response jsonDictionary]); +} + +@end diff --git a/IdentityCore/tests/MSIDBrowserNativeMessageSignOutRequestTests.m b/IdentityCore/tests/MSIDBrowserNativeMessageSignOutRequestTests.m new file mode 100644 index 000000000..682aad482 --- /dev/null +++ b/IdentityCore/tests/MSIDBrowserNativeMessageSignOutRequestTests.m @@ -0,0 +1,75 @@ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +#import +#import "MSIDBrowserNativeMessageSignOutRequest.h" +#import "MSIDAccountIdentifier.h" + +@interface MSIDBrowserNativeMessageSignOutRequestTests : XCTestCase + +@end + +@implementation MSIDBrowserNativeMessageSignOutRequestTests + +- (void)testOperation_shouldBeCorrect +{ + XCTAssertEqualObjects(@"SignOut", [MSIDBrowserNativeMessageSignOutRequest operation]); +} + +- (void)testInitWithJSONDictionary_whenAccountIdIsValid_shouldInit +{ + __auto_type json = @{ + @"method": @"SignOut", + @"accountId": @"uid.utid", + @"sender": @"https://login.microsoft.com" + }; + + NSError *error; + __auto_type request = [[MSIDBrowserNativeMessageSignOutRequest alloc] initWithJSONDictionary:json error:&error]; + + XCTAssertNil(error); + XCTAssertNotNil(request); + XCTAssertEqualObjects(@"https://login.microsoft.com", request.sender.absoluteString); + XCTAssertEqualObjects(@"uid", request.accountId.uid); + XCTAssertEqualObjects(@"utid", request.accountId.utid); +} + +- (void)testInitWithJSONDictionary_whenAccountIdIsInvalid_shouldFail +{ + __auto_type json = @{ + @"method": @"SignOut", + @"accountId": @"qwerty", + @"sender": @"https://localhost:8000" + }; + + NSError *error; + __auto_type request = [[MSIDBrowserNativeMessageSignOutRequest alloc] initWithJSONDictionary:json error:&error]; + + XCTAssertNil(request); + XCTAssertNotNil(error); + XCTAssertEqualObjects(error.userInfo[MSIDErrorDescriptionKey], @"account Id is invalid."); +} + +@end diff --git a/IdentityCore/tests/MSIDBrowserNativeMessageSignOutResponseTests.m b/IdentityCore/tests/MSIDBrowserNativeMessageSignOutResponseTests.m new file mode 100644 index 000000000..5a7718001 --- /dev/null +++ b/IdentityCore/tests/MSIDBrowserNativeMessageSignOutResponseTests.m @@ -0,0 +1,48 @@ +// +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +#import +#import "MSIDBrowserNativeMessageSignOutResponse.h" + +@interface MSIDBrowserNativeMessageSignOutResponseTests : XCTestCase + +@end + +@implementation MSIDBrowserNativeMessageSignOutResponseTests + +- (void)testResponseType_shouldBeGenericResponse +{ + // We don't use this operation directly, it is wrapped by "BrokerOperationBrowserNativeMessage" operation, so we don't care about response type and return generic response. + XCTAssertEqualObjects(@"operation_generic_response", [MSIDBrowserNativeMessageSignOutResponse responseType]); +} + +- (void)testJsonDictionary_shouldBeEmptyJson +{ + __auto_type response = [[MSIDBrowserNativeMessageSignOutResponse alloc] initWithDeviceInfo:nil]; + + XCTAssertNotNil([response jsonDictionary]); + XCTAssertEqualObjects(@{}, [response jsonDictionary]); +} +@end diff --git a/IdentityCore/tests/MSIDJITTroubleshootingResponseTests.m b/IdentityCore/tests/MSIDJITTroubleshootingResponseTests.m index 16b285cb8..1dd5f3b77 100644 --- a/IdentityCore/tests/MSIDJITTroubleshootingResponseTests.m +++ b/IdentityCore/tests/MSIDJITTroubleshootingResponseTests.m @@ -135,7 +135,7 @@ - (void)testIsJITTroubleshootingResponse_whenQueryCorrectValue_shouldReturnStatu - (void)testIsJITTroubleshootingResponse_whenIsJITTroubleshootingResponse_shouldReturnStatusAndJITTTroubleshootingRequiredError { - NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"msauth://%@", JIT_TROUBLESHOOTING_HOST]]; + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"msauth://%@", MSID_JIT_TROUBLESHOOTING_HOST]]; NSError *error; MSIDJITTroubleshootingResponse *response = [[MSIDJITTroubleshootingResponse alloc] initWithURL:url context:nil error:&error]; diff --git a/IdentityCore/tests/MSIDRequestParametersTests.m b/IdentityCore/tests/MSIDRequestParametersTests.m index 966480e53..47451a3d2 100644 --- a/IdentityCore/tests/MSIDRequestParametersTests.m +++ b/IdentityCore/tests/MSIDRequestParametersTests.m @@ -165,6 +165,63 @@ - (void)testInitParameters_withClientIdAsScope_andB2CAuthority_shouldInitReturnN XCTAssertNotNil(parameters.appRequestMetadata); } +- (void)testParameterValidation_withNoBypassRedirectUriValidation_andNilRedirectUri_shouldFail +{ + MSIDAuthority *authority = [@"https://login.microsoftonline.com/common" aadAuthority]; + NSOrderedSet *scopes = [NSOrderedSet orderedSetWithObjects:@"myscope1", @"myscope2", nil]; + NSOrderedSet *oidcScopes = [NSOrderedSet orderedSetWithObjects:@"openid", @"offline_access", @"profile", nil]; + + NSError *error = nil; + MSIDRequestParameters *parameters = [[MSIDRequestParameters alloc] initWithAuthority:authority + authScheme:[MSIDAuthenticationScheme new] + redirectUri:nil + clientId:@"myclient_id" + scopes:scopes + oidcScopes:oidcScopes + correlationId:nil + telemetryApiId:nil + intuneAppIdentifier:@"com.microsoft.mytest" + requestType:MSIDRequestLocalType + error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(parameters); + + parameters.bypassRedirectURIValidation = false; + BOOL result = [parameters validateParametersWithError:&error]; + + XCTAssertNotNil(error); + XCTAssertEqual(result, false); + XCTAssertEqual(error.code, MSIDErrorInvalidDeveloperParameter); +} + +- (void)testParameterValidation_withBypassRedirectUriValidation_andNilRedirectUri_shouldNotFail +{ + MSIDAuthority *authority = [@"https://login.microsoftonline.com/common" aadAuthority]; + NSOrderedSet *scopes = [NSOrderedSet orderedSetWithObjects:@"myscope1", @"myscope2", nil]; + NSOrderedSet *oidcScopes = [NSOrderedSet orderedSetWithObjects:@"openid", @"offline_access", @"profile", nil]; + + NSError *error = nil; + MSIDRequestParameters *parameters = [[MSIDRequestParameters alloc] initWithAuthority:authority + authScheme:[MSIDAuthenticationScheme new] + redirectUri:nil + clientId:@"myclient_id" + scopes:scopes + oidcScopes:oidcScopes + correlationId:nil + telemetryApiId:nil + intuneAppIdentifier:@"com.microsoft.mytest" + requestType:MSIDRequestLocalType + error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(parameters); + + parameters.bypassRedirectURIValidation = true; + BOOL result = [parameters validateParametersWithError:&error]; + + XCTAssertNil(error); + XCTAssertEqual(result, true); +} + - (void)testUpdateAppRequestMetadata_whenAccountIdIsNil_shouldNotChangeMetadata { MSIDAuthority *authority = [@"https://login.microsoftonline.com/common" aadAuthority]; diff --git a/IdentityCore/tests/MSIDTelemetryExtensionsTests.m b/IdentityCore/tests/MSIDTelemetryExtensionsTests.m index 5381d2038..63613ef87 100644 --- a/IdentityCore/tests/MSIDTelemetryExtensionsTests.m +++ b/IdentityCore/tests/MSIDTelemetryExtensionsTests.m @@ -142,4 +142,44 @@ - (void)testParsedClientTelemetry_whenErrorHasZeroes_shouldReturnAllPropertiesBu XCTAssertEqualObjects([parsedTelemetry objectForKey:MSID_TELEMETRY_KEY_SPE_INFO], @"I"); } +- (void)testmsidUpdatePlatformSequenceParamWithSrcName_whenValidNameAndVersionNewSequence_shouldCreateValidSequence +{ + NSString *platformSequence = [NSString msidUpdatePlatformSequenceParamWithSrcName:@"name" srcVersion:@"v1" sequence:nil]; + + XCTAssertNotNil(platformSequence); + XCTAssertEqualObjects(platformSequence, @"name|v1,,,"); +} + +- (void)testmsidUpdatePlatformSequenceParamWithSrcName_whenValidNameAndVersionAndInvalidSequence_shouldReturnOriginal +{ + NSString *platformSequence = [NSString msidUpdatePlatformSequenceParamWithSrcName:@"name" srcVersion:@"v1" sequence:@"0,1"]; + + XCTAssertNotNil(platformSequence); + XCTAssertEqualObjects(platformSequence, @"0,1"); +} + +- (void)testmsidUpdatePlatformSequenceParamWithSrcName_whenValidNameAndVersionAndValidSequence_shouldUpdate +{ + NSString *platformSequence = [NSString msidUpdatePlatformSequenceParamWithSrcName:@"name" srcVersion:@"v1" sequence:@"0,1,2,3"]; + + XCTAssertNotNil(platformSequence); + XCTAssertEqualObjects(platformSequence, @"name|v1,1,2,3"); +} + +- (void)testmsidUpdatePlatformSequenceParamWithSrcName_whenValidNameAndNilVersionAndValidSequence_shouldReturnOriginal +{ + NSString *platformSequence = [NSString msidUpdatePlatformSequenceParamWithSrcName:@"name" srcVersion:nil sequence:@"0,1,2,3"]; + + XCTAssertNotNil(platformSequence); + XCTAssertEqualObjects(platformSequence, @"0,1,2,3"); +} + +- (void)testmsidUpdatePlatformSequenceParamWithSrcName_whenNilNameAndValidVersionAndValidSequence_shouldReturnOriginal +{ + NSString *platformSequence = [NSString msidUpdatePlatformSequenceParamWithSrcName:nil srcVersion:@"v1" sequence:@"0,1,2,3"]; + + XCTAssertNotNil(platformSequence); + XCTAssertEqualObjects(platformSequence, @"0,1,2,3"); +} + @end diff --git a/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.h b/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.h index b4a774e29..aed13e629 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.h +++ b/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.h @@ -77,6 +77,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)aadEnterPassword:(XCUIApplication *)application; - (void)enterPassword:(NSString *)password app:(XCUIApplication *)application; - (void)enterPassword:(NSString *)password app:(XCUIApplication *)app isMainApp:(BOOL)isMainApp; +- (void)setupPassword:(NSString *)password app:(XCUIApplication *)application; - (void)adfsEnterPassword:(XCUIApplication *)application;; - (void)adfsEnterPassword:(NSString *)password app:(XCUIApplication *)application; diff --git a/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.m b/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.m index 9179ac5d6..0f8ee0189 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.m +++ b/IdentityCore/tests/automation/ui_tests_lib/MSIDBaseUITest.m @@ -266,6 +266,8 @@ - (void)enterEmail:(NSString *)email app:(XCUIApplication *)application isMainAp - (void)aadEnterPassword:(XCUIApplication *)application { [self enterPassword:self.primaryAccount.password app:application]; + // New Password reset API requires to force providing a new password after logging in with original password. + [self setupPassword:self.primaryAccount.password app:application]; } - (void)enterPassword:(NSString *)password app:(XCUIApplication *)application @@ -273,6 +275,40 @@ - (void)enterPassword:(NSString *)password app:(XCUIApplication *)application [self enterPassword:password app:application isMainApp:YES]; } +- (void)setupPassword:(NSString *)password app:(XCUIApplication *)application +{ + [self setupPassword:password app:application isMainApp:YES]; +} + +- (void)setupPassword:(NSString *)password app:(XCUIApplication *)application isMainApp:(BOOL)isMainApp +{ + sleep(3); + if (application.secureTextFields.count > 1) + { + // New password flow + //Current password + NSPredicate *passwordFieldPredicate = [NSPredicate predicateWithFormat:@"placeholderValue CONTAINS[c] %@", @"Current password"]; + XCUIElement *currentPasswordSecureTextField = [[application.secureTextFields matchingPredicate:passwordFieldPredicate] elementBoundByIndex:0]; + [self tapElementAndWaitForKeyboardToAppear:currentPasswordSecureTextField app:application]; + NSString *passwordString = [NSString stringWithFormat:@"%@\n", password]; + [self enterText:currentPasswordSecureTextField isMainApp:isMainApp text:passwordString]; + + passwordFieldPredicate = [NSPredicate predicateWithFormat:@"placeholderValue CONTAINS[c] %@", @"New password"]; + XCUIElement *newPasswordSecureTextField = [[application.secureTextFields matchingPredicate:passwordFieldPredicate] elementBoundByIndex:0]; + [self tapElementAndWaitForKeyboardToAppear:newPasswordSecureTextField app:application]; + passwordString = [NSString stringWithFormat:@"%@apple\n", password]; + [self enterText:newPasswordSecureTextField isMainApp:isMainApp text:passwordString]; + + passwordFieldPredicate = [NSPredicate predicateWithFormat:@"placeholderValue CONTAINS[c] %@", @"Confirm password"]; + XCUIElement *confirmPasswordSecureTextField = [[application.secureTextFields matchingPredicate:passwordFieldPredicate] elementBoundByIndex:0]; + [self tapElementAndWaitForKeyboardToAppear:confirmPasswordSecureTextField app:application]; + passwordString = [NSString stringWithFormat:@"%@apple\n", password]; + [self enterText:confirmPasswordSecureTextField isMainApp:isMainApp text:passwordString]; + + } +} + + - (void)enterPassword:(NSString *)password app:(XCUIApplication *)application isMainApp:(BOOL)isMainApp { // Enter password diff --git a/IdentityCore/tests/automation/ui_tests_lib/MSIDTestConfigurationProvider.m b/IdentityCore/tests/automation/ui_tests_lib/MSIDTestConfigurationProvider.m index 927241332..7ab4767dd 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/MSIDTestConfigurationProvider.m +++ b/IdentityCore/tests/automation/ui_tests_lib/MSIDTestConfigurationProvider.m @@ -58,6 +58,7 @@ - (instancetype)initWithClientCertificateContents:(NSString *)certificate defaultScopes:(NSDictionary *)defaultScopes defaultResources:(NSDictionary *)defaultResources operationAPIConf:(NSDictionary *)operationAPIConfiguration + funcAppAPIConf:(NSDictionary *)funcAppAPIConfiguration jitConfig:(NSDictionary *)jitConfig { self = [super init]; @@ -76,6 +77,8 @@ - (instancetype)initWithClientCertificateContents:(NSString *)certificate MSIDAutomationOperationAPIInMemoryCacheHandler *cacheHandler = [[MSIDAutomationOperationAPIInMemoryCacheHandler alloc] initWithDictionary:additionalConfigurations]; _operationAPIRequestHandler = [[MSIDAutomationOperationAPIRequestHandler alloc] initWithAPIPath:operationAPIConfiguration[@"operation_api_path"] + newAPIPath:funcAppAPIConfiguration[@"operation_api_path"] + newAPICode:funcAppAPIConfiguration encodedCertificate:certificate certificatePassword:password operationAPIConfiguration:operationAPIConfiguration]; @@ -147,6 +150,7 @@ - (instancetype)initWithConfigurationPath:(NSString *)configurationPath defaultScopes:configurationDictionary[@"scopes"] defaultResources:configurationDictionary[@"resources"] operationAPIConf:configurationDictionary[@"operation_api_conf"] + funcAppAPIConf:configurationDictionary[@"function_app_api_code"] jitConfig:configurationDictionary[@"jit_intune_ids"]]; } diff --git a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.h b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.h index e5ee0d42d..2b58d9952 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.h +++ b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.h @@ -28,6 +28,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MSIDAutomationBaseApiRequest : NSObject - (NSURL *)requestURLWithAPIPath:(NSString *)apiPath; +- (NSURL *)requestURLWithAPIPath:(NSString *)apiPath apiCode:(NSDictionary *)apiCode; + (MSIDAutomationBaseApiRequest *)requestWithDictionary:(NSDictionary *)dictionary; - (NSString *)httpMethod; - (BOOL)shouldCacheResponse; diff --git a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.m b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.m index deefe5e4a..4bdb6b5b7 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.m +++ b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationBaseApiRequest.m @@ -23,6 +23,12 @@ #import "MSIDAutomationBaseApiRequest.h" +@interface MSIDAutomationBaseApiRequest() + +@property(nonatomic) NSDictionary *requestOperationCode; + +@end + @implementation MSIDAutomationBaseApiRequest #pragma mark - NSCopying @@ -35,6 +41,12 @@ - (nonnull id)copyWithZone:(nullable NSZone *)zone #pragma mark - MSIDTestAutomationRequest +- (NSURL *)requestURLWithAPIPath:(NSString *)apiPath apiCode:(NSDictionary *)apiCode +{ + self.requestOperationCode = apiCode; + return [self requestURLWithAPIPath:apiPath]; +} + - (NSURL *)requestURLWithAPIPath:(NSString *)apiPath { NSString *requestOperationPath = [self requestOperationPath]; @@ -56,6 +68,13 @@ - (NSURL *)requestURLWithAPIPath:(NSString *)apiPath return nil; } + + if (![NSString msidIsStringNilOrBlank:[self requestOperationCodeKey]] + && ![NSString msidIsStringNilOrBlank:self.requestOperationCode[[self requestOperationCodeKey]]]) + { + [queryItems addObject:[[NSURLQueryItem alloc] initWithName:@"code" value:self.requestOperationCode[[self requestOperationCodeKey]]]]; + } + [queryItems addObjectsFromArray:extraQueryItems]; components.queryItems = queryItems; NSURL *resultURL = [components URL]; @@ -70,6 +89,12 @@ - (NSString *)requestOperationPath return nil; } +- (NSString *)requestOperationCodeKey +{ + //Implement in subclasses, otherwise leave as nil + return nil; +} + - (NSArray *)queryItems { NSAssert(NO, @"Abstract method, implement in subclasses"); diff --git a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationDeleteDeviceAPIRequest.m b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationDeleteDeviceAPIRequest.m index 62abeb1f7..76870c520 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationDeleteDeviceAPIRequest.m +++ b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationDeleteDeviceAPIRequest.m @@ -34,7 +34,7 @@ - (NSString *)requestOperationPath - (NSString *)httpMethod { - return @"DELETE"; + return @"POST"; } - (NSArray *)queryItems @@ -54,6 +54,11 @@ - (NSString *)httpMethod return queryItems; } +- (NSString *)requestOperationCodeKey +{ + return @"delete_device_api_code"; +} + - (NSUInteger)hash { NSUInteger hash = self.userUPN.hash; diff --git a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.h b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.h index 7a7429afa..a69a5d5eb 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.h +++ b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.h @@ -43,6 +43,8 @@ @property (nonatomic) id apiCacheHandler; - (instancetype)initWithAPIPath:(NSString *)apiPath + newAPIPath:(NSString *)funcAppAPIPath + newAPICode:(NSDictionary *)funcAppAPICode encodedCertificate:(NSString *)encodedCertificate certificatePassword:(NSString *)certificatePassword operationAPIConfiguration:(NSDictionary *)operationAPIConfiguration; diff --git a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.m b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.m index 900f7a321..7e439c8bf 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.m +++ b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationOperationAPIRequestHandler.m @@ -24,10 +24,15 @@ #import "MSIDAutomationOperationAPIRequestHandler.h" #import "MSIDAutomation-Swift.h" #import "MSIDClientCredentialHelper.h" +#import "MSIDAutomationTemporaryAccountRequest.h" +#import "MSIDAutomationResetAPIRequest.h" +#import "MSIDAutomationDeleteDeviceAPIRequest.h" @interface MSIDAutomationOperationAPIRequestHandler() @property (nonatomic) NSString *labAPIPath; +@property (nonatomic) NSString *funcAppAPIPath; +@property (nonatomic) NSDictionary *funcAppAPICode; @property (nonatomic) NSDictionary *configurationParams; @property (nonatomic) NSString *encodedCertificate; @property (nonatomic) NSString *certificatePassword; @@ -39,6 +44,8 @@ @implementation MSIDAutomationOperationAPIRequestHandler #pragma mark - Init - (instancetype)initWithAPIPath:(NSString *)apiPath + newAPIPath:(NSString *)funcAppAPIPath + newAPICode:(NSDictionary *)funcAppAPICode encodedCertificate:(NSString *)encodedCertificate certificatePassword:(NSString *)certificatePassword operationAPIConfiguration:(NSDictionary *)operationAPIConfiguration @@ -48,6 +55,8 @@ - (instancetype)initWithAPIPath:(NSString *)apiPath if (self) { _labAPIPath = apiPath; + _funcAppAPIPath = funcAppAPIPath; + _funcAppAPICode = funcAppAPICode; _configurationParams = operationAPIConfiguration; _encodedCertificate = encodedCertificate; _certificatePassword = certificatePassword; @@ -123,7 +132,17 @@ - (void)executeAPIRequestImpl:(MSIDAutomationBaseApiRequest *)request accessToken:(NSString *)accessToken completionHandler:(void (^)(id result, NSError *error))completionHandler { - NSURL *resultURL = [request requestURLWithAPIPath:self.labAPIPath]; + NSURL *resultURL = nil; + if ([request isKindOfClass:[MSIDAutomationTemporaryAccountRequest class]] + || [request isKindOfClass:[MSIDAutomationResetAPIRequest class]] + || [request isKindOfClass:[MSIDAutomationDeleteDeviceAPIRequest class]]) + { + resultURL = [request requestURLWithAPIPath:self.funcAppAPIPath apiCode:self.funcAppAPICode]; + } + else + { + resultURL = [request requestURLWithAPIPath:self.labAPIPath]; + } NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:resultURL]; NSString *bearerHeader = [NSString stringWithFormat:@"Bearer %@", accessToken]; diff --git a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationResetAPIRequest.m b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationResetAPIRequest.m index ea16a7f83..9d6c08231 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationResetAPIRequest.m +++ b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationResetAPIRequest.m @@ -32,9 +32,14 @@ - (NSString *)requestOperationPath return @"Reset"; } +- (NSString *)requestOperationCodeKey +{ + return @"reset_api_code"; +} + - (NSString *)httpMethod { - return @"PUT"; + return @"POST"; } - (NSArray *)queryItems diff --git a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationTemporaryAccountRequest.m b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationTemporaryAccountRequest.m index 32d4d4c84..feb90ed20 100644 --- a/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationTemporaryAccountRequest.m +++ b/IdentityCore/tests/automation/ui_tests_lib/lab_api/MSIDAutomationTemporaryAccountRequest.m @@ -41,6 +41,11 @@ - (NSString *)requestOperationPath return @"CreateTempUser"; } +- (NSString *)requestOperationCodeKey +{ + return @"create_user_api_code"; +} + - (NSArray *)queryItems { NSString *accountType = [self accountTypeAsString]; diff --git a/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.h b/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.h index 07ed78da9..77313b2a8 100644 --- a/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.h +++ b/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.h @@ -52,6 +52,9 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) NSInteger removeAccountMetadataForHomeAccountIdInvokedCount; @property (nonatomic) MSIDAccountMetadataCacheMockRemoveAccountMetadataForHomeAccountIdParams *removeAccountMetadataForHomeAccountIdParams; +@property (nonatomic) NSInteger updateSignInStateForHomeAccountIdInvokedCount; +@property (nonatomic) NSError *updateSignInStateForHomeAccountIdError; +@property (nonatomic) BOOL updateSignInStateForHomeAccountIdResult; @end diff --git a/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.m b/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.m index a3197760b..addf910ab 100644 --- a/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.m +++ b/IdentityCore/tests/mocks/MSIDAccountMetadataCacheAccessorMock.m @@ -119,4 +119,17 @@ - (BOOL)removeAccountMetadataForHomeAccountId:(NSString *)homeAccountId return self.removeAccountMetadataForHomeAccountIdResult; } +- (BOOL)updateSignInStateForHomeAccountId:(NSString *)homeAccountId + clientId:(NSString *)clientId + state:(MSIDAccountMetadataState)state + context:(id)context + error:(NSError **)error +{ + self.updateSignInStateForHomeAccountIdInvokedCount++; + + if (error) *error = self.updateSignInStateForHomeAccountIdError; + + return self.updateSignInStateForHomeAccountIdResult; +} + @end diff --git a/IdentityCore/tests/util/MSIDTestCacheDataSource.m b/IdentityCore/tests/util/MSIDTestCacheDataSource.m index cfa610eae..06351f544 100644 --- a/IdentityCore/tests/util/MSIDTestCacheDataSource.m +++ b/IdentityCore/tests/util/MSIDTestCacheDataSource.m @@ -35,6 +35,7 @@ #import "MSIDAccountCacheItem.h" #import "MSIDAccountMetadata.h" #import "MSIDAccountMetadataCacheItem.h" +#import "MSIDJsonObject.h" @interface MSIDTestCacheDataSource() { @@ -320,19 +321,61 @@ - (MSIDAccountCacheItem *)accountWithKey:(MSIDCacheKey *)key context:(__unused id)context error:(__unused NSError *__autoreleasing *)error { - // TODO - return nil; + if (!serializer) + { + if (error) + { + *error = MSIDCreateError(MSIDErrorDomain, MSIDErrorInvalidInternalParameter, @"Missing parameter", nil, nil, nil, nil, nil, YES); + } + + return nil; + } + + NSMutableArray *resultItems = [NSMutableArray array]; + + NSArray *items = [self itemsWithKey:key + keysDictionary:_tokenKeys + contentDictionary:_tokenContents + context:context + error:error]; + + for (NSData *itemData in items) + { + MSIDJsonObject *jsonObject = (MSIDJsonObject *)[serializer deserializeCacheItem:itemData ofClass:[MSIDJsonObject class]]; + + if (jsonObject) + { + [resultItems addObject:jsonObject]; + } + } + + return resultItems; } -- (BOOL)saveJsonObject:(__unused MSIDJsonObject *)jsonObject - serializer:(__unused id)serializer - key:(__unused MSIDCacheKey *)key - context:(__unused id)context - error:(__unused NSError *__autoreleasing *)error +- (BOOL)saveJsonObject:(MSIDJsonObject *)jsonObject + serializer:(id)serializer + key:(MSIDCacheKey *)key + context:(id)context + error:(NSError **)error { - // TODO - return NO; + if (!jsonObject || !serializer) + { + if (error) + { + *error = MSIDCreateError(MSIDErrorDomain, MSIDErrorInvalidInternalParameter, @"Missing parameter", nil, nil, nil, nil, nil, YES); + } + + return NO; + } + + NSData *serializedItem = [serializer serializeCacheItem:jsonObject]; + return [self saveItemData:serializedItem + key:key + cacheKeys:_tokenKeys + cacheContent:_tokenContents + context:context + error:error]; } diff --git a/IdentityCore/tests/util/MSIDTestURLResponse+Util.h b/IdentityCore/tests/util/MSIDTestURLResponse+Util.h index 47601198e..5cce09dbe 100644 --- a/IdentityCore/tests/util/MSIDTestURLResponse+Util.h +++ b/IdentityCore/tests/util/MSIDTestURLResponse+Util.h @@ -26,6 +26,7 @@ @interface MSIDTestURLResponse (Util) + (NSDictionary *)msidDefaultRequestHeaders; ++ (NSMutableDictionary *)msidIgnoreRequestHeaders; + (MSIDTestURLResponse *)oidcResponseForAuthority:(NSString *)authority; + (MSIDTestURLResponse *)discoveryResponseForAuthority:(NSString *)authority; diff --git a/IdentityCore/tests/util/MSIDTestURLResponse+Util.m b/IdentityCore/tests/util/MSIDTestURLResponse+Util.m index 85bc5198f..0f77b022c 100644 --- a/IdentityCore/tests/util/MSIDTestURLResponse+Util.m +++ b/IdentityCore/tests/util/MSIDTestURLResponse+Util.m @@ -53,6 +53,36 @@ + (NSDictionary *)msidDefaultRequestHeaders return s_msidHeaders; } ++ (NSMutableDictionary *)msidIgnoreRequestHeaders +{ + static NSMutableDictionary *s_msidHeaders = nil; + static dispatch_once_t headersOnce; + + dispatch_once(&headersOnce, ^{ + NSDictionary *headers = + @{ + @"Accept" : [[MSIDTestIgnoreSentinel alloc] init], + @"Content-Length" : [[MSIDTestIgnoreSentinel alloc] init], + @"Content-Type" : [[MSIDTestIgnoreSentinel alloc] init], + @"User-Agent" : [[MSIDTestIgnoreSentinel alloc] init], + @"x-client-SKU": [[MSIDTestIgnoreSentinel alloc] init], + @"x-client-OS": [[MSIDTestIgnoreSentinel alloc] init], + @"x-app-name": [[MSIDTestIgnoreSentinel alloc] init], + @"x-ms-PkeyAuth+": [[MSIDTestIgnoreSentinel alloc] init], + @"x-client-Ver": [[MSIDTestIgnoreSentinel alloc] init], + @"x-client-CPU": [[MSIDTestIgnoreSentinel alloc] init], + @"x-app-ver": [[MSIDTestIgnoreSentinel alloc] init], + @"x-client-DM": [[MSIDTestIgnoreSentinel alloc] init], + @"Connection": [MSIDTestIgnoreSentinel sentinel], + }; + + + s_msidHeaders = [headers mutableCopy]; + }); + + return s_msidHeaders; +} + + (MSIDTestURLResponse *)discoveryResponseForAuthority:(NSString *)authority { NSURL *authorityURL = [NSURL URLWithString:authority]; diff --git a/azure_pipelines/verify_msalcpp_per_pr_ios.yml b/azure_pipelines/verify_msalcpp_per_pr_ios.yml index 9afedef55..841295627 100644 --- a/azure_pipelines/verify_msalcpp_per_pr_ios.yml +++ b/azure_pipelines/verify_msalcpp_per_pr_ios.yml @@ -59,7 +59,7 @@ jobs: displayName: 'Build x64 Debug iOS' inputs: scriptPath: build.py - arguments: '--clean --arch x64 --configuration Debug --platform iOS --djinni hashfail --test --test-type unit integration' + arguments: '--clean --arch x64 --configuration Debug --platform iOS --djinni hashfail --test --test-type unit integration --build-projects tests' env: MSAL_LAB_VAULT_ACCESS_CERT_LOCATION: $(Agent.TempDirectory) MSAL_CERTIFICATE_PASSWORD: $(MSAL_CERTIFICATE_PASSWORD) diff --git a/azure_pipelines/verify_msalcpp_per_pr_mac.yml b/azure_pipelines/verify_msalcpp_per_pr_mac.yml index 61512e95b..3c4bf9a84 100644 --- a/azure_pipelines/verify_msalcpp_per_pr_mac.yml +++ b/azure_pipelines/verify_msalcpp_per_pr_mac.yml @@ -60,7 +60,7 @@ jobs: displayName: 'Build x64 Debug macOS' inputs: scriptPath: build.py - arguments: '--clean --arch x64 --configuration Debug --platform macOS --djinni hashfail --test --test-type unit integration' + arguments: '--clean --arch x64 --configuration Debug --platform macOS --djinni hashfail --test --test-type unit integration --build-projects tests' env: MSAL_LAB_VAULT_ACCESS_CERT_LOCATION: $(Agent.TempDirectory) MSAL_CERTIFICATE_PASSWORD: $(MSAL_CERTIFICATE_PASSWORD) diff --git a/changelog.txt b/changelog.txt index 36fabaf56..19e481218 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,8 @@ +Version 1.7.36 +* Add platform sequence telemetry param. (#1378) +* Update broker automations lab API. (#1377) +* Fix incorrect constant name without MSID prefix. (#1374) + Version 1.7.35 * Include email as scope returned if it was requested and server did not include it. (#1364) * Fix throttling bug in fallback legacy broker interactive controller. (#1371)