alchemy-devise 8.4.0 → 8.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d09ae141f2a8fffa21c51258fa5d20d1b8b6d6b2dc93b5ace87d1be54e77652
4
- data.tar.gz: d4671dc0ea62d25ddc2744025636e41fb3d447dc5a00a80c1106ab7298cd7a4e
3
+ metadata.gz: 6435b830a21aa21f4699a8417210a8005824974fb53ec4499a8bda06b80f4332
4
+ data.tar.gz: a9ef36882072e636046507157e41b07636a292030282e3c992997203f227a53c
5
5
  SHA512:
6
- metadata.gz: 3f2410f1c117abdfe91e7dc7b2b45ddf3a4a2428e08c78ed17cab964ecd60910a33dd1cd49f1805d58e701345549593a2f4dfdd75cc0823fba3c60e9c605df02
7
- data.tar.gz: 6ad17f1c4cc4b7775185c6417e5d7cd7dc53ce768dc0dc0fe29f9d12db4b928a15c8bf93b394e940f0237ba818595d4f2534c41fabd8b2989e42068f691b9779
6
+ metadata.gz: b87c4614c0048f138e2305cf3b0ddd9c196386bbf25f9e4aea1927c24d5de8a14fe626a03e657d33bea518f929e8bb1dad6a10878042a15aba5629d1e9a4055b
7
+ data.tar.gz: 21a224e9ad51dbfad4d6a15191586b5d4e3ebef0eef11a82f4422e9d97659703d3bf48eb2139a0642c461aa5520940b78e09cc6816a503d0991d698b06940493
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 8.4.2 (2026-10-22)
4
+
5
+ <!-- Release notes generated using configuration in .github/release.yml at 8.4-stable -->
6
+
7
+ ## What's Changed
8
+ ### New Features
9
+ * [8.4-stable] Merge pull request #312 from AlchemyCMS/stepup-auth-role-assignment by @alchemycms-bot[bot] in https://github.com/AlchemyCMS/alchemy-devise/pull/313
10
+ ### Other Changes
11
+ * [8.4-stable] Merge pull request #316 from AlchemyCMS/fix-ransack-6-user-search by @alchemycms-bot[bot] in https://github.com/AlchemyCMS/alchemy-devise/pull/317
12
+ * [8.4-stable] Merge pull request #320 from AlchemyCMS/fix-csp-test by @alchemycms-bot[bot] in https://github.com/AlchemyCMS/alchemy-devise/pull/321
13
+
14
+
15
+ **Full Changelog**: https://github.com/AlchemyCMS/alchemy-devise/compare/v8.4.1...v8.4.2
16
+
17
+ ## 8.4.1 (2026-09-23)
18
+
19
+ <!-- Release notes generated using configuration in .github/release.yml at 8.4-stable -->
20
+
21
+ ## What's Changed
22
+ ### Other Changes
23
+ * [8.4-stable] Merge pull request #306 from AlchemyCMS/fix-login-css-relative-color by @alchemycms-bot[bot] in https://github.com/AlchemyCMS/alchemy-devise/pull/307
24
+ * [8.4-stable] Merge pull request #309 from AlchemyCMS/fix/apply-csp-to-devise-controllers by @alchemycms-bot[bot] in https://github.com/AlchemyCMS/alchemy-devise/pull/310
25
+
26
+
27
+ **Full Changelog**: https://github.com/AlchemyCMS/alchemy-devise/compare/v8.4.0...v8.4.1
28
+
3
29
  ## 8.4.0 (2026-09-01)
4
30
 
5
31
  <!-- Release notes generated using configuration in .github/release.yml at 8.4-stable -->
data/README.md CHANGED
@@ -62,6 +62,27 @@ If your app uses an old encryption that needs the +devise-encryptable+ gem you a
62
62
  Alchemy::Devise.config.devise_modules << :encryptable
63
63
  ```
64
64
 
65
+ ## Role changes
66
+
67
+ Granting or revoking the `admin` role asks the admin performing the change to
68
+ confirm their own password, both when creating a user and when editing one.
69
+ Since `admin` is the only role that can manage users, every other role and
70
+ every other user attribute can be edited with a valid session alone.
71
+
72
+ Roles that need a password are configurable:
73
+
74
+ ```ruby
75
+ # config/initializers/alchemy.rb
76
+ Alchemy::Devise.config.privileged_user_roles << "editor"
77
+ ```
78
+
79
+ Set this to `false` to grant roles with a valid session alone:
80
+
81
+ ```ruby
82
+ # config/initializers/alchemy.rb
83
+ Alchemy::Devise.config.require_password_for_role_change = false
84
+ ```
85
+
65
86
  ## Testing
66
87
 
67
88
  If you want to contribute (and you should ^_^), you need to run the tests locally on your machine.
@@ -1 +1 @@
1
- body.signup,body.user_sessions,body.passwords{background-image:url("https://picsum.photos/1920/1200.webp?grayscale");background-size:cover;background-position:center}body.signup #errors,body.signup .message.info,body.user_sessions #errors,body.user_sessions .message.info,body.passwords #errors,body.passwords .message.info{border-color:rgba(0,0,0,0)}body.signup #errors,body.user_sessions #errors,body.passwords #errors{margin-left:157px}body.signup #main_content,body.user_sessions #main_content,body.passwords #main_content{padding-top:var(--spacing-2);display:flex;flex-direction:column;justify-content:center}body.signup::after,body.user_sessions::after,body.passwords::after{content:"Image from Unsplash";position:absolute;bottom:var(--spacing-2);right:var(--spacing-2);font-size:var(--font-size_small);color:var(--body-background-color)}.logo-box{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--spacing-4);background-color:hsl(from var(--body-background-color) h s l/50%);backdrop-filter:blur(5px);border-radius:var(--border-radius_large);box-shadow:var(--dialog-box-shadow);padding:var(--spacing-4);margin-bottom:var(--spacing-6);text-shadow:0 0 2px var(--body-background-color)}.logo-box svg{width:200px;height:auto}.login_signup_box{position:relative;max-width:450px;margin:auto;--form-right-column-width: 1.65fr}.no-js .login_signup_box{display:none}.login_signup_box alchemy-message{margin-bottom:1.5em}.login_signup_box .panel{--panel-background-color: var(--body-background-color);width:100%;max-width:100%;margin:0;box-shadow:var(--dialog-box-shadow);border-radius:var(--border-radius_large);border-color:rgba(0,0,0,0)}@media(max-width: 500px){.login_signup_box .input,.login_signup_box .submit{grid-template-columns:1fr}.login_signup_box .input label,.login_signup_box .submit label{text-align:start;margin-bottom:var(--spacing-1)}}.login_signup_box .submit>a{display:inline-flex;align-items:center;gap:var(--spacing-0);width:fit-content}.login_signup_box .submit>a:hover alchemy-icon{transform:translateX(-2px);transition:transform var(--transition-duration)}@media(min-width: 501px){.login_signup_box .submit{grid-template-columns:var(--form-left-column-width) minmax(254px, var(--form-right-column-width))}.login_signup_box .submit>label{text-align:start}.login_signup_box .submit>label input[type=checkbox]{margin:0 var(--spacing-0) 0 0}.login_signup_box .submit>a{grid-column:2;grid-row:1}}
1
+ body.signup,body.user_sessions,body.passwords{background-image:url("https://picsum.photos/1920/1200.webp?grayscale");background-size:cover;background-position:center}body.signup #errors,body.signup .message.info,body.user_sessions #errors,body.user_sessions .message.info,body.passwords #errors,body.passwords .message.info{border-color:rgba(0,0,0,0)}body.signup #errors,body.user_sessions #errors,body.passwords #errors{margin-left:157px}body.signup #main_content,body.user_sessions #main_content,body.passwords #main_content{padding-top:var(--spacing-2);display:flex;flex-direction:column;justify-content:center}body.signup::after,body.user_sessions::after,body.passwords::after{content:"Image from Unsplash";position:absolute;bottom:var(--spacing-2);right:var(--spacing-2);font-size:var(--font-size_small);color:var(--body-background-color)}.logo-box{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--spacing-4);background-color:color-mix(in srgb, var(--body-background-color) 50%, transparent);backdrop-filter:blur(5px);border-radius:var(--border-radius_large);box-shadow:var(--dialog-box-shadow);padding:var(--spacing-4);margin-bottom:var(--spacing-6);text-shadow:0 0 2px var(--body-background-color)}.logo-box svg{width:200px;height:auto}.login_signup_box{position:relative;max-width:450px;margin:auto;--form-right-column-width: 1.65fr}.no-js .login_signup_box{display:none}.login_signup_box alchemy-message{margin-bottom:1.5em}.login_signup_box .panel{--panel-background-color: var(--body-background-color);width:100%;max-width:100%;margin:0;box-shadow:var(--dialog-box-shadow);border-radius:var(--border-radius_large);border-color:rgba(0,0,0,0)}@media(max-width: 500px){.login_signup_box .input,.login_signup_box .submit{grid-template-columns:1fr}.login_signup_box .input label,.login_signup_box .submit label{text-align:start;margin-bottom:var(--spacing-1)}}.login_signup_box .submit>a{display:inline-flex;align-items:center;gap:var(--spacing-0);width:fit-content}.login_signup_box .submit>a:hover alchemy-icon{transform:translateX(-2px);transition:transform var(--transition-duration)}@media(min-width: 501px){.login_signup_box .submit{grid-template-columns:var(--form-left-column-width) minmax(254px, var(--form-right-column-width))}.login_signup_box .submit>label{text-align:start}.login_signup_box .submit>label input[type=checkbox]{margin:0 var(--spacing-0) 0 0}.login_signup_box .submit>a{grid-column:2;grid-row:1}}
@@ -37,7 +37,7 @@ body.passwords {
37
37
  align-items: center;
38
38
  justify-content: center;
39
39
  gap: var(--spacing-4);
40
- background-color: hsl(from var(--body-background-color) h s l / 50%);
40
+ background-color: color-mix(in srgb, var(--body-background-color) 50%, transparent);
41
41
  backdrop-filter: blur(5px);
42
42
  border-radius: var(--border-radius_large);
43
43
  box-shadow: var(--dialog-box-shadow);
@@ -6,6 +6,7 @@ module Alchemy
6
6
  module Admin
7
7
  class PasswordsController < ::Devise::PasswordsController
8
8
  include Alchemy::Admin::Locale
9
+ include Alchemy::Admin::CspProtection
9
10
 
10
11
  helper "Alchemy::Admin::Base"
11
12
 
@@ -6,6 +6,7 @@ module Alchemy
6
6
  module Admin
7
7
  class UserSessionsController < ::Devise::SessionsController
8
8
  include Alchemy::Admin::Locale
9
+ include Alchemy::Admin::CspProtection
9
10
 
10
11
  protect_from_forgery prepend: true
11
12
 
@@ -9,7 +9,10 @@ module Alchemy
9
9
  authorize_resource class: Alchemy::User,
10
10
  only: [:index, :new, :signup, :create]
11
11
 
12
- helper_method :while_signup?, :can_update_role?
12
+ before_action :confirm_password_for_role_change, only: [:create, :update]
13
+
14
+ helper_method :while_signup?, :can_update_role?, :password_confirmation_required?,
15
+ :carried_over_user_params, :confirmed_alchemy_roles
13
16
 
14
17
  def index
15
18
  @query = User.ransack(params[:q])
@@ -66,6 +69,69 @@ module Alchemy
66
69
 
67
70
  private
68
71
 
72
+ def confirm_password_for_role_change
73
+ return unless role_change_requested?
74
+
75
+ # Keeps the password field around if the save fails validation later on
76
+ @password_confirmation_required = true
77
+ # Captured before the submitted attributes are assigned, so that a
78
+ # revoked role is still known
79
+ @confirmed_alchemy_roles =
80
+ privileged_roles(requested_alchemy_roles) | privileged_roles(persisted_alchemy_roles)
81
+ current_password = params[:user][:current_password].to_s
82
+ return if current_alchemy_user.valid_password?(current_password)
83
+
84
+ @user ||= User.new
85
+ @user.assign_attributes(user_params)
86
+ @user.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
87
+ if user_password_required?
88
+ render action: (@user.new_record? ? :new : :edit), status: :unprocessable_content
89
+ else
90
+ render :confirm_password, status: :unprocessable_content
91
+ end
92
+ end
93
+
94
+ def role_change_requested?
95
+ return false unless Alchemy::Devise.config.require_password_for_role_change
96
+ return false if while_signup? || !can_update_role?
97
+ # An absent key leaves the roles untouched, it does not revoke them
98
+ return false unless params[:user].key?(:alchemy_roles)
99
+
100
+ privileged_roles(requested_alchemy_roles) != privileged_roles(persisted_alchemy_roles)
101
+ end
102
+
103
+ def privileged_roles(roles)
104
+ roles & Alchemy::Devise.config.privileged_user_roles.to_a
105
+ end
106
+
107
+ def requested_alchemy_roles
108
+ User.new(alchemy_roles: params.dig(:user, :alchemy_roles)).alchemy_roles.sort
109
+ end
110
+
111
+ def persisted_alchemy_roles
112
+ (@user || User.new).alchemy_roles.sort
113
+ end
114
+
115
+ def password_confirmation_required?
116
+ !!@password_confirmation_required
117
+ end
118
+
119
+ # The confirmation form replaces the real one, so the submitted attributes
120
+ # ride along in hidden fields. Passwords are deliberately left out: a
121
+ # hidden field would expose them to the very script execution this
122
+ # confirmation defends against.
123
+ def carried_over_user_params
124
+ user_params.except(:password, :password_confirmation)
125
+ end
126
+
127
+ def confirmed_alchemy_roles
128
+ @confirmed_alchemy_roles.map { User.human_alchemy_rolename(_1) }.to_sentence
129
+ end
130
+
131
+ def user_password_required?
132
+ @user.new_record? || params.dig(:user, :password).present?
133
+ end
134
+
69
135
  def set_roles
70
136
  if can_update_role?
71
137
  @user_roles = User::ROLES.map do |role|
@@ -0,0 +1,5 @@
1
+ <% action = f.object.new_record? ? "create" : "update" %>
2
+ <alchemy-message type="info">
3
+ <%= Alchemy.t("admin.users.confirm_password_for_role_change.#{action}",
4
+ roles: confirmed_alchemy_roles, user: f.object.alchemy_display_name) %>
5
+ </alchemy-message>
@@ -36,6 +36,13 @@
36
36
  object: f.object %>
37
37
  </div>
38
38
  <% end %>
39
+ <% if password_confirmation_required? %>
40
+ <%= render "confirm_password_notice", f: f %>
41
+ <%= f.input :current_password,
42
+ as: :password,
43
+ required: true,
44
+ input_html: {autocomplete: "current-password"} %>
45
+ <% end %>
39
46
  <div class="submit">
40
47
  <label class="checkbox">
41
48
  <%= f.check_box :send_credentials %>
@@ -8,7 +8,7 @@
8
8
  alchemy.edit_admin_user_path(user), {
9
9
  title: Alchemy.t(:edit_user),
10
10
  overflow: true,
11
- size: "460x530"
11
+ size: "460x190"
12
12
  },
13
13
  title: Alchemy.t(:edit_user) %>
14
14
  <% else %>
@@ -28,5 +28,5 @@
28
28
  <%= user.human_alchemy_roles %>
29
29
  <% end %>
30
30
  <% table.delete_button tooltip: Alchemy.t(:delete_user), confirm_message: Alchemy.t(:confirm_to_delete_user) %>
31
- <% table.edit_button tooltip: Alchemy.t(:edit_user), dialog_size: "460x530" %>
31
+ <% table.edit_button tooltip: Alchemy.t(:edit_user), dialog_size: "460x190" %>
32
32
  <% end %>
@@ -0,0 +1,22 @@
1
+ <%= alchemy_form_for [:admin, @user] do |f| %>
2
+ <% carried_over_user_params.each do |name, value| %>
3
+ <% if value.is_a?(Array) %>
4
+ <% value.each do |item| %>
5
+ <%= hidden_field_tag "user[#{name}][]", item, id: nil %>
6
+ <% end %>
7
+ <% else %>
8
+ <%= hidden_field_tag "user[#{name}]", value, id: nil %>
9
+ <% end %>
10
+ <% end %>
11
+ <%= render "confirm_password_notice", f: f %>
12
+ <%= f.input :current_password,
13
+ as: :password,
14
+ required: true,
15
+ autofocus: true,
16
+ input_html: {autocomplete: "current-password"} %>
17
+ <div class="submit">
18
+ <button type="submit">
19
+ <%= Alchemy.t(:save) %>
20
+ </button>
21
+ </div>
22
+ <% end %>
@@ -13,7 +13,7 @@
13
13
  tooltip_placement: "top-start",
14
14
  dialog_options: {
15
15
  title: Alchemy.t(:create_user),
16
- size: "460x530"
16
+ size: "460x190"
17
17
  },
18
18
  if_permitted_to: [:create, Alchemy::User]
19
19
  ) %>
@@ -1,7 +1,21 @@
1
1
  de:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Ihr Passwort"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "wird zum Ändern der Rollen benötigt"
12
+ invalid: "ist nicht korrekt"
2
13
  alchemy:
3
14
  admin:
4
15
  login:
5
16
  remember_me: "Für %{days} Tage angemeldet bleiben"
6
17
  users:
18
+ confirm_password_for_role_change:
19
+ create: Um einen Benutzer mit der Rolle %{roles} anzulegen, ist Ihr eigenes Passwort erforderlich.
20
+ update: Um die Rolle %{roles} von %{user} zu ändern, ist Ihr eigenes Passwort erforderlich.
7
21
  preferred_timezone: Wählen Sie eine bevorzugte Zeitzone, wenn sie sich von %{server_timezone} unterscheidet
@@ -1,7 +1,21 @@
1
1
  en:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Your password"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "is required to change roles"
12
+ invalid: "is not correct"
2
13
  alchemy:
3
14
  admin:
4
15
  login:
5
16
  remember_me: "Remember me for %{days} days"
6
17
  users:
18
+ confirm_password_for_role_change:
19
+ create: In order to create a user with the %{roles} role you have to confirm with your own password.
20
+ update: In order to change the %{roles} role of %{user} you have to confirm with your own password.
7
21
  preferred_timezone: Pick the users preferred timezone if it is different from %{server_timezone}
@@ -0,0 +1,18 @@
1
+ es:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Tu contraseña"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "es necesaria para cambiar los roles"
12
+ invalid: "no es correcta"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "Para crear un usuario con el rol %{roles} debes confirmar con tu propia contraseña."
18
+ update: "Para cambiar el rol %{roles} de %{user} debes confirmar con tu propia contraseña."
@@ -0,0 +1,18 @@
1
+ fr:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Votre mot de passe"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "est requis pour modifier les rôles"
12
+ invalid: "n'est pas correct"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "Pour créer un utilisateur avec le rôle %{roles}, vous devez confirmer avec votre propre mot de passe."
18
+ update: "Pour modifier le rôle %{roles} de %{user}, vous devez confirmer avec votre propre mot de passe."
@@ -0,0 +1,18 @@
1
+ it:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "La tua password"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "è necessaria per modificare i ruoli"
12
+ invalid: "non è corretta"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "Per creare un utente con il ruolo %{roles} devi confermare con la tua password."
18
+ update: "Per modificare il ruolo %{roles} di %{user} devi confermare con la tua password."
@@ -0,0 +1,18 @@
1
+ nb:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Passordet ditt"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "kreves for å endre roller"
12
+ invalid: "er ikke riktig"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "For å opprette en bruker med rollen %{roles} må du bekrefte med ditt eget passord."
18
+ update: "For å endre rollen %{roles} til %{user} må du bekrefte med ditt eget passord."
@@ -0,0 +1,18 @@
1
+ nl:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Je wachtwoord"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "is vereist om rollen te wijzigen"
12
+ invalid: "is niet juist"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "Om een gebruiker met de rol %{roles} aan te maken moet je met je eigen wachtwoord bevestigen."
18
+ update: "Om de rol %{roles} van %{user} te wijzigen moet je met je eigen wachtwoord bevestigen."
@@ -0,0 +1,18 @@
1
+ pl:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Twoje hasło"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "jest wymagane do zmiany ról"
12
+ invalid: "jest nieprawidłowe"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "Aby utworzyć użytkownika z rolą %{roles}, musisz potwierdzić własnym hasłem."
18
+ update: "Aby zmienić rolę %{roles} użytkownika %{user}, musisz potwierdzić własnym hasłem."
@@ -0,0 +1,18 @@
1
+ ru:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "Ваш пароль"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "необходим для изменения ролей"
12
+ invalid: "неверен"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "Чтобы создать пользователя с ролью %{roles}, подтвердите действие своим паролем."
18
+ update: "Чтобы изменить роль %{roles} у пользователя %{user}, подтвердите действие своим паролем."
@@ -0,0 +1,18 @@
1
+ zh-CN:
2
+ activerecord:
3
+ attributes:
4
+ alchemy/user:
5
+ current_password: "您的密码"
6
+ errors:
7
+ models:
8
+ alchemy/user:
9
+ attributes:
10
+ current_password:
11
+ blank: "是更改角色所必需的"
12
+ invalid: "不正确"
13
+ alchemy:
14
+ admin:
15
+ users:
16
+ confirm_password_for_role_change:
17
+ create: "要创建具有 %{roles} 角色的用户,您必须使用自己的密码进行确认。"
18
+ update: "要更改 %{user} 的 %{roles} 角色,您必须使用自己的密码进行确认。"
@@ -41,6 +41,32 @@ module Alchemy
41
41
  :recoverable,
42
42
  :rememberable
43
43
  ]
44
+
45
+ # Require the acting user to confirm their own password before Alchemy
46
+ # roles are granted or changed
47
+ #
48
+ # Creating a user with roles and changing the roles of an existing user
49
+ # both ask for the password of the user performing the change. Every
50
+ # other user attribute can be edited with a valid session alone.
51
+ #
52
+ # === Example
53
+ #
54
+ # # config/initializers/alchemy.rb
55
+ # Alchemy::Devise.config.require_password_for_role_change = false
56
+ #
57
+ option :require_password_for_role_change, :boolean, default: true
58
+
59
+ # Alchemy roles that may only be granted or revoked with a password
60
+ #
61
+ # Only +admin+ can manage users, so granting any other role does not
62
+ # cross a trust boundary and never asks for a password.
63
+ #
64
+ # === Example
65
+ #
66
+ # # config/initializers/alchemy.rb
67
+ # Alchemy::Devise.config.privileged_user_roles << "editor"
68
+ #
69
+ option :privileged_user_roles, :collection, item_type: :string, default: %w[admin]
44
70
  end
45
71
  end
46
72
  end
@@ -1,5 +1,5 @@
1
1
  module Alchemy
2
2
  module Devise
3
- VERSION = "8.4.0"
3
+ VERSION = "8.4.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy-devise
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.4.0
4
+ version: 8.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -199,8 +199,10 @@ files:
199
199
  - app/views/alchemy/admin/passwords/new.html.erb
200
200
  - app/views/alchemy/admin/user_sessions/_logo.html.erb
201
201
  - app/views/alchemy/admin/user_sessions/new.html.erb
202
+ - app/views/alchemy/admin/users/_confirm_password_notice.html.erb
202
203
  - app/views/alchemy/admin/users/_fields.html.erb
203
204
  - app/views/alchemy/admin/users/_resource_table.html.erb
205
+ - app/views/alchemy/admin/users/confirm_password.html.erb
204
206
  - app/views/alchemy/admin/users/edit.html.erb
205
207
  - app/views/alchemy/admin/users/index.html.erb
206
208
  - app/views/alchemy/admin/users/new.html.erb
@@ -230,6 +232,14 @@ files:
230
232
  - config/locales/devise.ru.yml
231
233
  - config/locales/devise.zh-CN.yml
232
234
  - config/locales/en.yml
235
+ - config/locales/es.yml
236
+ - config/locales/fr.yml
237
+ - config/locales/it.yml
238
+ - config/locales/nb.yml
239
+ - config/locales/nl.yml
240
+ - config/locales/pl.yml
241
+ - config/locales/ru.yml
242
+ - config/locales/zh-CN.yml
233
243
  - config/routes.rb
234
244
  - config/spring.rb
235
245
  - db/migrate/20131015124700_create_alchemy_users.rb
@@ -266,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
266
276
  - !ruby/object:Gem::Version
267
277
  version: '0'
268
278
  requirements: []
269
- rubygems_version: 4.0.16
279
+ rubygems_version: 4.0.20
270
280
  specification_version: 4
271
281
  summary: Devise based user authentication for AlchemyCMS.
272
282
  test_files: []