diff --git a/azure_pipelines/cred_management/cred-management-release.yml b/azure_pipelines/cred_management/cred-management-release.yml new file mode 100644 index 0000000000..8b2d302639 --- /dev/null +++ b/azure_pipelines/cred_management/cred-management-release.yml @@ -0,0 +1,289 @@ +# ============================================================================= +# MSALNativeCredManagment SDK — Release Pipeline (SPM + XCFramework) +# ============================================================================= +# +# This pipeline builds the credential management SDK for release distribution. +# +# Triggers: +# - Tag push matching 'credmgmt/*' (e.g., credmgmt/1.0.0) +# +# Stages: +# 1. PR Validation — Build iOS + macOS, run unit tests, validate SPM resolution +# 2. Build Release — Create versioned XCFramework artifact +# 3. Publish — Attach XCFramework to pipeline artifacts +# +# Distribution: Swift Package Manager only (no CocoaPods). +# ============================================================================= + +trigger: + tags: + include: + - 'credmgmt/*' + branches: + include: + - sedemche/ciam-cred-managment-release + +pr: + branches: + include: + - sedemche/ciam-cred-managment-release + +variables: + SDK_PATH: 'lib/native/MSALNativeCredManagment' + XCODE_VERSION: '16.2' + XCFRAMEWORK_OUTPUT: '$(Build.ArtifactStagingDirectory)/MSALNativeCredManagment.xcframework' + +stages: + +# ============================================================================= +# Stage 1: Validate — Build & Test +# ============================================================================= +- stage: Validate + displayName: 'Validate SDK (Build + Test)' + jobs: + + - job: Build_iOS + displayName: 'Build & Test — iOS' + pool: + vmImage: 'macOS-14' + timeoutInMinutes: 30 + steps: + - checkout: self + clean: true + submodules: true + fetchDepth: 1 + + - script: | + sudo xcode-select -s /Applications/Xcode_$(XCODE_VERSION).app + displayName: 'Select Xcode $(XCODE_VERSION)' + + - script: | + cd $(SDK_PATH) + xcodebuild -resolvePackageDependencies \ + -scheme MSALNativeCredManagment \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages + displayName: 'Resolve iOS Package Dependencies' + + - script: | + cd $(SDK_PATH) + xcodebuild build-for-testing \ + -scheme MSALNativeCredManagment \ + -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' \ + -derivedDataPath $(Build.BinariesDirectory)/ios \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages \ + | xcpretty + displayName: 'Build iOS' + + - script: | + cd $(SDK_PATH) + xcodebuild test-without-building \ + -scheme MSALNativeCredManagment \ + -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest' \ + -derivedDataPath $(Build.BinariesDirectory)/ios \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages \ + -resultBundlePath $(Build.ArtifactStagingDirectory)/TestResults-iOS.xcresult \ + | xcpretty --report junit --output $(Build.ArtifactStagingDirectory)/test-results-ios.xml + displayName: 'Run Unit Tests — iOS' + continueOnError: true + + - task: PublishTestResults@2 + condition: always() + displayName: 'Publish iOS Test Results' + inputs: + testResultsFormat: 'JUnit' + testResultsFiles: '$(Build.ArtifactStagingDirectory)/test-results-ios.xml' + testRunTitle: 'CredManagement iOS Tests' + + - job: Build_macOS + displayName: 'Build & Test — macOS' + pool: + vmImage: 'macOS-14' + timeoutInMinutes: 30 + steps: + - checkout: self + clean: true + submodules: true + fetchDepth: 1 + + - script: | + sudo xcode-select -s /Applications/Xcode_$(XCODE_VERSION).app + displayName: 'Select Xcode $(XCODE_VERSION)' + + - script: | + cd $(SDK_PATH) + xcodebuild -resolvePackageDependencies \ + -scheme MSALNativeCredManagment \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages + displayName: 'Resolve macOS Package Dependencies' + + - script: | + cd $(SDK_PATH) + xcodebuild build \ + -scheme MSALNativeCredManagment \ + -destination 'platform=macOS' \ + -derivedDataPath $(Build.BinariesDirectory)/macos \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages \ + CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO + displayName: 'Build macOS' + + - script: | + cd $(SDK_PATH) + xcodebuild test \ + -scheme MSALNativeCredManagment \ + -destination 'platform=macOS' \ + -derivedDataPath $(Build.BinariesDirectory)/macos \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages \ + -resultBundlePath $(Build.ArtifactStagingDirectory)/TestResults-macOS.xcresult \ + CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO \ + | xcpretty --report junit --output $(Build.ArtifactStagingDirectory)/test-results-macos.xml + displayName: 'Run Unit Tests — macOS' + continueOnError: true + + - task: PublishTestResults@2 + condition: always() + displayName: 'Publish macOS Test Results' + inputs: + testResultsFormat: 'JUnit' + testResultsFiles: '$(Build.ArtifactStagingDirectory)/test-results-macos.xml' + testRunTitle: 'CredManagement macOS Tests' + + - job: Validate_SPM + displayName: 'Validate SPM Resolution' + pool: + vmImage: 'macOS-14' + timeoutInMinutes: 15 + steps: + - checkout: self + clean: true + submodules: true + fetchDepth: 1 + + - script: | + sudo xcode-select -s /Applications/Xcode_$(XCODE_VERSION).app + displayName: 'Select Xcode $(XCODE_VERSION)' + + - script: | + cd $(SDK_PATH) + swift package resolve + displayName: 'SPM — Resolve Dependencies' + + - script: | + cd $(SDK_PATH) + swift build + displayName: 'SPM — Build (Debug)' + + - script: | + cd $(SDK_PATH) + swift build -c release + displayName: 'SPM — Build (Release)' + +# ============================================================================= +# Stage 2: Release — Build XCFramework +# ============================================================================= +- stage: Release + displayName: 'Build XCFramework' + dependsOn: Validate + condition: succeeded() + jobs: + + - job: Build_XCFramework + displayName: 'Archive & Create XCFramework' + pool: + vmImage: 'macOS-14' + timeoutInMinutes: 45 + steps: + - checkout: self + clean: true + submodules: true + fetchDepth: 1 + + - script: | + sudo xcode-select -s /Applications/Xcode_$(XCODE_VERSION).app + displayName: 'Select Xcode $(XCODE_VERSION)' + + # Extract version from tag (credmgmt/1.0.0 → 1.0.0) or use 'dev' for branch builds + - script: | + if [[ "$(Build.SourceBranch)" == refs/tags/credmgmt/* ]]; then + TAG_NAME=$(echo "$(Build.SourceBranchName)") + echo "##vso[task.setvariable variable=SDK_VERSION]${TAG_NAME}" + echo "SDK Version: ${TAG_NAME}" + else + echo "##vso[task.setvariable variable=SDK_VERSION]dev-$(Build.BuildNumber)" + echo "SDK Version: dev-$(Build.BuildNumber)" + fi + displayName: 'Extract Version' + + - script: | + cd $(SDK_PATH) + xcodebuild -resolvePackageDependencies \ + -scheme MSALNativeCredManagment \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages + displayName: 'Resolve Package Dependencies' + + # Archive for iOS device + - script: | + cd $(SDK_PATH) + xcodebuild archive \ + -scheme MSALNativeCredManagment \ + -destination 'generic/platform=iOS' \ + -archivePath $(Build.BinariesDirectory)/archives/ios.xcarchive \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO + displayName: 'Archive — iOS Device' + + # Archive for iOS Simulator + - script: | + cd $(SDK_PATH) + xcodebuild archive \ + -scheme MSALNativeCredManagment \ + -destination 'generic/platform=iOS Simulator' \ + -archivePath $(Build.BinariesDirectory)/archives/ios-simulator.xcarchive \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO + displayName: 'Archive — iOS Simulator' + + # Archive for macOS + - script: | + cd $(SDK_PATH) + xcodebuild archive \ + -scheme MSALNativeCredManagment \ + -destination 'generic/platform=macOS' \ + -archivePath $(Build.BinariesDirectory)/archives/macos.xcarchive \ + -clonedSourcePackagesDirPath $(Build.BinariesDirectory)/spm-packages \ + SKIP_INSTALL=NO \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO + displayName: 'Archive — macOS' + + # Create XCFramework from all archives + - script: | + xcodebuild -create-xcframework \ + -framework $(Build.BinariesDirectory)/archives/ios.xcarchive/Products/Library/Frameworks/MSALNativeCredManagment.framework \ + -framework $(Build.BinariesDirectory)/archives/ios-simulator.xcarchive/Products/Library/Frameworks/MSALNativeCredManagment.framework \ + -framework $(Build.BinariesDirectory)/archives/macos.xcarchive/Products/Library/Frameworks/MSALNativeCredManagment.framework \ + -output $(XCFRAMEWORK_OUTPUT) + displayName: 'Create XCFramework' + + # Zip for distribution + - script: | + cd $(Build.ArtifactStagingDirectory) + zip -r MSALNativeCredManagment-$(SDK_VERSION).xcframework.zip MSALNativeCredManagment.xcframework + displayName: 'Zip XCFramework' + + - task: PublishBuildArtifacts@1 + displayName: 'Publish XCFramework Artifact' + inputs: + pathToPublish: '$(Build.ArtifactStagingDirectory)/MSALNativeCredManagment-$(SDK_VERSION).xcframework.zip' + artifactName: 'MSALNativeCredManagment-XCFramework' + publishLocation: 'Container' + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Raw XCFramework' + inputs: + pathToPublish: '$(XCFRAMEWORK_OUTPUT)' + artifactName: 'MSALNativeCredManagment-XCFramework-Raw' + publishLocation: 'Container' diff --git a/lib/native/MSALNativeCredManagment/CHANGELOG.md b/lib/native/MSALNativeCredManagment/CHANGELOG.md new file mode 100644 index 0000000000..7ccae9d923 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/CHANGELOG.md @@ -0,0 +1,3 @@ +## [0.1.0] +* Initial implementation of MSAL Native Credential Management SDK. +* Add credential method support for CIAM scenarios. diff --git a/lib/native/MSALNativeCredManagment/CMSAL_Private/include/module.modulemap b/lib/native/MSALNativeCredManagment/CMSAL_Private/include/module.modulemap new file mode 100644 index 0000000000..876ac3c4b2 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/CMSAL_Private/include/module.modulemap @@ -0,0 +1,15 @@ +// Minimal MSAL_Private module for credential management. +// Exposes IdentityCore types needed by Swift code (logger, context). +// Paths are relative to this modulemap file's location. +module MSAL_Private { + header "../../../../../MSAL/IdentityCore/IdentityCore/src/MSIDBasicContext.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/logger/MSIDLogger.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/logger/MSIDLogger+Internal.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/logger/MSIDMaskedHashableLogParameter.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/logger/MSIDMaskedLogParameter.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/logger/MSIDMaskedUsernameLogParameter.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/MSIDError.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/oauth2/MSIDExternalSSOContext.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/parameters/MSIDRequestParameters.h" + export * +} diff --git a/lib/native/MSALNativeCredManagment/Info.plist b/lib/native/MSALNativeCredManagment/Info.plist new file mode 100644 index 0000000000..ec0cc7b0cb --- /dev/null +++ b/lib/native/MSALNativeCredManagment/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..fbf4845b04 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj @@ -0,0 +1,494 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + A1000001 /* MSAL in Frameworks */ = {isa = PBXBuildFile; productRef = A1000002 /* MSAL */; }; + A1000003 /* MSALNativeCredManagment.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1000010 /* MSALNativeCredManagment.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + A1000004 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A1000020 /* Project object */; + proxyType = 1; + remoteGlobalIDString = A1000011; + remoteInfo = MSALNativeCredManagment; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + A1000010 /* MSALNativeCredManagment.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MSALNativeCredManagment.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A1000015 /* MSALNativeCredManagmentTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MSALNativeCredManagmentTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + A1000030 /* MSALNativeCredManagment */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = MSALNativeCredManagment; + sourceTree = ""; + }; + A1000031 /* MSALNativeCredManagmentTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = MSALNativeCredManagmentTests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + A1000040 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A1000001 /* MSAL in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1000041 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A1000003 /* MSALNativeCredManagment.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A1000050 = { + isa = PBXGroup; + children = ( + A1000030 /* MSALNativeCredManagment */, + A1000031 /* MSALNativeCredManagmentTests */, + A1000051 /* Products */, + ); + sourceTree = ""; + }; + A1000051 /* Products */ = { + isa = PBXGroup; + children = ( + A1000010 /* MSALNativeCredManagment.framework */, + A1000015 /* MSALNativeCredManagmentTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + A1000060 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + A1000011 /* MSALNativeCredManagment */ = { + isa = PBXNativeTarget; + buildConfigurationList = A1000070 /* Build configuration list for PBXNativeTarget "MSALNativeCredManagment" */; + buildPhases = ( + A1000060 /* Headers */, + A1000061 /* Sources */, + A1000040 /* Frameworks */, + A1000062 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + A1000030 /* MSALNativeCredManagment */, + ); + name = MSALNativeCredManagment; + packageProductDependencies = ( + A1000002 /* MSAL */, + ); + productName = MSALNativeCredManagment; + productReference = A1000010 /* MSALNativeCredManagment.framework */; + productType = "com.apple.product-type.framework"; + }; + A1000012 /* MSALNativeCredManagmentTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A1000071 /* Build configuration list for PBXNativeTarget "MSALNativeCredManagmentTests" */; + buildPhases = ( + A1000063 /* Sources */, + A1000041 /* Frameworks */, + A1000064 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + A1000005 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + A1000031 /* MSALNativeCredManagmentTests */, + ); + name = MSALNativeCredManagmentTests; + packageProductDependencies = ( + ); + productName = MSALNativeCredManagmentTests; + productReference = A1000015 /* MSALNativeCredManagmentTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + A1000020 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1620; + LastUpgradeCheck = 1620; + }; + buildConfigurationList = A1000072 /* Build configuration list for PBXProject "MSALNativeCredManagment" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = A1000050; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + A1000080 /* XCLocalSwiftPackageReference "../../.." */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = A1000051 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A1000011 /* MSALNativeCredManagment */, + A1000012 /* MSALNativeCredManagmentTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + A1000062 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1000064 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + A1000061 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1000063 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + A1000005 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = A1000011 /* MSALNativeCredManagment */; + targetProxy = A1000004 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + A1000090 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + A1000091 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + A1000092 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = UBF8T346G9; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 13.0; + MARKETING_VERSION = 0.1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.MSALNativeCredManagment; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = auto; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INCLUDE_PATHS = "$(SRCROOT)/CMSAL_Private/include"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A1000093 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = UBF8T346G9; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 13.0; + MARKETING_VERSION = 0.1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.MSALNativeCredManagment; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = auto; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INCLUDE_PATHS = "$(SRCROOT)/CMSAL_Private/include"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + A1000094 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = UBF8T346G9; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; + PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.MSALNativeCredManagmentTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A1000095 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = UBF8T346G9; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MACOSX_DEPLOYMENT_TARGET = 13.0; + PRODUCT_BUNDLE_IDENTIFIER = com.microsoft.MSALNativeCredManagmentTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A1000070 /* Build configuration list for PBXNativeTarget "MSALNativeCredManagment" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A1000092 /* Debug */, + A1000093 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A1000071 /* Build configuration list for PBXNativeTarget "MSALNativeCredManagmentTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A1000094 /* Debug */, + A1000095 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A1000072 /* Build configuration list for PBXProject "MSALNativeCredManagment" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A1000090 /* Debug */, + A1000091 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + A1000080 /* XCLocalSwiftPackageReference "../../.." */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../../..; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + A1000002 /* MSAL */ = { + isa = XCSwiftPackageProductDependency; + productName = MSAL; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = A1000020 /* Project object */; +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..919434a625 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/xcshareddata/xcschemes/MSALNativeCredManagment.xcscheme b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/xcshareddata/xcschemes/MSALNativeCredManagment.xcscheme new file mode 100644 index 0000000000..a8b745e28d --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/xcshareddata/xcschemes/MSALNativeCredManagment.xcscheme @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.docc/MSALNativeCredManagment.md b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.docc/MSALNativeCredManagment.md new file mode 100644 index 0000000000..769c241024 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.docc/MSALNativeCredManagment.md @@ -0,0 +1,13 @@ +# ``MSALNativeCredManagment`` + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` \ No newline at end of file diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.h b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.h new file mode 100644 index 0000000000..03a4145664 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.h @@ -0,0 +1,31 @@ +// +// 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 + +//! Project version number for MSALNativeCredManagment. +FOUNDATION_EXPORT double MSALNativeCredManagmentVersionNumber; + +//! Project version string for MSALNativeCredManagment. +FOUNDATION_EXPORT const unsigned char MSALNativeCredManagmentVersionString[]; diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/MSALNativeCredManagment.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/MSALNativeCredManagment.swift new file mode 100644 index 0000000000..4309940cf0 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/MSALNativeCredManagment.swift @@ -0,0 +1,37 @@ +// +// 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 Foundation +import MSAL +@_implementationOnly import MSAL_Private + +/// MSALNativeCredManagment SDK — Credential management for CIAM users. +/// +/// This framework provides APIs for managing credential methods (e.g., passkey) +/// for users authenticated via Microsoft Entra External ID (CIAM). +public enum MSALNativeCredManagmentSDK +{ + /// The current version of the MSALNativeCredManagment SDK. + public static let version = "0.1.0" +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagmentTests/MSALNativeCredManagmentTests.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagmentTests/MSALNativeCredManagmentTests.swift new file mode 100644 index 0000000000..45253339af --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagmentTests/MSALNativeCredManagmentTests.swift @@ -0,0 +1,34 @@ +// +// 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 Testing +@testable import MSALNativeCredManagment + +struct MSALNativeCredManagmentTests +{ + @Test func sdkVersionIsSet() async throws + { + #expect(MSALNativeCredManagmentSDK.version == "0.1.0") + } +} diff --git a/lib/native/MSALNativeCredManagment/Package.swift b/lib/native/MSALNativeCredManagment/Package.swift new file mode 100644 index 0000000000..bc19cd2c66 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/Package.swift @@ -0,0 +1,68 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription +import Foundation + +// Compute absolute path to MSAL root from this Package.swift location +let packageDir = URL(fileURLWithPath: #filePath).deletingLastPathComponent().path +let msalRoot = URL(fileURLWithPath: packageDir + "/../../../MSAL").standardized.path + +// Dynamically discover all subdirectories containing .h files. +// This is necessary because IdentityCore headers use bare `#import "filename.h"` without relative paths. +func findHeaderDirs(in basePath: String) -> [String] { + let fm = FileManager.default + guard let enumerator = fm.enumerator(atPath: basePath) else { return [] } + var dirs = Set() + dirs.insert(basePath) + while let item = enumerator.nextObject() as? String { + if item.hasSuffix(".h") { + let dir = (item as NSString).deletingLastPathComponent + if !dir.isEmpty { + dirs.insert(basePath + "/" + dir) + } + } + } + return Array(dirs).sorted() +} + +let allHeaderDirs = findHeaderDirs(in: msalRoot + "/IdentityCore/IdentityCore/src") + +let package = Package( + name: "MSALNativeCredManagment", + platforms: [ + .iOS(.v16), + .macOS(.v13) + ], + products: [ + .library( + name: "MSALNativeCredManagment", + targets: ["MSALNativeCredManagment"] + ) + ], + dependencies: [ + // MSAL SDK — use the published binary package for SPM resolution. + // Xcode project builds use the local framework target directly. + .package(url: "https://github.com/AzureAD/microsoft-authentication-library-for-objc.git", from: "2.11.0") + ], + targets: [ + .target( + name: "MSALNativeCredManagment", + dependencies: [ + .product(name: "MSAL", package: "microsoft-authentication-library-for-objc") + ], + path: "MSALNativeCredManagment/src", + swiftSettings: [ + .unsafeFlags( + ["-Xcc", "-fmodule-map-file=\(packageDir)/CMSAL_Private/include/module.modulemap"] + + allHeaderDirs.flatMap { ["-Xcc", "-I\($0)"] } + ) + ] + ), + .testTarget( + name: "MSALNativeCredManagmentTests", + dependencies: ["MSALNativeCredManagment"], + path: "MSALNativeCredManagmentTests" + ) + ] +) diff --git a/lib/native/MSALNativeCredManagment/README.md b/lib/native/MSALNativeCredManagment/README.md new file mode 100644 index 0000000000..a4793ffad5 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/README.md @@ -0,0 +1,57 @@ +# MSAL Native Credential Management SDK + +The MSAL Native Credential Management SDK provides native credential management capabilities for iOS and macOS applications using Microsoft Identity Platform (CIAM / External ID). + +## Overview + +This SDK extends the Microsoft Authentication Library (MSAL) with native credential management support, enabling applications to manage credentials directly through the Microsoft identity platform without requiring browser-based interactions. + +## Requirements + +- iOS 16.0+ / macOS 13.0+ +- Swift 5.9+ +- Xcode 15+ + +## Installation + +### Swift Package Manager + +Add the package dependency to your `Package.swift`: + +```swift +dependencies: [ + .package(path: "path/to/MSALNativeCredManagment") +] +``` + +### As part of the MSAL workspace + +Open `MSAL.xcworkspace` and include the `MSALNativeCredManagment` target. + +## Dependencies + +- [MSAL for iOS/macOS](https://github.com/AzureAD/microsoft-authentication-library-for-objc) — Microsoft Authentication Library +- IdentityCore — Shared identity common library (via MSAL submodule) + +## Project Structure + +``` +MSALNativeCredManagment/ +├── CMSAL_Private/ # Private module map for IdentityCore bridging +├── MSALNativeCredManagment/ +│ ├── src/ # Source code +│ │ └── internal/ # Internal implementation +│ └── Info.plist # Framework version tracking +├── MSALNativeCredManagmentTests/ +├── Package.swift # SPM manifest +├── CHANGELOG.md # Version history +└── README.md # This file +``` + +## Contributing + +This SDK is developed as part of the MSAL for iOS/macOS project. Please refer to the [main repository contribution guidelines](https://github.com/AzureAD/microsoft-authentication-library-for-objc/blob/dev/contributing.md). + +## License + +See [LICENSE](https://github.com/AzureAD/microsoft-authentication-library-for-objc/blob/dev/LICENSE).