easy-admin-rails 0.2.5 → 0.2.6
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/app/assets/builds/easy_admin.base.js +88 -0
- data/app/assets/builds/easy_admin.base.js.map +3 -3
- data/app/assets/builds/easy_admin.css +54 -0
- data/app/components/easy_admin/navbar_component.rb +19 -4
- data/app/components/easy_admin/profile/change_password_modal_component.rb +75 -0
- data/app/components/easy_admin/profile/profile_tab_component.rb +92 -0
- data/app/components/easy_admin/profile/security_tab_component.rb +53 -0
- data/app/components/easy_admin/profile/settings_component.rb +103 -0
- data/app/components/easy_admin/two_factor/backup_codes_component.rb +118 -0
- data/app/components/easy_admin/two_factor/setup_component.rb +124 -0
- data/app/components/easy_admin/two_factor/status_component.rb +92 -0
- data/app/controllers/concerns/easy_admin/two_factor.rb +110 -0
- data/app/controllers/easy_admin/application_controller.rb +10 -0
- data/app/controllers/easy_admin/profile_controller.rb +25 -0
- data/app/controllers/easy_admin/sessions_controller.rb +107 -1
- data/app/javascript/easy_admin/controllers/vertical_tabs_controller.js +112 -0
- data/app/javascript/easy_admin/controllers.js +3 -1
- data/app/models/easy_admin/admin_user.rb +3 -0
- data/app/views/easy_admin/profile/backup_codes_regenerated.turbo_stream.erb +12 -0
- data/app/views/easy_admin/profile/change_password.html.erb +24 -0
- data/app/views/easy_admin/profile/index.html.erb +1 -0
- data/app/views/easy_admin/profile/password_error.turbo_stream.erb +6 -0
- data/app/views/easy_admin/profile/password_invalid_current.turbo_stream.erb +6 -0
- data/app/views/easy_admin/profile/password_updated.turbo_stream.erb +9 -0
- data/app/views/easy_admin/profile/two_factor_backup_codes.html.erb +24 -0
- data/app/views/easy_admin/profile/two_factor_enabled.turbo_stream.erb +12 -0
- data/app/views/easy_admin/profile/two_factor_invalid_code.turbo_stream.erb +6 -0
- data/app/views/easy_admin/profile/two_factor_not_enabled.turbo_stream.erb +6 -0
- data/app/views/easy_admin/profile/two_factor_setup.html.erb +24 -0
- data/app/views/easy_admin/profile/two_factor_unavailable.turbo_stream.erb +6 -0
- data/app/views/easy_admin/sessions/two_factor_verification.html.erb +48 -0
- data/app/views/easy_admin/sessions/verify_2fa_error.turbo_stream.erb +13 -0
- data/config/routes.rb +20 -1
- data/lib/easy-admin-rails.rb +1 -0
- data/lib/easy_admin/two_factor_authentication.rb +156 -0
- data/lib/easy_admin/version.rb +1 -1
- data/lib/generators/easy_admin/two_factor/templates/README +29 -0
- data/lib/generators/easy_admin/two_factor/templates/migration.rb +10 -0
- data/lib/generators/easy_admin/two_factor/two_factor_generator.rb +22 -0
- metadata +30 -2
@@ -0,0 +1,24 @@
|
|
1
|
+
<% if turbo_frame_request? %>
|
2
|
+
<turbo-frame id="modal">
|
3
|
+
<div id="modal-backdrop" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50 opacity-100 transition-opacity duration-300" data-controller="modal" data-action="click->modal#closeOnBackdrop">
|
4
|
+
<div class="relative top-20 mx-auto p-5 border w-11/12 md:w-3/4 lg:w-1/2 xl:w-2/5 shadow-lg rounded-md bg-white">
|
5
|
+
<div class="mt-3">
|
6
|
+
<!-- Modal header -->
|
7
|
+
<div class="flex items-center justify-between mb-4">
|
8
|
+
<h3 class="text-lg font-medium text-gray-900">Backup Codes</h3>
|
9
|
+
<button class="text-gray-400 hover:text-gray-600 focus:outline-none" data-action="click->modal#close">
|
10
|
+
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
11
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
12
|
+
</svg>
|
13
|
+
</button>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<!-- Modal content -->
|
17
|
+
<%== EasyAdmin::TwoFactor::BackupCodesComponent.new(user: current_admin_user).call %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</turbo-frame>
|
22
|
+
<% else %>
|
23
|
+
<%== EasyAdmin::TwoFactor::BackupCodesComponent.new(user: current_admin_user).call %>
|
24
|
+
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= turbo_stream.replace "two_factor_section" do %>
|
2
|
+
<div id="two_factor_section">
|
3
|
+
<%== EasyAdmin::TwoFactor::StatusComponent.new(user: current_admin_user).call %>
|
4
|
+
</div>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
<%= turbo_stream.replace "notifications" do %>
|
8
|
+
<%== EasyAdmin::NotificationComponent.new(
|
9
|
+
message: "Two-factor authentication has been enabled successfully!",
|
10
|
+
type: :success
|
11
|
+
).call %>
|
12
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% if turbo_frame_request? %>
|
2
|
+
<turbo-frame id="modal">
|
3
|
+
<div id="modal-backdrop" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50 opacity-100 transition-opacity duration-300" data-controller="modal" data-action="click->modal#closeOnBackdrop">
|
4
|
+
<div class="relative top-20 mx-auto p-5 border w-11/12 md:w-3/4 lg:w-1/2 xl:w-2/5 shadow-lg rounded-md bg-white">
|
5
|
+
<div class="mt-3">
|
6
|
+
<!-- Modal header -->
|
7
|
+
<div class="flex items-center justify-between mb-4">
|
8
|
+
<h3 class="text-lg font-medium text-gray-900">Set up Two-Factor Authentication</h3>
|
9
|
+
<button class="text-gray-400 hover:text-gray-600 focus:outline-none" data-action="click->modal#close">
|
10
|
+
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
11
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
12
|
+
</svg>
|
13
|
+
</button>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<!-- Modal content -->
|
17
|
+
<%== EasyAdmin::TwoFactor::SetupComponent.new(user: current_admin_user).call %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</turbo-frame>
|
22
|
+
<% else %>
|
23
|
+
<%== EasyAdmin::TwoFactor::SetupComponent.new(user: current_admin_user).call %>
|
24
|
+
<% end %>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<!-- Form -->
|
2
|
+
<div class="p-10">
|
3
|
+
<%= form_with url: verify_2fa_path, method: :post, local: true, html: { class: "space-y-8" } do |f| %>
|
4
|
+
|
5
|
+
<!-- Header -->
|
6
|
+
<div class="text-center mb-6">
|
7
|
+
<h2 class="text-xl font-bold text-gray-900 mb-2">Two-Factor Authentication</h2>
|
8
|
+
<p class="text-gray-600">Enter the 6-digit code from your authenticator app</p>
|
9
|
+
<% if @user %>
|
10
|
+
<p class="text-sm text-gray-500 mt-2">Signing in as <%= @user.email %></p>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<!-- Input Fields Container -->
|
15
|
+
<div class="space-y-4">
|
16
|
+
<!-- OTP Code Field -->
|
17
|
+
<div class="relative">
|
18
|
+
<%= text_field_tag :otp_code, '', autofocus: true, autocomplete: "one-time-code",
|
19
|
+
maxlength: 6, pattern: "[0-9]{6}", id: "otp_code",
|
20
|
+
class: "w-full px-6 py-5 bg-gray-50/80 border-0 text-gray-900 placeholder-gray-400 focus:bg-gray-100/80 focus:ring-0 focus:outline-none text-base rounded-2xl transition-colors duration-200 font-medium text-center tracking-widest",
|
21
|
+
placeholder: "000000" %>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<!-- Submit Button -->
|
26
|
+
<div class="pt-4">
|
27
|
+
<%= f.submit "Verify Code",
|
28
|
+
class: "w-full bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white font-bold py-5 px-6 rounded-2xl transition-all duration-200 focus:outline-none focus:ring-4 focus:ring-blue-500/30 text-base shadow-xl shadow-blue-500/20 active:scale-[0.98]" %>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<!-- Help Text -->
|
34
|
+
<div class="text-center pt-6">
|
35
|
+
<p class="text-sm text-gray-500 mb-2">
|
36
|
+
Can't access your authenticator app?
|
37
|
+
</p>
|
38
|
+
<p class="text-sm text-gray-400">
|
39
|
+
Contact your administrator for help with account recovery.
|
40
|
+
</p>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<!-- Back to Sign In -->
|
44
|
+
<div class="text-center pt-4">
|
45
|
+
<%= link_to "← Back to Sign In", cancel_2fa_path,
|
46
|
+
class: "text-sm text-blue-500 hover:text-blue-600 font-medium transition-colors duration-200" %>
|
47
|
+
</div>
|
48
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%= turbo_stream.replace "notifications" do %>
|
2
|
+
<%== EasyAdmin::NotificationComponent.new(
|
3
|
+
message: "Invalid authentication code. Please try again.",
|
4
|
+
type: :error
|
5
|
+
).call %>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<%= turbo_stream.replace "otp_code" do %>
|
9
|
+
<%= text_field_tag :otp_code, '', autofocus: true, autocomplete: "one-time-code",
|
10
|
+
maxlength: 6, pattern: "[0-9]{6}",
|
11
|
+
class: "w-full px-6 py-5 bg-gray-50/80 border-0 text-gray-900 placeholder-gray-400 focus:bg-gray-100/80 focus:ring-0 focus:outline-none text-base rounded-2xl transition-colors duration-200 font-medium text-center tracking-widest",
|
12
|
+
placeholder: "000000" %>
|
13
|
+
<% end %>
|
data/config/routes.rb
CHANGED
@@ -13,13 +13,32 @@ EasyAdmin::Engine.routes.draw do
|
|
13
13
|
sign_out: 'sign_out',
|
14
14
|
sign_up: 'sign_up'
|
15
15
|
}
|
16
|
+
|
17
|
+
# 2FA verification routes (wrapped in devise_scope)
|
18
|
+
devise_scope :admin_user do
|
19
|
+
get 'two_factor_verification', to: 'sessions#two_factor_verification', as: 'two_factor_verification'
|
20
|
+
post 'verify_2fa', to: 'sessions#verify_2fa', as: 'verify_2fa'
|
21
|
+
get 'cancel_2fa', to: 'sessions#cancel_2fa', as: 'cancel_2fa'
|
22
|
+
end
|
16
23
|
|
17
24
|
root 'dashboard#index'
|
18
25
|
|
19
|
-
#
|
26
|
+
# Global settings routes (Flipper)
|
20
27
|
get 'settings', to: 'settings#index'
|
21
28
|
patch 'settings', to: 'settings#update'
|
22
29
|
|
30
|
+
# User profile settings routes
|
31
|
+
get 'profile', to: 'profile#index', as: 'profile'
|
32
|
+
patch 'profile', to: 'profile#update', as: 'update_profile'
|
33
|
+
get 'profile/change_password', to: 'profile#change_password', as: 'change_password'
|
34
|
+
patch 'profile/change_password', to: 'profile#update_password', as: 'update_password'
|
35
|
+
|
36
|
+
# Two-factor authentication routes (via profile controller)
|
37
|
+
get 'profile/two_factor/setup', to: 'profile#two_factor_setup', as: 'two_factor_setup'
|
38
|
+
post 'profile/two_factor/enable', to: 'profile#two_factor_enable', as: 'two_factor_enable'
|
39
|
+
get 'profile/two_factor/backup_codes', to: 'profile#two_factor_backup_codes', as: 'two_factor_backup_codes'
|
40
|
+
post 'profile/two_factor/regenerate_backup_codes', to: 'profile#regenerate_backup_codes', as: 'two_factor_regenerate_backup_codes'
|
41
|
+
|
23
42
|
# Confirmation modal
|
24
43
|
get 'confirmation_modal', to: 'confirmation_modal#show'
|
25
44
|
|
data/lib/easy-admin-rails.rb
CHANGED
@@ -0,0 +1,156 @@
|
|
1
|
+
module EasyAdmin
|
2
|
+
module TwoFactorAuthentication
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
# Check if required gems are available
|
6
|
+
def self.available?
|
7
|
+
@available ||= begin
|
8
|
+
require 'rotp'
|
9
|
+
require 'rqrcode'
|
10
|
+
true
|
11
|
+
rescue LoadError
|
12
|
+
false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
included do
|
17
|
+
# Only add validations and callbacks if 2FA gems are available
|
18
|
+
if EasyAdmin::TwoFactorAuthentication.available?
|
19
|
+
validates :otp_secret, presence: true, if: :otp_required_for_login?
|
20
|
+
validates :otp_secret, uniqueness: true, allow_blank: true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def two_factor_available?
|
25
|
+
EasyAdmin::TwoFactorAuthentication.available?
|
26
|
+
end
|
27
|
+
|
28
|
+
def two_factor_enabled?
|
29
|
+
two_factor_available? && otp_required_for_login? && otp_secret.present?
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_otp_secret!
|
33
|
+
return false unless two_factor_available?
|
34
|
+
|
35
|
+
require 'rotp'
|
36
|
+
self.otp_secret = ROTP::Base32.random
|
37
|
+
save!
|
38
|
+
end
|
39
|
+
|
40
|
+
def current_otp
|
41
|
+
return nil unless two_factor_available? && otp_secret.present?
|
42
|
+
|
43
|
+
require 'rotp'
|
44
|
+
ROTP::TOTP.new(otp_secret, issuer: "EasyAdmin").now
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_and_consume_otp!(token)
|
48
|
+
return false unless two_factor_available? && otp_secret.present?
|
49
|
+
return false if token.blank?
|
50
|
+
|
51
|
+
require 'rotp'
|
52
|
+
|
53
|
+
totp = ROTP::TOTP.new(otp_secret, issuer: "EasyAdmin")
|
54
|
+
last_otp_at_timestamp = last_otp_at&.to_i
|
55
|
+
|
56
|
+
# Verify with 30-second drift tolerance and replay protection
|
57
|
+
if totp.verify(token.to_s, drift_behind: 30, drift_ahead: 30, after: last_otp_at_timestamp)
|
58
|
+
touch(:last_otp_at)
|
59
|
+
true
|
60
|
+
else
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate_backup_code!(code)
|
66
|
+
return false unless two_factor_available?
|
67
|
+
return false if code.blank? || otp_backup_codes.blank?
|
68
|
+
|
69
|
+
normalized_code = code.to_s.upcase.strip
|
70
|
+
|
71
|
+
if otp_backup_codes.include?(normalized_code)
|
72
|
+
invalidate_backup_code!(normalized_code)
|
73
|
+
true
|
74
|
+
else
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_backup_codes!
|
80
|
+
return false unless two_factor_available?
|
81
|
+
|
82
|
+
# Generate 10 backup codes (8 characters each)
|
83
|
+
codes = 10.times.map { SecureRandom.hex(4).upcase }
|
84
|
+
self.otp_backup_codes = codes
|
85
|
+
save!
|
86
|
+
codes
|
87
|
+
end
|
88
|
+
|
89
|
+
def invalidate_backup_code!(code)
|
90
|
+
return false unless two_factor_available?
|
91
|
+
|
92
|
+
normalized_code = code.to_s.upcase.strip
|
93
|
+
self.otp_backup_codes = otp_backup_codes.reject { |c| c == normalized_code }
|
94
|
+
save!
|
95
|
+
end
|
96
|
+
|
97
|
+
def backup_codes_remaining
|
98
|
+
two_factor_available? ? (otp_backup_codes&.length || 0) : 0
|
99
|
+
end
|
100
|
+
|
101
|
+
def provisioning_uri
|
102
|
+
return nil unless two_factor_available? && otp_secret.present?
|
103
|
+
|
104
|
+
require 'rotp'
|
105
|
+
ROTP::TOTP.new(otp_secret, issuer: "EasyAdmin").provisioning_uri(email)
|
106
|
+
end
|
107
|
+
|
108
|
+
def qr_code_svg(size: 200)
|
109
|
+
return nil unless two_factor_available?
|
110
|
+
|
111
|
+
uri = provisioning_uri
|
112
|
+
return nil if uri.blank?
|
113
|
+
|
114
|
+
require 'rqrcode'
|
115
|
+
|
116
|
+
qr_code = RQRCode::QRCode.new(uri)
|
117
|
+
qr_code.as_svg(
|
118
|
+
viewbox: true,
|
119
|
+
module_size: 4,
|
120
|
+
standalone: true,
|
121
|
+
use_path: true
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def enable_two_factor!
|
126
|
+
return false unless two_factor_available? && otp_secret.present?
|
127
|
+
|
128
|
+
update!(otp_required_for_login: true)
|
129
|
+
end
|
130
|
+
|
131
|
+
def disable_two_factor!
|
132
|
+
update!(
|
133
|
+
otp_required_for_login: false,
|
134
|
+
otp_secret: nil,
|
135
|
+
otp_backup_codes: nil,
|
136
|
+
last_otp_at: nil
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Check if user needs 2FA based on role requirements
|
141
|
+
def two_factor_required?
|
142
|
+
return false unless two_factor_available?
|
143
|
+
|
144
|
+
# Check if role requires 2FA (if role system exists)
|
145
|
+
if respond_to?(:role) && role.respond_to?(:require_two_factor?)
|
146
|
+
role.require_two_factor?
|
147
|
+
else
|
148
|
+
false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def should_enable_two_factor?
|
153
|
+
two_factor_required? && !two_factor_enabled?
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
data/lib/easy_admin/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
Two-Factor Authentication has been added to EasyAdmin!
|
4
|
+
|
5
|
+
To complete the setup, you'll need to:
|
6
|
+
|
7
|
+
1. Install the required gems for 2FA functionality:
|
8
|
+
|
9
|
+
gem 'rotp', '~> 6.3' # TOTP generation/validation
|
10
|
+
gem 'rqrcode', '~> 2.2' # QR code generation
|
11
|
+
|
12
|
+
2. Run the migration:
|
13
|
+
|
14
|
+
rails db:migrate
|
15
|
+
|
16
|
+
3. Restart your server
|
17
|
+
|
18
|
+
4. Two-factor authentication is now available in user settings!
|
19
|
+
|
20
|
+
Features:
|
21
|
+
• Optional 2FA (disabled by default)
|
22
|
+
• TOTP-based (compatible with Google Authenticator, Authy, etc.)
|
23
|
+
• QR code setup for easy configuration
|
24
|
+
• Backup codes for account recovery
|
25
|
+
• Admin can view/manage 2FA status for users
|
26
|
+
|
27
|
+
Without the optional gems, 2FA features will be gracefully hidden.
|
28
|
+
|
29
|
+
===============================================================================
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class AddTwoFactorToEasyAdminAdminUsers < ActiveRecord::Migration[<%= ActiveRecord::VERSION::MAJOR %>.<%= ActiveRecord::VERSION::MINOR %>]
|
2
|
+
def change
|
3
|
+
add_column :easy_admin_admin_users, :otp_secret, :string
|
4
|
+
add_column :easy_admin_admin_users, :otp_required_for_login, :boolean, default: false, null: false
|
5
|
+
add_column :easy_admin_admin_users, :otp_backup_codes, :json
|
6
|
+
add_column :easy_admin_admin_users, :last_otp_at, :datetime
|
7
|
+
|
8
|
+
add_index :easy_admin_admin_users, :otp_secret, unique: true
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module EasyAdmin
|
4
|
+
module Generators
|
5
|
+
class TwoFactorGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
|
8
|
+
desc "Add two-factor authentication fields to EasyAdmin AdminUser model"
|
9
|
+
|
10
|
+
def create_migration
|
11
|
+
timestamp = Time.current.utc.strftime("%Y%m%d%H%M%S")
|
12
|
+
migration_file = "#{timestamp}_add_two_factor_to_easy_admin_admin_users.rb"
|
13
|
+
|
14
|
+
template 'migration.rb', "db/migrate/#{migration_file}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def show_readme
|
18
|
+
readme "README" if behavior == :invoke
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy-admin-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Slaurmagan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -271,6 +271,10 @@ files:
|
|
271
271
|
- app/components/easy_admin/pagination_component.rb
|
272
272
|
- app/components/easy_admin/permissions/user_role_assignment_component.rb
|
273
273
|
- app/components/easy_admin/permissions/user_role_permissions_component.rb
|
274
|
+
- app/components/easy_admin/profile/change_password_modal_component.rb
|
275
|
+
- app/components/easy_admin/profile/profile_tab_component.rb
|
276
|
+
- app/components/easy_admin/profile/security_tab_component.rb
|
277
|
+
- app/components/easy_admin/profile/settings_component.rb
|
274
278
|
- app/components/easy_admin/quick_filters_component.rb
|
275
279
|
- app/components/easy_admin/resource_pagination_component.rb
|
276
280
|
- app/components/easy_admin/resources/index_component.rb
|
@@ -286,12 +290,16 @@ files:
|
|
286
290
|
- app/components/easy_admin/sidebar_component.rb
|
287
291
|
- app/components/easy_admin/turbo/response_component.rb
|
288
292
|
- app/components/easy_admin/turbo/stream_component.rb
|
293
|
+
- app/components/easy_admin/two_factor/backup_codes_component.rb
|
294
|
+
- app/components/easy_admin/two_factor/setup_component.rb
|
295
|
+
- app/components/easy_admin/two_factor/status_component.rb
|
289
296
|
- app/components/easy_admin/versions/diff_component.rb
|
290
297
|
- app/components/easy_admin/versions/diff_modal_component.rb
|
291
298
|
- app/components/easy_admin/versions/history_component.rb
|
292
299
|
- app/components/easy_admin/versions/pagination_component.rb
|
293
300
|
- app/components/easy_admin/versions/timeline_component.rb
|
294
301
|
- app/concerns/easy_admin/resource_versions.rb
|
302
|
+
- app/controllers/concerns/easy_admin/two_factor.rb
|
295
303
|
- app/controllers/easy_admin/application_controller.rb
|
296
304
|
- app/controllers/easy_admin/batch_actions_controller.rb
|
297
305
|
- app/controllers/easy_admin/concerns/belongs_to_editing.rb
|
@@ -304,6 +312,7 @@ files:
|
|
304
312
|
- app/controllers/easy_admin/dashboard_controller.rb
|
305
313
|
- app/controllers/easy_admin/dashboards_controller.rb
|
306
314
|
- app/controllers/easy_admin/passwords_controller.rb
|
315
|
+
- app/controllers/easy_admin/profile_controller.rb
|
307
316
|
- app/controllers/easy_admin/registrations_controller.rb
|
308
317
|
- app/controllers/easy_admin/resources_controller.rb
|
309
318
|
- app/controllers/easy_admin/row_actions_controller.rb
|
@@ -351,6 +360,7 @@ files:
|
|
351
360
|
- app/javascript/easy_admin/controllers/toggle_switch_controller.js
|
352
361
|
- app/javascript/easy_admin/controllers/turbo_stream_redirect.js
|
353
362
|
- app/javascript/easy_admin/controllers/version_revert_controller.js
|
363
|
+
- app/javascript/easy_admin/controllers/vertical_tabs_controller.js
|
354
364
|
- app/models/easy_admin/admin_user.rb
|
355
365
|
- app/models/easy_admin/application_record.rb
|
356
366
|
- app/policies/admin_user_policy.rb
|
@@ -366,6 +376,18 @@ files:
|
|
366
376
|
- app/views/easy_admin/dashboards/show.turbo_stream.erb
|
367
377
|
- app/views/easy_admin/passwords/edit.html.erb
|
368
378
|
- app/views/easy_admin/passwords/new.html.erb
|
379
|
+
- app/views/easy_admin/profile/backup_codes_regenerated.turbo_stream.erb
|
380
|
+
- app/views/easy_admin/profile/change_password.html.erb
|
381
|
+
- app/views/easy_admin/profile/index.html.erb
|
382
|
+
- app/views/easy_admin/profile/password_error.turbo_stream.erb
|
383
|
+
- app/views/easy_admin/profile/password_invalid_current.turbo_stream.erb
|
384
|
+
- app/views/easy_admin/profile/password_updated.turbo_stream.erb
|
385
|
+
- app/views/easy_admin/profile/two_factor_backup_codes.html.erb
|
386
|
+
- app/views/easy_admin/profile/two_factor_enabled.turbo_stream.erb
|
387
|
+
- app/views/easy_admin/profile/two_factor_invalid_code.turbo_stream.erb
|
388
|
+
- app/views/easy_admin/profile/two_factor_not_enabled.turbo_stream.erb
|
389
|
+
- app/views/easy_admin/profile/two_factor_setup.html.erb
|
390
|
+
- app/views/easy_admin/profile/two_factor_unavailable.turbo_stream.erb
|
369
391
|
- app/views/easy_admin/registrations/new.html.erb
|
370
392
|
- app/views/easy_admin/resources/_redirect.turbo_stream.erb
|
371
393
|
- app/views/easy_admin/resources/_table_rows.html.erb
|
@@ -382,6 +404,8 @@ files:
|
|
382
404
|
- app/views/easy_admin/resources/show.html.erb
|
383
405
|
- app/views/easy_admin/resources/update_belongs_to_attached.turbo_stream.erb
|
384
406
|
- app/views/easy_admin/sessions/new.html.erb
|
407
|
+
- app/views/easy_admin/sessions/two_factor_verification.html.erb
|
408
|
+
- app/views/easy_admin/sessions/verify_2fa_error.turbo_stream.erb
|
385
409
|
- app/views/easy_admin/settings/_form.html.erb
|
386
410
|
- app/views/easy_admin/settings/index.html.erb
|
387
411
|
- app/views/layouts/easy_admin/application.html.erb
|
@@ -424,6 +448,7 @@ files:
|
|
424
448
|
- lib/easy_admin/resource/show_builder.rb
|
425
449
|
- lib/easy_admin/resource_modules.rb
|
426
450
|
- lib/easy_admin/resource_registry.rb
|
451
|
+
- lib/easy_admin/two_factor_authentication.rb
|
427
452
|
- lib/easy_admin/types/json_type.rb
|
428
453
|
- lib/easy_admin/version.rb
|
429
454
|
- lib/easy_admin/versioning.rb
|
@@ -454,6 +479,9 @@ files:
|
|
454
479
|
- lib/generators/easy_admin/templates/devise.rb
|
455
480
|
- lib/generators/easy_admin/templates/easy_admin.rb
|
456
481
|
- lib/generators/easy_admin/templates/resource.rb
|
482
|
+
- lib/generators/easy_admin/two_factor/templates/README
|
483
|
+
- lib/generators/easy_admin/two_factor/templates/migration.rb
|
484
|
+
- lib/generators/easy_admin/two_factor/two_factor_generator.rb
|
457
485
|
- lib/tasks/easy_admin_tasks.rake
|
458
486
|
homepage: https://github.com/Slaurmagan/easy-admin
|
459
487
|
licenses:
|