improve user password reset

This commit is contained in:
Alex Turchyn
2025-09-05 21:48:22 +03:00
committed by Pete Matsyburka
parent aeea619059
commit f7be74eb73
9 changed files with 110 additions and 12 deletions
+4
View File
@@ -1,6 +1,10 @@
# frozen_string_literal: true
class PasswordsController < Devise::PasswordsController
# rubocop:disable Rails/LexicallyScopedActionFilter
skip_before_action :require_no_authentication, only: %i[edit update]
# rubocop:enable Rails/LexicallyScopedActionFilter
class Current < ActiveSupport::CurrentAttributes
attribute :user
end
+2 -2
View File
@@ -16,7 +16,7 @@ class ProfileController < ApplicationController
end
def update_password
if current_user.update(password_params)
if current_user.update_with_password(password_params)
bypass_sign_in(current_user)
redirect_to settings_profile_index_path, notice: I18n.t('password_has_been_changed')
else
@@ -31,6 +31,6 @@ class ProfileController < ApplicationController
end
def password_params
params.require(:user).permit(:password, :password_confirmation)
params.require(:user).permit(:password, :password_confirmation, :current_password)
end
end
+8 -1
View File
@@ -1,7 +1,7 @@
# frozen_string_literal: true
class UsersController < ApplicationController
load_and_authorize_resource :user, only: %i[index edit update destroy]
load_and_authorize_resource :user, only: %i[index edit update destroy resend_reset_password]
before_action :build_user, only: %i[new create]
authorize_resource :user, only: %i[new create]
@@ -71,6 +71,13 @@ class UsersController < ApplicationController
redirect_back fallback_location: settings_users_path, notice: I18n.t('user_has_been_removed')
end
def resend_reset_password
current_user.send_reset_password_instructions
redirect_back fallback_location: settings_users_path,
notice: I18n.t('you_will_receive_an_email_with_password_reset_instructions_in_a_few_minutes')
end
private
def role_valid?(role)
+2
View File
@@ -39,6 +39,7 @@ import RequiredCheckboxGroup from './elements/required_checkbox_group'
import PageContainer from './elements/page_container'
import EmailEditor from './elements/email_editor'
import MountOnClick from './elements/mount_on_click'
import VisibleOnInput from './elements/visible_on_input'
import * as TurboInstantClick from './lib/turbo_instant_click'
@@ -113,6 +114,7 @@ safeRegisterElement('required-checkbox-group', RequiredCheckboxGroup)
safeRegisterElement('page-container', PageContainer)
safeRegisterElement('email-editor', EmailEditor)
safeRegisterElement('mount-on-click', MountOnClick)
safeRegisterElement('visible-on-input', VisibleOnInput)
safeRegisterElement('template-builder', class extends HTMLElement {
connectedCallback () {
@@ -0,0 +1,14 @@
export default class extends HTMLElement {
connectedCallback () {
this.input = document.getElementById(this.dataset.inputId)
this.input.addEventListener('input', () => {
if (this.input.value.trim().length > 0) {
this.classList.remove('hidden')
} else {
this.classList.add('hidden')
this.querySelectorAll('input').forEach(input => { input.value = '' })
}
})
}
}
+17 -7
View File
@@ -59,14 +59,24 @@
<%= f.label :password, t('new_password'), class: 'label' %>
<%= f.password_field :password, autocomplete: 'off', class: 'base-input' %>
</div>
<div class="form-control">
<%= f.label :password_confirmation, t('confirm_password'), class: 'label' %>
<%= f.password_field :password_confirmation, autocomplete: 'off', class: 'base-input' %>
</div>
<div class="form-control pt-2">
<%= f.button button_title(title: t('update'), disabled_with: t('updating')), class: 'base-button' %>
</div>
<visible-on-input data-input-id="user_password" class="block space-y-4 <%= 'hidden' if f.object.errors.blank? %>">
<div class="form-control">
<%= f.label :password_confirmation, t('confirm_password'), class: 'label' %>
<%= f.password_field :password_confirmation, autocomplete: 'off', class: 'base-input' %>
</div>
<div class="form-control">
<%= f.label :current_password, t('current_password'), class: 'label' %>
<%= f.password_field :current_password, autocomplete: 'current-password', class: 'base-input' %>
<span class="label-text-alt mt-1">
<%= t('dont_remember_your_current_password_click_here_to_reset_it_html', link: new_user_password_url) %>
</span>
</div>
<div class="form-control">
<%= f.button button_title(title: t('update'), disabled_with: t('updating')), class: 'base-button' %>
</div>
</visible-on-input>
<% end %>
<%= button_to nil, resend_reset_password_users_path, id: 'resend_password_button', class: 'hidden', data: { turbo_confirm: t('are_you_sure_') } %>
<p class="text-2xl font-bold mt-8 mb-4">
<%= t('two_factor_authentication') %>
</p>