devise-otp 0.6.0 → 0.8.0
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/.github/workflows/ci.yml +7 -10
- data/.gitignore +3 -1
- data/CHANGELOG.md +54 -8
- data/Gemfile +10 -0
- data/README.md +8 -2
- data/app/controllers/devise_otp/devise/otp_credentials_controller.rb +46 -27
- data/app/controllers/devise_otp/devise/otp_tokens_controller.rb +28 -10
- data/app/views/devise/otp_credentials/show.html.erb +6 -6
- data/app/views/devise/otp_tokens/_token_secret.html.erb +3 -4
- data/app/views/devise/otp_tokens/edit.html.erb +26 -0
- data/app/views/devise/otp_tokens/show.html.erb +7 -14
- data/config/locales/en.yml +23 -14
- data/devise-otp.gemspec +3 -13
- data/docs/QR_CODES.md +1 -40
- data/lib/devise/strategies/database_authenticatable.rb +64 -0
- data/lib/devise-otp/version.rb +1 -1
- data/lib/devise-otp.rb +31 -11
- data/lib/devise_otp_authenticatable/controllers/helpers.rb +9 -10
- data/lib/devise_otp_authenticatable/controllers/public_helpers.rb +39 -0
- data/lib/devise_otp_authenticatable/controllers/url_helpers.rb +10 -0
- data/lib/devise_otp_authenticatable/engine.rb +2 -5
- data/lib/devise_otp_authenticatable/hooks/refreshable.rb +5 -0
- data/lib/devise_otp_authenticatable/models/otp_authenticatable.rb +22 -20
- data/lib/devise_otp_authenticatable/routes.rb +3 -1
- data/lib/generators/active_record/templates/migration.rb +1 -1
- data/test/dummy/app/controllers/admin_posts_controller.rb +85 -0
- data/test/dummy/app/controllers/application_controller.rb +0 -1
- data/test/dummy/app/controllers/base_controller.rb +6 -0
- data/test/dummy/app/models/admin.rb +25 -0
- data/test/dummy/app/views/admin_posts/_form.html.erb +25 -0
- data/test/dummy/app/views/admin_posts/edit.html.erb +6 -0
- data/test/dummy/app/views/admin_posts/index.html.erb +25 -0
- data/test/dummy/app/views/admin_posts/new.html.erb +5 -0
- data/test/dummy/app/views/admin_posts/show.html.erb +15 -0
- data/test/dummy/app/views/base/home.html.erb +1 -0
- data/test/dummy/config/application.rb +0 -2
- data/test/dummy/config/routes.rb +4 -1
- data/test/dummy/db/migrate/20240604000001_create_admins.rb +9 -0
- data/test/dummy/db/migrate/20240604000002_add_devise_to_admins.rb +52 -0
- data/test/dummy/db/migrate/20240604000003_devise_otp_add_to_admins.rb +28 -0
- data/test/integration/disable_token_test.rb +53 -0
- data/test/integration/enable_otp_form_test.rb +57 -0
- data/test/integration/persistence_test.rb +3 -6
- data/test/integration/refresh_test.rb +32 -0
- data/test/integration/reset_token_test.rb +45 -0
- data/test/integration/sign_in_test.rb +10 -14
- data/test/integration/trackable_test.rb +50 -0
- data/test/integration_tests_helper.rb +24 -6
- data/test/models/otp_authenticatable_test.rb +62 -27
- data/test/orm/active_record.rb +6 -1
- data/test/test_helper.rb +1 -71
- metadata +26 -135
- data/lib/devise_otp_authenticatable/hooks/sessions.rb +0 -58
- data/lib/devise_otp_authenticatable/hooks.rb +0 -11
- data/test/integration/token_test.rb +0 -30
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise-otp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lele Forzani
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-09-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -17,20 +17,20 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '7.0'
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: '
|
23
|
+
version: '8.0'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
28
|
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version: '
|
30
|
+
version: '7.0'
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '8.0'
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: devise
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -65,132 +65,6 @@ dependencies:
|
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: 2.0.0
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
name: capybara
|
70
|
-
requirement: !ruby/object:Gem::Requirement
|
71
|
-
requirements:
|
72
|
-
- - ">="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '0'
|
75
|
-
type: :development
|
76
|
-
prerelease: false
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - ">="
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: '0'
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: cuprite
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - ">="
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '0'
|
89
|
-
type: :development
|
90
|
-
prerelease: false
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - ">="
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '0'
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: minitest-reporters
|
98
|
-
requirement: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - ">="
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: 0.5.0
|
103
|
-
type: :development
|
104
|
-
prerelease: false
|
105
|
-
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
requirements:
|
107
|
-
- - ">="
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: 0.5.0
|
110
|
-
- !ruby/object:Gem::Dependency
|
111
|
-
name: puma
|
112
|
-
requirement: !ruby/object:Gem::Requirement
|
113
|
-
requirements:
|
114
|
-
- - ">="
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: '0'
|
117
|
-
type: :development
|
118
|
-
prerelease: false
|
119
|
-
version_requirements: !ruby/object:Gem::Requirement
|
120
|
-
requirements:
|
121
|
-
- - ">="
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
version: '0'
|
124
|
-
- !ruby/object:Gem::Dependency
|
125
|
-
name: rdoc
|
126
|
-
requirement: !ruby/object:Gem::Requirement
|
127
|
-
requirements:
|
128
|
-
- - ">="
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: '0'
|
131
|
-
type: :development
|
132
|
-
prerelease: false
|
133
|
-
version_requirements: !ruby/object:Gem::Requirement
|
134
|
-
requirements:
|
135
|
-
- - ">="
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: '0'
|
138
|
-
- !ruby/object:Gem::Dependency
|
139
|
-
name: shoulda
|
140
|
-
requirement: !ruby/object:Gem::Requirement
|
141
|
-
requirements:
|
142
|
-
- - ">="
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
version: '0'
|
145
|
-
type: :development
|
146
|
-
prerelease: false
|
147
|
-
version_requirements: !ruby/object:Gem::Requirement
|
148
|
-
requirements:
|
149
|
-
- - ">="
|
150
|
-
- !ruby/object:Gem::Version
|
151
|
-
version: '0'
|
152
|
-
- !ruby/object:Gem::Dependency
|
153
|
-
name: sprockets-rails
|
154
|
-
requirement: !ruby/object:Gem::Requirement
|
155
|
-
requirements:
|
156
|
-
- - ">="
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
version: '0'
|
159
|
-
type: :development
|
160
|
-
prerelease: false
|
161
|
-
version_requirements: !ruby/object:Gem::Requirement
|
162
|
-
requirements:
|
163
|
-
- - ">="
|
164
|
-
- !ruby/object:Gem::Version
|
165
|
-
version: '0'
|
166
|
-
- !ruby/object:Gem::Dependency
|
167
|
-
name: sqlite3
|
168
|
-
requirement: !ruby/object:Gem::Requirement
|
169
|
-
requirements:
|
170
|
-
- - ">="
|
171
|
-
- !ruby/object:Gem::Version
|
172
|
-
version: '0'
|
173
|
-
type: :development
|
174
|
-
prerelease: false
|
175
|
-
version_requirements: !ruby/object:Gem::Requirement
|
176
|
-
requirements:
|
177
|
-
- - ">="
|
178
|
-
- !ruby/object:Gem::Version
|
179
|
-
version: '0'
|
180
|
-
- !ruby/object:Gem::Dependency
|
181
|
-
name: standardrb
|
182
|
-
requirement: !ruby/object:Gem::Requirement
|
183
|
-
requirements:
|
184
|
-
- - ">="
|
185
|
-
- !ruby/object:Gem::Version
|
186
|
-
version: '0'
|
187
|
-
type: :development
|
188
|
-
prerelease: false
|
189
|
-
version_requirements: !ruby/object:Gem::Requirement
|
190
|
-
requirements:
|
191
|
-
- - ">="
|
192
|
-
- !ruby/object:Gem::Version
|
193
|
-
version: '0'
|
194
68
|
description: Time Based OTP/rfc6238 compatible authentication for Devise
|
195
69
|
email:
|
196
70
|
- lele@windmill.it
|
@@ -214,6 +88,7 @@ files:
|
|
214
88
|
- app/views/devise/otp_credentials/show.html.erb
|
215
89
|
- app/views/devise/otp_tokens/_token_secret.html.erb
|
216
90
|
- app/views/devise/otp_tokens/_trusted_devices.html.erb
|
91
|
+
- app/views/devise/otp_tokens/edit.html.erb
|
217
92
|
- app/views/devise/otp_tokens/recovery.html.erb
|
218
93
|
- app/views/devise/otp_tokens/recovery_codes.text.erb
|
219
94
|
- app/views/devise/otp_tokens/show.html.erb
|
@@ -222,11 +97,12 @@ files:
|
|
222
97
|
- docs/QR_CODES.md
|
223
98
|
- lib/devise-otp.rb
|
224
99
|
- lib/devise-otp/version.rb
|
100
|
+
- lib/devise/strategies/database_authenticatable.rb
|
225
101
|
- lib/devise_otp_authenticatable/controllers/helpers.rb
|
102
|
+
- lib/devise_otp_authenticatable/controllers/public_helpers.rb
|
226
103
|
- lib/devise_otp_authenticatable/controllers/url_helpers.rb
|
227
104
|
- lib/devise_otp_authenticatable/engine.rb
|
228
|
-
- lib/devise_otp_authenticatable/hooks.rb
|
229
|
-
- lib/devise_otp_authenticatable/hooks/sessions.rb
|
105
|
+
- lib/devise_otp_authenticatable/hooks/refreshable.rb
|
230
106
|
- lib/devise_otp_authenticatable/models/otp_authenticatable.rb
|
231
107
|
- lib/devise_otp_authenticatable/routes.rb
|
232
108
|
- lib/generators/active_record/devise_otp_generator.rb
|
@@ -239,13 +115,22 @@ files:
|
|
239
115
|
- test/dummy/app/assets/config/manifest.js
|
240
116
|
- test/dummy/app/assets/javascripts/application.js
|
241
117
|
- test/dummy/app/assets/stylesheets/application.css
|
118
|
+
- test/dummy/app/controllers/admin_posts_controller.rb
|
242
119
|
- test/dummy/app/controllers/application_controller.rb
|
120
|
+
- test/dummy/app/controllers/base_controller.rb
|
243
121
|
- test/dummy/app/controllers/posts_controller.rb
|
244
122
|
- test/dummy/app/helpers/application_helper.rb
|
245
123
|
- test/dummy/app/helpers/posts_helper.rb
|
246
124
|
- test/dummy/app/mailers/.gitkeep
|
125
|
+
- test/dummy/app/models/admin.rb
|
247
126
|
- test/dummy/app/models/post.rb
|
248
127
|
- test/dummy/app/models/user.rb
|
128
|
+
- test/dummy/app/views/admin_posts/_form.html.erb
|
129
|
+
- test/dummy/app/views/admin_posts/edit.html.erb
|
130
|
+
- test/dummy/app/views/admin_posts/index.html.erb
|
131
|
+
- test/dummy/app/views/admin_posts/new.html.erb
|
132
|
+
- test/dummy/app/views/admin_posts/show.html.erb
|
133
|
+
- test/dummy/app/views/base/home.html.erb
|
249
134
|
- test/dummy/app/views/layouts/application.html.erb
|
250
135
|
- test/dummy/app/views/posts/_form.html.erb
|
251
136
|
- test/dummy/app/views/posts/edit.html.erb
|
@@ -273,16 +158,22 @@ files:
|
|
273
158
|
- test/dummy/db/migrate/20130131092406_add_devise_to_users.rb
|
274
159
|
- test/dummy/db/migrate/20130131142320_create_posts.rb
|
275
160
|
- test/dummy/db/migrate/20130131160351_devise_otp_add_to_users.rb
|
161
|
+
- test/dummy/db/migrate/20240604000001_create_admins.rb
|
162
|
+
- test/dummy/db/migrate/20240604000002_add_devise_to_admins.rb
|
163
|
+
- test/dummy/db/migrate/20240604000003_devise_otp_add_to_admins.rb
|
276
164
|
- test/dummy/lib/assets/.gitkeep
|
277
165
|
- test/dummy/public/404.html
|
278
166
|
- test/dummy/public/422.html
|
279
167
|
- test/dummy/public/500.html
|
280
168
|
- test/dummy/public/favicon.ico
|
281
169
|
- test/dummy/script/rails
|
170
|
+
- test/integration/disable_token_test.rb
|
171
|
+
- test/integration/enable_otp_form_test.rb
|
282
172
|
- test/integration/persistence_test.rb
|
283
173
|
- test/integration/refresh_test.rb
|
174
|
+
- test/integration/reset_token_test.rb
|
284
175
|
- test/integration/sign_in_test.rb
|
285
|
-
- test/integration/
|
176
|
+
- test/integration/trackable_test.rb
|
286
177
|
- test/integration_tests_helper.rb
|
287
178
|
- test/model_tests_helper.rb
|
288
179
|
- test/models/otp_authenticatable_test.rb
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module DeviseOtpAuthenticatable::Hooks
|
2
|
-
module Sessions
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
include DeviseOtpAuthenticatable::Controllers::UrlHelpers
|
5
|
-
|
6
|
-
included do
|
7
|
-
alias_method :create, :create_with_otp
|
8
|
-
end
|
9
|
-
|
10
|
-
#
|
11
|
-
# replaces Devise::SessionsController#create
|
12
|
-
#
|
13
|
-
def create_with_otp
|
14
|
-
resource = warden.authenticate!(auth_options)
|
15
|
-
|
16
|
-
devise_stored_location = stored_location_for(resource) # Grab the current stored location before it gets lost by warden.logout
|
17
|
-
store_location_for(resource, devise_stored_location) # Restore it since #stored_location_for removes it
|
18
|
-
|
19
|
-
otp_refresh_credentials_for(resource)
|
20
|
-
|
21
|
-
yield resource if block_given?
|
22
|
-
if otp_challenge_required_on?(resource)
|
23
|
-
challenge = resource.generate_otp_challenge!
|
24
|
-
warden.logout
|
25
|
-
store_location_for(resource, devise_stored_location) # restore the stored location
|
26
|
-
respond_with resource, location: otp_credential_path_for(resource, {challenge: challenge})
|
27
|
-
elsif otp_mandatory_on?(resource) # if mandatory, log in user but send him to the must activate otp
|
28
|
-
set_flash_message(:notice, :signed_in_but_otp) if is_navigational_format?
|
29
|
-
sign_in(resource_name, resource)
|
30
|
-
respond_with resource, location: otp_token_path_for(resource)
|
31
|
-
else
|
32
|
-
sign_in(resource_name, resource)
|
33
|
-
respond_with resource, location: after_sign_in_path_for(resource)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
#
|
40
|
-
# resource should be challenged for otp
|
41
|
-
#
|
42
|
-
def otp_challenge_required_on?(resource)
|
43
|
-
return false unless resource.respond_to?(:otp_enabled) && resource.respond_to?(:otp_auth_secret)
|
44
|
-
|
45
|
-
resource.otp_enabled && !is_otp_trusted_browser_for?(resource)
|
46
|
-
end
|
47
|
-
|
48
|
-
#
|
49
|
-
# the resource -should- have otp turned on, but it isn't
|
50
|
-
#
|
51
|
-
def otp_mandatory_on?(resource)
|
52
|
-
return true if resource.class.otp_mandatory && !resource.otp_enabled
|
53
|
-
return false unless resource.respond_to?(:otp_mandatory)
|
54
|
-
|
55
|
-
resource.otp_mandatory && !resource.otp_enabled
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
require "integration_tests_helper"
|
3
|
-
|
4
|
-
class TokenTest < ActionDispatch::IntegrationTest
|
5
|
-
def teardown
|
6
|
-
Capybara.reset_sessions!
|
7
|
-
end
|
8
|
-
|
9
|
-
test "disabling OTP after successfully enabling" do
|
10
|
-
# log in 1fa
|
11
|
-
user = enable_otp_and_sign_in
|
12
|
-
assert_equal user_otp_credential_path, current_path
|
13
|
-
|
14
|
-
# otp 2fa
|
15
|
-
fill_in "user_token", with: ROTP::TOTP.new(user.otp_auth_secret).at(Time.now)
|
16
|
-
click_button "Submit Token"
|
17
|
-
assert_equal root_path, current_path
|
18
|
-
|
19
|
-
# disable OTP
|
20
|
-
disable_otp
|
21
|
-
|
22
|
-
# logout
|
23
|
-
sign_out
|
24
|
-
|
25
|
-
# log back in 1fa
|
26
|
-
sign_user_in(user)
|
27
|
-
|
28
|
-
assert_equal root_path, current_path
|
29
|
-
end
|
30
|
-
end
|