pages_core 3.13.0 → 3.14.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/VERSION +1 -1
- data/app/assets/builds/pages_core/admin-dist.js +1 -1
- data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
- data/app/assets/builds/pages_core/admin.css +27 -4
- data/app/assets/stylesheets/pages_core/admin/components/login.css +0 -6
- data/app/assets/stylesheets/pages_core/admin/components/totp.css +26 -0
- data/app/controllers/admin/account_recoveries_controller.rb +87 -0
- data/app/controllers/admin/invites_controller.rb +3 -2
- data/app/controllers/admin/otp_secrets_controller.rb +45 -0
- data/app/controllers/admin/recovery_codes_controller.rb +32 -0
- data/app/controllers/admin/sessions_controller.rb +65 -0
- data/app/controllers/admin/users_controller.rb +2 -8
- data/app/controllers/concerns/pages_core/authentication.rb +12 -10
- data/app/controllers/pages_core/admin_controller.rb +1 -1
- data/app/helpers/pages_core/admin/admin_helper.rb +11 -0
- data/app/javascript/index.ts +0 -2
- data/app/mailers/admin_mailer.rb +2 -2
- data/app/models/concerns/pages_core/has_otp.rb +27 -0
- data/app/models/otp_secret.rb +101 -0
- data/app/models/user.rb +15 -37
- data/app/policies/user_policy.rb +4 -0
- data/app/views/admin/account_recoveries/new.html.erb +22 -0
- data/app/views/admin/account_recoveries/show.html.erb +37 -0
- data/app/views/admin/invites/show.html.erb +1 -1
- data/app/views/admin/otp_secrets/create.html.erb +7 -0
- data/app/views/admin/otp_secrets/new.html.erb +60 -0
- data/app/views/admin/recovery_codes/_codes.html.erb +14 -0
- data/app/views/admin/recovery_codes/create.html.erb +7 -0
- data/app/views/admin/recovery_codes/new.html.erb +11 -0
- data/app/views/admin/sessions/_otp_form.html.erb +13 -0
- data/app/views/admin/sessions/new.html.erb +33 -0
- data/app/views/admin/sessions/verify_otp.html.erb +19 -0
- data/app/views/admin/users/edit.html.erb +31 -1
- data/app/views/admin/users/new.html.erb +1 -1
- data/app/views/admin_mailer/account_recovery.text.erb +10 -0
- data/app/views/layouts/admin/_header.html.erb +1 -1
- data/app/views/layouts/admin/_toast.html.erb +12 -0
- data/app/views/layouts/admin.html.erb +1 -1
- data/config/locales/en.yml +11 -3
- data/config/routes.rb +11 -6
- data/db/migrate/20240126160700_add_2fa_fields.rb +22 -0
- data/db/migrate/20240129201300_remove_password_reset_tokens.rb +13 -0
- data/lib/pages_core.rb +6 -0
- metadata +51 -9
- data/app/controllers/admin/password_resets_controller.rb +0 -85
- data/app/controllers/sessions_controller.rb +0 -27
- data/app/javascript/controllers/LoginController.ts +0 -32
- data/app/models/password_reset_token.rb +0 -34
- data/app/views/admin/password_resets/show.html.erb +0 -21
- data/app/views/admin/users/login.html.erb +0 -65
- data/app/views/admin_mailer/password_reset.text.erb +0 -11
@@ -0,0 +1,22 @@
|
|
1
|
+
<% content_for :page_title, "Account recovery" %>
|
2
|
+
<% content_for :page_description, "Account recovery" %>
|
3
|
+
|
4
|
+
<%= form_tag admin_account_recovery_path do %>
|
5
|
+
<h2>
|
6
|
+
Forgot your password or lost your authenticator?
|
7
|
+
</h2>
|
8
|
+
<p>
|
9
|
+
Don't worry, it happens.
|
10
|
+
Enter your email address below, and we'll send you a link where you
|
11
|
+
can recover your account.
|
12
|
+
</p>
|
13
|
+
<div class="field">
|
14
|
+
<label for="email">Email address</label>
|
15
|
+
<%= text_field_tag(:email, "", autocomplete: "email", autofocus: true) %>
|
16
|
+
</div>
|
17
|
+
<p>
|
18
|
+
<button type="submit">
|
19
|
+
Send
|
20
|
+
</button>
|
21
|
+
</p>
|
22
|
+
<% end %>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<% content_for :page_title, "Account recovery" %>
|
2
|
+
<% content_for :page_description, "Please choose a new password to proceed" %>
|
3
|
+
<% content_for :body_class, "login" %>
|
4
|
+
|
5
|
+
<div class="login-form">
|
6
|
+
<%= form_for(@user,
|
7
|
+
url: admin_account_recovery_path,
|
8
|
+
builder: PagesCore::Admin::FormBuilder,
|
9
|
+
class: 'form') do |f| %>
|
10
|
+
<%= hidden_field_tag :token, @token %>
|
11
|
+
<%= f.labelled_password_field(:password,
|
12
|
+
autofocus: true,
|
13
|
+
autocomplete: "new-password") %>
|
14
|
+
<%= f.labelled_password_field(:password_confirmation,
|
15
|
+
autocomplete: "new-password") %>
|
16
|
+
|
17
|
+
<% if @user.otp_enabled? %>
|
18
|
+
<div class="field">
|
19
|
+
<label for="otp">6 digit code or recovery code</label>
|
20
|
+
<%= text_field_tag(:otp, "",
|
21
|
+
autocomplete: "one-time-code",
|
22
|
+
size: 6) %>
|
23
|
+
</div>
|
24
|
+
<p>
|
25
|
+
Lost your authenticator device? You can use one of your
|
26
|
+
emergency recovery codes instead.
|
27
|
+
</p>
|
28
|
+
<% end %>
|
29
|
+
|
30
|
+
<p>
|
31
|
+
<button type="submit">
|
32
|
+
Change password
|
33
|
+
</button>
|
34
|
+
or <%= link_to "Return to login screen", admin_login_path %>
|
35
|
+
</p>
|
36
|
+
<% end %>
|
37
|
+
</div>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<%= f.labelled_text_field :email, autocomplete: "email" %>
|
15
15
|
<%= f.labelled_password_field(:password,
|
16
16
|
autocomplete: "new-password") %>
|
17
|
-
<%= f.labelled_password_field(:
|
17
|
+
<%= f.labelled_password_field(:password_confirmation,
|
18
18
|
autocomplete: "new-password") %>
|
19
19
|
<p>
|
20
20
|
<button type="submit">
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<% content_for :page_title, "Enable 2FA" %>
|
2
|
+
<% content_for :page_description, "Enable two-factor authentication" %>
|
3
|
+
|
4
|
+
<%= form_tag(admin_otp_secret_path, method: :post, class: "totp-enrollment") do |f| %>
|
5
|
+
<h2>
|
6
|
+
Scan the QR-code
|
7
|
+
</h2>
|
8
|
+
<p>
|
9
|
+
Use an authenticator app or browser extension to scan the QR code below.<br>
|
10
|
+
Don't have one? Some options are
|
11
|
+
<%= link_to("1Password", "https://1password.com/") %>,
|
12
|
+
<%= link_to("LastPass Authenticator", "https://www.lastpass.com/") %>,
|
13
|
+
<%= link_to("Microsoft Authenticator",
|
14
|
+
"https://www.microsoft.com/en-us/security/mobile-authenticator-app") %>
|
15
|
+
or
|
16
|
+
<%= link_to("Google Authenticator",
|
17
|
+
"https://support.google.com/accounts/answer/1066447") %>.
|
18
|
+
</p>
|
19
|
+
|
20
|
+
|
21
|
+
<div class="qr-code">
|
22
|
+
<%= qr_code(@otp_secret.provisioning_uri) %>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<p>
|
26
|
+
If you are unable to scan the code, you can enter the following
|
27
|
+
info instead:
|
28
|
+
</p>
|
29
|
+
|
30
|
+
<p>
|
31
|
+
<b>Account name:</b><br>
|
32
|
+
<%= @otp_secret.account_name %>
|
33
|
+
</p>
|
34
|
+
<p>
|
35
|
+
<b>Secret:</b><br>
|
36
|
+
<span class="otp-secret">
|
37
|
+
<%= @otp_secret.secret %>
|
38
|
+
</span>
|
39
|
+
</p>
|
40
|
+
|
41
|
+
<h2>
|
42
|
+
Enter the code from the app
|
43
|
+
</h2>
|
44
|
+
|
45
|
+
<div class="field">
|
46
|
+
<label for="otp">6 digit code</label>
|
47
|
+
<%= text_field_tag(:otp, "",
|
48
|
+
autofocus: true,
|
49
|
+
autocomplete: "one-time-code",
|
50
|
+
size: 6) %>
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<%= hidden_field_tag :signed_message, @otp_secret.signed_message %>
|
54
|
+
|
55
|
+
<p>
|
56
|
+
<button type="submit">
|
57
|
+
Verify
|
58
|
+
</button>
|
59
|
+
</p>
|
60
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<h2>
|
2
|
+
Recovery codes
|
3
|
+
</h2>
|
4
|
+
<p>
|
5
|
+
Please save the recovery codes below in a safe place, ideally
|
6
|
+
using a secure password manager.<br>
|
7
|
+
Without them, you will lose access to your account if you lose your device.
|
8
|
+
</p>
|
9
|
+
|
10
|
+
<ul class="recovery-codes">
|
11
|
+
<% recovery_codes.each do |c| %>
|
12
|
+
<li><%= c %></li>
|
13
|
+
<% end %>
|
14
|
+
</ul>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% content_for :page_title, "New recovery codes" %>
|
2
|
+
<% content_for :page_description, "Generate new recovery codes" %>
|
3
|
+
|
4
|
+
<%= form_tag(admin_recovery_codes_path, method: :post) do |f| %>
|
5
|
+
<%= render(partial: "admin/sessions/otp_form") %>
|
6
|
+
<p>
|
7
|
+
<button type="submit">
|
8
|
+
Verify
|
9
|
+
</button>
|
10
|
+
</p>
|
11
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<h2>
|
2
|
+
Two-factor authentication
|
3
|
+
</h2>
|
4
|
+
<p>
|
5
|
+
Enter a one-time code from your authenticator app to proceed.
|
6
|
+
</p>
|
7
|
+
<div class="field">
|
8
|
+
<label for="otp">6 digit code</label>
|
9
|
+
<%= text_field_tag(:otp, "",
|
10
|
+
autofocus: true,
|
11
|
+
autocomplete: "one-time-code",
|
12
|
+
size: 6) %>
|
13
|
+
</div>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<% content_for :page_title, "Sign in" %>
|
2
|
+
<% content_for(:page_description,
|
3
|
+
"Please enter your email address and password to sign in") %>
|
4
|
+
<% content_for :body_class, "login" %>
|
5
|
+
|
6
|
+
<% content_for :sidebar do %>
|
7
|
+
<h2>Please note</h2>
|
8
|
+
<p>
|
9
|
+
Please contact support if you experience problems logging in or using Pages.
|
10
|
+
</p>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<div class="login-form">
|
14
|
+
<%= form_tag admin_session_path do %>
|
15
|
+
<p>
|
16
|
+
<label>Email address</label>
|
17
|
+
<%= text_field_tag(:email, "", autocomplete: "email") %>
|
18
|
+
</p>
|
19
|
+
<p>
|
20
|
+
<label>Password</label>
|
21
|
+
<%= password_field_tag(:password, "", autocomplete: "current-password") %>
|
22
|
+
</p>
|
23
|
+
<p>
|
24
|
+
<button type="submit">Sign in</button>
|
25
|
+
</p>
|
26
|
+
<ul>
|
27
|
+
<li>
|
28
|
+
<%= link_to("<b>Help!</b> I forgot my password!".html_safe,
|
29
|
+
new_admin_account_recovery_path) %>
|
30
|
+
</li>
|
31
|
+
</ul>
|
32
|
+
<% end %>
|
33
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<% content_for :page_title, "Two-factor authentication" %>
|
2
|
+
<% content_for :page_description, "Two-factor authentication" %>
|
3
|
+
|
4
|
+
<%= form_tag(verify_otp_admin_session_path, method: :post) do |f| %>
|
5
|
+
<%= hidden_field_tag :signed_user_id, @signed_user_id %>
|
6
|
+
<%= render(partial: "admin/sessions/otp_form") %>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
<button type="submit">
|
10
|
+
Verify
|
11
|
+
</button>
|
12
|
+
</p>
|
13
|
+
|
14
|
+
<p>
|
15
|
+
Lost your authenticator device?
|
16
|
+
<%= link_to("Recover your account here",
|
17
|
+
new_admin_account_recovery_path) %>.
|
18
|
+
</p>
|
19
|
+
<% end %>
|
@@ -31,12 +31,42 @@
|
|
31
31
|
<% if policy(@user).change_password? %>
|
32
32
|
<h2>Password</h2>
|
33
33
|
<%= f.labelled_password_field :password, 'Change password' %>
|
34
|
-
<%= f.labelled_password_field :
|
34
|
+
<%= f.labelled_password_field :password_confirmation, 'Confirm password' %>
|
35
35
|
<p>
|
36
36
|
Leave the password blank if you do not wish to change the password.
|
37
37
|
</p>
|
38
38
|
<% end %>
|
39
39
|
|
40
|
+
<% if policy(@user).otp? %>
|
41
|
+
<h2>Two-factor authentication</h2>
|
42
|
+
<% if @user.otp_enabled? %>
|
43
|
+
<p>
|
44
|
+
Two-factor authentication has been enabled.
|
45
|
+
<%= link_to("Disable",
|
46
|
+
admin_otp_secret_path,
|
47
|
+
class: :delete,
|
48
|
+
method: :delete,
|
49
|
+
data: { confirm: "Are you sure you want to disable 2FA?" }) %>
|
50
|
+
</p>
|
51
|
+
<p>
|
52
|
+
|
53
|
+
You have
|
54
|
+
<%= t("pages_core.recovery_codes",
|
55
|
+
count: @user.hashed_recovery_codes.length) %>
|
56
|
+
remaining.
|
57
|
+
<%= link_to("Generate new codes", new_admin_recovery_codes_path) %>
|
58
|
+
</p>
|
59
|
+
<% else %>
|
60
|
+
<p>
|
61
|
+
Protect your account with an additional layer of security by
|
62
|
+
requiring an authentication app to sign in.
|
63
|
+
</p>
|
64
|
+
<p>
|
65
|
+
<%= link_to("Enable 2FA", new_admin_otp_secret_path) %>
|
66
|
+
</p>
|
67
|
+
<% end %>
|
68
|
+
<% end %>
|
69
|
+
|
40
70
|
<%= render partial: "access_control", locals: { user: @user, f: f } %>
|
41
71
|
|
42
72
|
<p>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<%= f.labelled_text_field(:email, autocomplete: "email") %>
|
12
12
|
<%= f.labelled_password_field(:password,
|
13
13
|
autocomplete: "new-password") %>
|
14
|
-
<%= f.labelled_password_field(:
|
14
|
+
<%= f.labelled_password_field(:password_confirmation,
|
15
15
|
autocomplete: "new-password") %>
|
16
16
|
|
17
17
|
<p>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Hi, <%= @user.name %>!
|
2
|
+
|
3
|
+
We've received a request to recover your account on <%= PagesCore.config(:site_name) %>.
|
4
|
+
|
5
|
+
Please click the following link to continue:
|
6
|
+
<%= @url %>
|
7
|
+
|
8
|
+
The link will expire in 24 hours.
|
9
|
+
|
10
|
+
If you do not want to recover your password, please ignore this email.
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<% if logged_in? %>
|
11
11
|
<div class="user">
|
12
12
|
Hello, <%= link_to(current_user.name, admin_user_url(current_user)) %>
|
13
|
-
<%= link_to("Log out",
|
13
|
+
<%= link_to("Log out", admin_session_path, method: "delete") %>
|
14
14
|
</div>
|
15
15
|
<% end %>
|
16
16
|
<nav class="tabs">
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= react_component "Toast", { notice: flash[:notice], error: flash[:error] } %>
|
2
|
+
<% if Rails.env.test? && flash.any? %>
|
3
|
+
<div class="flash-test-helper">
|
4
|
+
<% %i[notice error].each do |type| %>
|
5
|
+
<% if flash[type] || true %>
|
6
|
+
<div class="<%= type %>">
|
7
|
+
<%= flash[type] %>
|
8
|
+
</div>
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
data/config/locales/en.yml
CHANGED
@@ -28,13 +28,21 @@ en:
|
|
28
28
|
The provided email address and password combination was not valid
|
29
29
|
invite_expired: This invite is no longer valid.
|
30
30
|
logged_out: You have been logged out
|
31
|
-
|
31
|
+
otp:
|
32
|
+
already_enabled: 2FA has already been enabled
|
33
|
+
disabled: 2FA has been disabled
|
34
|
+
invalid_code: Invalid 2FA code
|
35
|
+
required: 2FA is required for this
|
36
|
+
account_recovery:
|
32
37
|
changed: Your password has been changed
|
33
|
-
|
34
|
-
invalid_request: Invalid password reset request
|
38
|
+
invalid_request: This link is no longer valid
|
35
39
|
not_found: Couldn't find a user with that email address
|
36
40
|
sent: An email with further instructions has been sent
|
37
41
|
problems_saving: There were problems saving your changes
|
42
|
+
recovery_codes:
|
43
|
+
zero: "no recovery codes"
|
44
|
+
one: "one recovery code"
|
45
|
+
other: "%{count} recovery codes"
|
38
46
|
templates:
|
39
47
|
default:
|
40
48
|
blocks:
|
data/config/routes.rb
CHANGED
@@ -33,9 +33,6 @@ Rails.application.routes.draw do
|
|
33
33
|
get "pages/:locale/*glob" => redirect("/%{locale}/pages/%{glob}"),
|
34
34
|
locale: /\w\w\w/
|
35
35
|
|
36
|
-
# Authentication
|
37
|
-
resource :session, only: %i[create destroy]
|
38
|
-
|
39
36
|
# Sitemap
|
40
37
|
resource :sitemap, only: [:show]
|
41
38
|
|
@@ -51,9 +48,9 @@ Rails.application.routes.draw do
|
|
51
48
|
end
|
52
49
|
|
53
50
|
# Password resets
|
54
|
-
|
55
|
-
controller :
|
56
|
-
get "/
|
51
|
+
resource :account_recovery
|
52
|
+
controller :account_recoveries do
|
53
|
+
get "/account_recovery/:token" => :show, as: :account_recovery_with_token
|
57
54
|
end
|
58
55
|
|
59
56
|
# Attachments
|
@@ -76,6 +73,14 @@ Rails.application.routes.draw do
|
|
76
73
|
# Categories
|
77
74
|
resources :categories
|
78
75
|
|
76
|
+
# Authentication
|
77
|
+
resource :session, only: %i[create destroy] do
|
78
|
+
member { post :verify_otp }
|
79
|
+
end
|
80
|
+
resource :otp_secret, only: %i[new create destroy]
|
81
|
+
resource :recovery_codes, only: %i[new create]
|
82
|
+
get "login" => "sessions#new", as: "login"
|
83
|
+
|
79
84
|
# Pages
|
80
85
|
scope ":locale" do
|
81
86
|
resources :news,
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Add2faFields < ActiveRecord::Migration[7.0]
|
4
|
+
def change
|
5
|
+
change_table :users do |t|
|
6
|
+
t.boolean :otp_enabled, null: false, default: false
|
7
|
+
t.string :otp_secret
|
8
|
+
t.datetime :last_otp_at
|
9
|
+
t.jsonb :hashed_recovery_codes, null: false, default: []
|
10
|
+
t.string :session_token
|
11
|
+
end
|
12
|
+
|
13
|
+
rename_column :users, :hashed_password, :password_digest
|
14
|
+
|
15
|
+
reversible do |dir|
|
16
|
+
dir.up do
|
17
|
+
User.find_each { |u| u.update(session_token: SecureRandom.hex(32)) }
|
18
|
+
change_column_null :users, :session_token, false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RemovePasswordResetTokens < ActiveRecord::Migration[7.0]
|
4
|
+
def change
|
5
|
+
drop_table :password_reset_tokens do |t|
|
6
|
+
t.integer :user_id
|
7
|
+
t.string :token
|
8
|
+
t.datetime :expires_at
|
9
|
+
t.datetime :created_at
|
10
|
+
t.datetime :updated_at
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/pages_core.rb
CHANGED
@@ -32,6 +32,8 @@ require "pg_search"
|
|
32
32
|
require "progress_bar"
|
33
33
|
require "rails_i18n"
|
34
34
|
require "RedCloth"
|
35
|
+
require "rotp"
|
36
|
+
require "rqrcode"
|
35
37
|
require "sass-rails"
|
36
38
|
require "typhoeus"
|
37
39
|
require "will_paginate"
|
@@ -83,5 +85,9 @@ module PagesCore
|
|
83
85
|
end
|
84
86
|
end
|
85
87
|
alias config configuration
|
88
|
+
|
89
|
+
def reset_configuration!
|
90
|
+
@configuration = PagesCore::Configuration::Pages.new
|
91
|
+
end
|
86
92
|
end
|
87
93
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pages_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Inge Jørgensen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -206,6 +206,34 @@ dependencies:
|
|
206
206
|
- - "~>"
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: 4.3.2
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: rotp
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: 6.3.0
|
216
|
+
type: :runtime
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 6.3.0
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: rqrcode
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :runtime
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
209
237
|
- !ruby/object:Gem::Dependency
|
210
238
|
name: tty-table
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -377,6 +405,7 @@ files:
|
|
377
405
|
- app/assets/stylesheets/pages_core/admin/components/textarea.css
|
378
406
|
- app/assets/stylesheets/pages_core/admin/components/toast.css
|
379
407
|
- app/assets/stylesheets/pages_core/admin/components/toolbar.css
|
408
|
+
- app/assets/stylesheets/pages_core/admin/components/totp.css
|
380
409
|
- app/assets/stylesheets/pages_core/admin/controllers/pages.css
|
381
410
|
- app/assets/stylesheets/pages_core/admin/controllers/users.css
|
382
411
|
- app/assets/stylesheets/pages_core/admin/vars.css
|
@@ -388,14 +417,17 @@ files:
|
|
388
417
|
- app/controller_dummies/page_files_controller.rb
|
389
418
|
- app/controller_dummies/pages_controller.rb
|
390
419
|
- app/controller_dummies/sitemaps_controller.rb
|
420
|
+
- app/controllers/admin/account_recoveries_controller.rb
|
391
421
|
- app/controllers/admin/attachments_controller.rb
|
392
422
|
- app/controllers/admin/calendars_controller.rb
|
393
423
|
- app/controllers/admin/categories_controller.rb
|
394
424
|
- app/controllers/admin/images_controller.rb
|
395
425
|
- app/controllers/admin/invites_controller.rb
|
396
426
|
- app/controllers/admin/news_controller.rb
|
427
|
+
- app/controllers/admin/otp_secrets_controller.rb
|
397
428
|
- app/controllers/admin/pages_controller.rb
|
398
|
-
- app/controllers/admin/
|
429
|
+
- app/controllers/admin/recovery_codes_controller.rb
|
430
|
+
- app/controllers/admin/sessions_controller.rb
|
399
431
|
- app/controllers/admin/users_controller.rb
|
400
432
|
- app/controllers/concerns/pages_core/admin/persistent_params.rb
|
401
433
|
- app/controllers/concerns/pages_core/authentication.rb
|
@@ -416,7 +448,6 @@ files:
|
|
416
448
|
- app/controllers/pages_core/frontend_controller.rb
|
417
449
|
- app/controllers/pages_core/images_controller.rb
|
418
450
|
- app/controllers/pages_core/sitemaps_controller.rb
|
419
|
-
- app/controllers/sessions_controller.rb
|
420
451
|
- app/formatters/pages_core/html_formatter.rb
|
421
452
|
- app/formatters/pages_core/image_embedder.rb
|
422
453
|
- app/formatters/pages_core/link_renderer.rb
|
@@ -492,7 +523,6 @@ files:
|
|
492
523
|
- app/javascript/components/drag/useDragUploader.ts
|
493
524
|
- app/javascript/components/drag/useDraggable.ts
|
494
525
|
- app/javascript/controllers/EditPageController.ts
|
495
|
-
- app/javascript/controllers/LoginController.ts
|
496
526
|
- app/javascript/controllers/MainController.ts
|
497
527
|
- app/javascript/controllers/PageOptionsController.js
|
498
528
|
- app/javascript/features/RichText.tsx
|
@@ -512,6 +542,7 @@ files:
|
|
512
542
|
- app/models/attachment.rb
|
513
543
|
- app/models/autopublisher.rb
|
514
544
|
- app/models/category.rb
|
545
|
+
- app/models/concerns/pages_core/has_otp.rb
|
515
546
|
- app/models/concerns/pages_core/has_roles.rb
|
516
547
|
- app/models/concerns/pages_core/humanizable_param.rb
|
517
548
|
- app/models/concerns/pages_core/page_model/attachments.rb
|
@@ -532,6 +563,7 @@ files:
|
|
532
563
|
- app/models/image.rb
|
533
564
|
- app/models/invite.rb
|
534
565
|
- app/models/invite_role.rb
|
566
|
+
- app/models/otp_secret.rb
|
535
567
|
- app/models/page.rb
|
536
568
|
- app/models/page_builder.rb
|
537
569
|
- app/models/page_category.rb
|
@@ -539,7 +571,6 @@ files:
|
|
539
571
|
- app/models/page_file.rb
|
540
572
|
- app/models/page_image.rb
|
541
573
|
- app/models/page_path.rb
|
542
|
-
- app/models/password_reset_token.rb
|
543
574
|
- app/models/role.rb
|
544
575
|
- app/models/search_document.rb
|
545
576
|
- app/models/tag.rb
|
@@ -563,6 +594,8 @@ files:
|
|
563
594
|
- app/services/pages_core/create_user_service.rb
|
564
595
|
- app/services/pages_core/destroy_invite_service.rb
|
565
596
|
- app/services/pages_core/invite_service.rb
|
597
|
+
- app/views/admin/account_recoveries/new.html.erb
|
598
|
+
- app/views/admin/account_recoveries/show.html.erb
|
566
599
|
- app/views/admin/calendars/_sidebar.html.erb
|
567
600
|
- app/views/admin/calendars/show.html.erb
|
568
601
|
- app/views/admin/images/show.json.jbuilder
|
@@ -570,6 +603,8 @@ files:
|
|
570
603
|
- app/views/admin/invites/show.html.erb
|
571
604
|
- app/views/admin/news/_sidebar.html.erb
|
572
605
|
- app/views/admin/news/index.html.erb
|
606
|
+
- app/views/admin/otp_secrets/create.html.erb
|
607
|
+
- app/views/admin/otp_secrets/new.html.erb
|
573
608
|
- app/views/admin/pages/_edit_content.html.erb
|
574
609
|
- app/views/admin/pages/_edit_files.html.erb
|
575
610
|
- app/views/admin/pages/_edit_images.html.erb
|
@@ -583,18 +618,22 @@ files:
|
|
583
618
|
- app/views/admin/pages/index.html.erb
|
584
619
|
- app/views/admin/pages/new.html.erb
|
585
620
|
- app/views/admin/pages/search.html.erb
|
586
|
-
- app/views/admin/
|
621
|
+
- app/views/admin/recovery_codes/_codes.html.erb
|
622
|
+
- app/views/admin/recovery_codes/create.html.erb
|
623
|
+
- app/views/admin/recovery_codes/new.html.erb
|
624
|
+
- app/views/admin/sessions/_otp_form.html.erb
|
625
|
+
- app/views/admin/sessions/new.html.erb
|
626
|
+
- app/views/admin/sessions/verify_otp.html.erb
|
587
627
|
- app/views/admin/users/_access_control.html.erb
|
588
628
|
- app/views/admin/users/_list.html.erb
|
589
629
|
- app/views/admin/users/deactivated.html.erb
|
590
630
|
- app/views/admin/users/edit.html.erb
|
591
631
|
- app/views/admin/users/index.html.erb
|
592
|
-
- app/views/admin/users/login.html.erb
|
593
632
|
- app/views/admin/users/new.html.erb
|
594
633
|
- app/views/admin/users/new_password.html.erb
|
595
634
|
- app/views/admin/users/show.html.erb
|
635
|
+
- app/views/admin_mailer/account_recovery.text.erb
|
596
636
|
- app/views/admin_mailer/invite.text.erb
|
597
|
-
- app/views/admin_mailer/password_reset.text.erb
|
598
637
|
- app/views/errors/401.html.erb
|
599
638
|
- app/views/errors/403.html.erb
|
600
639
|
- app/views/errors/404.html.erb
|
@@ -606,6 +645,7 @@ files:
|
|
606
645
|
- app/views/layouts/admin.html.erb
|
607
646
|
- app/views/layouts/admin/_header.html.erb
|
608
647
|
- app/views/layouts/admin/_page_header.html.erb
|
648
|
+
- app/views/layouts/admin/_toast.html.erb
|
609
649
|
- app/views/layouts/errors.html.erb
|
610
650
|
- app/views/sitemaps/show.xml.builder
|
611
651
|
- config/locales/en.yml
|
@@ -615,6 +655,8 @@ files:
|
|
615
655
|
- db/migrate/20210209151400_create_search_configurations.rb
|
616
656
|
- db/migrate/20210210235200_create_search_documents.rb
|
617
657
|
- db/migrate/20220615160300_remove_username.rb
|
658
|
+
- db/migrate/20240126160700_add_2fa_fields.rb
|
659
|
+
- db/migrate/20240129201300_remove_password_reset_tokens.rb
|
618
660
|
- lib/pages_core.rb
|
619
661
|
- lib/pages_core/admin_menu_item.rb
|
620
662
|
- lib/pages_core/archive_finder.rb
|