Skip to content

Commit

Permalink
Merge pull request #7 from passageidentity/PSG-5176
Browse files Browse the repository at this point in the history
PSG-5176
  • Loading branch information
SinaSeylani authored Oct 29, 2024
2 parents 2fee226 + cfa660d commit abed423
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 13 deletions.
2 changes: 1 addition & 1 deletion PassageFlex.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'PassageFlex'
s.version = '0.2.0'
s.version = '0.3.0'
s.summary = 'Passkey Flex for Apple Platforms - Go completely passwordless with a standalone auth solution in your iOS, MacOS, and tvOS apps with Passage by 1Password'
s.description = <<-DESC
Passkey Flex for Apple Platforms - Go completely passwordless with a standalone auth solution in your iOS, MacOS, and tvOS apps with Passage by 1Password
Expand Down
10 changes: 4 additions & 6 deletions Sources/PassageFlex/PassageFlexPasskey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ public class PassageFlexPasskey {
///
/// - Parameters:
/// - transactionId: The Passage transaction id provided by your app's server.
/// - authenticatorAttachment: (Optional) The type of authentication that will be used in this
/// WebAuthN flow request. Defaults to `.platform`. Use `.cross-platform` for physical security
/// key registration.
/// - options: (Optional) options configuration for passkey creation
///
/// - Returns: A single-use "nonce" from Passage server to be exchanged for an authentication token on
/// your app's server.
Expand All @@ -30,11 +28,11 @@ public class PassageFlexPasskey {
@available(iOS 16.0, macOS 12.0, tvOS 16.0, visionOS 1.0, *)
public func register(
with transactionId: String,
authenticatorAttachment: AuthenticatorAttachment = .platform
) async throws -> String {
options: PasskeyCreationOptions? = nil
) async throws -> String {
let nonce = try await PassagePasskeyAuthentication.register(
with: transactionId,
authenticatorAttachment: authenticatorAttachment,
authenticatorAttachment: options?.authenticatorAttachment ?? .platform,
appId: appId
)
return nonce
Expand Down
3 changes: 2 additions & 1 deletion Sources/PassageFlex/PassagePasskeyAuthentication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ internal struct PassagePasskeyAuthentication {
let registrationRequest = try PasskeyRegistrationRequest.from(startResponse)
let authController = PasskeyAuthorizationController()
let credential = try await authController.requestPasskeyRegistration(
registrationRequest: registrationRequest
registrationRequest: registrationRequest,
includeSecurityKeyOption: authenticatorAttachment == .crossPlatform
)
// Send the new Credential Handshake Response to Passage server
let finishRequest = RegisterWebAuthnFinishWithTransactionRequest(
Expand Down
31 changes: 26 additions & 5 deletions Sources/PassageFlex/PasskeyAuthorizationController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,42 @@ internal class PasskeyAuthorizationController:
private var passkeyAutoFillWindow: PasskeyAutoFillWindow?

internal func requestPasskeyRegistration(
registrationRequest: PasskeyRegistrationRequest
registrationRequest: PasskeyRegistrationRequest,
includeSecurityKeyOption: Bool = false
) async throws -> ASAuthorizationPlatformPublicKeyCredentialRegistration {
let publicKeyCredentialProvider = ASAuthorizationPlatformPublicKeyCredentialProvider(
relyingPartyIdentifier: registrationRequest.relyingPartyIdentifier
)
let authRegistrationRequest = publicKeyCredentialProvider
let platformRegistrationRequest = publicKeyCredentialProvider
.createCredentialRegistrationRequest(
challenge: registrationRequest.challenge,
name: registrationRequest.userName,
userID: registrationRequest.userId
)
let authController = ASAuthorizationController(
authorizationRequests: [ authRegistrationRequest ]
)
var requests: [ASAuthorizationRequest] = [ platformRegistrationRequest ]
#if os(iOS) || os(macOS)
if includeSecurityKeyOption {
let securityKeyCredentialProvider = ASAuthorizationSecurityKeyPublicKeyCredentialProvider(
relyingPartyIdentifier: registrationRequest.relyingPartyIdentifier
)
let securityKeyRegistrationRequest = securityKeyCredentialProvider
.createCredentialRegistrationRequest(
challenge: registrationRequest.challenge,
displayName: registrationRequest.userName,
name: registrationRequest.userName,
userID: registrationRequest.userId
)
securityKeyRegistrationRequest.credentialParameters = [
ASAuthorizationPublicKeyCredentialParameters(
algorithm: ASCOSEAlgorithmIdentifier.ES256
)
]
requests.append(securityKeyRegistrationRequest)
}
#endif
let authController = ASAuthorizationController(authorizationRequests: requests)
authController.delegate = self
authController.presentationContextProvider = self
authController.performRequests()
return try await withCheckedThrowingContinuation(
{ [weak self] (continuation: RegistrationCredentialContinuation) in
Expand Down
7 changes: 7 additions & 0 deletions Sources/PassageFlex/models/PasskeyCreationOptions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
public struct PasskeyCreationOptions {
public let authenticatorAttachment: AuthenticatorAttachment

public init(authenticatorAttachment: AuthenticatorAttachment = .platform) {
self.authenticatorAttachment = authenticatorAttachment
}
}

0 comments on commit abed423

Please sign in to comment.