Firefox-Marionette
view release on metacpan or search on metacpan
extension, any test of user presence
<https://www.w3.org/TR/webauthn-2/#test-of-user-presence> performed
on the Virtual Authenticator
<https://www.w3.org/TR/webauthn-2/#virtual-authenticators>. If set to
true, a user consent will always be granted. If set to false, it will
not be granted.
* is_user_verified - boolean value to determine the result of User
Verification <https://www.w3.org/TR/webauthn-2/#user-verification>
performed on the Virtual Authenticator
<https://www.w3.org/TR/webauthn-2/#virtual-authenticators>. If set to
true, User Verification will always succeed. If set to false, it will
fail.
* protocol - the protocol spoken by the authenticator. This may be
CTAP1_U2F, CTAP2 or CTAP2_1.
* transport - the transport simulated by the authenticator. This may
be BLE, HYBRID, INTERNAL, NFC, SMART_CARD or USB.
It returns the newly created authenticator.
use Firefox::Marionette();
use Crypt::URandom();
my $user_name = MIME::Base64::encode_base64( Crypt::URandom::urandom( 10 ), q[] ) . q[@example.com];
my $firefox = Firefox::Marionette->new( webauthn => 0 );
my $authenticator = $firefox->add_webauthn_authenticator( transport => Firefox::Marionette::WebAuthn::Authenticator::INTERNAL(), protocol => Firefox::Marionette::WebAuthn::Authenticator::CTAP2() );
$firefox->go('https://webauthn.io');
$firefox->find_id('input-email')->type($user_name);
$firefox->find_id('register-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('alert-success'); });
$firefox->find_id('login-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('hero confetti'); });
add_webauthn_credential
accepts a hash of the following keys;
* authenticator - contains the authenticator that the credential will
be added to. If this parameter is not supplied, the credential will
be added to the default authenticator, if one exists.
* host - contains the domain that this credential is to be used for.
In the language of WebAuthn <https://www.w3.org/TR/webauthn-2>, this
field is referred to as the relying party identifier
<https://www.w3.org/TR/webauthn-2/#relying-party-identifier> or RP ID
<https://www.w3.org/TR/webauthn-2/#rp-id>.
* id - contains the unique id for this credential, also known as the
Credential ID <https://www.w3.org/TR/webauthn-2/#credential-id>. If
this is not supplied, one will be generated.
* is_resident - contains a boolean that if set to true, a client-side
discoverable credential
<https://w3c.github.io/webauthn/#client-side-discoverable-credential>
is created. If set to false, a server-side credential
<https://w3c.github.io/webauthn/#server-side-credential> is created
instead.
* private_key - either a RFC5958
<https://www.rfc-editor.org/rfc/rfc5958> encoded private key encoded
using encode_base64url or a hash containing the following keys;
* name - contains the name of the private key algorithm, such as
"RSA-PSS" (the default), "RSASSA-PKCS1-v1_5", "ECDSA" or "ECDH".
* size - contains the modulus length of the private key. This is
only valid for "RSA-PSS" or "RSASSA-PKCS1-v1_5" private keys.
* hash - contains the name of the hash algorithm, such as "SHA-512"
(the default). This is only valid for "RSA-PSS" or
"RSASSA-PKCS1-v1_5" private keys.
* curve - contains the name of the curve for the private key, such
as "P-384" (the default). This is only valid for "ECDSA" or "ECDH"
private keys.
* sign_count - contains the initial value for a signature counter
<https://w3c.github.io/webauthn/#signature-counter> associated to the
public key credential source
<https://w3c.github.io/webauthn/#public-key-credential-source>. It
will default to 0 (zero).
* user - contains the userHandle
<https://w3c.github.io/webauthn/#public-key-credential-source-userhandle>
associated to the credential encoded using encode_base64url. This
property is optional.
It returns the newly created credential. If of course, the credential
is just created, it probably won't be much good by itself. However, you
can use it to recreate a credential, so long as you know all the
parameters.
use Firefox::Marionette();
use Crypt::URandom();
my $user_name = MIME::Base64::encode_base64( Crypt::URandom::urandom( 10 ), q[] ) . q[@example.com];
my $firefox = Firefox::Marionette->new();
$firefox->go('https://webauthn.io');
$firefox->find_id('input-email')->type($user_name);
$firefox->find_id('register-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('alert-success'); });
$firefox->find_id('login-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('hero confetti'); });
foreach my $credential ($firefox->webauthn_credentials()) {
$firefox->delete_webauthn_credential($credential);
# ... time passes ...
$firefox->add_webauthn_credential(
id => $credential->id(),
host => $credential->host(),
user => $credential->user(),
private_key => $credential->private_key(),
is_resident => $credential->is_resident(),
sign_count => $credential->sign_count(),
);
}
$firefox->go('about:blank');
$firefox->clear_cache(Firefox::Marionette::Cache::CLEAR_COOKIES());
$firefox->go('https://webauthn.io');
$firefox->find_id('input-email')->type($user_name);
$firefox->find_id('login-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('hero confetti'); });
addons
returns if pre-existing addons (extensions/themes) are allowed to run.
This will be true for Firefox versions less than 55, as -safe-mode
<http://kb.mozillazine.org/Command_line_arguments#List_of_command_line_arguments_.28incomplete.29>
cannot be automated.
agent
accepts an optional value for the User-Agent
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent>
header and sets this using the profile preferences and inserting
javascript into the current page. It returns the current value, such as
'Mozilla/5.0 (<system-information>) <platform> (<platform-details>)
<extensions>'. This value is retrieved with navigator.userAgent
<https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent>.
This method can be used to set a user agent string like so;
use Firefox::Marionette();
use strict;
# useragents.me should only be queried once a month or less.
# these UA strings should be cached locally.
my %user_agent_strings = map { $_->{ua} => $_->{pct} } @{$firefox->json("https://www.useragents.me/api")->{data}};
my ($user_agent) = reverse sort { $user_agent_strings{$a} <=> $user_agent_strings{$b} } keys %user_agent_strings;
my $firefox = Firefox::Marionette->new();
$firefox->agent($user_agent); # agent is now the most popular agent from useragents.me
If the user agent string that is passed as a parameter looks like a
Chrome <https://www.google.com/chrome/>, Edge
<https://microsoft.com/edge> or Safari <https://www.apple.com/safari/>
user agent string, then this method will also try and change other
profile preferences to match the new agent string. These parameters
are;
* general.appversion.override
* general.oscpu.override
* general.platform.override
* network.http.accept
* network.http.accept-encoding
* network.http.accept-encoding.secure
( run in 2.667 seconds using v1.01-cache-2.11-cpan-0bb4e1dffa6 )