From 574c28db6af07d60a55e818869651550f2c04d7b Mon Sep 17 00:00:00 2001 From: Sergey Demchenko Date: Mon, 8 Jun 2026 14:59:29 -0700 Subject: [PATCH 1/6] Initial cred sdk commit. --- .../CMSAL_Private/include/module.modulemap | 22 + .../project.pbxproj | 497 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../MSALNativeCredManagment.xcscheme | 70 +++ .../MSALNativeCredManagment.h | 31 ++ .../src/MSALNativeCredManagment.swift | 37 ++ .../MSALNativeCredManagmentTests.swift | 34 ++ .../MSALNativeCredManagment/Package.swift | 67 +++ 8 files changed, 765 insertions(+) create mode 100644 lib/native/MSALNativeCredManagment/CMSAL_Private/include/module.modulemap create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/xcshareddata/xcschemes/MSALNativeCredManagment.xcscheme create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.h create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/MSALNativeCredManagment.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagmentTests/MSALNativeCredManagmentTests.swift create mode 100644 lib/native/MSALNativeCredManagment/Package.swift 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..b418a50775 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/CMSAL_Private/include/module.modulemap @@ -0,0 +1,22 @@ +// Minimal MSAL_Private module for credential management. +// Exposes IdentityCore types needed by Swift code (network, logger, context). +// Paths are relative to this modulemap file's location. +module MSAL_Private { + header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/MSIDHttpRequest.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/MSIDHttpRequestInterceptorProtocol.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/request_server_telemetry/MSIDHttpRequestServerTelemetryHandling.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/request_serializer/MSIDRequestSerialization.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/request_configurator/MSIDHttpRequestConfiguratorProtocol.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/response_serializer/MSIDResponseSerialization.h" + header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/error_handler/MSIDHttpRequestErrorHandling.h" + 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/MSALNativeCredManagment.xcodeproj/project.pbxproj b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..8afdb8f496 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj @@ -0,0 +1,497 @@ +// !$*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 /* Root */ = { + 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 /* Root */; + 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; + GENERATE_INFOPLIST_FILE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + 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; + GENERATE_INFOPLIST_FILE = YES; + HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + 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.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..fddb7f65ca --- /dev/null +++ b/lib/native/MSALNativeCredManagment/Package.swift @@ -0,0 +1,67 @@ +// 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 as a local dependency (relative path to the root of microsoft-authentication-library-for-objc) + .package(path: "../../..") + ], + 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" + ) + ] +) From 21c135bc4d3d3cb1b22af4cbf12964d4cf456695 Mon Sep 17 00:00:00 2001 From: Sergey Demchenko Date: Mon, 8 Jun 2026 15:09:00 -0700 Subject: [PATCH 2/6] add version and md files. --- .../MSALNativeCredManagment/CHANGELOG.md | 3 + .../CMSAL_Private/include/module.modulemap | 9 +-- .../project.pbxproj | 13 ++--- .../MSALNativeCredManagment/Info.plist | 24 ++++++++ lib/native/MSALNativeCredManagment/README.md | 57 +++++++++++++++++++ 5 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 lib/native/MSALNativeCredManagment/CHANGELOG.md create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/Info.plist create mode 100644 lib/native/MSALNativeCredManagment/README.md 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 index b418a50775..876ac3c4b2 100644 --- a/lib/native/MSALNativeCredManagment/CMSAL_Private/include/module.modulemap +++ b/lib/native/MSALNativeCredManagment/CMSAL_Private/include/module.modulemap @@ -1,14 +1,7 @@ // Minimal MSAL_Private module for credential management. -// Exposes IdentityCore types needed by Swift code (network, logger, context). +// 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/network/MSIDHttpRequest.h" - header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/MSIDHttpRequestInterceptorProtocol.h" - header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/request_server_telemetry/MSIDHttpRequestServerTelemetryHandling.h" - header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/request_serializer/MSIDRequestSerialization.h" - header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/request_configurator/MSIDHttpRequestConfiguratorProtocol.h" - header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/response_serializer/MSIDResponseSerialization.h" - header "../../../../../MSAL/IdentityCore/IdentityCore/src/network/error_handler/MSIDHttpRequestErrorHandling.h" header "../../../../../MSAL/IdentityCore/IdentityCore/src/MSIDBasicContext.h" header "../../../../../MSAL/IdentityCore/IdentityCore/src/logger/MSIDLogger.h" header "../../../../../MSAL/IdentityCore/IdentityCore/src/logger/MSIDLogger+Internal.h" diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj index 8afdb8f496..7067125760 100644 --- a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj @@ -59,7 +59,7 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - A1000050 /* Root */ = { + A1000050 = { isa = PBXGroup; children = ( A1000030 /* MSALNativeCredManagment */, @@ -154,7 +154,7 @@ en, Base, ); - mainGroup = A1000050 /* Root */; + mainGroup = A1000050; minimizedProjectReferenceProxies = 1; packageReferences = ( A1000080 /* XCLocalSwiftPackageReference "../../.." */, @@ -338,9 +338,8 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_MODULE_VERIFIER = YES; - GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_FILE = "$(SRCROOT)/MSALNativeCredManagment/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -379,9 +378,8 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_MODULE_VERIFIER = YES; - GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_FILE = "$(SRCROOT)/MSALNativeCredManagment/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -481,7 +479,7 @@ /* Begin XCLocalSwiftPackageReference section */ A1000080 /* XCLocalSwiftPackageReference "../../.." */ = { isa = XCLocalSwiftPackageReference; - relativePath = "../../.."; + relativePath = ../../..; }; /* End XCLocalSwiftPackageReference section */ @@ -491,7 +489,6 @@ productName = MSAL; }; /* End XCSwiftPackageProductDependency section */ - }; rootObject = A1000020 /* Project object */; } diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/Info.plist b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/Info.plist new file mode 100644 index 0000000000..ec0cc7b0cb --- /dev/null +++ b/lib/native/MSALNativeCredManagment/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/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). From b3c46b83e1371b35b5adfcf1ac9a74c945a9db93 Mon Sep 17 00:00:00 2001 From: Sergey Demchenko Date: Mon, 8 Jun 2026 15:21:49 -0700 Subject: [PATCH 3/6] Fix build errors. --- .../{MSALNativeCredManagment => }/Info.plist | 0 .../MSALNativeCredManagment.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename lib/native/MSALNativeCredManagment/{MSALNativeCredManagment => }/Info.plist (100%) diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/Info.plist b/lib/native/MSALNativeCredManagment/Info.plist similarity index 100% rename from lib/native/MSALNativeCredManagment/MSALNativeCredManagment/Info.plist rename to lib/native/MSALNativeCredManagment/Info.plist diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj index 7067125760..fbf4845b04 100644 --- a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment.xcodeproj/project.pbxproj @@ -339,7 +339,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_MODULE_VERIFIER = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; - INFOPLIST_FILE = "$(SRCROOT)/MSALNativeCredManagment/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -379,7 +379,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_MODULE_VERIFIER = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../MSAL/IdentityCore/IdentityCore/src/**"; - INFOPLIST_FILE = "$(SRCROOT)/MSALNativeCredManagment/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( From f88064a7030b69899513ffd94b731a2f5bdd1f48 Mon Sep 17 00:00:00 2001 From: Sergey Demchenko Date: Mon, 8 Jun 2026 16:36:56 -0700 Subject: [PATCH 4/6] new file: MSALNativeCredManagment/MSALNativeCredManagment.docc/MSALNativeCredManagment.md --- .../MSALNativeCredManagment.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/MSALNativeCredManagment.docc/MSALNativeCredManagment.md 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 From f7f0e77222a3cc8ddd3ea390d23977833c00fc58 Mon Sep 17 00:00:00 2001 From: Sergey Demchenko Date: Mon, 8 Jun 2026 17:23:19 -0700 Subject: [PATCH 5/6] Add public API surface stubs for credential management (passkey only) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds the complete public API surface for the Credential Management SDK, limited to passkey (FIDO2/WebAuthn) credential type only. All implementations are stubs (fatalError) — this PR is purely for API shape review. New files: - MSALNativeCredentialMethodsClient — Main client (list/register/delete) - MSALNativeCredentialManagementConfig — Configuration class - MSALNativeCredentialManagementError — Error types - MSALCredentialMethodProtocol — Protocol for credential methods - MSALCredentialType — Extensible type identifier - MSALCredentialMethod — Internal base class - MSALPasskeyCredentialMethod — Passkey concrete type - MSALRegisterMethods — Registration namespace - MSALRegisterMethods+Passkey — Passkey registration extension - MSALRegisterParams/MSALRegisterPasskeyParams — Params classes - MSALCredentialMethodRegistrationResult — Result enum + ChallengeState - MSALNativeCredentialManagementTokenProvider — Token provider protocol - MSALNativeAuthTokenProvider — Built-in MSAL token provider (stub) Work item: AB#3654791 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../MSALCredentialMethod.swift | 67 ++++++++++ ...ALCredentialMethodRegistrationResult.swift | 99 +++++++++++++++ ...MSALNativeCredentialManagementConfig.swift | 57 +++++++++ .../MSALNativeCredentialManagementError.swift | 103 +++++++++++++++ .../MSALNativeCredentialMethodsClient.swift | 119 ++++++++++++++++++ .../src/public/MSALRegisterMethods.swift | 43 +++++++ .../src/public/MSALRegisterParams.swift | 46 +++++++ .../MSALCredentialMethodProtocol.swift | 46 +++++++ .../MSALCredentialType.swift | 51 ++++++++ .../passkey/MSALPasskeyCredentialMethod.swift | 88 +++++++++++++ .../passkey/MSALRegisterMethods+Passkey.swift | 59 +++++++++ .../passkey/MSALRegisterPasskeyParams.swift | 61 +++++++++ .../MSALNativeAuthTokenProvider.swift | 74 +++++++++++ ...iveCredentialManagementTokenProvider.swift | 53 ++++++++ 14 files changed, 966 insertions(+) create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/internal/credential_method/MSALCredentialMethod.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALCredentialMethodRegistrationResult.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementConfig.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterMethods.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterParams.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialMethodProtocol.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialType.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALPasskeyCredentialMethod.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterMethods+Passkey.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterPasskeyParams.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeAuthTokenProvider.swift create mode 100644 lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeCredentialManagementTokenProvider.swift diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/internal/credential_method/MSALCredentialMethod.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/internal/credential_method/MSALCredentialMethod.swift new file mode 100644 index 0000000000..281a971ee8 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/internal/credential_method/MSALCredentialMethod.swift @@ -0,0 +1,67 @@ +// +// 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 + +/// Internal abstract base class for all credential methods. +/// +/// Each credential type (e.g., passkey) is represented by a concrete subclass. +/// New credential types can be added by subclassing without modifying existing +/// classes (Open/Closed Principle). +/// +/// **Do not instantiate `MSALCredentialMethod` directly** — use a concrete subclass +/// such as `MSALPasskeyCredentialMethod`. +@objcMembers +public class MSALCredentialMethod: NSObject, MSALCredentialMethodProtocol +{ + /// Unique identifier of the credential method (set by the server). + /// + /// - Important: This is a persistent unique identifier. Do not log without PII gating. + public internal(set) var id: String + + /// The type identifier (e.g., `.passkey`). + public let credentialType: MSALCredentialType + + /// Display-friendly name or hint. + /// + /// - Important: May contain user-provided data. Do not log without PII gating. + public internal(set) var displayName: String? + + /// Timestamp of when this method was registered (set by the server). + public internal(set) var createdAt: Date? + + internal init( + id: String, + credentialType: MSALCredentialType, + displayName: String?, + createdAt: Date? + ) + { + self.id = id + self.credentialType = credentialType + self.displayName = displayName + self.createdAt = createdAt + super.init() + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALCredentialMethodRegistrationResult.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALCredentialMethodRegistrationResult.swift new file mode 100644 index 0000000000..9886645a12 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALCredentialMethodRegistrationResult.swift @@ -0,0 +1,99 @@ +// +// 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 + +/// The result of a credential method registration attempt. +/// +/// Registration may complete immediately or require a verification challenge (e.g., OOB code). +public enum MSALCredentialMethodRegistrationResult +{ + /// Registration completed successfully. + case completed(any MSALCredentialMethodProtocol) + + /// A verification challenge is required to complete registration. + /// Use the provided `MSALCredentialMethodChallengeState` to submit the code or resend. + case challengeRequired(MSALCredentialMethodChallengeState) +} + +/// Represents the state of a pending challenge during credential registration. +/// +/// Use `submitChallenge(code:)` to verify or `resendChallenge()` to request a new code. +/// +/// - Important: The `continuationToken` is opaque, short-lived, and must not be logged or persisted. +public class MSALCredentialMethodChallengeState +{ + /// The channel the code was sent to (e.g., masked email or phone hint). + /// + /// - Important: May contain partially masked PII. Do not log without PII gating. + public let sentTo: String? + + /// The channel type (e.g., "email", "phone"). + public let channelType: String? + + /// The number of digits in the expected code. + public let codeLength: Int? + + // MARK: - Internal + + private let continuationToken: String + private weak var client: MSALNativeCredentialMethodsClient? + private let correlationId: UUID + + internal init( + sentTo: String?, + channelType: String?, + codeLength: Int?, + continuationToken: String, + client: MSALNativeCredentialMethodsClient, + correlationId: UUID + ) + { + self.sentTo = sentTo + self.channelType = channelType + self.codeLength = codeLength + self.continuationToken = continuationToken + self.client = client + self.correlationId = correlationId + } + + /// Submit the verification code to complete registration. + /// + /// - Parameter code: The verification code received by the user. + /// - Returns: A `Result` containing the registered credential method or an error. + public func submitChallenge( + code: String + ) async -> Result + { + fatalError("Not implemented — stub only") + } + + /// Request a new verification code. + /// + /// - Returns: A new `MSALCredentialMethodChallengeState` with updated delivery info, or an error. + public func resendChallenge() async -> Result + { + fatalError("Not implemented — stub only") + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementConfig.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementConfig.swift new file mode 100644 index 0000000000..79010dfb7a --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementConfig.swift @@ -0,0 +1,57 @@ +// +// 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 + +/// Configuration for the credential management client. +/// +/// Use this class to configure the `MSALNativeCredentialMethodsClient` with a token provider +/// and tenant subdomain. +/// +/// Example: +/// ```swift +/// let config = MSALNativeCredentialManagementConfig() +/// config.tokenProvider = MyCustomTokenProvider() +/// config.tenantSubdomain = "contoso" +/// let client = try MSALNativeCredentialMethodsClient(config: config) +/// ``` +@objcMembers +public class MSALNativeCredentialManagementConfig: NSObject +{ + /// The token provider used to obtain access tokens for credential management API calls. + /// + /// Must be set before initializing `MSALNativeCredentialMethodsClient`. + public var tokenProvider: MSALNativeCredentialManagementTokenProvider? + + /// The tenant subdomain for the CIAM tenant (e.g., "contoso" for contoso.ciamlogin.com). + /// + /// The credential management API base URL is derived from this value. + /// Must be set before initializing `MSALNativeCredentialMethodsClient`. + public var tenantSubdomain: String? + + public override init() + { + super.init() + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift new file mode 100644 index 0000000000..87f251846a --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift @@ -0,0 +1,103 @@ +// +// 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 + +/// Error domain for credential management operations. +public let MSALNativeCredentialManagementErrorDomain = "MSALNativeCredentialManagementErrorDomain" + +/// Error types for credential management operations. +@objc public enum MSALNativeCredentialManagementErrorType: Int +{ + /// A general, unclassified error occurred. + case generalError = 0 + /// A network error occurred (timeout, connectivity, etc.). + case networkError = 1 + /// The access token is invalid or expired. + case unauthorized = 2 + /// The user lacks permission for this operation. + case forbidden = 3 + /// The specified credential method was not found. + case notFound = 4 + /// A conflict occurred (e.g., method already registered). + case conflict = 5 + /// Challenge verification failed. + case challengeFailed = 6 + /// The token provider reports no valid session. + case sessionExpired = 7 + /// The client configuration is invalid. + case invalidConfiguration = 8 + /// The input provided is invalid. + case invalidInput = 9 +} + +/// Error class for credential management operations. +/// +/// Contains a typed error code, human-readable message, and optional correlation ID +/// for diagnostics. +/// +/// - Important: The `message` property must never contain tokens, credentials, or PII. +/// Use only for diagnostic text safe for logging. +@objcMembers +public class MSALNativeCredentialManagementError: NSObject, Error +{ + /// The type of error that occurred. + public let type: MSALNativeCredentialManagementErrorType + + /// A human-readable error message describing what went wrong. + /// + /// - Important: Must not contain tokens, PII, or sensitive data. + public let message: String? + + /// The correlation ID associated with this error for diagnostic purposes. + public let correlationId: UUID? + + /// The underlying error, if any. + public let underlyingError: Error? + + internal init( + type: MSALNativeCredentialManagementErrorType, + message: String? = nil, + correlationId: UUID? = nil, + underlyingError: Error? = nil + ) + { + self.type = type + self.message = message + self.correlationId = correlationId + self.underlyingError = underlyingError + super.init() + } + + public override var description: String + { + var desc = "MSALNativeCredentialManagementError(type: \(type)" + if let correlationId = correlationId + { + desc += ", correlationId: \(correlationId)" + } + desc += ")" + return desc + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift new file mode 100644 index 0000000000..c167544d83 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift @@ -0,0 +1,119 @@ +// +// 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 + +/// Client for managing credential methods of an authenticated CIAM user. +/// +/// This client provides APIs to list, register, and delete credential methods +/// (e.g., passkey) for the currently signed-in user. +/// +/// Example: +/// ```swift +/// let config = MSALNativeCredentialManagementConfig() +/// config.tokenProvider = myTokenProvider +/// config.tenantSubdomain = "contoso" +/// let client = try MSALNativeCredentialMethodsClient(config: config) +/// +/// let result = await client.listCredentialMethods() +/// ``` +@objcMembers +public class MSALNativeCredentialMethodsClient: NSObject +{ + // MARK: - Public: Initialization + + /// Initialize the credential methods client. + /// + /// - Parameter config: Configuration including token provider and tenant subdomain. + /// - Throws: `MSALNativeCredentialManagementError` if the configuration is invalid + /// (e.g., no token provider or tenant subdomain set). + public init(config: MSALNativeCredentialManagementConfig) throws + { + guard config.tokenProvider != nil else + { + throw MSALNativeCredentialManagementError( + type: .invalidConfiguration, + message: "A token provider must be set on MSALNativeCredentialManagementConfig before initializing the client." + ) + } + guard config.tenantSubdomain != nil else + { + throw MSALNativeCredentialManagementError( + type: .invalidConfiguration, + message: "A tenantSubdomain must be set on MSALNativeCredentialManagementConfig before initializing the client." + ) + } + self.config = config + super.init() + } + + // MARK: - Public: List Credential Methods + + /// Retrieve the list of credential methods registered for the current user. + /// + /// - Parameter correlationId: Optional correlation ID for request tracing. + /// A new UUID is generated if nil. + /// - Returns: A `Result` containing the array of credential methods or an error. + public func listCredentialMethods( + correlationId: UUID? = nil + ) async -> Result<[any MSALCredentialMethodProtocol], MSALNativeCredentialManagementError> + { + fatalError("Not implemented — stub only") + } + + // MARK: - Public: Register Operations + + /// Namespace grouping for method-specific registration flows. + /// + /// Each credential type has its own function because registration inputs + /// and activation flows differ per type. + /// + /// Usage: + /// ```swift + /// let params = MSALRegisterPasskeyParams(presentationAnchor: window, displayName: "My Key") + /// let result = await client.register.passkey(params: params) + /// ``` + public private(set) lazy var register: MSALRegisterMethods = MSALRegisterMethods(client: self) + + // MARK: - Public: Delete Credential Method + + /// Delete a credential method. + /// + /// - Parameters: + /// - credentialMethod: The credential method to remove. + /// - correlationId: Optional correlation ID for request tracing. + /// A new UUID is generated if nil. + /// - Returns: A `Result` indicating success or containing an error. + public func deleteCredentialMethod( + _ credentialMethod: any MSALCredentialMethodProtocol, + correlationId: UUID? = nil + ) async -> Result + { + fatalError("Not implemented — stub only") + } + + // MARK: - Internal + + internal let config: MSALNativeCredentialManagementConfig +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterMethods.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterMethods.swift new file mode 100644 index 0000000000..4de53e5ad0 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterMethods.swift @@ -0,0 +1,43 @@ +// +// 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 + +/// Namespace for credential method registration operations. +/// +/// Access via `client.register.passkey(...)`. +/// +/// Each credential type adds its registration method via an extension in its +/// own folder under `credential_method//`. This follows the Open/Closed +/// Principle — adding a new credential type requires only new files, without +/// modifying existing code. +public class MSALRegisterMethods +{ + internal weak var client: MSALNativeCredentialMethodsClient? + + internal init(client: MSALNativeCredentialMethodsClient) + { + self.client = client + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterParams.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterParams.swift new file mode 100644 index 0000000000..f1e37fc9ef --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALRegisterParams.swift @@ -0,0 +1,46 @@ +// +// 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 + +/// Base class for all credential method registration parameters. +/// +/// Subclasses add credential-specific fields (e.g., display name for passkey). +@objcMembers +public class MSALRegisterParams: NSObject +{ + /// Optional correlation ID for request tracing. A new UUID is generated if nil. + public var correlationId: UUID? + + public override init() + { + super.init() + } + + public init(correlationId: UUID?) + { + self.correlationId = correlationId + super.init() + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialMethodProtocol.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialMethodProtocol.swift new file mode 100644 index 0000000000..43d6aebcf8 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialMethodProtocol.swift @@ -0,0 +1,46 @@ +// +// 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 + +/// Protocol defining the contract for all credential method types. +/// +/// All credential method classes must conform to this protocol. +/// Use this protocol when you need to work with credential methods generically. +public protocol MSALCredentialMethodProtocol: AnyObject +{ + /// Unique identifier of the credential method. + var id: String { get } + + /// The type identifier (e.g., `.passkey`). + var credentialType: MSALCredentialType { get } + + /// Display-friendly name or hint. + /// + /// - Important: This property may contain user-provided data. Do not log without PII gating. + var displayName: String? { get } + + /// Timestamp of when this method was registered. + var createdAt: Date? { get } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialType.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialType.swift new file mode 100644 index 0000000000..4904ed4a47 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/MSALCredentialType.swift @@ -0,0 +1,51 @@ +// +// 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 + +/// A type-safe, extensible identifier for credential method types. +/// +/// New credential types are defined by adding a `static let` extension +/// in the corresponding credential class file — no central registry needed. +/// +/// Example (in a new credential file): +/// ```swift +/// extension MSALCredentialType { +/// public static let myNewType = MSALCredentialType("myNewType") +/// } +/// ``` +public struct MSALCredentialType: RawRepresentable, Hashable, Sendable +{ + public let rawValue: String + + public init(rawValue: String) + { + self.rawValue = rawValue + } + + public init(_ rawValue: String) + { + self.rawValue = rawValue + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALPasskeyCredentialMethod.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALPasskeyCredentialMethod.swift new file mode 100644 index 0000000000..f07c295e90 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALPasskeyCredentialMethod.swift @@ -0,0 +1,88 @@ +// +// 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 + +extension MSALCredentialType +{ + /// Passkey (FIDO2/WebAuthn) credential type. + public static let passkey = MSALCredentialType("fido") +} + +/// Represents a passkey (FIDO2/WebAuthn) credential method. +/// +/// - Important: The `credentialID` is a persistent unique identifier. +/// Do not log without PII gating. +@objcMembers +public class MSALPasskeyCredentialMethod: MSALCredentialMethod +{ + /// The base64url-encoded credential ID from WebAuthn registration. + /// + /// - Important: This is a persistent unique identifier. Do not log without PII gating. + public let credentialID: String? + + /// The AAGUID of the authenticator that created this passkey. + public let aaguid: String? + + /// Creates a passkey credential method. + /// + /// - Parameters: + /// - displayName: Optional human-readable name for the passkey. + /// - credentialID: The base64url-encoded credential ID. + /// - aaguid: The authenticator AAGUID. + public init( + displayName: String?, + credentialID: String?, + aaguid: String? = nil + ) + { + self.credentialID = credentialID + self.aaguid = aaguid + super.init( + id: "", + credentialType: .passkey, + displayName: displayName, + createdAt: nil + ) + } + + /// Internal initializer used by the SDK when hydrating from server responses. + internal init( + id: String, + displayName: String?, + createdAt: Date?, + credentialID: String?, + aaguid: String? = nil + ) + { + self.credentialID = credentialID + self.aaguid = aaguid + super.init( + id: id, + credentialType: .passkey, + displayName: displayName, + createdAt: createdAt + ) + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterMethods+Passkey.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterMethods+Passkey.swift new file mode 100644 index 0000000000..7404d15d82 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterMethods+Passkey.swift @@ -0,0 +1,59 @@ +// +// 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 + +extension MSALRegisterMethods +{ + /// Registers a new passkey (FIDO2/WebAuthn) credential. + /// + /// This single call handles the entire flow: + /// 1. Requests creation options from the server. + /// 2. Presents the system passkey sheet to the user. + /// 3. Submits the attestation back to the server. + /// + /// - Parameter params: Parameters including the presentation anchor and optional display name. + /// - Returns: A `Result` containing the registration result or an error. + /// + /// Example: + /// ```swift + /// let params = MSALRegisterPasskeyParams( + /// presentationAnchor: view.window!, + /// displayName: "My iPhone" + /// ) + /// let result = await client.register.passkey(params: params) + /// switch result { + /// case .success(.completed(let method)): + /// print("Registered: \(method.id)") + /// case .failure(let error): + /// print("Failed: \(error.message ?? "")") + /// } + /// ``` + public func passkey( + params: MSALRegisterPasskeyParams + ) async -> Result + { + fatalError("Not implemented — stub only") + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterPasskeyParams.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterPasskeyParams.swift new file mode 100644 index 0000000000..e9f4a36745 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/credential_method/passkey/MSALRegisterPasskeyParams.swift @@ -0,0 +1,61 @@ +// +// 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 AuthenticationServices +#if os(macOS) +import AppKit +#else +import UIKit +#endif + +/// Parameters for `client.register.passkey()`. +/// +/// The `presentationAnchor` is required — it provides the window in which the system +/// passkey sheet is presented. +@objcMembers +public class MSALRegisterPasskeyParams: MSALRegisterParams +{ + /// The window used to present the passkey authorization sheet. + public var presentationAnchor: ASPresentationAnchor + + /// Optional human-readable label for the passkey (e.g., "Work YubiKey"). + public var displayName: String? + + /// Creates passkey registration parameters. + /// + /// - Parameters: + /// - presentationAnchor: The window that will present the system passkey UI. + /// - displayName: Optional friendly name for the passkey. + /// - correlationId: Optional correlation ID for logging/diagnostics. + public init( + presentationAnchor: ASPresentationAnchor, + displayName: String? = nil, + correlationId: UUID? = nil + ) + { + self.presentationAnchor = presentationAnchor + self.displayName = displayName + super.init(correlationId: correlationId) + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeAuthTokenProvider.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeAuthTokenProvider.swift new file mode 100644 index 0000000000..aca4328041 --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeAuthTokenProvider.swift @@ -0,0 +1,74 @@ +// +// 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 + +/// A built-in token provider that uses MSAL's web-based interactive flow to acquire tokens. +/// +/// On first call, it presents a web view for interactive sign-in. On subsequent calls, +/// it attempts silent token acquisition using the cached account, falling back to interactive +/// if the silent attempt fails with `MSALErrorInteractionRequired`. +/// +/// Usage: +/// ```swift +/// let tokenProvider = try MSALNativeAuthTokenProvider(clientId: "your-client-id") +/// config.tokenProvider = tokenProvider +/// ``` +@objcMembers +public class MSALNativeAuthTokenProvider: NSObject, MSALNativeCredentialManagementTokenProvider +{ + /// Initialize with a client ID. Uses the default MSAL authority. + /// + /// - Parameter clientId: The application (client) ID registered in the identity platform. + /// - Throws: If the MSAL configuration is invalid. + public init(clientId: String) throws + { + super.init() + fatalError("Not implemented — stub only") + } + + /// Retrieve an access token using MSAL web flow. + /// + /// Attempts silent acquisition first. If no cached account exists or interaction is required, + /// falls back to interactive web view sign-in. + /// + /// - Parameters: + /// - scopes: The scopes required by the credential management operation. + /// - completionBlock: Called exactly once with the access token on success, + /// or nil and an error on failure. + public func getAccessToken( + scopes: [String], + completionBlock: @escaping MSALNativeCredentialManagementTokenCompletionBlock + ) + { + fatalError("Not implemented — stub only") + } + + /// Clear the cached account so the next token request triggers interactive sign-in. + public func signOut() + { + fatalError("Not implemented — stub only") + } +} diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeCredentialManagementTokenProvider.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeCredentialManagementTokenProvider.swift new file mode 100644 index 0000000000..c7aac95bec --- /dev/null +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/token_provider/MSALNativeCredentialManagementTokenProvider.swift @@ -0,0 +1,53 @@ +// +// 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 + +/// Completion block type for token retrieval. +/// +/// - Important: Implementations must not log or persist the token string. +/// The completion must always be called exactly once. +public typealias MSALNativeCredentialManagementTokenCompletionBlock = @convention(block) (String?, Error?) -> Void + +/// Protocol for providing access tokens to the credential management client. +/// +/// Implement this protocol to supply access tokens for credential management API calls. +/// - P0: Provide a custom implementation that calls your own backend. +/// - P1: Use the built-in `MSALNativeAuthTokenProvider` that wraps MSAL interactive/silent flow. +/// +/// - Important: Implementations must call the completion block exactly once and must not +/// persist or log the returned token. +@objc public protocol MSALNativeCredentialManagementTokenProvider: NSObjectProtocol +{ + /// Retrieve an access token suitable for calling the credential management API. + /// + /// - Parameters: + /// - scopes: The scopes required by the credential management operation. + /// - completionBlock: Must be called exactly once with an access token string on success, + /// or nil and an error on failure. + func getAccessToken( + scopes: [String], + completionBlock: @escaping MSALNativeCredentialManagementTokenCompletionBlock + ) +} From caf4388994f8775a2f32babac3d84ad9008428d4 Mon Sep 17 00:00:00 2001 From: Sergey Demchenko Date: Mon, 8 Jun 2026 18:06:14 -0700 Subject: [PATCH 6/6] Simplify error contract to base class with generalError only The error contract is not finalized yet. Keep only the base MSALNativeCredentialManagementError class with a single generalError case. All detailed error types (networkError, unauthorized, forbidden, notFound, conflict, challengeFailed, sessionExpired, invalidConfiguration, invalidInput) will be added in a future PR once the contract is finalized. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../MSALNativeCredentialManagementError.swift | 21 +++---------------- .../MSALNativeCredentialMethodsClient.swift | 4 ++-- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift index 87f251846a..f6c7a0dbe2 100644 --- a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialManagementError.swift @@ -28,28 +28,13 @@ import Foundation public let MSALNativeCredentialManagementErrorDomain = "MSALNativeCredentialManagementErrorDomain" /// Error types for credential management operations. +/// +/// - Note: This enum currently contains only a general error case. +/// Additional error cases will be added once the error contract is finalized. @objc public enum MSALNativeCredentialManagementErrorType: Int { /// A general, unclassified error occurred. case generalError = 0 - /// A network error occurred (timeout, connectivity, etc.). - case networkError = 1 - /// The access token is invalid or expired. - case unauthorized = 2 - /// The user lacks permission for this operation. - case forbidden = 3 - /// The specified credential method was not found. - case notFound = 4 - /// A conflict occurred (e.g., method already registered). - case conflict = 5 - /// Challenge verification failed. - case challengeFailed = 6 - /// The token provider reports no valid session. - case sessionExpired = 7 - /// The client configuration is invalid. - case invalidConfiguration = 8 - /// The input provided is invalid. - case invalidInput = 9 } /// Error class for credential management operations. diff --git a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift index c167544d83..e7725e9bfb 100644 --- a/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift +++ b/lib/native/MSALNativeCredManagment/MSALNativeCredManagment/src/public/MSALNativeCredentialMethodsClient.swift @@ -53,14 +53,14 @@ public class MSALNativeCredentialMethodsClient: NSObject guard config.tokenProvider != nil else { throw MSALNativeCredentialManagementError( - type: .invalidConfiguration, + type: .generalError, message: "A token provider must be set on MSALNativeCredentialManagementConfig before initializing the client." ) } guard config.tenantSubdomain != nil else { throw MSALNativeCredentialManagementError( - type: .invalidConfiguration, + type: .generalError, message: "A tenantSubdomain must be set on MSALNativeCredentialManagementConfig before initializing the client." ) }