Module: Unmagic::Passkeys::Test::Helpers
- Defined in:
- lib/unmagic/passkeys/test/helpers.rb
Overview
Mints valid WebAuthn ceremony payloads from a fixed EC P-256 key pair, so passkey registration and authentication can be exercised end to end without a browser. Ported from fizzy's test helper.
In a Rails app, requiring this file auto-includes it into integration tests. Elsewhere (e.g. RSpec) include it yourself:
require "unmagic/passkeys/test/helpers"
RSpec.configure { |c| c.include Unmagic::Passkeys::Test::Helpers }
The relying party defaults to "www.example.com" / "http://www.example.com"
(the Rails integration-test host, so the engine's request context lines up
automatically). Override webauthn_rp_id / webauthn_origin in your test
class to test under a different host.
Constant Summary collapse
- WEBAUTHN_PRIVATE_KEY =
OpenSSL::PKey::EC.new( [ "307702010104201dd589de7210b3318620f32150e3012cce021519df1d6e9e01" \ "0471146d395cdca00a06082a8648ce3d030107a14403420004116847fe19e1ad" \ "4471ab9980d7ff9cc1e4c7cb7a3af00e082b64fcd84f5ae70114c2495eef16f" \ "542b5e57dd1b263661624e3cf28f581b57a441edbd756a41d0e" ].pack("H*") )
- COSE_PUBLIC_KEY =
Pre-encoded COSE EC2/ES256 public key (CBOR) for the key above.
[ "a5010203262001215820116847fe19e1ad4471ab9980d7ff9cc1" \ "e4c7cb7a3af00e082b64fcd84f5ae70122582014c2495eef16f542b5e57dd1b2" \ "63661624e3cf28f581b57a441edbd756a41d0e" ].pack("H*")
- ATTESTATION_OBJECT_CBOR_PREFIX =
CBOR prefix for "none", "attStmt": {, "authData": bytes(164)}.
[ "a363666d74646e6f6e656761747453746d74a068617574684461746158a4" ].pack("H*")
- RP_ID =
"www.example.com"- ORIGIN =
"http://www.example.com"
Instance Method Summary collapse
- #build_assertion_params(challenge:, credential:, sign_count: 1) ⇒ Object
- #build_attestation_params(challenge:) ⇒ Object
-
#register_passkey_for(holder) ⇒ Object
Registers a passkey for
holderdirectly (used to set up the "already enrolled" state). - #webauthn_challenge(purpose: nil) ⇒ Object
- #webauthn_origin ⇒ Object
-
#webauthn_rp_id ⇒ Object
The relying party identity used to mint payloads.
- #with_webauthn_request_context ⇒ Object (also: #in_webauthn_context)
Instance Method Details
#build_assertion_params(challenge:, credential:, sign_count: 1) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/unmagic/passkeys/test/helpers.rb', line 83 def build_assertion_params(challenge:, credential:, sign_count: 1) client_data_json = webauthn_client_data_json(challenge: challenge, type: "webauthn.get") authenticator_data = build_assertion_auth_data(sign_count: sign_count) signature = webauthn_sign(authenticator_data, client_data_json) { id: credential.credential_id, client_data_json: client_data_json, authenticator_data: Base64.urlsafe_encode64(authenticator_data, padding: false), signature: Base64.urlsafe_encode64(signature, padding: false) } end |
#build_attestation_params(challenge:) ⇒ Object
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/unmagic/passkeys/test/helpers.rb', line 72 def build_attestation_params(challenge:) credential_id = SecureRandom.random_bytes(32) auth_data = build_attestation_auth_data(credential_id: credential_id) { client_data_json: webauthn_client_data_json(challenge: challenge, type: "webauthn.create"), attestation_object: Base64.urlsafe_encode64(ATTESTATION_OBJECT_CBOR_PREFIX + auth_data, padding: false), transports: [ "internal" ] } end |
#register_passkey_for(holder) ⇒ Object
Registers a passkey for holder directly (used to set up the
"already enrolled" state). Returns the persisted credential.
53 54 55 56 57 |
# File 'lib/unmagic/passkeys/test/helpers.rb', line 53 def register_passkey_for(holder) with_webauthn_request_context do holder.passkeys.register(build_attestation_params(challenge: webauthn_challenge(purpose: "registration"))) end end |
#webauthn_challenge(purpose: nil) ⇒ Object
68 69 70 |
# File 'lib/unmagic/passkeys/test/helpers.rb', line 68 def webauthn_challenge(purpose: nil) Unmagic::Passkeys::WebAuthn::PublicKeyCredential::Options.new(challenge_purpose: purpose).challenge end |
#webauthn_origin ⇒ Object
49 |
# File 'lib/unmagic/passkeys/test/helpers.rb', line 49 def webauthn_origin = ORIGIN |
#webauthn_rp_id ⇒ Object
The relying party identity used to mint payloads. Override in a test class to exercise a different host.
48 |
# File 'lib/unmagic/passkeys/test/helpers.rb', line 48 def webauthn_rp_id = RP_ID |
#with_webauthn_request_context ⇒ Object Also known as: in_webauthn_context
59 60 61 62 63 64 65 |
# File 'lib/unmagic/passkeys/test/helpers.rb', line 59 def with_webauthn_request_context Unmagic::Passkeys::WebAuthn::Current.host = webauthn_rp_id Unmagic::Passkeys::WebAuthn::Current.origin = webauthn_origin yield ensure Unmagic::Passkeys::WebAuthn::Current.reset end |