[WIP] Native Auth V2 - #3039
Conversation
…3033) This PR isolates the Native Auth V2 server-driven **public contract** from `origin/sedemche/native-auth-v2` into a compile-safe, self-contained Part 1. It intentionally excludes controllers/networking/telemetry/tests and keeps the new V2 entry points and state continuations as `notImplemented` stubs until follow-up implementation PRs land. - **Public V2 contract added (new files only)** - Added `MSALNativeAuthFlowDelegate`, `MSALNativeAuthFlowError`, `MSALNativeAuthFlowScenario` - Added V2 state types under `public/state_machine/v2/state/`: - `MSALNativeAuthState` - `MSALNativeAuthCodeRequiredState` - `MSALNativeAuthPasswordRequiredState` - `MSALNativeAuthNewPasswordRequiredState` - `MSALNativeAuthAttributesRequiredState` - `MSALNativeAuthAttributesInvalidState` - `MSALNativeAuthMFARequiredState` - `MSALNativeAuthMFAVerificationRequiredState` - `MSALNativeAuthStrongAuthRegistrationRequiredState` - `MSALNativeAuthStrongAuthVerificationRequiredState` - **Public surface updates copied from source branch** - `MSALNativeAuthPublicClientApplication.swift`: adds `signInV2`, `signUpV2`, `resetPasswordV2` (stubbed bodies) - Updated public native-auth parameter/error types exactly per contract split: - `MSALNativeAuthResetPasswordParameters.swift` - `MSALNativeAuthSignUpParameters.swift` - `MSALNativeAuthError.swift` - `MSALNativeAuthGenericError.swift` - `MFARequestChallengeError.swift` - `MFASubmitChallengeError.swift` - `PasswordRequiredError.swift` - `RegisterStrongAuthChallengeError.swift` - `RegisterStrongAuthSubmitChallengeError.swift` - `ResetPasswordStartError.swift` - `RetrieveAccessTokenError.swift` - `SignInStartError.swift` - `SignUpStartError.swift` - `VerifyCodeError.swift` - **Compile-only glue** - `MSALNativeAuthErrorMessage.swift`: adds only: - `notImplemented = "This flow is not implemented yet"` - `invalidContinuationToken = "Invalid continuation token"` - **Project + docs** - `MSAL.xcodeproj/project.pbxproj`: registers only the 13 new public V2 Swift files - Adds `docs/NativeAuthV2-CrossPlatform-Contract.md` from source branch - **Stubbing contract (intentional for Part 1)** - `MSALNativeAuthState` removes internal continuation/controller wiring and execution helpers tied to excluded implementation - All V2 continuation methods and V2 entry points dispatch `onFlowError` on main actor with `.notImplemented` ```swift Task { @mainactor in delegate.onFlowError( error: MSALNativeAuthFlowError( type: .notImplemented, correlationId: parameters.correlationId ?? UUID() ), scenario: .signIn // .signUp / .passwordReset / .unknown in state stubs ) } ``` <!-- START COPILOT CODING AGENT SUFFIX --> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> # Native Auth V2 — Public API contract only (Part 1 of a multi-PR split) ## Objective Open a **focused, self-contained PR against the `dev` branch** of `AzureAD/microsoft-authentication-library-for-objc` that introduces **ONLY the Native Auth V2 (server-driven) public API contract** — the public types, delegate protocols, error/scenario types, the three V2 entry points, and supporting public error/parameter edits. **All implementation logic (controllers, networking, validators, telemetry, tests) is intentionally excluded and will land in separate follow-up PRs.** A complete, working reference implementation already exists on the branch **`sedemche/native-auth-v2`** (already pushed to `origin`). **Use that branch as the source of truth** for the exact contents of each public file — copy the public files from it, then apply the small "stubbing" adjustments below so the PR compiles on its own without the (excluded) implementation. ## Source branch `origin/sedemche/native-auth-v2` — contains the full V2 POC (public API + implementation). This PR must extract ONLY the public-contract subset listed below. ## Files to INCLUDE (exact allow-list) Copy these **new** files verbatim from `origin/sedemche/native-auth-v2` (then apply stubbing where noted): - MSAL/src/native_auth/public/state_machine/v2/MSALNativeAuthFlowDelegate.swift - MSAL/src/native_auth/public/state_machine/v2/MSALNativeAuthFlowError.swift - MSAL/src/native_auth/public/state_machine/v2/MSALNativeAuthFlowScenario.swift - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthState.swift (STUB — see below) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthCodeRequiredState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthPasswordRequiredState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthNewPasswordRequiredState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthAttributesRequiredState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthAttributesInvalidState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthMFARequiredState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthMFAVerificationRequiredState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthStrongAuthRegistrationRequiredState.swift (STUB) - MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthStrongAuthVerificationRequiredState.swift (STUB) Apply these **modifications** exactly as they appear on `origin/sedemche/native-auth-v2` (they are public surface changes), EXCEPT the entry-point method bodies which must be stubbed (see below): - MSAL/src/native_auth/public/MSALNativeAuthPublicClientApplication.swift (add signInV2/signUpV2/resetPasswordV2 — STUB the bodies) - MSAL/src/native_auth/public/parameters/MSALNativeAuthResetPasswordParameters.swift - MSAL/src/native_auth/public/parameters/MSALNativeAuthSignUpParameters.swift - MSAL/src/native_auth/public/state_machine/error/MSALNativeAuthError.swift - MSAL/src/native_auth/public/state_machine/error/MSALNativeAuthGenericError.swift - MSAL/src/native_auth/public/state_machine/error/MFARequestChallengeError.swift - MSAL/src/native_auth/public/state_machine/error/MFASubmitChallengeError.swift - MSAL/src/native_auth/public/state_machine/error/PasswordRequiredError.swift - MSAL/src/native_auth/public/state_machine/error/RegisterStrongAuthChallengeError.swift - MSAL/src/native_auth/public/state_machine/error/RegisterStrongAuthSubmitChallengeError.swift - MSAL/src/native_auth/public/state_machine/error/ResetPasswordStartError.swift - MSAL/src/native_auth/public/state_machine/error/RetrieveAccessTokenError.swift - MSAL/src/native_auth/public/state_machine/error/SignInStartError.swift - MSAL/src/native_auth/public/state_machine/error/SignUpStartError.swift - MSAL/src/native_auth/public/state_machine/error/VerifyCodeError.swift Required compile-only glue (small, additive — take from `origin/sedemche/native-auth-v2`): - MSAL/src/native_auth/network/errors/MSALNativeAuthErrorMessage.swift — add ONLY these two static constants (referenced by MSALNativeAuthFlowError): static let notImplemented = "This flow is not implemented yet" static let invalidContinuationToken = "Invalid continuation token" Do NOT pull in any other implementation changes to this file. Documentation (include as-is from the source branch): - docs/NativeAuthV2-CrossPlatform-Contract.md Xcode project registration: - MSAL/MSAL.xcodeproj/project.pbxproj — add build/file references for the **new public .swift files listed above ONLY** (the 13 files under public/state_machine/v2/**). Do NOT add references to any excluded implementation/test files. Keep the file valid (it must still `plutil -lint` cleanly). ## Files to EXCLUDE (do NOT ... </details> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Sergey Demchenko <sedemche@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: antrix1989 <antrix1989@users.noreply.github.com>
| @@ -7,6 +7,32 @@ | |||
| objects = { | |||
There was a problem hiding this comment.
This pull request does not update CHANGELOG.md.
Please consider if this change would be noticeable to a partner or user and either update CHANGELOG.md or resolve this conversation.
There was a problem hiding this comment.
Pull request overview
Introduces initial scaffolding for a Native Auth V2 (server-driven) public state-machine surface (states + unified delegate/error types), and refactors existing Native Auth errors to centralize isBrowserRequired plus add isGeneralError.
Changes:
- Add Native Auth V2 public state classes (e.g., code/password/MFA/strong-auth states) and V2 delegate + scenario + unified flow error types.
- Add V2-specific sign-up/reset-password parameter wrappers and public
*V2entry points onMSALNativeAuthPublicClientApplication. - Update existing Native Auth error types to set
isBrowserRequired/isGeneralErrorvia the baseMSALNativeAuthErrorinitializer and remove per-errorisBrowserRequiredimplementations.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthStrongAuthVerificationRequiredState.swift | New V2 state for strong-auth verification challenge (currently stubbed to .notImplemented). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthStrongAuthRegistrationRequiredState.swift | New V2 state for strong-auth registration method selection (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthState.swift | New V2 base state class carrying scenario metadata. |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthPasswordRequiredState.swift | New V2 state for password entry (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthNewPasswordRequiredState.swift | New V2 state for new-password (SSPR) entry (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthMFAVerificationRequiredState.swift | New V2 state for MFA verification challenge (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthMFARequiredState.swift | New V2 state for MFA method selection (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthCodeRequiredState.swift | New V2 state for one-time-code submit/resend (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthAttributesRequiredState.swift | New V2 state for collecting required attributes (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthAttributesInvalidState.swift | New V2 state for correcting invalid attributes (stubbed). |
| MSAL/src/native_auth/public/state_machine/v2/MSALNativeAuthFlowScenario.swift | New enum describing which V2 flow produced a callback (signUp/signIn/passwordReset). |
| MSAL/src/native_auth/public/state_machine/v2/MSALNativeAuthFlowError.swift | New unified V2 flow error class with typed classification + helper booleans. |
| MSAL/src/native_auth/public/state_machine/v2/MSALNativeAuthFlowDelegate.swift | New unified V2 delegate with terminal callbacks and main-actor contract. |
| MSAL/src/native_auth/public/state_machine/error/VerifyCodeError.swift | Refactor to set isBrowserRequired / isGeneralError in base init and remove redundant property. |
| MSAL/src/native_auth/public/state_machine/error/SignUpStartError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/state_machine/error/SignInStartError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/state_machine/error/RetrieveAccessTokenError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/state_machine/error/ResetPasswordStartError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/state_machine/error/RegisterStrongAuthSubmitChallengeError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/state_machine/error/RegisterStrongAuthChallengeError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/state_machine/error/PasswordRequiredError.swift | Same error base-init refactor (including bridge init). |
| MSAL/src/native_auth/public/state_machine/error/MSALNativeAuthGenericError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/state_machine/error/MSALNativeAuthError.swift | Add isBrowserRequired and isGeneralError as base public properties; extend initializer. |
| MSAL/src/native_auth/public/state_machine/error/MFASubmitChallengeError.swift | Same error base-init refactor (including bridge init). |
| MSAL/src/native_auth/public/state_machine/error/MFARequestChallengeError.swift | Same error base-init refactor. |
| MSAL/src/native_auth/public/parameters/MSALNativeAuthSignUpParametersV2.swift | New V2 sign-up parameter wrapper (adds optional scopes). |
| MSAL/src/native_auth/public/parameters/MSALNativeAuthResetPasswordParametersV2.swift | New V2 reset-password parameter wrapper (adds optional scopes). |
| MSAL/src/native_auth/public/MSALNativeAuthPublicClientApplication.swift | Add public signUpV2 / signInV2 / resetPasswordV2 entry points (currently stubbed). |
| MSAL/src/native_auth/network/errors/MSALNativeAuthErrorMessage.swift | Add new V2 error message constants used by MSALNativeAuthFlowError. |
| MSAL/MSAL.xcodeproj/project.pbxproj | Wire new V2 source files and new parameter files into the Xcode project. |
| static let invalidCode = "Invalid code" | ||
| static let delegateNotImplementedV2 = "Delegate %@ is not implemented" | ||
| static let invalidContinuationToken = "Invalid continuation token" |
| /// - parameters: Parameters used for the Sign In flow. | ||
| /// - delegate: Unified delegate that receives callbacks for the flow. | ||
| public func signInV2( | ||
| parameters: MSALNativeAuthSignInParameters, | ||
| delegate: MSALNativeAuthFlowDelegate | ||
| ) { | ||
| Task { @MainActor in | ||
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()), | ||
| scenario: .signIn | ||
| ) |
| /// Sign up a user using the server-driven (V2) flow. | ||
| /// | ||
| /// - Warning: This API is experimental. It may be changed in the future without notice. Do not use in production applications. | ||
| /// - Parameters: | ||
| /// - parameters: Parameters used for the Sign Up flow. | ||
| /// - delegate: Unified delegate that receives callbacks for the flow. | ||
| public func signUpV2( | ||
| parameters: MSALNativeAuthSignUpParametersV2, | ||
| delegate: MSALNativeAuthFlowDelegate | ||
| ) { | ||
| Task { @MainActor in | ||
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()), | ||
| scenario: .signUp | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| /// Sign in a user using the server-driven (V2) flow. | ||
| /// | ||
| /// - Warning: This API is experimental. It may be changed in the future without notice. Do not use in production applications. | ||
| /// - Parameters: | ||
| /// - parameters: Parameters used for the Sign In flow. | ||
| /// - delegate: Unified delegate that receives callbacks for the flow. | ||
| public func signInV2( | ||
| parameters: MSALNativeAuthSignInParameters, | ||
| delegate: MSALNativeAuthFlowDelegate | ||
| ) { | ||
| Task { @MainActor in | ||
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()), | ||
| scenario: .signIn | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| /// Reset the password using the server-driven (V2) flow. | ||
| /// | ||
| /// - Warning: This API is experimental. It may be changed in the future without notice. Do not use in production applications. | ||
| /// - Parameters: | ||
| /// - parameters: Parameters used for the Reset Password flow. | ||
| /// - delegate: Unified delegate that receives callbacks for the flow. | ||
| public func resetPasswordV2( | ||
| parameters: MSALNativeAuthResetPasswordParametersV2, | ||
| delegate: MSALNativeAuthFlowDelegate | ||
| ) { | ||
| Task { @MainActor in | ||
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()), | ||
| scenario: .passwordReset | ||
| ) | ||
| } | ||
| } |
| /// Submit a one-time verification code. | ||
| public func submitCode(_ code: String, delegate: MSALNativeAuthFlowDelegate) { | ||
| Task { @MainActor in | ||
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| /// Request the server to resend the one-time code. | ||
| public func resendCode(delegate: MSALNativeAuthFlowDelegate) { | ||
| Task { @MainActor in | ||
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) | ||
| } |
| /// Indicates whether the error can only be resolved by falling back to the browser-based interactive flow. | ||
| public let isBrowserRequired: Bool | ||
|
|
||
| /// Indicates whether the error is an unclassified or unexpected error with no more specific handling. | ||
| public let isGeneralError: Bool | ||
|
|
||
| private let message: String? | ||
|
|
||
| init(message: String? = nil, correlationId: UUID, errorCodes: [Int] = [], errorUri: String? = nil) { | ||
| init( | ||
| message: String? = nil, | ||
| correlationId: UUID, | ||
| errorCodes: [Int] = [], | ||
| errorUri: String? = nil, | ||
| isBrowserRequired: Bool = false, | ||
| isGeneralError: Bool = false | ||
| ) { | ||
| self.message = message | ||
| self.correlationId = correlationId | ||
| self.errorCodes = errorCodes | ||
| self.errorUri = errorUri | ||
| self.isBrowserRequired = isBrowserRequired | ||
| self.isGeneralError = isGeneralError |
|
@copilot resolve the merge conflicts in this pull request |
|
@copilot resolve the merge conflicts in this pull request |
…hine and mail.tm entries
Resolved. The only conflict was in |
The branch is already up to date with |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (3)
MSAL/src/native_auth/network/errors/MSALNativeAuthErrorMessage.swift:44
delegateNotImplementedV2includes a%@placeholder butMSALNativeAuthFlowError.errorDescriptionreturns it directly without formatting. This will surface a literal%@to apps, which is confusing and not actionable.
Recommendation: either remove the placeholder or update the error construction to format it with the missing delegate/type name.
static let invalidCode = "Invalid code"
static let delegateNotImplementedV2 = "Delegate %@ is not implemented"
static let invalidContinuationToken = "Invalid continuation token"
static let invalidChallenge = "Invalid challenge"
MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthCodeRequiredState.swift:56
- Each continuation method generates a brand-new
correlationId: UUID()when reporting.notImplemented. This makes correlation IDs unstable across a single flow and inconsistent with the V1 state machine, where the correlationId is carried by the state (seeMSALNativeAuthBaseState), reducing diagnosability and end-to-end request correlation.
Recommendation: add an internal correlationId: UUID to MSALNativeAuthState (set by the SDK when creating the state) and reuse it when creating MSALNativeAuthFlowError (and other V2 errors).
Task { @MainActor in
delegate.onFlowError(
error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()),
scenario: self.scenario
)
MSAL/src/native_auth/public/MSALNativeAuthPublicClientApplication.swift:279
- These new public V2 entrypoints (
signUpV2/signInV2/resetPasswordV2) currently always calldelegate.onFlowErrorwith.notImplemented. As written, the API name/docs promise a functional flow but the implementation is a guaranteed failure path.
Recommendation: avoid exposing non-functional public APIs. Either (a) implement the V2 flow wiring, (b) mark these APIs as unavailable (e.g. @available(*, unavailable, message: ...)) until implemented, or (c) keep them internal/private until the end-to-end flow is ready.
/// Sign up a user using the server-driven (V2) flow.
///
/// - Warning: This API is experimental. It may be changed in the future without notice. Do not use in production applications.
/// - Parameters:
/// - parameters: Parameters used for the Sign Up flow.
/// - delegate: Unified delegate that receives callbacks for the flow.
public func signUpV2(
parameters: MSALNativeAuthSignUpParametersV2,
delegate: MSALNativeAuthFlowDelegate
) {
Task { @MainActor in
delegate.onFlowError(
error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()),
scenario: .signUp
)
}
| /* Begin PBXBuildFile section */ | ||
| <<<<<<< HEAD | ||
| 01462653AC546A8B95A0D912 /* MSALNativeAuthMFARequiredState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE5D3DE054DBA691A401E3D /* MSALNativeAuthMFARequiredState.swift */; }; | ||
| 06AAD69B63B7A013959ECEF7 /* MSALNativeAuthFlowScenario.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88219AB3EAB46203CD9729B9 /* MSALNativeAuthFlowScenario.swift */; }; |
| 28FDC4AB2A38D7D200E38BE1 /* MSALNativeAuthSignInControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSALNativeAuthSignInControllerMock.swift; sourceTree = "<group>"; }; | ||
| <<<<<<< HEAD | ||
| 509588E9A2AE1A919D2AF029 /* MSALNativeAuthStrongAuthRegistrationRequiredState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MSALNativeAuthStrongAuthRegistrationRequiredState.swift; sourceTree = "<group>"; }; | ||
| 6439500470AC3BBD79E7D046 /* MSALNativeAuthMFAVerificationRequiredState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MSALNativeAuthMFAVerificationRequiredState.swift; sourceTree = "<group>"; }; | ||
| 8273A2EAA82AE303691B976F /* MSALNativeAuthNewPasswordRequiredState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MSALNativeAuthNewPasswordRequiredState.swift; sourceTree = "<group>"; }; |
| /// In V2 the server drives the flow: at each step the SDK reports a concrete | ||
| /// ``MSALNativeAuthState`` subclass through its dedicated ``MSALNativeAuthFlowDelegate`` callback | ||
| /// (e.g. ``MSALNativeAuthFlowDelegate/onCodeRequired(state:)``). The app then continues the flow by | ||
| /// calling the method(s) exposed on that concrete state — each state exposes only the |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated 8 comments.
Comments suppressed due to low confidence (8)
MSAL/src/native_auth/network/errors/MSALNativeAuthErrorMessage.swift:42
delegateNotImplementedV2contains a%@placeholder but the string is returned directly (no formatting), so apps will see the raw placeholder inerrorDescription.
static let delegateNotImplementedV2 = "Delegate %@ is not implemented"
MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthState.swift:33
- The DocC link
MSALNativeAuthFlowDelegate/onCodeRequired(state:)doesn’t match the actual API surface (the base flow delegate only has terminal callbacks;onCodeRequiredlives onMSALNativeAuthCodeRequiredDelegateand includesscenario). This will generate broken documentation links and mislead consumers.
/// In V2 the server drives the flow: at each step the SDK reports a concrete
/// ``MSALNativeAuthState`` subclass through its dedicated ``MSALNativeAuthFlowDelegate`` callback
/// (e.g. ``MSALNativeAuthFlowDelegate/onCodeRequired(state:)``). The app then continues the flow by
/// calling the method(s) exposed on that concrete state — each state exposes only the
/// continuations valid for its step, so invalid calls are impossible.
MSAL/src/native_auth/public/MSALNativeAuthPublicClientApplication.swift:278
- These V2 entry points always report
.notImplemented, but the.notImplementedFlowError case is documented as a missing per-state delegate implementation. This means callers can get a misleading error even when their delegate conforms correctly.
delegate.onFlowError(
error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()),
scenario: .signUp
)
MSAL/src/native_auth/public/MSALNativeAuthPublicClientApplication.swift:296
- These V2 entry points always report
.notImplemented, but the.notImplementedFlowError case is documented as a missing per-state delegate implementation. This means callers can get a misleading error even when their delegate conforms correctly.
delegate.onFlowError(
error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()),
scenario: .signIn
)
MSAL/src/native_auth/public/MSALNativeAuthPublicClientApplication.swift:314
- These V2 entry points always report
.notImplemented, but the.notImplementedFlowError case is documented as a missing per-state delegate implementation. This means callers can get a misleading error even when their delegate conforms correctly.
delegate.onFlowError(
error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: parameters.correlationId ?? UUID()),
scenario: .passwordReset
)
MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthCodeRequiredState.swift:56
- This continuation currently always reports
.notImplemented, which (per the delegate-protocol docs) is meant to indicate the app didn’t implement the required per-state delegate callback. That’s misleading when the delegate is implemented and the SDK simply doesn’t yet support the continuation.
delegate.onFlowError(
error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()),
scenario: self.scenario
)
MSAL/src/native_auth/public/state_machine/v2/state/MSALNativeAuthCodeRequiredState.swift:66
- This continuation currently always reports
.notImplemented, which (per the delegate-protocol docs) is meant to indicate the app didn’t implement the required per-state delegate callback. That’s misleading when the delegate is implemented and the SDK simply doesn’t yet support the continuation.
delegate.onFlowError(
error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()),
scenario: self.scenario
)
MSAL/src/native_auth/public/state_machine/error/MSALNativeAuthError.swift:46
isGeneralErroris a new public signal onMSALNativeAuthError, but there’s no test coverage asserting it’s set correctly for.generalErroracross the existing Native Auth error types (unit tests currently only coverisBrowserRequiredand other per-error booleans). This can regress silently because the initializer defaults tofalse.
/// Indicates whether the error can only be resolved by falling back to the browser-based interactive flow.
public let isBrowserRequired: Bool
/// Indicates whether the error is an unclassified or unexpected error with no more specific handling.
public let isGeneralError: Bool
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
| delegate.onFlowError( | ||
| error: MSALNativeAuthFlowError(type: .notImplemented, correlationId: UUID()), | ||
| scenario: self.scenario | ||
| ) |
|
@copilot merge dev into this branch |
The branch is already up to date with |
PR Checklist (must be completed before review)
PR Title Format
Required Format:
[Keyword1] [Keyword2]: Descriptionmajor,minor, orpatch(case-insensitive)feature,bugfix,engg, ortests(case-insensitive)Examples:
[MAJOR] [Feature]: new API[minor] [bugfix]: fix crash[PATCH] [tests]: add coverageProposed changes
Describe what this PR is trying to do.
Type of change
Risk
Additional information