@@ -19,33 +19,33 @@ import Foundation
19
19
/// `Encodable` byte arrays are base64url encoded.
20
20
///
21
21
/// - SeeAlso: https://www.w3.org/TR/webauthn-2/#dictionary-makecredentialoptions
22
- public struct PublicKeyCredentialCreationOptions : Encodable , Sendable {
22
+ public struct PublicKeyCredentialCreationOptions : Codable , Sendable {
23
23
/// A byte array randomly generated by the Relying Party. Should be at least 16 bytes long to ensure sufficient
24
24
/// entropy.
25
25
///
26
26
/// The Relying Party should store the challenge temporarily until the registration flow is complete. When
27
27
/// encoding using `Encodable`, the challenge is base64url encoded.
28
- public let challenge : [ UInt8 ]
28
+ public var challenge : [ UInt8 ]
29
29
30
30
/// Contains names and an identifier for the user account performing the registration
31
- public let user : PublicKeyCredentialUserEntity
31
+ public var user : PublicKeyCredentialUserEntity
32
32
33
33
/// Contains a name and an identifier for the Relying Party responsible for the request
34
- public let relyingParty : PublicKeyCredentialRelyingPartyEntity
34
+ public var relyingParty : PublicKeyCredentialRelyingPartyEntity
35
35
36
36
/// A list of key types and signature algorithms the Relying Party supports. Ordered from most preferred to least
37
37
/// preferred.
38
- public let publicKeyCredentialParameters : [ PublicKeyCredentialParameters ]
38
+ public var publicKeyCredentialParameters : [ PublicKeyCredentialParameters ]
39
39
40
40
/// A time, in seconds, that the caller is willing to wait for the call to complete. This is treated as a
41
41
/// hint, and may be overridden by the client.
42
42
///
43
43
/// - Note: When encoded, this value is represented in milleseconds as a ``UInt32``.
44
- public let timeout : Duration ?
44
+ public var timeout : Duration ?
45
45
46
46
/// Sets the Relying Party's preference for attestation conveyance. At the time of writing only `none` is
47
47
/// supported.
48
- public let attestation : AttestationConveyancePreference
48
+ public var attestation : AttestationConveyancePreference
49
49
50
50
public func encode( to encoder: Encoder ) throws {
51
51
var container = encoder. container ( keyedBy: CodingKeys . self)
@@ -57,6 +57,29 @@ public struct PublicKeyCredentialCreationOptions: Encodable, Sendable {
57
57
try container. encodeIfPresent ( timeout? . milliseconds, forKey: . timeout)
58
58
try container. encode ( attestation, forKey: . attestation)
59
59
}
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 = Duration . milliseconds ( timeout)
70
+ }
71
+ self . attestation = try values. decode ( AttestationConveyancePreference . self, forKey: . attestation)
72
+ }
73
+
74
+ public init ( challenge: [ UInt8 ] , user: PublicKeyCredentialUserEntity , relyingParty: PublicKeyCredentialRelyingPartyEntity , publicKeyCredentialParameters: [ PublicKeyCredentialParameters ] ,
75
+ timeout: Duration ? , attestation: AttestationConveyancePreference ) {
76
+ self . challenge = challenge
77
+ self . user = user
78
+ self . relyingParty = relyingParty
79
+ self . publicKeyCredentialParameters = publicKeyCredentialParameters
80
+ self . timeout = timeout
81
+ self . attestation = attestation
82
+ }
60
83
61
84
private enum CodingKeys : String , CodingKey {
62
85
case challenge
@@ -70,7 +93,7 @@ public struct PublicKeyCredentialCreationOptions: Encodable, Sendable {
70
93
71
94
// MARK: - Credential parameters
72
95
/// From §5.3 (https://w3c.github.io/TR/webauthn/#dictionary-credential-params)
73
- public struct PublicKeyCredentialParameters : Equatable , Encodable , Sendable {
96
+ public struct PublicKeyCredentialParameters : Equatable , Codable , Sendable {
74
97
/// The type of credential to be created. At the time of writing always ``CredentialType/publicKey``.
75
98
public let type : CredentialType
76
99
/// 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 {
87
110
self . type = type
88
111
self . alg = alg
89
112
}
113
+
114
+ public init ( from decoder: any Decoder ) throws {
115
+ let container = try decoder. container ( keyedBy: CodingKeys . self)
116
+ let type = try container. decode ( CredentialType . self, forKey: . type)
117
+ let alg = try container. decode ( COSEAlgorithmIdentifier . self, forKey: . alg)
118
+ self . init ( type: type, alg: alg)
119
+ }
120
+
121
+ private enum CodingKeys : String , CodingKey {
122
+ case type
123
+ case alg
124
+ }
90
125
}
91
126
92
127
extension Array where Element == PublicKeyCredentialParameters {
@@ -103,22 +138,31 @@ extension Array where Element == PublicKeyCredentialParameters {
103
138
/// From §5.4.2 (https://www.w3.org/TR/webauthn/#sctn-rp-credential-params).
104
139
/// The PublicKeyCredentialRelyingPartyEntity dictionary is used to supply additional Relying Party attributes when
105
140
/// creating a new credential.
106
- public struct PublicKeyCredentialRelyingPartyEntity : Encodable , Sendable {
141
+ public struct PublicKeyCredentialRelyingPartyEntity : Codable , Sendable {
107
142
/// A unique identifier for the Relying Party entity.
108
143
public let id : String
109
144
110
145
/// A human-readable identifier for the Relying Party, intended only for display. For example, "ACME Corporation",
111
146
/// "Wonderful Widgets, Inc." or "ОАО Примертех".
112
147
public let name : String
113
148
149
+ public init ( _ src : PublicKeyCredentialRelyingPartyEntity ) {
150
+ self . id = src. id
151
+ self . name = src. name
152
+ }
153
+
154
+ public init ( id : String , name : String ) {
155
+ self . id = id
156
+ self . name = name
157
+ }
114
158
}
115
159
116
160
/// From §5.4.3 (https://www.w3.org/TR/webauthn/#dictionary-user-credential-params)
117
161
/// The PublicKeyCredentialUserEntity dictionary is used to supply additional user account attributes when
118
162
/// creating a new credential.
119
163
///
120
164
/// When encoding using `Encodable`, `id` is base64url encoded.
121
- public struct PublicKeyCredentialUserEntity : Encodable , Sendable {
165
+ public struct PublicKeyCredentialUserEntity : Codable , Sendable {
122
166
/// Generated by the Relying Party, unique to the user account, and must not contain personally identifying
123
167
/// information about the user.
124
168
///
@@ -149,6 +193,15 @@ public struct PublicKeyCredentialUserEntity: Encodable, Sendable {
149
193
try container. encode ( name, forKey: . name)
150
194
try container. encode ( displayName, forKey: . displayName)
151
195
}
196
+
197
+ public init ( from decoder: any Decoder ) throws {
198
+ let container = try decoder. container ( keyedBy: CodingKeys . self)
199
+ let id = try container. decodeBytesFromURLEncodedBase64 ( forKey: . id)
200
+ let name = try container. decode ( String . self, forKey: . name)
201
+ let displayName = try container. decode ( String . self, forKey: . displayName)
202
+ self . init ( id: id, name: name, displayName: displayName)
203
+ }
204
+
152
205
153
206
private enum CodingKeys : String , CodingKey {
154
207
case id
0 commit comments