use URI;
use JSON;
use strict;
require 't/test-lib.pm';
SKIP: {
eval "use Authen::WebAuthn::Test; use Authen::WebAuthn;";
if ($@) {
skip 'Authen::WebAuthn not found';
}
my $ecdsa_key = <<ENDKEY;
-----BEGIN EC PRIVATE KEY-----
MIIBUQIBAQQgWEGujn2kkOVckTIKhIJDSqH99bxydPGloXvbeaq9swiggeMwgeAC
AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////
MEQEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr
vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwRBBGsX0fLhLEJH+Lzm5WOkQPJ3A32BLesz
oPShOUXYmMKWT+NC4v4af5uO5+tKfA+eFivOM1drMV7Oy7ZAaDe/UfUCIQD/////
AAAAAP//////////vOb6racXnoTzucrC/GMlUQIBAaFEA0IABM/oQXEUzjPwEhM4
gWmIbCuOXc4Ja8jPDKxbQaZckal7/9a693/nkf7flk1S9AV2tjrtJPF6kg8TCGbF
KoeD9Wc=
-----END EC PRIVATE KEY-----
ENDKEY
my $credential_id_1 = "lZYltP9MtoRNuXK8f8tWf";
my $credential_id_2 = "d2ViYXV0aG5fdGVzdGVyXzI";
my $webauthn_tester = Authen::WebAuthn::Test->new(
rp_id => "auth.example.com",
credential_id => $credential_id_1,
aaguid => "00000000-0000-0000-0000-000000000000",
key => $ecdsa_key,
sign_count => 6,
);
my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
authentication => 'Choice',
restSessionServer => 1,
requireToken => 1,
userDB => 'Same',
'authChoiceModules' => {
'1_WebAuthn' => 'WebAuthn;Demo;Null;;;{}',
'2_Demo' => 'Demo;Demo;Null;;;{}'
},
}
}
);
ok(
$res = $client->_get(
'/', accept => 'text/html'
),
'Try to login'
);
expectPortalError( $res, 9, "Prompted to authenticate" );
my $info = {
'_2fDevices' => to_json( [ {
'_credentialId' => 'bFpZbHRQOU10b1JOdVhLOGY4dFdm',
'_credentialPublicKey' =>
'pQECAyYgASFYIM_oQXEUzjPwEhM4gWmIbCuOXc4Ja8jPDKxbQaZckal7Ilgg_9a693_nkf7flk1S9AV2tjrtJPF6kg8TCGbFKoeD9Wc',
'_signCount' => 5,
'epoch' => '1704384566',
'name' => 'MyFirstDevice',
'type' => 'WebAuthn'
},
]
),
'_webAuthnUserHandle' => "xxx",
'_session_id' => 'cb3c92b07fb624c9975186b57c627ae0',
'_session_kind' => 'Persistent',
'_session_uid' => 'dwho',
'_updateTime' => '20240102142212',
'_utime' => '1704201732'
};
$client->p->getPersistentSession( "dwho", $info );
expectXpath( $res,
'//script[@src="/static/common/js/webauthn-json.browser-global.min.js"]'
);
expectXpath( $res,
'//script[@src="/static/common/js/webauthncheck.min.js"]' );
my $js_vars = getJsVars($res);
my $request = $js_vars->{request};
my $challenge = $request->{challenge};
ok( $challenge, "Found challenge" );
is( $js_vars->{webauthn_autostart}, "0", "WebAuthn is set to auto start" );
my ( $host, $url, $query ) =
expectForm( $res, "#", undef, 'token', 'credential' );
my $credential = $webauthn_tester->get_assertion_response( {
request => $request,
},
{ response => { userHandle => "xxx" } }
);
$credential = $webauthn_tester->encode_credential($credential);
my $urlencoded_credential = buildForm( {
credential => $credential
}
);
$query =~ s/credential=/$urlencoded_credential/;
$query =~ s/lmAuth=\w*/lmAuth=1_WebAuthn/;
ok(
$res = $client->_post(
"/",
IO::String->new($query),
length => length($query),
),
'Auth query'
);
my $id = expectCookie($res);
expectSessionAttributes( $client, $id, uid => "dwho", _auth => "WebAuthn" );
}
done_testing();