rails_base 0.75.6 → 0.80.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rails_base/rails_base_query_checker.js +36 -0
  3. data/app/controllers/rails_base/admin_controller.rb +54 -9
  4. data/app/controllers/rails_base/mfa/evaluation_controller.rb +59 -0
  5. data/app/controllers/rails_base/mfa/register/sms_controller.rb +45 -0
  6. data/app/controllers/rails_base/mfa/register/totp_controller.rb +42 -0
  7. data/app/controllers/rails_base/mfa/validate/sms_controller.rb +83 -0
  8. data/app/controllers/rails_base/mfa/validate/totp_controller.rb +35 -0
  9. data/app/controllers/rails_base/secondary_authentication_controller.rb +40 -96
  10. data/app/controllers/rails_base/user_settings_controller.rb +11 -1
  11. data/app/controllers/rails_base/users/registrations_controller.rb +1 -1
  12. data/app/controllers/rails_base/users/sessions_controller.rb +16 -13
  13. data/app/controllers/rails_base_application_controller.rb +96 -1
  14. data/app/jobs/twilio_job.rb +1 -1
  15. data/app/mailers/rails_base/email_verification_mailer.rb +6 -4
  16. data/app/mailers/rails_base/event_mailer.rb +4 -2
  17. data/app/mailers/rails_base/mailer_kwarg_inject.rb +31 -0
  18. data/app/models/rails_base/user_constants.rb +6 -3
  19. data/app/models/rails_base/user_helper/totp/backup_method_options.rb +33 -0
  20. data/app/models/rails_base/user_helper/totp/class_options.rb +35 -0
  21. data/app/models/rails_base/user_helper/totp/consume_method_options.rb +60 -0
  22. data/app/models/rails_base/user_helper/totp.rb +41 -0
  23. data/app/models/user.rb +28 -13
  24. data/app/services/rails_base/authentication/constants.rb +1 -1
  25. data/app/services/rails_base/authentication/decision_twofa_type.rb +61 -30
  26. data/app/services/rails_base/authentication/send_forgot_password.rb +0 -1
  27. data/app/services/rails_base/authentication/single_sign_on_send.rb +1 -1
  28. data/app/services/rails_base/authentication/sso_verify_email.rb +3 -1
  29. data/app/services/rails_base/authentication/update_phone_send_verification.rb +2 -2
  30. data/app/services/rails_base/authentication/verify_forgot_password.rb +8 -11
  31. data/app/services/rails_base/mfa/decision.rb +70 -0
  32. data/app/services/rails_base/mfa/encrypt_token.rb +34 -0
  33. data/app/services/rails_base/mfa/sms/remove.rb +35 -0
  34. data/app/services/rails_base/{authentication/send_login_mfa_to_user.rb → mfa/sms/send.rb} +19 -13
  35. data/app/services/rails_base/mfa/sms/validate.rb +105 -0
  36. data/app/services/rails_base/mfa/strategy/base.rb +44 -0
  37. data/app/services/rails_base/mfa/strategy/every_request.rb +14 -0
  38. data/app/services/rails_base/mfa/strategy/skip_every_request.rb +14 -0
  39. data/app/services/rails_base/mfa/strategy/time_based.rb +24 -0
  40. data/app/services/rails_base/mfa/totp/helper.rb +21 -0
  41. data/app/services/rails_base/mfa/totp/otp_metadata.rb +19 -0
  42. data/app/services/rails_base/mfa/totp/remove.rb +40 -0
  43. data/app/services/rails_base/mfa/totp/validate_code.rb +52 -0
  44. data/app/services/rails_base/mfa/totp/validate_temporary_code.rb +37 -0
  45. data/app/services/rails_base/mfa.rb +18 -0
  46. data/app/services/rails_base/name_change.rb +3 -3
  47. data/app/views/layouts/rails_base/application.html.erb +22 -6
  48. data/app/views/rails_base/devise/passwords/new.html.erb +1 -1
  49. data/app/views/rails_base/mfa/_switch_mfa_type.html.erb +17 -0
  50. data/app/views/rails_base/mfa/validate/sms/sms_event_input.html.erb +2 -0
  51. data/app/views/rails_base/mfa/validate/totp/totp_event_input.html.erb +1 -0
  52. data/app/views/rails_base/secondary_authentication/reset_password_input.html.erb +4 -0
  53. data/app/views/rails_base/shared/_enable_mfa_auth_modal.html.erb +1 -1
  54. data/app/views/rails_base/shared/_logged_in_header.html.erb +1 -25
  55. data/app/views/rails_base/shared/_modify_mfa_auth_modal.html.erb +102 -3
  56. data/app/views/rails_base/shared/mfa/sms/_login_input.html.erb +13 -0
  57. data/app/views/rails_base/shared/mfa/totp/_login_input.html.erb +22 -0
  58. data/app/views/rails_base/shared/totp/_add_authenticator.html.erb +76 -0
  59. data/app/views/rails_base/shared/totp/_add_authenticator_modal.html.erb +25 -0
  60. data/app/views/rails_base/shared/totp/_confirm_code.html.erb +31 -0
  61. data/app/views/rails_base/shared/totp/_confirm_code_ajax.html.erb +3 -0
  62. data/app/views/rails_base/shared/totp/_confirm_code_rest.html.erb +5 -0
  63. data/app/views/rails_base/shared/totp/_remove_authenticator_modal.html.erb +50 -0
  64. data/app/views/rails_base/user_settings/index.html.erb +84 -1
  65. data/config/initializers/admin_action_helper.rb +44 -8
  66. data/config/routes.rb +42 -7
  67. data/db/migrate/20240808013706_add_totp_to_users.rb +9 -0
  68. data/db/migrate/20240825012724_reconfigure_mfa_variable_names.rb +10 -0
  69. data/lib/rails_base/admin/action_helper.rb +0 -1
  70. data/lib/rails_base/admin/default_index_tile.rb +3 -3
  71. data/lib/rails_base/config.rb +26 -22
  72. data/lib/rails_base/configuration/admin.rb +5 -5
  73. data/lib/rails_base/configuration/base.rb +1 -0
  74. data/lib/rails_base/configuration/mfa.rb +27 -60
  75. data/lib/rails_base/configuration/totp.rb +82 -0
  76. data/lib/rails_base/configuration/twilio.rb +85 -0
  77. data/lib/rails_base/mfa_event.rb +186 -0
  78. data/lib/rails_base/version.rb +3 -3
  79. data/lib/rails_base.rb +1 -0
  80. data/lib/twilio_helper.rb +3 -3
  81. metadata +129 -64
  82. data/app/controllers/rails_base/mfa_auth_controller.rb +0 -50
  83. data/app/services/rails_base/authentication/mfa_set_encrypt_token.rb +0 -32
  84. data/app/services/rails_base/authentication/mfa_validator.rb +0 -88
  85. data/app/views/rails_base/mfa_auth/mfa_code.html.erb +0 -11
  86. data/app/views/rails_base/secondary_authentication/forgot_password.html.erb +0 -9
metadata CHANGED
@@ -1,45 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.75.6
4
+ version: 0.80.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Taylor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-21 00:00:00.000000000 Z
11
+ date: 2024-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: allow_numeric
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6.1'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '6.1'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: zeitwerk
28
+ name: bootstrap
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.6.5
33
+ version: 4.6.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.6.5
40
+ version: 4.6.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: mysql2
42
+ name: browser
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: sass-rails
56
+ name: coffee-rails
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: uglifier
70
+ name: devise
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: turbolinks
84
+ name: dotiw
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: coffee-rails
98
+ name: interactor
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -129,63 +129,91 @@ dependencies:
129
129
  - !ruby/object:Gem::Version
130
130
  version: 4.3.3
131
131
  - !ruby/object:Gem::Dependency
132
- name: rails-ujs
132
+ name: jquery_mask_rails
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
- - - "~>"
135
+ - - ">="
136
136
  - !ruby/object:Gem::Version
137
- version: 0.1.0
137
+ version: '0'
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
- - - "~>"
142
+ - - ">="
143
143
  - !ruby/object:Gem::Version
144
- version: 0.1.0
144
+ version: '0'
145
145
  - !ruby/object:Gem::Dependency
146
- name: bootstrap
146
+ name: mysql2
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: rails
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '6'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '6'
173
+ - !ruby/object:Gem::Dependency
174
+ name: rails-ujs
147
175
  requirement: !ruby/object:Gem::Requirement
148
176
  requirements:
149
177
  - - "~>"
150
178
  - !ruby/object:Gem::Version
151
- version: 4.6.0
179
+ version: 0.1.0
152
180
  type: :runtime
153
181
  prerelease: false
154
182
  version_requirements: !ruby/object:Gem::Requirement
155
183
  requirements:
156
184
  - - "~>"
157
185
  - !ruby/object:Gem::Version
158
- version: 4.6.0
186
+ version: 0.1.0
159
187
  - !ruby/object:Gem::Dependency
160
- name: devise
188
+ name: redis
161
189
  requirement: !ruby/object:Gem::Requirement
162
190
  requirements:
163
191
  - - ">="
164
192
  - !ruby/object:Gem::Version
165
- version: '0'
193
+ version: 4.2.5
166
194
  type: :runtime
167
195
  prerelease: false
168
196
  version_requirements: !ruby/object:Gem::Requirement
169
197
  requirements:
170
198
  - - ">="
171
199
  - !ruby/object:Gem::Version
172
- version: '0'
200
+ version: 4.2.5
173
201
  - !ruby/object:Gem::Dependency
174
- name: twilio-ruby
202
+ name: redis-namespace
175
203
  requirement: !ruby/object:Gem::Requirement
176
204
  requirements:
177
205
  - - ">="
178
206
  - !ruby/object:Gem::Version
179
- version: '0'
207
+ version: 1.8.1
180
208
  type: :runtime
181
209
  prerelease: false
182
210
  version_requirements: !ruby/object:Gem::Requirement
183
211
  requirements:
184
212
  - - ">="
185
213
  - !ruby/object:Gem::Version
186
- version: '0'
214
+ version: 1.8.1
187
215
  - !ruby/object:Gem::Dependency
188
- name: interactor
216
+ name: rotp
189
217
  requirement: !ruby/object:Gem::Requirement
190
218
  requirements:
191
219
  - - ">="
@@ -199,7 +227,7 @@ dependencies:
199
227
  - !ruby/object:Gem::Version
200
228
  version: '0'
201
229
  - !ruby/object:Gem::Dependency
202
- name: allow_numeric
230
+ name: rqrcode
203
231
  requirement: !ruby/object:Gem::Requirement
204
232
  requirements:
205
233
  - - ">="
@@ -213,7 +241,7 @@ dependencies:
213
241
  - !ruby/object:Gem::Version
214
242
  version: '0'
215
243
  - !ruby/object:Gem::Dependency
216
- name: jquery_mask_rails
244
+ name: sass-rails
217
245
  requirement: !ruby/object:Gem::Requirement
218
246
  requirements:
219
247
  - - ">="
@@ -227,7 +255,7 @@ dependencies:
227
255
  - !ruby/object:Gem::Version
228
256
  version: '0'
229
257
  - !ruby/object:Gem::Dependency
230
- name: browser
258
+ name: switch_user
231
259
  requirement: !ruby/object:Gem::Requirement
232
260
  requirements:
233
261
  - - ">="
@@ -241,7 +269,7 @@ dependencies:
241
269
  - !ruby/object:Gem::Version
242
270
  version: '0'
243
271
  - !ruby/object:Gem::Dependency
244
- name: dotiw
272
+ name: turbolinks
245
273
  requirement: !ruby/object:Gem::Requirement
246
274
  requirements:
247
275
  - - ">="
@@ -255,47 +283,47 @@ dependencies:
255
283
  - !ruby/object:Gem::Version
256
284
  version: '0'
257
285
  - !ruby/object:Gem::Dependency
258
- name: redis
286
+ name: twilio-ruby
259
287
  requirement: !ruby/object:Gem::Requirement
260
288
  requirements:
261
289
  - - ">="
262
290
  - !ruby/object:Gem::Version
263
- version: 4.2.5
291
+ version: '0'
264
292
  type: :runtime
265
293
  prerelease: false
266
294
  version_requirements: !ruby/object:Gem::Requirement
267
295
  requirements:
268
296
  - - ">="
269
297
  - !ruby/object:Gem::Version
270
- version: 4.2.5
298
+ version: '0'
271
299
  - !ruby/object:Gem::Dependency
272
- name: redis-namespace
300
+ name: uglifier
273
301
  requirement: !ruby/object:Gem::Requirement
274
302
  requirements:
275
303
  - - ">="
276
304
  - !ruby/object:Gem::Version
277
- version: 1.8.1
305
+ version: '0'
278
306
  type: :runtime
279
307
  prerelease: false
280
308
  version_requirements: !ruby/object:Gem::Requirement
281
309
  requirements:
282
310
  - - ">="
283
311
  - !ruby/object:Gem::Version
284
- version: 1.8.1
312
+ version: '0'
285
313
  - !ruby/object:Gem::Dependency
286
- name: switch_user
314
+ name: zeitwerk
287
315
  requirement: !ruby/object:Gem::Requirement
288
316
  requirements:
289
317
  - - ">="
290
318
  - !ruby/object:Gem::Version
291
- version: '0'
319
+ version: 2.6.5
292
320
  type: :runtime
293
321
  prerelease: false
294
322
  version_requirements: !ruby/object:Gem::Requirement
295
323
  requirements:
296
324
  - - ">="
297
325
  - !ruby/object:Gem::Version
298
- version: '0'
326
+ version: 2.6.5
299
327
  - !ruby/object:Gem::Dependency
300
328
  name: annotate
301
329
  requirement: !ruby/object:Gem::Requirement
@@ -311,21 +339,21 @@ dependencies:
311
339
  - !ruby/object:Gem::Version
312
340
  version: '0'
313
341
  - !ruby/object:Gem::Dependency
314
- name: spring-watcher-listen
342
+ name: capybara
315
343
  requirement: !ruby/object:Gem::Requirement
316
344
  requirements:
317
345
  - - ">="
318
346
  - !ruby/object:Gem::Version
319
- version: '0'
347
+ version: '2.15'
320
348
  type: :development
321
349
  prerelease: false
322
350
  version_requirements: !ruby/object:Gem::Requirement
323
351
  requirements:
324
352
  - - ">="
325
353
  - !ruby/object:Gem::Version
326
- version: '0'
354
+ version: '2.15'
327
355
  - !ruby/object:Gem::Dependency
328
- name: spring
356
+ name: listen
329
357
  requirement: !ruby/object:Gem::Requirement
330
358
  requirements:
331
359
  - - ">="
@@ -339,7 +367,7 @@ dependencies:
339
367
  - !ruby/object:Gem::Version
340
368
  version: '0'
341
369
  - !ruby/object:Gem::Dependency
342
- name: listen
370
+ name: pry
343
371
  requirement: !ruby/object:Gem::Requirement
344
372
  requirements:
345
373
  - - ">="
@@ -353,7 +381,7 @@ dependencies:
353
381
  - !ruby/object:Gem::Version
354
382
  version: '0'
355
383
  - !ruby/object:Gem::Dependency
356
- name: web-console
384
+ name: pry-nav
357
385
  requirement: !ruby/object:Gem::Requirement
358
386
  requirements:
359
387
  - - ">="
@@ -367,7 +395,7 @@ dependencies:
367
395
  - !ruby/object:Gem::Version
368
396
  version: '0'
369
397
  - !ruby/object:Gem::Dependency
370
- name: pry
398
+ name: pry-stack_explorer
371
399
  requirement: !ruby/object:Gem::Requirement
372
400
  requirements:
373
401
  - - ">="
@@ -381,7 +409,7 @@ dependencies:
381
409
  - !ruby/object:Gem::Version
382
410
  version: '0'
383
411
  - !ruby/object:Gem::Dependency
384
- name: pry-nav
412
+ name: spring
385
413
  requirement: !ruby/object:Gem::Requirement
386
414
  requirements:
387
415
  - - ">="
@@ -395,7 +423,7 @@ dependencies:
395
423
  - !ruby/object:Gem::Version
396
424
  version: '0'
397
425
  - !ruby/object:Gem::Dependency
398
- name: pry-stack_explorer
426
+ name: spring-watcher-listen
399
427
  requirement: !ruby/object:Gem::Requirement
400
428
  requirements:
401
429
  - - ">="
@@ -409,19 +437,19 @@ dependencies:
409
437
  - !ruby/object:Gem::Version
410
438
  version: '0'
411
439
  - !ruby/object:Gem::Dependency
412
- name: capybara
440
+ name: web-console
413
441
  requirement: !ruby/object:Gem::Requirement
414
442
  requirements:
415
443
  - - ">="
416
444
  - !ruby/object:Gem::Version
417
- version: '2.15'
445
+ version: '0'
418
446
  type: :development
419
447
  prerelease: false
420
448
  version_requirements: !ruby/object:Gem::Requirement
421
449
  requirements:
422
450
  - - ">="
423
451
  - !ruby/object:Gem::Version
424
- version: '2.15'
452
+ version: '0'
425
453
  description: Rails Engine that handles authentication, admin, 2fa, audit tracking,
426
454
  with insane configuration abilites
427
455
  email:
@@ -438,6 +466,7 @@ files:
438
466
  - app/assets/javascripts/rails_base/admin.js
439
467
  - app/assets/javascripts/rails_base/application.js
440
468
  - app/assets/javascripts/rails_base/mfa_auth.coffee
469
+ - app/assets/javascripts/rails_base/rails_base_query_checker.js
441
470
  - app/assets/javascripts/rails_base/secondary_authentication.coffee
442
471
  - app/assets/javascripts/rails_base/sessions.js
443
472
  - app/assets/javascripts/rails_base/user_settings.coffee
@@ -449,7 +478,11 @@ files:
449
478
  - app/assets/stylesheets/rails_base/user_settings.scss
450
479
  - app/controllers/rails_base/admin_controller.rb
451
480
  - app/controllers/rails_base/errors_controller.rb
452
- - app/controllers/rails_base/mfa_auth_controller.rb
481
+ - app/controllers/rails_base/mfa/evaluation_controller.rb
482
+ - app/controllers/rails_base/mfa/register/sms_controller.rb
483
+ - app/controllers/rails_base/mfa/register/totp_controller.rb
484
+ - app/controllers/rails_base/mfa/validate/sms_controller.rb
485
+ - app/controllers/rails_base/mfa/validate/totp_controller.rb
453
486
  - app/controllers/rails_base/secondary_authentication_controller.rb
454
487
  - app/controllers/rails_base/switch_user_controller.rb
455
488
  - app/controllers/rails_base/user_settings_controller.rb
@@ -470,9 +503,14 @@ files:
470
503
  - app/mailers/rails_base/application_mailer.rb
471
504
  - app/mailers/rails_base/email_verification_mailer.rb
472
505
  - app/mailers/rails_base/event_mailer.rb
506
+ - app/mailers/rails_base/mailer_kwarg_inject.rb
473
507
  - app/models/admin_action.rb
474
508
  - app/models/rails_base/application_record.rb
475
509
  - app/models/rails_base/user_constants.rb
510
+ - app/models/rails_base/user_helper/totp.rb
511
+ - app/models/rails_base/user_helper/totp/backup_method_options.rb
512
+ - app/models/rails_base/user_helper/totp/class_options.rb
513
+ - app/models/rails_base/user_helper/totp/consume_method_options.rb
476
514
  - app/models/secret.rb
477
515
  - app/models/short_lived_data.rb
478
516
  - app/models/user.rb
@@ -482,11 +520,8 @@ files:
482
520
  - app/services/rails_base/authentication/constants.rb
483
521
  - app/services/rails_base/authentication/decision_twofa_type.rb
484
522
  - app/services/rails_base/authentication/destroy_user.rb
485
- - app/services/rails_base/authentication/mfa_set_encrypt_token.rb
486
- - app/services/rails_base/authentication/mfa_validator.rb
487
523
  - app/services/rails_base/authentication/modify_password.rb
488
524
  - app/services/rails_base/authentication/send_forgot_password.rb
489
- - app/services/rails_base/authentication/send_login_mfa_to_user.rb
490
525
  - app/services/rails_base/authentication/send_verification_email.rb
491
526
  - app/services/rails_base/authentication/session_token_verifier.rb
492
527
  - app/services/rails_base/authentication/single_sign_on_create.rb
@@ -497,6 +532,21 @@ files:
497
532
  - app/services/rails_base/authentication/verify_forgot_password.rb
498
533
  - app/services/rails_base/email_change.rb
499
534
  - app/services/rails_base/encryption.rb
535
+ - app/services/rails_base/mfa.rb
536
+ - app/services/rails_base/mfa/decision.rb
537
+ - app/services/rails_base/mfa/encrypt_token.rb
538
+ - app/services/rails_base/mfa/sms/remove.rb
539
+ - app/services/rails_base/mfa/sms/send.rb
540
+ - app/services/rails_base/mfa/sms/validate.rb
541
+ - app/services/rails_base/mfa/strategy/base.rb
542
+ - app/services/rails_base/mfa/strategy/every_request.rb
543
+ - app/services/rails_base/mfa/strategy/skip_every_request.rb
544
+ - app/services/rails_base/mfa/strategy/time_based.rb
545
+ - app/services/rails_base/mfa/totp/helper.rb
546
+ - app/services/rails_base/mfa/totp/otp_metadata.rb
547
+ - app/services/rails_base/mfa/totp/remove.rb
548
+ - app/services/rails_base/mfa/totp/validate_code.rb
549
+ - app/services/rails_base/mfa/totp/validate_temporary_code.rb
500
550
  - app/services/rails_base/name_change.rb
501
551
  - app/services/rails_base/service_base.rb
502
552
  - app/services/rails_base/service_logging.rb
@@ -528,10 +578,12 @@ files:
528
578
  - app/views/rails_base/errors/not_found.html.erb
529
579
  - app/views/rails_base/errors/unacceptable.html.erb
530
580
  - app/views/rails_base/event_mailer/event.html.erb
531
- - app/views/rails_base/mfa_auth/mfa_code.html.erb
581
+ - app/views/rails_base/mfa/_switch_mfa_type.html.erb
582
+ - app/views/rails_base/mfa/validate/sms/sms_event_input.html.erb
583
+ - app/views/rails_base/mfa/validate/totp/totp_event_input.html.erb
532
584
  - app/views/rails_base/secondary_authentication/after_email_login_session_new.html.erb
533
- - app/views/rails_base/secondary_authentication/forgot_password.html.erb
534
585
  - app/views/rails_base/secondary_authentication/remove_me.html.erb
586
+ - app/views/rails_base/secondary_authentication/reset_password_input.html.erb
535
587
  - app/views/rails_base/secondary_authentication/static.html.erb
536
588
  - app/views/rails_base/shared/_admin_actions_modal.html.erb
537
589
  - app/views/rails_base/shared/_admin_config_class.html.erb
@@ -560,6 +612,14 @@ files:
560
612
  - app/views/rails_base/shared/_session_create_form.html.erb
561
613
  - app/views/rails_base/shared/_session_timeout_modal.html.erb
562
614
  - app/views/rails_base/shared/_standardized_collapse.html.erb
615
+ - app/views/rails_base/shared/mfa/sms/_login_input.html.erb
616
+ - app/views/rails_base/shared/mfa/totp/_login_input.html.erb
617
+ - app/views/rails_base/shared/totp/_add_authenticator.html.erb
618
+ - app/views/rails_base/shared/totp/_add_authenticator_modal.html.erb
619
+ - app/views/rails_base/shared/totp/_confirm_code.html.erb
620
+ - app/views/rails_base/shared/totp/_confirm_code_ajax.html.erb
621
+ - app/views/rails_base/shared/totp/_confirm_code_rest.html.erb
622
+ - app/views/rails_base/shared/totp/_remove_authenticator_modal.html.erb
563
623
  - app/views/rails_base/switch_user/_widget.html.erb
564
624
  - app/views/rails_base/user_settings/_confirm_destroy_user.html.erb
565
625
  - app/views/rails_base/user_settings/_destroy_user.html.erb
@@ -581,6 +641,8 @@ files:
581
641
  - db/migrate/20210212190537_create_rails_base_short_lived_data.rb
582
642
  - db/migrate/20210212192645_create_rails_base_secrets.rb
583
643
  - db/migrate/20210406015744_create_rails_base_admin_actions.rb
644
+ - db/migrate/20240808013706_add_totp_to_users.rb
645
+ - db/migrate/20240825012724_reconfigure_mfa_variable_names.rb
584
646
  - db/seeds.rb
585
647
  - lib/link_decision_helper.rb
586
648
  - lib/rails_base.rb
@@ -620,8 +682,11 @@ files:
620
682
  - lib/rails_base/configuration/owner.rb
621
683
  - lib/rails_base/configuration/redis.rb
622
684
  - lib/rails_base/configuration/templates.rb
685
+ - lib/rails_base/configuration/totp.rb
686
+ - lib/rails_base/configuration/twilio.rb
623
687
  - lib/rails_base/configuration/user.rb
624
688
  - lib/rails_base/engine.rb
689
+ - lib/rails_base/mfa_event.rb
625
690
  - lib/rails_base/switch_user_helper.rb
626
691
  - lib/rails_base/version.rb
627
692
  - lib/tasks/rails_base_tasks.rake
@@ -637,16 +702,16 @@ require_paths:
637
702
  - lib
638
703
  required_ruby_version: !ruby/object:Gem::Requirement
639
704
  requirements:
640
- - - ">="
705
+ - - "~>"
641
706
  - !ruby/object:Gem::Version
642
- version: '0'
707
+ version: '3.2'
643
708
  required_rubygems_version: !ruby/object:Gem::Requirement
644
709
  requirements:
645
710
  - - ">="
646
711
  - !ruby/object:Gem::Version
647
712
  version: '0'
648
713
  requirements: []
649
- rubygems_version: 3.4.19
714
+ rubygems_version: 3.5.9
650
715
  signing_key:
651
716
  specification_version: 4
652
717
  summary: Rails engine that takes care of the stuff you dont want to!
@@ -1,50 +0,0 @@
1
- module RailsBase
2
- class MfaAuthController < RailsBaseApplicationController
3
- before_action :validate_token, only: [:mfa_code, :mfa_code_verify, :resend_mfa]
4
-
5
- # GET /mfa_verify
6
- def mfa_code
7
- @masked_phone = User.find(@token_verifier.user_id).masked_phone
8
- end
9
-
10
- # POST /mfa_verify
11
- def mfa_code_verify
12
- mfa_validity = RailsBase::Authentication::MfaValidator.call(params: params, session_mfa_user_id: @token_verifier.user_id)
13
- if mfa_validity.failure?
14
- redirect_to(mfa_validity.redirect_url, alert: mfa_validity.message)
15
- return
16
- end
17
-
18
- mfa_validity.user.set_last_mfa_login!
19
-
20
- sign_in(mfa_validity.user)
21
- redirect_to RailsBase.url_routes.authenticated_root_path, notice: "Welcome #{mfa_validity.user.full_name}"
22
- end
23
-
24
- # POST /mfa_verify
25
- def resend_mfa
26
- user = User.find(@token_verifier.user_id)
27
- mfa_token = RailsBase::Authentication::SendLoginMfaToUser.call(user: user)
28
- if mfa_token.failure?
29
- flash[:error] = mfa_token.message
30
- session[:mfa_randomized_token] = nil
31
- redirect_to RailsBase.url_routes.new_user_session_path, email: params.dig(:user,:email), alert: mfa_token.message
32
- return
33
- end
34
- expired_at = Time.zone.parse(@token_verifier.expires_at)
35
- session[:mfa_randomized_token] =
36
- RailsBase::Authentication::MfaSetEncryptToken.call(user: user, expires_at: expired_at).encrypted_val
37
-
38
- redirect_to RailsBase.url_routes.mfa_code_path, notice: "MFA has been sent via SMS to number on file"
39
- end
40
-
41
- def validate_token
42
- @token_verifier =
43
- RailsBase::Authentication::SessionTokenVerifier.call(mfa_randomized_token: session[:mfa_randomized_token])
44
- return if @token_verifier.success?
45
-
46
- redirect_to RailsBase.url_routes.new_user_session_path, alert: @token_verifier.message
47
- return false
48
- end
49
- end
50
- end
@@ -1,32 +0,0 @@
1
- module RailsBase::Authentication
2
- class MfaSetEncryptToken < RailsBase::ServiceBase
3
- delegate :user, to: :context
4
- delegate :expires_at, to: :context
5
- delegate :purpose, to: :context
6
-
7
- def call
8
- params = {
9
- value: value,
10
- purpose: purpose || Constants::MSET_PURPOSE,
11
- expires_at: expires_at
12
- }
13
-
14
- context.encrypted_val = RailsBase::Encryption.encode(**params)
15
- end
16
-
17
- def value
18
- # user_id with the same expires_at will return the same Encryption token
19
- # to overcome this, do 2 things
20
- # 1: Rotate the secret on every boot (ensures tplem changes on semi regular basis)
21
- # 2: Add rand strings to the hash -- Ensures the token is different every time
22
- { user_id: user.id, rand: rand.to_s, expires_at: expires_at }.to_json
23
- end
24
-
25
- def validate!
26
- raise "Expected user to be a User. Received #{user.class}" unless user.is_a? User
27
-
28
- time_class = ActiveSupport::TimeWithZone
29
- raise "Expected expires_at to be a Received #{time_class}. Received #{expires_at.class}" unless expires_at.is_a? time_class
30
- end
31
- end
32
- end
@@ -1,88 +0,0 @@
1
- module RailsBase::Authentication
2
- class MfaValidator < RailsBase::ServiceBase
3
- delegate :params, to: :context
4
- delegate :session_mfa_user_id, to: :context
5
- delegate :current_user, to: :context
6
- delegate :input_reason, to: :context
7
-
8
- def call
9
- array = convert_to_array
10
- if array.length != Constants::MFA_LENGTH
11
- log(level: :warn, msg: "Not enough params for MFA code. Given #{array}. Expected of length #{Constants::MFA_LENGTH}")
12
- context.fail!(message: Constants::MV_FISHY, redirect_url: Constants::URL_HELPER.new_user_session_path, level: :alert)
13
- end
14
-
15
- mfa_code = array.join
16
- log(level: :info, msg: "mfa code received: #{mfa_code}")
17
- datum = get_short_lived_datum(mfa_code)
18
- log(level: :info, msg: "Datum returned with: #{datum}")
19
-
20
- validate_datum?(datum)
21
- validate_user_consistency?(datum)
22
- validate_current_user?(datum) if current_user
23
-
24
- context.user = datum[:user]
25
- end
26
-
27
- def validate_current_user?(datum)
28
- return true if current_user.id == datum[:user].id
29
-
30
- # User MFA for a different user matched the session token
31
- # However, those did not match the current user signed in
32
- # Something is very 🐟
33
- log(level: :error, msg: "Someone is a teapot. Current logged in user does not equal mfa code.")
34
- context.fail!(message: 'You are a teapot', redirect_url: Constants::URL_HELPER.signout_path, level: :warn)
35
- end
36
-
37
- def validate_datum?(datum)
38
- return true if datum[:valid]
39
-
40
- if datum[:found]
41
- # MFA is either expired or the incorrect reason. Either way it does not match
42
- msg = "Errors with MFA: #{datum[:invalid_reason].join(", ")}. Please login again"
43
- log(level: :warn, msg: msg)
44
- context.fail!(message: msg, redirect_url: Constants::URL_HELPER.new_user_session_path, level: :warn)
45
- end
46
-
47
- # MFA does not exist for any reason type
48
- log(level: :warn, msg: "Could not find MFA code. Incorrect MFA code")
49
-
50
- context.fail!(message: "Incorrect MFA code.", redirect_url: Constants::URL_HELPER.mfa_code_path, level: :warn)
51
- end
52
-
53
- def validate_user_consistency?(datum)
54
- return true if datum[:user].id == session_mfa_user_id.to_i
55
- log(level: :warn, msg: "Datum user does not match session user. [#{datum[:user].id}, #{session_mfa_user_id.to_i}]")
56
-
57
- # MFA session token user does not match the datum user
58
- # Something is very 🐟
59
- context.fail!(message: Constants::MV_FISHY, redirect_url: Constants::URL_HELPER.new_user_session_path, level: :alert)
60
- end
61
-
62
- def get_short_lived_datum(mfa_code)
63
- log(level: :debug, msg: "Looking for #{mfa_code} with reason #{reason}")
64
- ShortLivedData.find_datum(data: mfa_code, reason: reason)
65
- end
66
-
67
- def convert_to_array
68
- array = []
69
- return array unless params.dig(:mfa).respond_to? :keys
70
-
71
- Constants::MFA_LENGTH.times do |index|
72
- var_name = "#{Constants::MV_BASE_NAME}#{index}".to_sym
73
- array << params[:mfa][var_name]
74
- end
75
-
76
- array.compact
77
- end
78
-
79
- def reason
80
- input_reason || Constants::MFA_REASON
81
- end
82
-
83
- def validate!
84
- raise 'Expected the params passed' if params.nil?
85
- raise 'session_mfa_user_id is not present' if session_mfa_user_id.nil?
86
- end
87
- end
88
- end