Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1ed2476
Add native sign-in callback regression tests
azooz2003-bit Jun 19, 2026
7b904eb
Surface native sign-in callback failures
azooz2003-bit Jun 19, 2026
13e4654
Localize native sign-in callback strings
azooz2003-bit Jun 19, 2026
4d323fc
Merge remote-tracking branch 'origin/main' into task-connect-device-a…
azooz2003-bit Jun 19, 2026
ade58d7
Split browser sign-in flow tests
azooz2003-bit Jun 19, 2026
db5af51
Bound host browser sign-in test waits
azooz2003-bit Jun 19, 2026
5873031
Localize iOS invalid auth callbacks
azooz2003-bit Jun 19, 2026
82a73c9
Ignore stale auth callbacks after sign-out
azooz2003-bit Jun 19, 2026
8591f77
Merge remote-tracking branch 'origin/main' into task-connect-device-a…
azooz2003-bit Jun 19, 2026
0c49f5f
Refresh Swift length budget after main merge
azooz2003-bit Jun 19, 2026
5e20598
Add fallback callback retry regression
azooz2003-bit Jun 19, 2026
c3cdbb5
Preserve fallback callback state until sign-in succeeds
azooz2003-bit Jun 19, 2026
d1554ef
Add hosted browser failure message regression
azooz2003-bit Jun 19, 2026
daaf8f3
Use generic hosted browser callback failure
azooz2003-bit Jun 19, 2026
d19aae0
Merge remote-tracking branch 'origin/main' into task-connect-device-a…
azooz2003-bit Jun 19, 2026
1f4e2ee
Refresh Swift length budget after main update
azooz2003-bit Jun 19, 2026
08ce03c
Keep browser sign-in helpers private
azooz2003-bit Jun 20, 2026
c45f703
Merge remote-tracking branch 'origin/main' into task-connect-device-a…
azooz2003-bit Jun 20, 2026
ba5768b
Clean up browser sign-in deadline helper
azooz2003-bit Jun 20, 2026
01cde11
Keep host browser test helpers on harness
azooz2003-bit Jun 20, 2026
7caef00
Localize pairing browser fallback
azooz2003-bit Jun 20, 2026
fe931bc
Add stale sign-out callback failure regression
azooz2003-bit Jun 20, 2026
15dba5d
Ignore stale callback failures after sign-out
azooz2003-bit Jun 20, 2026
1f00653
Surface browser sign-in session failures
azooz2003-bit Jun 20, 2026
5c00324
Bound host browser sign-in test waits
azooz2003-bit Jun 20, 2026
2a000cd
Merge remote-tracking branch 'origin/main' into task-connect-device-a…
azooz2003-bit Jun 20, 2026
a068307
Split host browser auth session result type
azooz2003-bit Jun 20, 2026
b2b321c
Keep browser auth result classification on factory instance
azooz2003-bit Jun 20, 2026
bd4b75f
Merge origin/main into task-connect-device-auth-hang
azooz2003-bit Jun 21, 2026
8245509
Localize browser sign-in failure message
azooz2003-bit Jun 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/swift-file-length-budget.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@
527 CLI/CLISocketPathResolver.swift
526 Packages/macOS/CmuxSettings/Sources/CmuxSettings/SocketControl/SocketControlSettings.swift
524 CLI/CMUXCLI+AutoNaming.swift
524 Packages/Shared/CmuxAuthRuntime/Tests/CmuxAuthRuntimeTests/HostBrowserSignInFlowTests.swift
522 Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/AutomationSection.swift
520 CLI/CMUXCLI+AmpExtension.swift
520 cmuxTests/MainWindowVisibilityControllerTests.swift
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public final class ASWebBrowserAuthSessionFactory: HostBrowserAuthSessionFactory
public func makeSession(
signInURL: URL,
callbackScheme: String,
completion: @escaping @MainActor (URL?) -> Void
completion: @escaping @MainActor (HostBrowserAuthSessionResult) -> Void
) -> any HostBrowserAuthSession {
log.log("auth.webauth.makeSession signInURL=\(signInURL.absoluteString) callbackScheme=\(callbackScheme)")
let session = ASWebAuthenticationSession(
Expand All @@ -41,10 +41,11 @@ public final class ASWebBrowserAuthSessionFactory: HostBrowserAuthSessionFactory
/// boundary when that off-main delivery happens. This bridge carries no
/// isolation assumption and hops to the main actor itself.
nonisolated func sessionCompletionBridge(
completion: @escaping @MainActor (URL?) -> Void
completion: @escaping @MainActor (HostBrowserAuthSessionResult) -> Void
) -> @Sendable (URL?, (any Error)?) -> Void {
let log = self.log
return { callbackURL, error in
let result = self.sessionResult(callbackURL: callbackURL, error: error)
Task { @MainActor in
if let error {
let nsError = error as NSError
Expand All @@ -53,10 +54,39 @@ public final class ASWebBrowserAuthSessionFactory: HostBrowserAuthSessionFactory
} else {
log.log("auth.webauth.completion error=nil callback=\(callbackURL == nil ? "nil" : "present")")
}
completion(callbackURL)
completion(result)
}
}
}

nonisolated private func sessionResult(
callbackURL: URL?,
error: (any Error)?
) -> HostBrowserAuthSessionResult {
if let callbackURL {
return .callback(callbackURL)
}
guard let error else {
return .failed(reason: "missing_callback")
}
let nsError = error as NSError
if nsError.domain == ASWebAuthenticationSessionError.errorDomain {
switch nsError.code {
case ASWebAuthenticationSessionError.Code.canceledLogin.rawValue:
return .cancelled(reason: "canceled_login")
case ASWebAuthenticationSessionError.Code.presentationContextInvalid.rawValue:
return .failed(reason: "presentation_context_invalid")
case ASWebAuthenticationSessionError.Code.presentationContextNotProvided.rawValue:
return .failed(reason: "presentation_context_not_provided")
default:
return .failed(reason: "aswebauthentication_\(nsError.code)")
}
}
if nsError.domain == NSURLErrorDomain {
return .failed(reason: "network_\(nsError.code)")
}
return .failed(reason: "error_\(nsError.code)")
}
}

/// Wraps one `ASWebAuthenticationSession` as a ``HostBrowserAuthSession``.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public protocol HostBrowserAuthSessionFactory {
/// - signInURL: The hosted sign-in page URL.
/// - callbackScheme: The custom scheme the callback redirect uses.
/// - completion: Delivered exactly once on the main actor with the
/// callback URL, or `nil` on error/cancellation.
/// browser session's terminal result.
func makeSession(
signInURL: URL,
callbackScheme: String,
completion: @escaping @MainActor (URL?) -> Void
completion: @escaping @MainActor (HostBrowserAuthSessionResult) -> Void
) -> any HostBrowserAuthSession
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public import Foundation

/// The terminal result of one hosted-browser auth attempt.
public enum HostBrowserAuthSessionResult: Equatable, Sendable {
/// The hosted page redirected to the app's auth callback URL.
case callback(URL)
/// The user or app deliberately cancelled the browser session.
case cancelled(reason: String)
/// The browser session failed before returning a usable callback.
case failed(reason: String)
}
Loading
Loading