-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsecond_factor_webauthn_credentials_controller_spec.rb
More file actions
160 lines (132 loc) · 5.04 KB
/
second_factor_webauthn_credentials_controller_spec.rb
File metadata and controls
160 lines (132 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# frozen_string_literal: true
require "spec_helper"
require "webauthn/fake_client"
RSpec.describe Devise::SecondFactorWebauthnCredentialsController, type: :request do
let(:user) { Account.create!(email: "test@example.com", password: "password123") }
let(:client) { WebAuthn::FakeClient.new(WebAuthn.configuration.allowed_origins.first) }
describe "GET #new" do
context "when user is not authenticated" do
it "redirects to the sign-in page" do
get new_account_second_factor_webauthn_credential_path
expect(response).to redirect_to(new_account_session_path)
end
end
context "when user is authenticated" do
before do
sign_in user
end
it "renders the new template" do
get new_account_second_factor_webauthn_credential_path
expect(response).to have_http_status(:ok)
end
end
end
describe "POST #create" do
context "when user is not authenticated" do
it "redirects to the sign-in page" do
post account_second_factor_webauthn_credentials_path
expect(response).to redirect_to(new_account_session_path)
end
end
context "when user is authenticated" do
before do
sign_in user
get account_security_key_registration_options_path # To set the challenge in session
end
context "with valid parameters" do
let(:credential) do
client.create(
challenge: session[:webauthn_challenge],
user_verified: false
)
end
it "creates a new security key and redirects" do
assert_difference("user.second_factor_webauthn_credentials.count", 1) do
post account_second_factor_webauthn_credentials_path, params: {
public_key_credential: credential.to_json,
name: "My Security Key"
}
end
expect(response).to redirect_to(new_account_second_factor_webauthn_credential_path)
expect(flash[:notice]).to eq "Security Key created successfully."
expect(session[:webauthn_challenge]).to be_nil
end
end
context "with invalid credential" do
let(:invalid_credential) do
client.create(
challenge: session[:webauthn_challenge],
user_present: false
)
end
it "does not create a new security key and redirects" do
assert_difference("user.second_factor_webauthn_credentials.count", 0) do
post account_second_factor_webauthn_credentials_path, params: {
public_key_credential: invalid_credential.to_json,
name: "My Security Key"
}
end
expect(response).to redirect_to(new_account_second_factor_webauthn_credential_path)
expect(flash[:alert]).to eq "Webauthn credential verification failed."
expect(session[:webauthn_challenge]).to be_nil
end
end
end
end
describe "PATCH #update" do
let!(:security_key) do
user.second_factor_webauthn_credentials.create!(
external_id: "external-id",
name: "My Security Key",
public_key: "public-key",
sign_count: 0,
authentication_factor: "second_factor"
)
end
context "when user is not authenticated" do
it "redirects to the sign-in page" do
patch account_second_factor_webauthn_credential_path(security_key)
expect(response).to redirect_to(new_account_session_path)
end
end
context "when user is authenticated" do
before do
sign_in user, scope: :account
end
it "promotes the security key, sets a notice and redirects" do
patch account_second_factor_webauthn_credential_path(security_key)
expect(response).to redirect_to(new_account_second_factor_webauthn_credential_path)
expect(flash[:notice]).to eq I18n.t("devise.second_factor_webauthn_credentials.security_key_promoted")
expect(security_key.reload.authentication_factor).to eq("first_factor")
end
end
end
describe "DELETE #destroy" do
context "when user is not authenticated" do
it "redirects to the sign-in page" do
delete account_second_factor_webauthn_credential_path(1)
expect(response).to redirect_to(new_account_session_path)
end
end
context "when user is authenticated" do
let!(:security_key) do
user.second_factor_webauthn_credentials.create!(
external_id: "external-id",
name: "My Passkey",
public_key: "public-key",
sign_count: 0
)
end
before do
sign_in user, scope: :account
end
it "deletes the security key and redirects" do
assert_difference("user.second_factor_webauthn_credentials.count", -1) do
delete account_second_factor_webauthn_credential_path(security_key)
expect(flash[:notice]).to eq I18n.t("devise.second_factor_webauthn_credentials.security_key_deleted")
expect(response).to redirect_to(new_account_second_factor_webauthn_credential_path)
end
end
end
end
end