From 5d0f52b57cc0f80666723958d10d971b4be635ac Mon Sep 17 00:00:00 2001 From: "Stanko K.R." Date: Wed, 25 Mar 2026 17:14:20 +0100 Subject: [PATCH] Update as_json to return string keys --- .../public_key_credential/request_options.rb | 6 ++- .../creation_options_test.rb | 48 ++++++++++--------- .../request_options_test.rb | 24 +++++----- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/lib/action_pack/web_authn/public_key_credential/request_options.rb b/lib/action_pack/web_authn/public_key_credential/request_options.rb index ab1b5cb47..99f06ccf4 100644 --- a/lib/action_pack/web_authn/public_key_credential/request_options.rb +++ b/lib/action_pack/web_authn/public_key_credential/request_options.rb @@ -35,12 +35,14 @@ class ActionPack::WebAuthn::PublicKeyCredential::RequestOptions < ActionPack::We # Returns a Hash suitable for JSON serialization and passing to the # WebAuthn JavaScript API. def as_json(options = {}) - { + json = { challenge: challenge, rpId: relying_party.id, allowCredentials: credentials.map { |credential| allow_credential_json(credential) }, userVerification: user_verification.to_s - }.as_json(options) + } + + json.as_json(options) end private diff --git a/test/lib/action_pack/web_authn/public_key_credential/creation_options_test.rb b/test/lib/action_pack/web_authn/public_key_credential/creation_options_test.rb index 8e8fd686a..9c9b37ea0 100644 --- a/test/lib/action_pack/web_authn/public_key_credential/creation_options_test.rb +++ b/test/lib/action_pack/web_authn/public_key_credential/creation_options_test.rb @@ -31,24 +31,26 @@ class ActionPack::WebAuthn::PublicKeyCredential::CreationOptionsTest < ActiveSup end test "as_json" do - assert_equal @options.challenge, @options.as_json[:challenge] + json = @options.as_json - assert_equal({ id: "example.com", name: "Example App" }, @options.as_json[:rp]) + assert_equal @options.challenge, json["challenge"] - user = @options.as_json[:user] - assert_equal Base64.urlsafe_encode64("user-123", padding: false), user[:id] - assert_equal "user@example.com", user[:name] - assert_equal "Test User", user[:displayName] + assert_equal({ "id" => "example.com", "name" => "Example App" }, json["rp"]) + + user = json["user"] + assert_equal Base64.urlsafe_encode64("user-123", padding: false), user["id"] + assert_equal "user@example.com", user["name"] + assert_equal "Test User", user["displayName"] assert_equal [ - { type: "public-key", alg: -7 }, - { type: "public-key", alg: -8 }, - { type: "public-key", alg: -257 } - ], @options.as_json[:pubKeyCredParams] + { "type" => "public-key", "alg" => -7 }, + { "type" => "public-key", "alg" => -8 }, + { "type" => "public-key", "alg" => -257 } + ], json["pubKeyCredParams"] - assert_equal "required", @options.as_json[:authenticatorSelection][:residentKey] - assert_equal true, @options.as_json[:authenticatorSelection][:requireResidentKey] - assert_equal "preferred", @options.as_json[:authenticatorSelection][:userVerification] + assert_equal "required", json["authenticatorSelection"]["residentKey"] + assert_equal true, json["authenticatorSelection"]["requireResidentKey"] + assert_equal "preferred", json["authenticatorSelection"]["userVerification"] end test "as_json includes residentKey in authenticatorSelection" do @@ -60,12 +62,12 @@ class ActionPack::WebAuthn::PublicKeyCredential::CreationOptionsTest < ActiveSup relying_party: @relying_party ) - assert_equal "required", options.as_json[:authenticatorSelection][:residentKey] - assert_equal true, options.as_json[:authenticatorSelection][:requireResidentKey] + assert_equal "required", options.as_json["authenticatorSelection"]["residentKey"] + assert_equal true, options.as_json["authenticatorSelection"]["requireResidentKey"] end test "as_json excludes excludeCredentials when empty" do - assert_nil @options.as_json[:excludeCredentials] + assert_nil @options.as_json["excludeCredentials"] end test "as_json includes excludeCredentials" do @@ -83,13 +85,13 @@ class ActionPack::WebAuthn::PublicKeyCredential::CreationOptionsTest < ActiveSup ) assert_equal [ - { type: "public-key", id: "cred-1", transports: [ "usb", "nfc" ] }, - { type: "public-key", id: "cred-2", transports: [ "internal" ] } - ], options.as_json[:excludeCredentials] + { "type" => "public-key", "id" => "cred-1", "transports" => [ "usb", "nfc" ] }, + { "type" => "public-key", "id" => "cred-2", "transports" => [ "internal" ] } + ], options.as_json["excludeCredentials"] end test "as_json excludes attestation when none" do - assert_nil @options.as_json[:attestation] + assert_nil @options.as_json["attestation"] end test "as_json includes attestation when not none" do @@ -101,7 +103,7 @@ class ActionPack::WebAuthn::PublicKeyCredential::CreationOptionsTest < ActiveSup relying_party: @relying_party ) - assert_equal "direct", options.as_json[:attestation] + assert_equal "direct", options.as_json["attestation"] end test "raises with invalid attestation preference" do @@ -126,8 +128,8 @@ class ActionPack::WebAuthn::PublicKeyCredential::CreationOptionsTest < ActiveSup ) assert_equal [ - { type: "public-key", id: "cred-1" } - ], options.as_json[:excludeCredentials] + { "type" => "public-key", "id" => "cred-1" } + ], options.as_json["excludeCredentials"] end private diff --git a/test/lib/action_pack/web_authn/public_key_credential/request_options_test.rb b/test/lib/action_pack/web_authn/public_key_credential/request_options_test.rb index 0ef7981af..d9631d73e 100644 --- a/test/lib/action_pack/web_authn/public_key_credential/request_options_test.rb +++ b/test/lib/action_pack/web_authn/public_key_credential/request_options_test.rb @@ -31,13 +31,15 @@ class ActionPack::WebAuthn::PublicKeyCredential::RequestOptionsTest < ActiveSupp end test "as_json" do - assert_equal @options.challenge, @options.as_json[:challenge] - assert_equal "example.com", @options.as_json[:rpId] + json = @options.as_json + + assert_equal @options.challenge, json["challenge"] + assert_equal "example.com", json["rpId"] assert_equal [ - { type: "public-key", id: "credential-1" }, - { type: "public-key", id: "credential-2" } - ], @options.as_json[:allowCredentials] - assert_equal "preferred", @options.as_json[:userVerification] + { "type" => "public-key", "id" => "credential-1" }, + { "type" => "public-key", "id" => "credential-2" } + ], json["allowCredentials"] + assert_equal "preferred", json["userVerification"] end test "as_json includes transports when present" do @@ -52,9 +54,9 @@ class ActionPack::WebAuthn::PublicKeyCredential::RequestOptionsTest < ActiveSupp ) assert_equal [ - { type: "public-key", id: "cred-1", transports: [ "usb", "nfc" ] }, - { type: "public-key", id: "cred-2", transports: [ "internal" ] } - ], options.as_json[:allowCredentials] + { "type" => "public-key", "id" => "cred-1", "transports" => [ "usb", "nfc" ] }, + { "type" => "public-key", "id" => "cred-2", "transports" => [ "internal" ] } + ], options.as_json["allowCredentials"] end test "as_json omits transports when empty" do @@ -66,8 +68,8 @@ class ActionPack::WebAuthn::PublicKeyCredential::RequestOptionsTest < ActiveSupp ) assert_equal [ - { type: "public-key", id: "cred-1" } - ], options.as_json[:allowCredentials] + { "type" => "public-key", "id" => "cred-1" } + ], options.as_json["allowCredentials"] end private