From b41c23bd0b855422873b7aae6606d0192bc9cabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Scre=CC=80ve?= Date: Tue, 28 Jan 2025 11:21:35 +0100 Subject: [PATCH 01/17] Public inits, mutable properties and full Codable support --- .../AuthenticationCredential.swift | 13 +++- .../AuthenticatorAssertionResponse.swift | 13 +++- .../PublicKeyCredentialRequestOptions.swift | 56 +++++++++++--- .../AttestationConveyancePreference.swift | 2 +- .../AuthenticatorAttestationResponse.swift | 10 ++- .../PublicKeyCredentialCreationOptions.swift | 73 ++++++++++++++++--- .../Registration/RegistrationCredential.swift | 11 ++- .../Shared/COSE/COSEAlgorithmIdentifier.swift | 2 +- .../WebAuthn/Helpers/ChallengeGenerator.swift | 2 +- ...edDecodingContainer+decodeURLEncoded.swift | 2 +- Sources/WebAuthn/WebAuthnManager.swift | 7 +- 11 files changed, 161 insertions(+), 30 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift index 88dc884..166099d 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift @@ -34,7 +34,7 @@ public struct AuthenticationCredential: Sendable { public let type: CredentialType } -extension AuthenticationCredential: Decodable { +extension AuthenticationCredential: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -44,6 +44,17 @@ extension AuthenticationCredential: Decodable { authenticatorAttachment = try container.decodeIfPresent(AuthenticatorAttachment.self, forKey: .authenticatorAttachment) type = try container.decode(CredentialType.self, forKey: .type) } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(id, forKey: .id) + try container.encode(rawID.base64URLEncodedString(), forKey: .rawID) + try container.encode(response, forKey: .response) + try container.encodeIfPresent(authenticatorAttachment, forKey: .authenticatorAttachment) + try container.encode(type, forKey: .type) + } + private enum CodingKeys: String, CodingKey { case id diff --git a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift index 979ba08..932b154 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift @@ -48,7 +48,7 @@ public struct AuthenticatorAssertionResponse: Sendable { public let attestationObject: [UInt8]? } -extension AuthenticatorAssertionResponse: Decodable { +extension AuthenticatorAssertionResponse: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -58,6 +58,17 @@ extension AuthenticatorAssertionResponse: Decodable { userHandle = try container.decodeBytesFromURLEncodedBase64IfPresent(forKey: .userHandle) attestationObject = try container.decodeBytesFromURLEncodedBase64IfPresent(forKey: .attestationObject) } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(clientDataJSON.base64URLEncodedString(), forKey: .clientDataJSON) + try container.encode(authenticatorData.base64URLEncodedString(), forKey: .authenticatorData) + try container.encode(signature.base64URLEncodedString(), forKey: .signature) + try container.encodeIfPresent(userHandle?.base64URLEncodedString(),forKey: .userHandle) + try container.encodeIfPresent(attestationObject?.base64URLEncodedString(),forKey: .attestationObject) + } + private enum CodingKeys: String, CodingKey { case clientDataJSON diff --git a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift index e142aa3..96610c7 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift @@ -18,30 +18,30 @@ import Foundation /// When encoding using `Encodable`, the byte arrays are encoded as base64url. /// /// - SeeAlso: https://www.w3.org/TR/webauthn-2/#dictionary-assertion-options -public struct PublicKeyCredentialRequestOptions: Encodable, Sendable { +public struct PublicKeyCredentialRequestOptions: Codable, Sendable { /// A challenge that the authenticator signs, along with other data, when producing an authentication assertion /// /// When encoding using `Encodable` this is encoded as base64url. - public let challenge: [UInt8] + public var challenge: [UInt8] /// A time, in seconds, that the caller is willing to wait for the call to complete. This is treated as a /// hint, and may be overridden by the client. /// /// - Note: When encoded, this value is represented in milleseconds as a ``UInt32``. /// See https://www.w3.org/TR/webauthn-2/#dictionary-assertion-options - public let timeout: Duration? + public var timeout: Duration? /// The ID of the Relying Party making the request. /// /// This is configured on ``WebAuthnManager`` before its ``WebAuthnManager/beginAuthentication(timeout:allowCredentials:userVerification:)`` method is called. /// - Note: When encoded, this field appears as `rpId` to match the expectations of `navigator.credentials.get()`. - public let relyingPartyID: String + public var relyingPartyID: String /// Optionally used by the client to find authenticators eligible for this authentication ceremony. - public let allowCredentials: [PublicKeyCredentialDescriptor]? + public var allowCredentials: [PublicKeyCredentialDescriptor]? /// Specifies whether the user should be verified during the authentication ceremony. - public let userVerification: UserVerificationRequirement? + public var userVerification: UserVerificationRequirement? // let extensions: [String: Any] @@ -50,15 +50,41 @@ public struct PublicKeyCredentialRequestOptions: Encodable, Sendable { try container.encode(challenge.base64URLEncodedString(), forKey: .challenge) try container.encodeIfPresent(timeout?.milliseconds, forKey: .timeout) - try container.encode(relyingPartyID, forKey: .rpID) + try container.encode(relyingPartyID, forKey: .relyingPartyID) try container.encodeIfPresent(allowCredentials, forKey: .allowCredentials) try container.encodeIfPresent(userVerification, forKey: .userVerification) } + + public init( + challenge: [UInt8], + timeout: Duration?, + relyingPartyID: String, + allowCredentials: [PublicKeyCredentialDescriptor]?, + userVerification: UserVerificationRequirement?) { + self.challenge = challenge + self.timeout = timeout + self.relyingPartyID = relyingPartyID + self.allowCredentials = allowCredentials + self.userVerification = userVerification + } + + public init(from decoder: any Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + + self.challenge = try values.decodeBytesFromURLEncodedBase64(forKey: .challenge) + + if let timeout = try values.decodeIfPresent(UInt32.self, forKey:.timeout) { + self.timeout=Duration.milliseconds(timeout) + } + self.relyingPartyID=try values.decode(String.self, forKey:.relyingPartyID) + self.allowCredentials=try values.decodeIfPresent([PublicKeyCredentialDescriptor].self,forKey: .allowCredentials) + self.userVerification=try values.decodeIfPresent(UserVerificationRequirement.self,forKey: .userVerification) + } private enum CodingKeys: String, CodingKey { case challenge case timeout - case rpID = "rpId" + case relyingPartyID = "rpId" case allowCredentials case userVerification } @@ -67,10 +93,10 @@ public struct PublicKeyCredentialRequestOptions: Encodable, Sendable { /// Information about a generated credential. /// /// When encoding using `Encodable`, `id` is encoded as base64url. -public struct PublicKeyCredentialDescriptor: Equatable, Encodable, Sendable { +public struct PublicKeyCredentialDescriptor: Equatable, Codable, Sendable { /// Defines hints as to how clients might communicate with a particular authenticator in order to obtain an /// assertion for a specific credential - public enum AuthenticatorTransport: String, Equatable, Encodable, Sendable { + public enum AuthenticatorTransport: String, Equatable, Codable, Sendable { /// Indicates the respective authenticator can be contacted over removable USB. case usb /// Indicates the respective authenticator can be contacted over Near Field Communication (NFC). @@ -114,6 +140,14 @@ public struct PublicKeyCredentialDescriptor: Equatable, Encodable, Sendable { try container.encode(id.base64URLEncodedString(), forKey: .id) try container.encodeIfPresent(transports, forKey: .transports) } + + public init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let type = try container.decode(CredentialType.self,forKey: .type) + let id = try container.decodeBytesFromURLEncodedBase64( forKey: .id) + let transports = try container.decodeIfPresent([AuthenticatorTransport].self,forKey:.transports) ?? [] + self.init(type: type, id:id, transports: transports) + } private enum CodingKeys: String, CodingKey { case type @@ -124,7 +158,7 @@ public struct PublicKeyCredentialDescriptor: Equatable, Encodable, Sendable { /// The Relying Party may require user verification for some of its operations but not for others, and may use this /// type to express its needs. -public enum UserVerificationRequirement: String, Encodable, Sendable { +public enum UserVerificationRequirement: String, Codable, Sendable { /// The Relying Party requires user verification for the operation and will fail the overall ceremony if the /// user wasn't verified. case required diff --git a/Sources/WebAuthn/Ceremonies/Registration/AttestationConveyancePreference.swift b/Sources/WebAuthn/Ceremonies/Registration/AttestationConveyancePreference.swift index 770af12..a720bc8 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/AttestationConveyancePreference.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/AttestationConveyancePreference.swift @@ -14,7 +14,7 @@ /// Options to specify the Relying Party's preference regarding attestation conveyance during credential generation. /// /// Currently only supports `none`. -public enum AttestationConveyancePreference: String, Encodable, Sendable { +public enum AttestationConveyancePreference: String, Codable, Sendable { /// Indicates the Relying Party is not interested in authenticator attestation. case none // case indirect diff --git a/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift b/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift index 0d45439..b986485 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift @@ -29,13 +29,21 @@ public struct AuthenticatorAttestationResponse: Sendable { public let attestationObject: [UInt8] } -extension AuthenticatorAttestationResponse: Decodable { +extension AuthenticatorAttestationResponse: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) clientDataJSON = try container.decodeBytesFromURLEncodedBase64(forKey: .clientDataJSON) attestationObject = try container.decodeBytesFromURLEncodedBase64(forKey: .attestationObject) } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(clientDataJSON.base64URLEncodedString(), forKey: .clientDataJSON) + try container.encode(attestationObject.base64URLEncodedString(), forKey: .attestationObject) + } + private enum CodingKeys: String, CodingKey { case clientDataJSON diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index a069c4a..1139abe 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -19,33 +19,33 @@ import Foundation /// `Encodable` byte arrays are base64url encoded. /// /// - SeeAlso: https://www.w3.org/TR/webauthn-2/#dictionary-makecredentialoptions -public struct PublicKeyCredentialCreationOptions: Encodable, Sendable { +public struct PublicKeyCredentialCreationOptions: Codable, Sendable { /// A byte array randomly generated by the Relying Party. Should be at least 16 bytes long to ensure sufficient /// entropy. /// /// The Relying Party should store the challenge temporarily until the registration flow is complete. When /// encoding using `Encodable`, the challenge is base64url encoded. - public let challenge: [UInt8] + public var challenge: [UInt8] /// Contains names and an identifier for the user account performing the registration - public let user: PublicKeyCredentialUserEntity + public var user: PublicKeyCredentialUserEntity /// Contains a name and an identifier for the Relying Party responsible for the request - public let relyingParty: PublicKeyCredentialRelyingPartyEntity + public var relyingParty: PublicKeyCredentialRelyingPartyEntity /// A list of key types and signature algorithms the Relying Party supports. Ordered from most preferred to least /// preferred. - public let publicKeyCredentialParameters: [PublicKeyCredentialParameters] + public var publicKeyCredentialParameters: [PublicKeyCredentialParameters] /// A time, in seconds, that the caller is willing to wait for the call to complete. This is treated as a /// hint, and may be overridden by the client. /// /// - Note: When encoded, this value is represented in milleseconds as a ``UInt32``. - public let timeout: Duration? + public var timeout: Duration? /// Sets the Relying Party's preference for attestation conveyance. At the time of writing only `none` is /// supported. - public let attestation: AttestationConveyancePreference + public var attestation: AttestationConveyancePreference public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) @@ -57,6 +57,29 @@ public struct PublicKeyCredentialCreationOptions: Encodable, Sendable { try container.encodeIfPresent(timeout?.milliseconds, forKey: .timeout) try container.encode(attestation, forKey: .attestation) } + + public init(from decoder: any Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + + self.challenge = try values.decodeBytesFromURLEncodedBase64(forKey: .challenge) + self.user = try values.decode(PublicKeyCredentialUserEntity.self, forKey: .user) + self.relyingParty = try values.decode(PublicKeyCredentialRelyingPartyEntity.self, forKey:.relyingParty) + self.publicKeyCredentialParameters = try values.decode([PublicKeyCredentialParameters].self, forKey:.publicKeyCredentialParameters) + if let timeout = try values.decodeIfPresent(UInt32.self,forKey:.timeout) { + self.timeout = Duration.milliseconds(timeout) + } + self.attestation = try values.decode(AttestationConveyancePreference.self, forKey:.attestation) + } + + public init(challenge: [UInt8],user: PublicKeyCredentialUserEntity,relyingParty: PublicKeyCredentialRelyingPartyEntity,publicKeyCredentialParameters: [PublicKeyCredentialParameters], + timeout: Duration?,attestation: AttestationConveyancePreference) { + self.challenge = challenge + self.user = user + self.relyingParty = relyingParty + self.publicKeyCredentialParameters = publicKeyCredentialParameters + self.timeout = timeout + self.attestation = attestation + } private enum CodingKeys: String, CodingKey { case challenge @@ -70,7 +93,7 @@ public struct PublicKeyCredentialCreationOptions: Encodable, Sendable { // MARK: - Credential parameters /// From §5.3 (https://w3c.github.io/TR/webauthn/#dictionary-credential-params) -public struct PublicKeyCredentialParameters: Equatable, Encodable, Sendable { +public struct PublicKeyCredentialParameters: Equatable, Codable, Sendable { /// The type of credential to be created. At the time of writing always ``CredentialType/publicKey``. public let type: CredentialType /// The cryptographic signature algorithm with which the newly generated credential will be used, and thus also @@ -87,6 +110,18 @@ public struct PublicKeyCredentialParameters: Equatable, Encodable, Sendable { self.type = type self.alg = alg } + + public init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let type = try container.decode(CredentialType.self,forKey: .type) + let alg = try container.decode(COSEAlgorithmIdentifier.self, forKey: .alg) + self.init(type:type,alg:alg) + } + + private enum CodingKeys: String, CodingKey { + case type + case alg + } } extension Array where Element == PublicKeyCredentialParameters { @@ -103,7 +138,7 @@ extension Array where Element == PublicKeyCredentialParameters { /// From §5.4.2 (https://www.w3.org/TR/webauthn/#sctn-rp-credential-params). /// The PublicKeyCredentialRelyingPartyEntity dictionary is used to supply additional Relying Party attributes when /// creating a new credential. -public struct PublicKeyCredentialRelyingPartyEntity: Encodable, Sendable { +public struct PublicKeyCredentialRelyingPartyEntity: Codable, Sendable { /// A unique identifier for the Relying Party entity. public let id: String @@ -111,6 +146,15 @@ public struct PublicKeyCredentialRelyingPartyEntity: Encodable, Sendable { /// "Wonderful Widgets, Inc." or "ОАО Примертех". public let name: String + public init(_ src : PublicKeyCredentialRelyingPartyEntity) { + self.id = src.id + self.name = src.name + } + + public init(id : String, name : String) { + self.id = id + self.name = name + } } /// From §5.4.3 (https://www.w3.org/TR/webauthn/#dictionary-user-credential-params) @@ -118,7 +162,7 @@ public struct PublicKeyCredentialRelyingPartyEntity: Encodable, Sendable { /// creating a new credential. /// /// When encoding using `Encodable`, `id` is base64url encoded. -public struct PublicKeyCredentialUserEntity: Encodable, Sendable { +public struct PublicKeyCredentialUserEntity: Codable, Sendable { /// Generated by the Relying Party, unique to the user account, and must not contain personally identifying /// information about the user. /// @@ -149,6 +193,15 @@ public struct PublicKeyCredentialUserEntity: Encodable, Sendable { try container.encode(name, forKey: .name) try container.encode(displayName, forKey: .displayName) } + + public init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let id = try container.decodeBytesFromURLEncodedBase64(forKey: .id) + let name = try container.decode(String.self, forKey: .name) + let displayName = try container.decode(String.self, forKey: .displayName) + self.init(id: id, name: name, displayName: displayName) + } + private enum CodingKeys: String, CodingKey { case id diff --git a/Sources/WebAuthn/Ceremonies/Registration/RegistrationCredential.swift b/Sources/WebAuthn/Ceremonies/Registration/RegistrationCredential.swift index fe8a88f..112be8e 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/RegistrationCredential.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/RegistrationCredential.swift @@ -31,7 +31,7 @@ public struct RegistrationCredential: Sendable { public let attestationResponse: AuthenticatorAttestationResponse } -extension RegistrationCredential: Decodable { +extension RegistrationCredential: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -47,6 +47,15 @@ extension RegistrationCredential: Decodable { self.rawID = rawID attestationResponse = try container.decode(AuthenticatorAttestationResponse.self, forKey: .attestationResponse) } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(id, forKey: .id) + try container.encode(rawID.base64URLEncodedString(), forKey: .rawID) + try container.encode(attestationResponse, forKey: .attestationResponse) + } + private enum CodingKeys: String, CodingKey { case id diff --git a/Sources/WebAuthn/Ceremonies/Shared/COSE/COSEAlgorithmIdentifier.swift b/Sources/WebAuthn/Ceremonies/Shared/COSE/COSEAlgorithmIdentifier.swift index 50ecee2..0f60325 100644 --- a/Sources/WebAuthn/Ceremonies/Shared/COSE/COSEAlgorithmIdentifier.swift +++ b/Sources/WebAuthn/Ceremonies/Shared/COSE/COSEAlgorithmIdentifier.swift @@ -17,7 +17,7 @@ import Crypto /// COSEAlgorithmIdentifier From §5.10.5. A number identifying a cryptographic algorithm. The algorithm /// identifiers SHOULD be values registered in the IANA COSE Algorithms registry /// [https://www.w3.org/TR/webauthn/#biblio-iana-cose-algs-reg], for instance, -7 for "ES256" and -257 for "RS256". -public enum COSEAlgorithmIdentifier: Int, RawRepresentable, CaseIterable, Encodable, Sendable { +public enum COSEAlgorithmIdentifier: Int, RawRepresentable, CaseIterable, Codable, Sendable { /// AlgES256 ECDSA with SHA-256 case algES256 = -7 /// AlgES384 ECDSA with SHA-384 diff --git a/Sources/WebAuthn/Helpers/ChallengeGenerator.swift b/Sources/WebAuthn/Helpers/ChallengeGenerator.swift index ecbaa69..9d78ffb 100644 --- a/Sources/WebAuthn/Helpers/ChallengeGenerator.swift +++ b/Sources/WebAuthn/Helpers/ChallengeGenerator.swift @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -package struct ChallengeGenerator: Sendable { +public struct ChallengeGenerator: Sendable { var generate: @Sendable () -> [UInt8] package static var live: Self { diff --git a/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift b/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift index e6af1b5..fe59a59 100644 --- a/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift +++ b/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift @@ -13,7 +13,7 @@ import Foundation -extension KeyedDecodingContainer { +public extension KeyedDecodingContainer { func decodeBytesFromURLEncodedBase64(forKey key: KeyedDecodingContainer.Key) throws -> [UInt8] { guard let bytes = try decode( URLEncodedBase64.self, diff --git a/Sources/WebAuthn/WebAuthnManager.swift b/Sources/WebAuthn/WebAuthnManager.swift index 1da063b..1014a1a 100644 --- a/Sources/WebAuthn/WebAuthnManager.swift +++ b/Sources/WebAuthn/WebAuthnManager.swift @@ -39,7 +39,12 @@ public struct WebAuthnManager: Sendable { self.init(configuration: configuration, challengeGenerator: .live) } - package init(configuration: Configuration, challengeGenerator: ChallengeGenerator) { + /// Create a new WebAuthnManager using the given configuration and custom challenge generator + /// + /// - Parameters: + /// - configuration: The configuration to use for this manager. + /// - challengeGenerator: The challenge generator + public init(configuration: Configuration, challengeGenerator: ChallengeGenerator) { self.configuration = configuration self.challengeGenerator = challengeGenerator } From 6a6cbfa342012e1cefb383e8ddf7f180c3860c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Scre=CC=80ve?= Date: Wed, 29 Jan 2025 11:10:41 +0100 Subject: [PATCH 02/17] Fix reported issues --- .../Registration/PublicKeyCredentialCreationOptions.swift | 2 +- Sources/WebAuthn/Helpers/ChallengeGenerator.swift | 2 +- Sources/WebAuthn/WebAuthnManager.swift | 7 +------ 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index 1139abe..60f3372 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -25,7 +25,7 @@ public struct PublicKeyCredentialCreationOptions: Codable, Sendable { /// /// The Relying Party should store the challenge temporarily until the registration flow is complete. When /// encoding using `Encodable`, the challenge is base64url encoded. - public var challenge: [UInt8] + public let challenge: [UInt8] /// Contains names and an identifier for the user account performing the registration public var user: PublicKeyCredentialUserEntity diff --git a/Sources/WebAuthn/Helpers/ChallengeGenerator.swift b/Sources/WebAuthn/Helpers/ChallengeGenerator.swift index 9d78ffb..ecbaa69 100644 --- a/Sources/WebAuthn/Helpers/ChallengeGenerator.swift +++ b/Sources/WebAuthn/Helpers/ChallengeGenerator.swift @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -public struct ChallengeGenerator: Sendable { +package struct ChallengeGenerator: Sendable { var generate: @Sendable () -> [UInt8] package static var live: Self { diff --git a/Sources/WebAuthn/WebAuthnManager.swift b/Sources/WebAuthn/WebAuthnManager.swift index 1014a1a..1da063b 100644 --- a/Sources/WebAuthn/WebAuthnManager.swift +++ b/Sources/WebAuthn/WebAuthnManager.swift @@ -39,12 +39,7 @@ public struct WebAuthnManager: Sendable { self.init(configuration: configuration, challengeGenerator: .live) } - /// Create a new WebAuthnManager using the given configuration and custom challenge generator - /// - /// - Parameters: - /// - configuration: The configuration to use for this manager. - /// - challengeGenerator: The challenge generator - public init(configuration: Configuration, challengeGenerator: ChallengeGenerator) { + package init(configuration: Configuration, challengeGenerator: ChallengeGenerator) { self.configuration = configuration self.challengeGenerator = challengeGenerator } From 6118cd1412b61b1c5dcb9c2c11de15090bbd7ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Scre=CC=80ve?= Date: Wed, 5 Feb 2025 19:25:05 +0100 Subject: [PATCH 03/17] Fix requested issues --- .../PublicKeyCredentialCreationOptions.swift | 9 ++------- .../KeyedDecodingContainer+decodeURLEncoded.swift | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index 60f3372..80dacfd 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -71,8 +71,8 @@ public struct PublicKeyCredentialCreationOptions: Codable, Sendable { self.attestation = try values.decode(AttestationConveyancePreference.self, forKey:.attestation) } - public init(challenge: [UInt8],user: PublicKeyCredentialUserEntity,relyingParty: PublicKeyCredentialRelyingPartyEntity,publicKeyCredentialParameters: [PublicKeyCredentialParameters], - timeout: Duration?,attestation: AttestationConveyancePreference) { + public init(challenge: [UInt8], user: PublicKeyCredentialUserEntity, relyingParty: PublicKeyCredentialRelyingPartyEntity, publicKeyCredentialParameters: [PublicKeyCredentialParameters], + timeout: Duration?, attestation: AttestationConveyancePreference) { self.challenge = challenge self.user = user self.relyingParty = relyingParty @@ -117,11 +117,6 @@ public struct PublicKeyCredentialParameters: Equatable, Codable, Sendable { let alg = try container.decode(COSEAlgorithmIdentifier.self, forKey: .alg) self.init(type:type,alg:alg) } - - private enum CodingKeys: String, CodingKey { - case type - case alg - } } extension Array where Element == PublicKeyCredentialParameters { diff --git a/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift b/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift index fe59a59..e6af1b5 100644 --- a/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift +++ b/Sources/WebAuthn/Helpers/KeyedDecodingContainer+decodeURLEncoded.swift @@ -13,7 +13,7 @@ import Foundation -public extension KeyedDecodingContainer { +extension KeyedDecodingContainer { func decodeBytesFromURLEncodedBase64(forKey key: KeyedDecodingContainer.Key) throws -> [UInt8] { guard let bytes = try decode( URLEncodedBase64.self, From a05d52139da19ffb1939058673569b9789623346 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:10:29 -0700 Subject: [PATCH 04/17] Apply suggestion from @dimitribouniol --- .../AuthenticationCredential.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift index c9b8aaf..744423e 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift @@ -46,14 +46,14 @@ extension AuthenticationCredential: Codable { } public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - try container.encode(id, forKey: .id) - try container.encode(rawID.base64URLEncodedString(), forKey: .rawID) - try container.encode(response, forKey: .response) - try container.encodeIfPresent(authenticatorAttachment, forKey: .authenticatorAttachment) - try container.encode(type, forKey: .type) - } + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(id, forKey: .id) + try container.encode(rawID.base64URLEncodedString(), forKey: .rawID) + try container.encode(response, forKey: .response) + try container.encodeIfPresent(authenticatorAttachment, forKey: .authenticatorAttachment) + try container.encode(type, forKey: .type) + } private enum CodingKeys: String, CodingKey { From 5e11662c3ccd186e9f83ba099e0bf3b59e0afd88 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:10:46 -0700 Subject: [PATCH 05/17] Apply suggestion from @dimitribouniol --- .../AuthenticatorAssertionResponse.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift index 91e7d9c..2daa5df 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/AuthenticatorAssertionResponse.swift @@ -60,14 +60,14 @@ extension AuthenticatorAssertionResponse: Codable { } public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(clientDataJSON.base64URLEncodedString(), forKey: .clientDataJSON) try container.encode(authenticatorData.base64URLEncodedString(), forKey: .authenticatorData) try container.encode(signature.base64URLEncodedString(), forKey: .signature) - try container.encodeIfPresent(userHandle?.base64URLEncodedString(),forKey: .userHandle) - try container.encodeIfPresent(attestationObject?.base64URLEncodedString(),forKey: .attestationObject) - } + try container.encodeIfPresent(userHandle?.base64URLEncodedString(), forKey: .userHandle) + try container.encodeIfPresent(attestationObject?.base64URLEncodedString(), forKey: .attestationObject) + } private enum CodingKeys: String, CodingKey { From a4d3bc8f059cb80ada346c2b610b909d1d12800f Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:10:59 -0700 Subject: [PATCH 06/17] Apply suggestion from @dimitribouniol --- .../Authentication/PublicKeyCredentialRequestOptions.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift index 316ff6f..e187eeb 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift @@ -60,7 +60,8 @@ public struct PublicKeyCredentialRequestOptions: Codable, Sendable { timeout: Duration?, relyingPartyID: String, allowCredentials: [PublicKeyCredentialDescriptor]?, - userVerification: UserVerificationRequirement?) { + userVerification: UserVerificationRequirement? + ) { self.challenge = challenge self.timeout = timeout self.relyingPartyID = relyingPartyID From ca71904ca8976a9a38fb7dcc2c9577735739ee24 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:11:16 -0700 Subject: [PATCH 07/17] Apply suggestion from @dimitribouniol --- .../PublicKeyCredentialRequestOptions.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift index e187eeb..25e3a03 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift @@ -74,12 +74,12 @@ public struct PublicKeyCredentialRequestOptions: Codable, Sendable { self.challenge = try values.decodeBytesFromURLEncodedBase64(forKey: .challenge) - if let timeout = try values.decodeIfPresent(UInt32.self, forKey:.timeout) { - self.timeout=Duration.milliseconds(timeout) + if let timeout = try values.decodeIfPresent(UInt32.self, forKey: .timeout) { + self.timeout = .milliseconds(timeout) } - self.relyingPartyID=try values.decode(String.self, forKey:.relyingPartyID) - self.allowCredentials=try values.decodeIfPresent([PublicKeyCredentialDescriptor].self,forKey: .allowCredentials) - self.userVerification=try values.decodeIfPresent(UserVerificationRequirement.self,forKey: .userVerification) + self.relyingPartyID = try values.decode(String.self, forKey: .relyingPartyID) + self.allowCredentials = try values.decodeIfPresent([PublicKeyCredentialDescriptor].self, forKey: .allowCredentials) + self.userVerification = try values.decodeIfPresent(UserVerificationRequirement.self, forKey: .userVerification) } private enum CodingKeys: String, CodingKey { From 2e63289fdddbc6d0f5960d04ef3b2a44fd149430 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:11:51 -0700 Subject: [PATCH 08/17] Apply suggestion from @dimitribouniol --- .../PublicKeyCredentialRequestOptions.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift index 25e3a03..9dc5fd9 100644 --- a/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Authentication/PublicKeyCredentialRequestOptions.swift @@ -144,10 +144,10 @@ public struct PublicKeyCredentialDescriptor: Equatable, Codable, Sendable { public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let type = try container.decode(CredentialType.self,forKey: .type) - let id = try container.decodeBytesFromURLEncodedBase64( forKey: .id) - let transports = try container.decodeIfPresent([AuthenticatorTransport].self,forKey:.transports) ?? [] - self.init(type: type, id:id, transports: transports) + + self.type = try container.decode(CredentialType.self, forKey: .type) + self.id = try container.decodeBytesFromURLEncodedBase64(forKey: .id) + self.transports = try container.decodeIfPresent([AuthenticatorTransport].self, forKey: .transports) ?? [] } private enum CodingKeys: String, CodingKey { From 2ff374ac7601b23b29dacc626085b8e58b08f50a Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:12:04 -0700 Subject: [PATCH 09/17] Apply suggestion from @dimitribouniol --- .../Registration/AuthenticatorAttestationResponse.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift b/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift index b831703..dc22173 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift @@ -39,10 +39,10 @@ extension AuthenticatorAttestationResponse: Codable { public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - + try container.encode(clientDataJSON.base64URLEncodedString(), forKey: .clientDataJSON) try container.encode(attestationObject.base64URLEncodedString(), forKey: .attestationObject) - } + } private enum CodingKeys: String, CodingKey { From c71f17831fdc5db47467a6e85380576a55a7e239 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:12:23 -0700 Subject: [PATCH 10/17] Apply suggestion from @dimitribouniol --- .../PublicKeyCredentialCreationOptions.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index 91775ed..f505100 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -63,12 +63,12 @@ public struct PublicKeyCredentialCreationOptions: Codable, Sendable { self.challenge = try values.decodeBytesFromURLEncodedBase64(forKey: .challenge) self.user = try values.decode(PublicKeyCredentialUserEntity.self, forKey: .user) - self.relyingParty = try values.decode(PublicKeyCredentialRelyingPartyEntity.self, forKey:.relyingParty) - self.publicKeyCredentialParameters = try values.decode([PublicKeyCredentialParameters].self, forKey:.publicKeyCredentialParameters) - if let timeout = try values.decodeIfPresent(UInt32.self,forKey:.timeout) { - self.timeout = Duration.milliseconds(timeout) + self.relyingParty = try values.decode(PublicKeyCredentialRelyingPartyEntity.self, forKey: .relyingParty) + self.publicKeyCredentialParameters = try values.decode([PublicKeyCredentialParameters].self, forKey: .publicKeyCredentialParameters) + if let timeout = try values.decodeIfPresent(UInt32.self, forKey: .timeout) { + self.timeout = .milliseconds(timeout) } - self.attestation = try values.decode(AttestationConveyancePreference.self, forKey:.attestation) + self.attestation = try values.decode(AttestationConveyancePreference.self, forKey: .attestation) } public init(challenge: [UInt8], user: PublicKeyCredentialUserEntity, relyingParty: PublicKeyCredentialRelyingPartyEntity, publicKeyCredentialParameters: [PublicKeyCredentialParameters], From 109d3bcb6dceb51e5c925e8798f2b76c3b40b66c Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:12:38 -0700 Subject: [PATCH 11/17] Apply suggestion from @dimitribouniol --- .../PublicKeyCredentialCreationOptions.swift | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index f505100..46c6677 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -71,8 +71,14 @@ public struct PublicKeyCredentialCreationOptions: Codable, Sendable { self.attestation = try values.decode(AttestationConveyancePreference.self, forKey: .attestation) } - public init(challenge: [UInt8], user: PublicKeyCredentialUserEntity, relyingParty: PublicKeyCredentialRelyingPartyEntity, publicKeyCredentialParameters: [PublicKeyCredentialParameters], - timeout: Duration?, attestation: AttestationConveyancePreference) { + public init( + challenge: [UInt8], + user: PublicKeyCredentialUserEntity, + relyingParty: PublicKeyCredentialRelyingPartyEntity, + publicKeyCredentialParameters: [PublicKeyCredentialParameters], + timeout: Duration?, + attestation: AttestationConveyancePreference + ) { self.challenge = challenge self.user = user self.relyingParty = relyingParty From 1c3e29474841046ce1ee41084c894540fc50fdb9 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:12:49 -0700 Subject: [PATCH 12/17] Apply suggestion from @dimitribouniol --- .../Registration/PublicKeyCredentialCreationOptions.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index 46c6677..6c2a5fe 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -119,9 +119,9 @@ public struct PublicKeyCredentialParameters: Equatable, Codable, Sendable { public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let type = try container.decode(CredentialType.self,forKey: .type) - let alg = try container.decode(COSEAlgorithmIdentifier.self, forKey: .alg) - self.init(type:type,alg:alg) + + self.type = try container.decode(CredentialType.self, forKey: .type) + self.alg = try container.decode(COSEAlgorithmIdentifier.self, forKey: .alg) } } From 8dcbe5100af1b5bb58bce24c898727785cb299ec Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:13:07 -0700 Subject: [PATCH 13/17] Apply suggestion from @dimitribouniol --- .../Registration/PublicKeyCredentialCreationOptions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index 6c2a5fe..dcd008e 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -141,7 +141,7 @@ extension Array where Element == PublicKeyCredentialParameters { /// creating a new credential. public struct PublicKeyCredentialRelyingPartyEntity: Codable, Sendable { /// A unique identifier for the Relying Party entity. - public let id: String + public var id: String /// A human-readable identifier for the Relying Party, intended only for display. For example, "ACME Corporation", /// "Wonderful Widgets, Inc." or "ОАО Примертех". From 3cc9fd0d19d16ea9e560144164e4ba0cf23c1471 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:13:20 -0700 Subject: [PATCH 14/17] Apply suggestion from @dimitribouniol --- .../Registration/PublicKeyCredentialCreationOptions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index dcd008e..11a3bc1 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -145,7 +145,7 @@ public struct PublicKeyCredentialRelyingPartyEntity: Codable, Sendable { /// A human-readable identifier for the Relying Party, intended only for display. For example, "ACME Corporation", /// "Wonderful Widgets, Inc." or "ОАО Примертех". - public let name: String + public var name: String public init(_ src : PublicKeyCredentialRelyingPartyEntity) { self.id = src.id From d8f6ae2d54f2a71fd7ad967dd30d706d387605ce Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:13:46 -0700 Subject: [PATCH 15/17] Apply suggestion from @dimitribouniol --- .../Registration/PublicKeyCredentialCreationOptions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index 11a3bc1..723995f 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -152,7 +152,7 @@ public struct PublicKeyCredentialRelyingPartyEntity: Codable, Sendable { self.name = src.name } - public init(id : String, name : String) { + public init(id: String, name: String) { self.id = id self.name = name } From a88087f411187960c615fe7d4f50e446ce79a0a1 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:13:59 -0700 Subject: [PATCH 16/17] Apply suggestion from @dimitribouniol --- .../Registration/PublicKeyCredentialCreationOptions.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index 723995f..ca2456b 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -197,10 +197,10 @@ public struct PublicKeyCredentialUserEntity: Codable, Sendable { public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let id = try container.decodeBytesFromURLEncodedBase64(forKey: .id) - let name = try container.decode(String.self, forKey: .name) - let displayName = try container.decode(String.self, forKey: .displayName) - self.init(id: id, name: name, displayName: displayName) + + self.id = try container.decodeBytesFromURLEncodedBase64(forKey: .id) + self.name = try container.decode(String.self, forKey: .name) + self.displayName = try container.decode(String.self, forKey: .displayName) } From ca47a8298d9cf25b89c3a04ed34cbab2e7180298 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 6 Oct 2025 06:38:32 -0700 Subject: [PATCH 17/17] Apply suggestion from @dimitribouniol --- .../Registration/PublicKeyCredentialCreationOptions.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift index ca2456b..2d0976b 100644 --- a/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift +++ b/Sources/WebAuthn/Ceremonies/Registration/PublicKeyCredentialCreationOptions.swift @@ -147,11 +147,6 @@ public struct PublicKeyCredentialRelyingPartyEntity: Codable, Sendable { /// "Wonderful Widgets, Inc." or "ОАО Примертех". public var name: String - public init(_ src : PublicKeyCredentialRelyingPartyEntity) { - self.id = src.id - self.name = src.name - } - public init(id: String, name: String) { self.id = id self.name = name