@@ -19,7 +19,7 @@ import Foundation
1919/// `Encodable` byte arrays are base64url encoded.
2020///
2121/// - SeeAlso: https://www.w3.org/TR/webauthn-2/#dictionary-makecredentialoptions
22- public struct PublicKeyCredentialCreationOptions : Encodable , Sendable {
22+ public struct PublicKeyCredentialCreationOptions : Codable , Sendable {
2323 /// A byte array randomly generated by the Relying Party. Should be at least 16 bytes long to ensure sufficient
2424 /// entropy.
2525 ///
@@ -28,24 +28,24 @@ public struct PublicKeyCredentialCreationOptions: Encodable, Sendable {
2828 public let challenge : [ UInt8 ]
2929
3030 /// Contains names and an identifier for the user account performing the registration
31- public let user : PublicKeyCredentialUserEntity
31+ public var user : PublicKeyCredentialUserEntity
3232
3333 /// Contains a name and an identifier for the Relying Party responsible for the request
34- public let relyingParty : PublicKeyCredentialRelyingPartyEntity
34+ public var relyingParty : PublicKeyCredentialRelyingPartyEntity
3535
3636 /// A list of key types and signature algorithms the Relying Party supports. Ordered from most preferred to least
3737 /// preferred.
38- public let publicKeyCredentialParameters : [ PublicKeyCredentialParameters ]
38+ public var publicKeyCredentialParameters : [ PublicKeyCredentialParameters ]
3939
4040 /// A time, in seconds, that the caller is willing to wait for the call to complete. This is treated as a
4141 /// hint, and may be overridden by the client.
4242 ///
4343 /// - Note: When encoded, this value is represented in milleseconds as a ``UInt32``.
44- public let timeout : Duration ?
44+ public var timeout : Duration ?
4545
4646 /// Sets the Relying Party's preference for attestation conveyance. At the time of writing only `none` is
4747 /// supported.
48- public let attestation : AttestationConveyancePreference
48+ public var attestation : AttestationConveyancePreference
4949
5050 public func encode( to encoder: any Encoder ) throws {
5151 var container = encoder. container ( keyedBy: CodingKeys . self)
@@ -57,6 +57,35 @@ public struct PublicKeyCredentialCreationOptions: Encodable, Sendable {
5757 try container. encodeIfPresent ( timeout? . milliseconds, forKey: . timeout)
5858 try container. encode ( attestation, forKey: . attestation)
5959 }
60+
61+ public init ( from decoder: any Decoder ) throws {
62+ let values = try decoder. container ( keyedBy: CodingKeys . self)
63+
64+ self . challenge = try values. decodeBytesFromURLEncodedBase64 ( forKey: . challenge)
65+ self . user = try values. decode ( PublicKeyCredentialUserEntity . self, forKey: . user)
66+ self . relyingParty = try values. decode ( PublicKeyCredentialRelyingPartyEntity . self, forKey: . relyingParty)
67+ self . publicKeyCredentialParameters = try values. decode ( [ PublicKeyCredentialParameters ] . self, forKey: . publicKeyCredentialParameters)
68+ if let timeout = try values. decodeIfPresent ( UInt32 . self, forKey: . timeout) {
69+ self . timeout = . milliseconds( timeout)
70+ }
71+ self . attestation = try values. decode ( AttestationConveyancePreference . self, forKey: . attestation)
72+ }
73+
74+ public init (
75+ challenge: [ UInt8 ] ,
76+ user: PublicKeyCredentialUserEntity ,
77+ relyingParty: PublicKeyCredentialRelyingPartyEntity ,
78+ publicKeyCredentialParameters: [ PublicKeyCredentialParameters ] ,
79+ timeout: Duration ? ,
80+ attestation: AttestationConveyancePreference
81+ ) {
82+ self . challenge = challenge
83+ self . user = user
84+ self . relyingParty = relyingParty
85+ self . publicKeyCredentialParameters = publicKeyCredentialParameters
86+ self . timeout = timeout
87+ self . attestation = attestation
88+ }
6089
6190 private enum CodingKeys : String , CodingKey {
6291 case challenge
@@ -70,7 +99,7 @@ public struct PublicKeyCredentialCreationOptions: Encodable, Sendable {
7099
71100// MARK: - Credential parameters
72101/// From §5.3 (https://w3c.github.io/TR/webauthn/#dictionary-credential-params)
73- public struct PublicKeyCredentialParameters : Equatable , Encodable , Sendable {
102+ public struct PublicKeyCredentialParameters : Equatable , Codable , Sendable {
74103 /// The type of credential to be created. At the time of writing always ``CredentialType/publicKey``.
75104 public let type : CredentialType
76105 /// The cryptographic signature algorithm with which the newly generated credential will be used, and thus also
@@ -87,6 +116,13 @@ public struct PublicKeyCredentialParameters: Equatable, Encodable, Sendable {
87116 self . type = type
88117 self . alg = alg
89118 }
119+
120+ public init ( from decoder: any Decoder ) throws {
121+ let container = try decoder. container ( keyedBy: CodingKeys . self)
122+
123+ self . type = try container. decode ( CredentialType . self, forKey: . type)
124+ self . alg = try container. decode ( COSEAlgorithmIdentifier . self, forKey: . alg)
125+ }
90126}
91127
92128extension Array where Element == PublicKeyCredentialParameters {
@@ -103,22 +139,26 @@ extension Array where Element == PublicKeyCredentialParameters {
103139/// From §5.4.2 (https://www.w3.org/TR/webauthn/#sctn-rp-credential-params).
104140/// The PublicKeyCredentialRelyingPartyEntity dictionary is used to supply additional Relying Party attributes when
105141/// creating a new credential.
106- public struct PublicKeyCredentialRelyingPartyEntity : Encodable , Sendable {
142+ public struct PublicKeyCredentialRelyingPartyEntity : Codable , Sendable {
107143 /// A unique identifier for the Relying Party entity.
108- public let id : String
144+ public var id : String
109145
110146 /// A human-readable identifier for the Relying Party, intended only for display. For example, "ACME Corporation",
111147 /// "Wonderful Widgets, Inc." or "ОАО Примертех".
112- public let name : String
148+ public var name : String
113149
150+ public init ( id: String , name: String ) {
151+ self . id = id
152+ self . name = name
153+ }
114154}
115155
116156 /// From §5.4.3 (https://www.w3.org/TR/webauthn/#dictionary-user-credential-params)
117157 /// The PublicKeyCredentialUserEntity dictionary is used to supply additional user account attributes when
118158 /// creating a new credential.
119159 ///
120160 /// When encoding using `Encodable`, `id` is base64url encoded.
121- public struct PublicKeyCredentialUserEntity : Encodable , Sendable {
161+ public struct PublicKeyCredentialUserEntity : Codable , Sendable {
122162 /// Generated by the Relying Party, unique to the user account, and must not contain personally identifying
123163 /// information about the user.
124164 ///
@@ -149,6 +189,15 @@ public struct PublicKeyCredentialUserEntity: Encodable, Sendable {
149189 try container. encode ( name, forKey: . name)
150190 try container. encode ( displayName, forKey: . displayName)
151191 }
192+
193+ public init ( from decoder: any Decoder ) throws {
194+ let container = try decoder. container ( keyedBy: CodingKeys . self)
195+
196+ self . id = try container. decodeBytesFromURLEncodedBase64 ( forKey: . id)
197+ self . name = try container. decode ( String . self, forKey: . name)
198+ self . displayName = try container. decode ( String . self, forKey: . displayName)
199+ }
200+
152201
153202 private enum CodingKeys : String , CodingKey {
154203 case id
0 commit comments