Class: Booth::Testing::Support::VirtualAuthenticators::Manager

Inherits:
Object
  • Object
show all
Includes:
Logging, Capybara::DSL
Defined in:
lib/booth/testing/support/virtual_authenticators/manager.rb

Overview

Capybara handles multiple separate Chrome sessions (like separate browsers). In Chrome each of those sessions is completely distinct and nows nothing about the others. To “simulate” having the same passkey in “two browsers”, we need to clone and sync it. This means transferring the secret key, and synchronizing the sign count. This class holds a state of all browser sessions to easier facilitate transfer and sync.

Instance Method Summary collapse

Instance Method Details

#clone_from_other_sessionObject

Takes a passkey from (the) other browser and injects it into this browser.



30
31
32
33
34
35
36
37
38
# File 'lib/booth/testing/support/virtual_authenticators/manager.rb', line 30

def clone_from_other_session
  new_device = ::Booth::Testing::Support::VirtualAuthenticators::Create.call(
    has_user_verification: true,
  )
  new_device.add_credential(other_credential)

  this_session[new_device.instance_variable_get(:@id)] = new_device
  nil
end

#create(has_user_verification: true) ⇒ Object

Creates a brand new passkey.



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/booth/testing/support/virtual_authenticators/manager.rb', line 17

def create(has_user_verification: true)
  ::Booth::Testing::Support::VirtualAuthenticators::Enable.call

  new_device = ::Booth::Testing::Support::VirtualAuthenticators::Create.call(
    has_user_verification:,
  )

  this_session[new_device.instance_variable_get(:@id)] = new_device

  nil
end

#refresh_from_other_sessionObject

Inspects a passkey in (the) other browser and syncs the passkey here if needed.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/booth/testing/support/virtual_authenticators/manager.rb', line 41

def refresh_from_other_session
  this_sign_count = this_credential.instance_variable_get(:@sign_count)
  other_sign_count = other_credential.instance_variable_get(:@sign_count)

  if this_sign_count == other_sign_count
    log { "Sign count of both Virtual Keys is #{this_sign_count}" }
    return
  end

  log { "Changing Virtual Key sign count from #{this_sign_count} to #{other_sign_count}" }

  new_credential = this_credential
  # This only affects the Credential here in our Ruby instance.
  new_credential.instance_variable_set(:@sign_count, other_sign_count)

  # So let us send our Ruby instance to the browser by replacing the key there.
  this_device.remove_all_credentials
  this_device.add_credential(new_credential)

  nil
end