webauthn-rails 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/generators/test_unit/webauthn_authentication/templates/test/controllers/passkeys_controller_test.rb +15 -23
- data/lib/generators/test_unit/webauthn_authentication/templates/test/controllers/second_factor_authentications_controller_test.rb +131 -0
- data/lib/generators/test_unit/webauthn_authentication/templates/test/controllers/second_factor_webauthn_credentials_controller_test.rb +103 -0
- data/lib/generators/test_unit/webauthn_authentication/templates/test/controllers/webauthn_sessions_controller_test.rb +8 -10
- data/lib/generators/test_unit/webauthn_authentication/webauthn_authentication_generator.rb +2 -0
- data/lib/generators/webauthn_authentication/templates/app/controllers/second_factor_authentications_controller.rb +3 -3
- data/lib/generators/webauthn_authentication/templates/app/controllers/second_factor_webauthn_credentials_controller.rb +2 -2
- data/lib/generators/webauthn_authentication/webauthn_authentication_generator.rb +6 -4
- data/lib/webauthn/rails/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20ded36acb2b7a3f4d67cdd4e860dc41e6f8490bb9143be6a0575117e1e7a84e
|
4
|
+
data.tar.gz: 8b2d46393c0d24e340b82f7f5d908e34fdd7cedb30501b8e8ba9663f217c23b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89c27f2bd69320aef0d3a36207788478ce85e7eea4b1f722950ec12749fa3fdcaa5a3eed1f322b77425d5d8b8e1d848cf912d84cd55c7872fa2142750626b345
|
7
|
+
data.tar.gz: d125c6229d26da7d19794479091ec59b706e10166a70a5e3f228a4d3571906a5b3d3a3db23c81cfb2c735e56c91c9bdf1ee01f249689761641d46aad1319f8ff
|
@@ -7,7 +7,7 @@ class PasskeysControllerTest < ActionDispatch::IntegrationTest
|
|
7
7
|
@client = WebAuthn::FakeClient.new(WebAuthn.configuration.allowed_origins.first)
|
8
8
|
end
|
9
9
|
|
10
|
-
test "
|
10
|
+
test "create_options" do
|
11
11
|
sign_in_as @user
|
12
12
|
post create_options_passkeys_url
|
13
13
|
|
@@ -20,14 +20,14 @@ class PasskeysControllerTest < ActionDispatch::IntegrationTest
|
|
20
20
|
assert_equal session[:current_registration][:challenge], body["challenge"]
|
21
21
|
end
|
22
22
|
|
23
|
-
test "
|
23
|
+
test "create_options unauthenticated" do
|
24
24
|
post create_options_passkeys_url
|
25
25
|
|
26
26
|
assert_response :redirect
|
27
27
|
assert_redirected_to new_session_url
|
28
28
|
end
|
29
29
|
|
30
|
-
test "
|
30
|
+
test "create" do
|
31
31
|
sign_in_as @user
|
32
32
|
|
33
33
|
post create_options_passkeys_url
|
@@ -52,7 +52,7 @@ class PasskeysControllerTest < ActionDispatch::IntegrationTest
|
|
52
52
|
assert_nil session[:current_registration]
|
53
53
|
end
|
54
54
|
|
55
|
-
test "
|
55
|
+
test "create with WebAuthn error" do
|
56
56
|
sign_in_as @user
|
57
57
|
|
58
58
|
post create_options_passkeys_url
|
@@ -77,34 +77,26 @@ class PasskeysControllerTest < ActionDispatch::IntegrationTest
|
|
77
77
|
assert_nil session[:current_registration]
|
78
78
|
end
|
79
79
|
|
80
|
-
test "
|
81
|
-
post passkeys_url
|
82
|
-
credential: {
|
83
|
-
nickname: "My Passkey",
|
84
|
-
public_key_credential: "{}"
|
85
|
-
}
|
86
|
-
}
|
80
|
+
test "create unauthenticated" do
|
81
|
+
post passkeys_url
|
87
82
|
|
88
83
|
assert_response :redirect
|
89
84
|
assert_redirected_to new_session_url
|
90
85
|
end
|
91
86
|
|
92
|
-
test "
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
authentication_factor: 0
|
101
|
-
)
|
102
|
-
end
|
87
|
+
test "destroy" do
|
88
|
+
credential = WebauthnCredential.passkey.create!(
|
89
|
+
nickname: "My Passkey",
|
90
|
+
user: @user,
|
91
|
+
external_id: "external-id",
|
92
|
+
public_key: "public-key",
|
93
|
+
sign_count: 0,
|
94
|
+
)
|
103
95
|
|
104
96
|
sign_in_as @user
|
105
97
|
|
106
98
|
assert_difference("WebauthnCredential.count", -1) do
|
107
|
-
delete passkey_url(
|
99
|
+
delete passkey_url(credential)
|
108
100
|
end
|
109
101
|
assert_redirected_to root_path
|
110
102
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "webauthn/fake_client"
|
3
|
+
|
4
|
+
class SecondFactorAuthenticationsControllerTest < ActionDispatch::IntegrationTest
|
5
|
+
setup do
|
6
|
+
@user = users(:one)
|
7
|
+
@client = WebAuthn::FakeClient.new(WebAuthn.configuration.allowed_origins.first)
|
8
|
+
|
9
|
+
creation_options = WebAuthn::Credential.options_for_create(
|
10
|
+
user: { id: @user.webauthn_id, name: @user.email_address },
|
11
|
+
authenticator_selection: { resident_key: "discouraged", user_verification: "discouraged" }
|
12
|
+
)
|
13
|
+
create_options = @client.create(challenge: creation_options.challenge)
|
14
|
+
credential = WebAuthn::Credential.from_create(create_options)
|
15
|
+
|
16
|
+
WebauthnCredential.second_factor.create!(
|
17
|
+
nickname: "My Security Key",
|
18
|
+
user: @user,
|
19
|
+
external_id: credential.id,
|
20
|
+
public_key: credential.public_key,
|
21
|
+
sign_count: 0
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
test "get_options" do
|
26
|
+
post session_path, params: { email_address: @user.email_address, password: "password" }
|
27
|
+
|
28
|
+
post get_options_second_factor_authentication_url
|
29
|
+
|
30
|
+
assert_response :success
|
31
|
+
body = JSON.parse(response.body)
|
32
|
+
assert body["challenge"].present?
|
33
|
+
assert body["userVerification"] == "discouraged"
|
34
|
+
|
35
|
+
assert_equal session[:current_authentication][:challenge], body["challenge"]
|
36
|
+
end
|
37
|
+
|
38
|
+
test "create" do
|
39
|
+
post session_path, params: { email_address: @user.email_address, password: "password" }
|
40
|
+
|
41
|
+
post get_options_second_factor_authentication_url
|
42
|
+
challenge = session[:current_authentication][:challenge]
|
43
|
+
|
44
|
+
public_key_credential = @client.get(challenge: challenge, user_verified: false)
|
45
|
+
|
46
|
+
post second_factor_authentication_url, params: {
|
47
|
+
session: {
|
48
|
+
public_key_credential: public_key_credential.to_json
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
assert_redirected_to root_path
|
53
|
+
assert_nil session[:current_authentication]
|
54
|
+
end
|
55
|
+
|
56
|
+
test "create with a passkey" do
|
57
|
+
client = WebAuthn::FakeClient.new(WebAuthn.configuration.allowed_origins.first)
|
58
|
+
|
59
|
+
creation_options = WebAuthn::Credential.options_for_create(
|
60
|
+
user: { id: @user.webauthn_id, name: @user.email_address },
|
61
|
+
authenticator_selection: { resident_key: "discouraged", user_verification: "discouraged" }
|
62
|
+
)
|
63
|
+
create_options = client.create(challenge: creation_options.challenge)
|
64
|
+
credential = WebAuthn::Credential.from_create(create_options)
|
65
|
+
|
66
|
+
|
67
|
+
WebauthnCredential.passkey.create!(
|
68
|
+
nickname: "My Security Key",
|
69
|
+
user: @user,
|
70
|
+
external_id: credential.id,
|
71
|
+
public_key: credential.public_key,
|
72
|
+
sign_count: 0
|
73
|
+
)
|
74
|
+
|
75
|
+
post session_path, params: { email_address: @user.email_address, password: "password" }
|
76
|
+
|
77
|
+
post get_options_second_factor_authentication_url
|
78
|
+
challenge = session[:current_authentication][:challenge]
|
79
|
+
|
80
|
+
public_key_credential = client.get(challenge: challenge, user_verified: false)
|
81
|
+
|
82
|
+
post second_factor_authentication_url, params: {
|
83
|
+
session: {
|
84
|
+
public_key_credential: public_key_credential.to_json
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
assert_redirected_to root_path
|
89
|
+
assert_nil session[:current_authentication]
|
90
|
+
end
|
91
|
+
|
92
|
+
test "create with WebAuthn error" do
|
93
|
+
post session_path, params: { email_address: @user.email_address, password: "password" }
|
94
|
+
|
95
|
+
post get_options_second_factor_authentication_url
|
96
|
+
|
97
|
+
public_key_credential = @client.get(
|
98
|
+
user_verified: false
|
99
|
+
)
|
100
|
+
|
101
|
+
post second_factor_authentication_url, params: {
|
102
|
+
session: {
|
103
|
+
public_key_credential: public_key_credential.to_json
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
assert_redirected_to new_second_factor_authentication_path
|
108
|
+
assert_match (/Verification failed/), flash[:alert]
|
109
|
+
assert_nil session[:current_authentication]
|
110
|
+
end
|
111
|
+
|
112
|
+
test "create with unrecognized credential" do
|
113
|
+
post session_path, params: { email_address: @user.email_address, password: "password" }
|
114
|
+
|
115
|
+
post get_options_second_factor_authentication_url
|
116
|
+
challenge = session[:current_authentication][:challenge]
|
117
|
+
|
118
|
+
public_key_credential = @client.get(challenge: challenge, user_verified: false)
|
119
|
+
public_key_credential["id"]= "invalid-id"
|
120
|
+
|
121
|
+
post second_factor_authentication_url, params: {
|
122
|
+
session: {
|
123
|
+
public_key_credential: public_key_credential.to_json
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
assert_redirected_to new_second_factor_authentication_path
|
128
|
+
assert_match (/Credential not recognized/), flash[:alert]
|
129
|
+
assert_nil session[:current_authentication]
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "webauthn/fake_client"
|
3
|
+
|
4
|
+
class SecondFactorWebauthnCredentialsControllerTest < ActionDispatch::IntegrationTest
|
5
|
+
setup do
|
6
|
+
@user = users(:one)
|
7
|
+
@client = WebAuthn::FakeClient.new(WebAuthn.configuration.allowed_origins.first)
|
8
|
+
end
|
9
|
+
|
10
|
+
test "create_options" do
|
11
|
+
sign_in_as @user
|
12
|
+
post create_options_second_factor_webauthn_credentials_url
|
13
|
+
|
14
|
+
assert_response :success
|
15
|
+
body = JSON.parse(response.body)
|
16
|
+
assert body["challenge"].present?
|
17
|
+
assert body["authenticatorSelection"]["residentKey"] == "discouraged"
|
18
|
+
assert body["authenticatorSelection"]["userVerification"] == "discouraged"
|
19
|
+
|
20
|
+
assert_equal session[:current_registration][:challenge], body["challenge"]
|
21
|
+
end
|
22
|
+
|
23
|
+
test "create_options unauthenticated" do
|
24
|
+
post create_options_second_factor_webauthn_credentials_url
|
25
|
+
|
26
|
+
assert_response :redirect
|
27
|
+
assert_redirected_to new_session_url
|
28
|
+
end
|
29
|
+
|
30
|
+
test "create" do
|
31
|
+
sign_in_as @user
|
32
|
+
|
33
|
+
post create_options_second_factor_webauthn_credentials_url
|
34
|
+
challenge = session[:current_registration][:challenge]
|
35
|
+
|
36
|
+
public_key_credential = @client.create(
|
37
|
+
challenge: challenge,
|
38
|
+
user_verified: false,
|
39
|
+
)
|
40
|
+
|
41
|
+
assert_difference("WebauthnCredential.second_factor.count", 1) do
|
42
|
+
post second_factor_webauthn_credentials_url, params: {
|
43
|
+
credential: {
|
44
|
+
nickname: "My Security Key",
|
45
|
+
public_key_credential: public_key_credential.to_json
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
assert_redirected_to root_path
|
51
|
+
assert_match (/Security Key registered successfully/), flash[:notice]
|
52
|
+
assert_nil session[:current_registration]
|
53
|
+
end
|
54
|
+
|
55
|
+
test "create with WebAuthn error" do
|
56
|
+
sign_in_as @user
|
57
|
+
|
58
|
+
post create_options_second_factor_webauthn_credentials_url
|
59
|
+
|
60
|
+
public_key_credential = @client.create(
|
61
|
+
user_verified: false,
|
62
|
+
)
|
63
|
+
|
64
|
+
assert_no_difference("WebauthnCredential.count") do
|
65
|
+
post second_factor_webauthn_credentials_url, params: {
|
66
|
+
credential: {
|
67
|
+
nickname: "My Security Key",
|
68
|
+
public_key_credential: public_key_credential.to_json
|
69
|
+
}
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
assert_redirected_to new_second_factor_webauthn_credential_path
|
74
|
+
assert_match (/Verification failed/), flash[:alert]
|
75
|
+
assert_nil session[:current_registration]
|
76
|
+
end
|
77
|
+
|
78
|
+
test "create unauthenticated" do
|
79
|
+
post second_factor_webauthn_credentials_url
|
80
|
+
|
81
|
+
assert_response :redirect
|
82
|
+
assert_redirected_to new_session_url
|
83
|
+
end
|
84
|
+
|
85
|
+
test "destroy" do
|
86
|
+
credential = WebauthnCredential.second_factor.create!(
|
87
|
+
user: @user,
|
88
|
+
nickname: "My Security Key",
|
89
|
+
external_id: "external_id",
|
90
|
+
public_key: "public_key",
|
91
|
+
sign_count: 0
|
92
|
+
)
|
93
|
+
|
94
|
+
sign_in_as @user
|
95
|
+
|
96
|
+
assert_difference("WebauthnCredential.second_factor.count", -1) do
|
97
|
+
delete second_factor_webauthn_credential_url(credential)
|
98
|
+
end
|
99
|
+
|
100
|
+
assert_redirected_to root_path
|
101
|
+
assert_match (/Security Key deleted successfully/), flash[:notice]
|
102
|
+
end
|
103
|
+
end
|
@@ -12,17 +12,16 @@ class WebauthnSessionsControllerTest < ActionDispatch::IntegrationTest
|
|
12
12
|
create_options = @client.create(challenge: creation_options.challenge)
|
13
13
|
credential = WebAuthn::Credential.from_create(create_options)
|
14
14
|
|
15
|
-
WebauthnCredential.create!(
|
15
|
+
WebauthnCredential.passkey.create!(
|
16
16
|
nickname: "My Passkey",
|
17
17
|
user: @user,
|
18
18
|
external_id: credential.id,
|
19
19
|
public_key: credential.public_key,
|
20
20
|
sign_count: 0,
|
21
|
-
authentication_factor: 0
|
22
21
|
)
|
23
22
|
end
|
24
23
|
|
25
|
-
test "
|
24
|
+
test "get_options" do
|
26
25
|
post get_options_webauthn_session_url
|
27
26
|
|
28
27
|
assert_response :success
|
@@ -33,7 +32,7 @@ class WebauthnSessionsControllerTest < ActionDispatch::IntegrationTest
|
|
33
32
|
assert_equal session[:current_authentication][:challenge], body["challenge"]
|
34
33
|
end
|
35
34
|
|
36
|
-
test "
|
35
|
+
test "create" do
|
37
36
|
post get_options_webauthn_session_url
|
38
37
|
challenge = session[:current_authentication][:challenge]
|
39
38
|
|
@@ -49,7 +48,7 @@ class WebauthnSessionsControllerTest < ActionDispatch::IntegrationTest
|
|
49
48
|
assert_nil session[:current_authentication]
|
50
49
|
end
|
51
50
|
|
52
|
-
test "
|
51
|
+
test "create with WebAuthn error" do
|
53
52
|
post get_options_webauthn_session_url
|
54
53
|
challenge = session[:current_authentication][:challenge]
|
55
54
|
|
@@ -66,7 +65,7 @@ class WebauthnSessionsControllerTest < ActionDispatch::IntegrationTest
|
|
66
65
|
assert_nil session[:current_authentication]
|
67
66
|
end
|
68
67
|
|
69
|
-
test "
|
68
|
+
test "create with unrecognized credential" do
|
70
69
|
post get_options_webauthn_session_url
|
71
70
|
challenge = session[:current_authentication][:challenge]
|
72
71
|
|
@@ -84,7 +83,7 @@ class WebauthnSessionsControllerTest < ActionDispatch::IntegrationTest
|
|
84
83
|
assert_nil session[:current_authentication]
|
85
84
|
end
|
86
85
|
|
87
|
-
test "
|
86
|
+
test "create with a second factor credential" do
|
88
87
|
client = WebAuthn::FakeClient.new(WebAuthn.configuration.allowed_origins.first)
|
89
88
|
|
90
89
|
creation_options = WebAuthn::Credential.options_for_create(
|
@@ -93,13 +92,12 @@ class WebauthnSessionsControllerTest < ActionDispatch::IntegrationTest
|
|
93
92
|
create_options = client.create(challenge: creation_options.challenge)
|
94
93
|
credential = WebAuthn::Credential.from_create(create_options)
|
95
94
|
|
96
|
-
WebauthnCredential.create!(
|
95
|
+
WebauthnCredential.second_factor.create!(
|
97
96
|
nickname: "Second Factor Key",
|
98
97
|
user: @user,
|
99
98
|
external_id: credential.id,
|
100
99
|
public_key: credential.public_key,
|
101
100
|
sign_count: 0,
|
102
|
-
authentication_factor: 1
|
103
101
|
)
|
104
102
|
|
105
103
|
post get_options_webauthn_session_url
|
@@ -118,7 +116,7 @@ class WebauthnSessionsControllerTest < ActionDispatch::IntegrationTest
|
|
118
116
|
assert_nil session[:current_authentication]
|
119
117
|
end
|
120
118
|
|
121
|
-
test "
|
119
|
+
test "destroy" do
|
122
120
|
delete webauthn_session_url
|
123
121
|
assert_redirected_to new_session_path
|
124
122
|
end
|
@@ -9,6 +9,8 @@ module TestUnit
|
|
9
9
|
def create_controller_test_files
|
10
10
|
template "test/controllers/passkeys_controller_test.rb"
|
11
11
|
template "test/controllers/webauthn_sessions_controller_test.rb"
|
12
|
+
template "test/controllers/second_factor_authentications_controller_test.rb"
|
13
|
+
template "test/controllers/second_factor_webauthn_credentials_controller_test.rb"
|
12
14
|
end
|
13
15
|
|
14
16
|
def create_system_test_files
|
@@ -35,9 +35,9 @@ class SecondFactorAuthenticationsController < ApplicationController
|
|
35
35
|
redirect_to after_authentication_url
|
36
36
|
rescue WebAuthn::Error => e
|
37
37
|
redirect_to new_second_factor_authentication_path, alert: "Verification failed: #{e.message}"
|
38
|
-
ensure
|
39
|
-
session.delete(:current_authentication)
|
40
38
|
end
|
39
|
+
ensure
|
40
|
+
session.delete(:current_authentication)
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
@@ -57,6 +57,6 @@ class SecondFactorAuthenticationsController < ApplicationController
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def current_authentication_user_id
|
60
|
-
session
|
60
|
+
session.dig(:current_authentication, :user_id) || session.dig(:current_authentication, "user_id")
|
61
61
|
end
|
62
62
|
end
|
@@ -40,9 +40,9 @@ class SecondFactorWebauthnCredentialsController < ApplicationController
|
|
40
40
|
end
|
41
41
|
rescue WebAuthn::Error => e
|
42
42
|
redirect_to new_second_factor_webauthn_credential_path, alert: "Verification failed: #{e.message}"
|
43
|
-
ensure
|
44
|
-
session.delete(:current_registration)
|
45
43
|
end
|
44
|
+
ensure
|
45
|
+
session.delete(:current_registration)
|
46
46
|
end
|
47
47
|
|
48
48
|
def destroy
|
@@ -8,7 +8,11 @@ end
|
|
8
8
|
|
9
9
|
class WebauthnAuthenticationGenerator < ::Rails::Generators::Base
|
10
10
|
include ActiveRecord::Generators::Migration
|
11
|
-
|
11
|
+
if Rails.version >= "8.1"
|
12
|
+
include Rails::Generators::BundleHelper
|
13
|
+
else
|
14
|
+
include BundleHelper
|
15
|
+
end
|
12
16
|
|
13
17
|
source_root File.expand_path("../templates", __FILE__)
|
14
18
|
|
@@ -54,9 +58,7 @@ class WebauthnAuthenticationGenerator < ::Rails::Generators::Base
|
|
54
58
|
<<-RUBY.strip_heredoc.indent(4)
|
55
59
|
|
56
60
|
def require_no_authentication
|
57
|
-
if
|
58
|
-
redirect_to root_path
|
59
|
-
end
|
61
|
+
redirect_to root_path if find_session_by_cookie
|
60
62
|
end
|
61
63
|
RUBY
|
62
64
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webauthn-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cedarcode
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -41,6 +41,8 @@ files:
|
|
41
41
|
- lib/generators/erb/webauthn_authentication/templates/app/views/second_factor_webauthn_credentials/new.html.erb.tt
|
42
42
|
- lib/generators/erb/webauthn_authentication/webauthn_authentication_generator.rb
|
43
43
|
- lib/generators/test_unit/webauthn_authentication/templates/test/controllers/passkeys_controller_test.rb
|
44
|
+
- lib/generators/test_unit/webauthn_authentication/templates/test/controllers/second_factor_authentications_controller_test.rb
|
45
|
+
- lib/generators/test_unit/webauthn_authentication/templates/test/controllers/second_factor_webauthn_credentials_controller_test.rb
|
44
46
|
- lib/generators/test_unit/webauthn_authentication/templates/test/controllers/webauthn_sessions_controller_test.rb
|
45
47
|
- lib/generators/test_unit/webauthn_authentication/templates/test/system/manage_webauthn_credentials_test.rb
|
46
48
|
- lib/generators/test_unit/webauthn_authentication/templates/test/test_helpers/virtual_authenticator_test_helper.rb
|