Skip to content

Swift 6 CI changes #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ jobs:
os:
# - ubuntu-latest
- macos-latest
swift:
- "5.10"
# swift:
# - "5.10"
runs-on: ${{ matrix.os }}
steps:
- uses: swift-actions/setup-swift@e1dca7c4a36344146bbc2803f0d538462477bb37 # 2.0.0
with:
swift-version: ${{ matrix.swift }}
# - uses: swift-actions/setup-swift@e1dca7c4a36344146bbc2803f0d538462477bb37 # 2.0.0
# with:
# swift-version: ${{ matrix.swift }}
- uses: actions/checkout@v4
- name: Build
run: swift build
Expand Down
5 changes: 3 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.10
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -24,7 +24,8 @@ let package = Package(
.target(
name: "SnapAuth",
swiftSettings: [
.define("HARDWARE_KEY_SUPPORT", .when(platforms: [.iOS, .macOS]))
.define("HARDWARE_KEY_SUPPORT", .when(platforms: [.iOS, .macOS])),
.swiftLanguageVersion(.v6),
]),
.testTarget(
name: "SnapAuthTests",
Expand Down
5 changes: 1 addition & 4 deletions Sources/SnapAuth/Errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,13 @@ extension ASAuthorizationError.Code {
case .invalidResponse: return .invalidResponse
case .notHandled: return .notHandled
case .notInteractive: return .notInteractive
@unknown default:
/* This is (AFAICT) correct, but doesn't seem to work on the Github
Actions runner version.
default:
// This case only exists on new OS platforms
if #available(iOS 18, visionOS 2, macOS 15, tvOS 18, *) {
if case .matchedExcludedCredential = self {
return .matchedExcludedCredential
}
}
*/
return .unknown
}
}
Expand Down
22 changes: 14 additions & 8 deletions Sources/SnapAuth/PresentationAnchor.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import AuthenticationServices

extension ASPresentationAnchor {
/// A platform-specific anchor, intended to be used by ASAuthorizationController
static var `default`: ASPresentationAnchor {
#if os(macOS)
// FIXME: Figure out better fallback mechanisms here.
// This will cause a new window to open _and remain open_
fileprivate let defaultPresentationAnchor: ASPresentationAnchor = NSApplication.shared.mainWindow ?? ASPresentationAnchor()
// FIXME: Figure out better fallback mechanisms here.
// This will cause a new window to open _and remain open_
return NSApplication.shared.mainWindow ?? ASPresentationAnchor()
#else
fileprivate let defaultPresentationAnchor: ASPresentationAnchor = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.windows.first?.rootViewController?.view.window ?? ASPresentationAnchor()
return (UIApplication.shared.connectedScenes.first as? UIWindowScene)?
.windows
.first?
.rootViewController?
.view
.window
?? ASPresentationAnchor()
#endif

extension ASPresentationAnchor {
/// A platform-specific anchor, intended to be used by ASAuthorizationController
static let `default` = defaultPresentationAnchor
}
}
44 changes: 22 additions & 22 deletions Sources/SnapAuth/SnapAuth+ASACD.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,45 @@ import AuthenticationServices
@available(macOS 12.0, iOS 15.0, visionOS 1.0, tvOS 16.0, *)
extension SnapAuth: ASAuthorizationControllerDelegate {

public func authorizationController(
nonisolated public func authorizationController(
controller: ASAuthorizationController,
didCompleteWithError error: Error
) {
logger.debug("ASACD error")
guard let asError = error as? ASAuthorizationError else {
logger.error("authorizationController didCompleteWithError error was not an ASAuthorizationError")
sendError(.unknown)
return
}
Task { @MainActor in
guard let asError = error as? ASAuthorizationError else {
logger.error("authorizationController didCompleteWithError error was not an ASAuthorizationError")
sendError(.unknown)
return
}

sendError(asError.code.snapAuthError)
// The start call can SILENTLY produce this error which never makes it into this handler
// ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"
sendError(asError.code.snapAuthError)
// The start call can SILENTLY produce this error which never makes it into this handler
// ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"
}
}

public func authorizationController(
nonisolated public func authorizationController(
controller: ASAuthorizationController,
didCompleteWithAuthorization authorization: ASAuthorization
) {
logger.debug("ASACD did complete")


switch authorization.credential {
case is ASAuthorizationPublicKeyCredentialAssertion:
handleAssertion(authorization.credential as! ASAuthorizationPublicKeyCredentialAssertion)
case is ASAuthorizationPublicKeyCredentialRegistration:
handleRegistration(authorization.credential as! ASAuthorizationPublicKeyCredentialRegistration)
default:
logger.error("Unexpected credential type \(String(describing: type(of: authorization.credential)))")
sendError(.unexpectedAuthorizationType)
Task { @MainActor in
switch authorization.credential {
case is ASAuthorizationPublicKeyCredentialAssertion:
handleAssertion(authorization.credential as! ASAuthorizationPublicKeyCredentialAssertion)
case is ASAuthorizationPublicKeyCredentialRegistration:
handleRegistration(authorization.credential as! ASAuthorizationPublicKeyCredentialRegistration)
default:
logger.error("Unexpected credential type \(String(describing: type(of: authorization.credential)))")
sendError(.unexpectedAuthorizationType)
}
}
}

/// Sends the error to the appropriate delegate method and resets the internal state back to idle
private func sendError(_ error: SnapAuthError) {
// One or the other should eb set, but not both
assert(continuation != nil)
continuation?.resume(returning: .failure(error))
continuation = nil
}
Expand Down Expand Up @@ -157,4 +158,3 @@ extension SnapAuth: ASAuthorizationControllerDelegate {
// }
// }
}

5 changes: 3 additions & 2 deletions Sources/SnapAuth/SnapAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import os
/// This is used to start the passkey registration and authentication processes,
/// typically in the `action` of a `Button`
@available(macOS 12.0, iOS 15.0, tvOS 16.0, *)
@MainActor
public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDelegate

internal let api: SnapAuthClient
Expand Down Expand Up @@ -39,7 +40,7 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg
}

/// Permitted authenticator types
public enum Authenticator: CaseIterable {
public enum Authenticator: CaseIterable, Sendable {
/// Allow all available authenticator types to be used
public static let all = Set(Authenticator.allCases)

Expand Down Expand Up @@ -223,7 +224,7 @@ public class SnapAuth: NSObject { // NSObject for ASAuthorizationControllerDeleg
}
}

public enum AuthenticatingUser {
public enum AuthenticatingUser: Sendable {
/// Your application's internal identifier for the user (usually a primary key)
case id(String)
/// The user's handle, such as a username or email address
Expand Down