pages_core 3.13.0 → 3.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|