Skip to content

Commit b9e0818

Browse files
authored
Merge pull request #284 from okta/okta-1209004-webauthn-credentials-merge-fix
Fix WebAuthn/Duo credentials merge bug (OKTA-1209004)
2 parents 34932b9 + ae113a6 commit b9e0818

2 files changed

Lines changed: 51 additions & 1 deletion

File tree

Sources/OktaIdxAuth/Internal/Extensions/IDXRemediation+Extensions.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,14 @@ extension Remediation.Form.Field {
6969
if let form = self.form,
7070
!form.allFields.isEmpty
7171
{
72+
var nestedJSON = JSON([:])
7273
for field in form.allFields {
7374
guard let nestedResult = try field.formValue else {
7475
continue
7576
}
76-
json[name] = nestedResult
77+
nestedJSON.value += nestedResult
7778
}
79+
json[name] = nestedJSON.value
7880
}
7981

8082
// Named form values that consist of multiple child options

Tests/OktaIdxAuthTests/IDXExtractFormValueTests.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,54 @@ class IDXExtractFormValueTests: XCTestCase {
8787
XCTAssertEqual(result["credentials"], .object(["passcode": "password"]))
8888
}
8989

90+
// OKTA-1209004: A named field with a nested `form` containing multiple
91+
// child fields (e.g. WebAuthn's `credentials` object) must merge all of
92+
// its children into a single object, not overwrite with only the last one.
93+
func testNestedWithMultipleChildValues() throws {
94+
let form = try XCTUnwrap(Form(fields: [
95+
Form.Field(name: "stateHandle",
96+
value: "abcEasyAs123",
97+
visible: false,
98+
mutable: false,
99+
required: true,
100+
secret: false),
101+
Form.Field(name: "credentials",
102+
type: "object",
103+
visible: true,
104+
mutable: true,
105+
required: true,
106+
secret: false,
107+
form: Form(fields: [
108+
Form.Field(name: "authenticatorData",
109+
visible: true,
110+
mutable: true,
111+
required: true,
112+
secret: false),
113+
Form.Field(name: "clientData",
114+
visible: true,
115+
mutable: true,
116+
required: true,
117+
secret: false),
118+
Form.Field(name: "signatureData",
119+
visible: true,
120+
mutable: true,
121+
required: true,
122+
secret: false)
123+
]))
124+
]))
125+
form["credentials.authenticatorData"]?.value = "IMIVPkdt3y..."
126+
form["credentials.clientData"]?.value = "eyJ0e..."
127+
form["credentials.signatureData"]?.value = "MEUC..."
128+
129+
let result = try form.formValue
130+
XCTAssertEqual(result["stateHandle"], "abcEasyAs123")
131+
XCTAssertEqual(result["credentials"], [
132+
"authenticatorData": "IMIVPkdt3y...",
133+
"clientData": "eyJ0e...",
134+
"signatureData": "MEUC..."
135+
])
136+
}
137+
90138
func testNestedWithNestedDefaults() throws {
91139
let nestedForm = Form.Field(label: "Security Question",
92140
visible: true,

0 commit comments

Comments
 (0)