Compare commits

...

2 Commits

Author SHA1 Message Date
Trevor Vallender 1ca30a9db2 Allow deletion of avatars 2024-06-04 14:21:11 +01:00
Trevor Vallender d1175870c2 Move password edit to own page 2024-06-04 09:09:59 +01:00
13 changed files with 119 additions and 28 deletions

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
class PasswordsController < ApplicationController
def edit
@user = Current.user
end
def update
if Current.user.update!(password_params)
redirect_to Current.user, notice: t(".success")
else
flash.now[:alert] = t(".error")
render :edit, status: :unprocessable_entity
end
end
private
def password_params
params.require(:user).permit(
:password_challenge,
:password,
:password_confirmation,
)
end
end

View File

@ -32,7 +32,9 @@ class UsersController < ApplicationController
end
def update
if @user.update(existing_user_params)
@user.avatar.purge if params["remove_avatar"] == "true"
if existing_user_params.present? && @user.update(existing_user_params)
redirect_to @user, notice: t(".success")
else
flash.now[:alert] = t(".error")
@ -55,9 +57,6 @@ class UsersController < ApplicationController
def existing_user_params
params.require(:user).permit(
:password,
:password_confirmation,
:password_challenge,
:first_name,
:last_name,
:profile,

View File

@ -0,0 +1,21 @@
<%= content_for :title, t(".change_password") %>
<h2><%= t(".change_password") %></h2>
<section class="inset">
<%= form_with model: @user, url: user_password_path(@user), method: :patch do |f| %>
<%= f.label :password_challenge, t(".current_password") %>
<%= f.password_field :password_challenge %>
<%= display_form_errors(@user, :password_challenge) %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= display_form_errors(@user, :password) %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= display_form_errors(@user, :password_confirmation) %>
<%= f.submit t(".update_password") %>
<% end %>
</section>

View File

@ -18,17 +18,10 @@
<%= f.text_field :email, required: true, disabled: user.persisted? %>
<%= display_form_errors(user, :email) %>
<% if user.new_record? %>
<fieldset>
<legend><%= t(".password") %></legend>
<% if user.persisted? %>
<%= f.label :password_challenge, t(".current_password") %>
<%= f.password_field :password_challenge, required: user.new_record? %>
<%= display_form_errors(user, :password_challenge) %>
<p><%= t(".password_hint") %></p>
<% end %>
<%= f.label :password %>
<%= f.password_field :password, required: user.new_record? %>
<%= display_form_errors(user, :password) %>
@ -37,10 +30,14 @@
<%= f.password_field :password_confirmation, required: user.new_record? %>
<%= display_form_errors(user, :password_confirmation) %>
</fieldset>
<% end %>
<hr>
<% if user.persisted? %>
<%= label_tag :remove_avatar %>
<%= check_box_tag :remove_avatar, value: true %>
<%= f.label :avatar %>
<%= f.file_field :avatar %>
<%= display_form_errors(user, :avatar) %>

View File

@ -4,3 +4,7 @@
<%= render partial: "users/form",
locals: { user: @user, button_text: t(".update_profile") } %>
<section class="inset">
<%= link_to t(".update_password"), edit_user_password_path(Current.user) %>
</section>

View File

@ -71,6 +71,15 @@ en:
invalid_token: That token seems to have expired, please try resettting your password again.
success: Your password has been reset, you may now log in.
error: Failed to reset password. Please try again or contact us for help.
passwords:
edit:
change_password: Change your password
current_password: Current password
update_password: Update password
update:
success: Your password has been updated
error: Failed to update password
sessions:
create:
success: "Hello, %{name}!"
@ -156,10 +165,12 @@ en:
edit:
edit_profile: Edit profile
update_profile: Update profile
update_password: Change your password
form:
password: Password
password_hint: To keep your existing password, leave the below fields blank
current_password: Current password
update_password: Change your password
update:
success: Your profile has been updated
error: Failed to update profile
@ -183,4 +194,3 @@ en:
If you did not request a password reset, please ignore this email.
Otherwise, please visit the link below to reset your password.

View File

@ -8,7 +8,9 @@ Rails.application.routes.draw do
get "login" => "sessions#new", as: :login
delete "logout" => "sessions#destroy", as: :logout
resources :users, only: [ :new, :create, :show, :edit, :update ]
resources :users, only: [ :new, :create, :show, :edit, :update ] do
resource :password, only: [ :edit, :update ]
end
resources :account_verifications, only: [ :show ]
resources :password_resets, only: [ :new, :create, :edit, :update ]
resources :sessions, only: [ :new, :create, :destroy ]

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
require "test_helper"
class PasswordsControllerTest < ActionDispatch::IntegrationTest
test "should get edit" do
user = users(:trevor)
sign_in user
get edit_user_password_path(user)
assert_response :success
end
test "should update password" do
user = users(:trevor)
sign_in user
patch user_password_path(user), params: { user: { password: "new_password", password_confirmation: "new_password" } }
assert_redirected_to user_path(user)
assert user.reload.authenticate("new_password")
end
end

View File

@ -52,6 +52,15 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert_redirected_to user_path(users(:trevor))
end
test "can delete avatar" do
user = users(:trevor)
assert user.avatar.attached?
sign_in users(:trevor)
patch(user_url(user), params: { remove_avatar: "true" })
assert_not user.reload.avatar.attached?
end
private
def user_params

View File

@ -0,0 +1,4 @@
trevor_avatar:
name: avatar
record: trevor (User)
blob: trevor_avatar_blob

View File

@ -0,0 +1 @@
trevor_avatar_blob: <%= ActiveStorage::FixtureSet.blob(filename: "trevor.png", service_name: "test") %>

BIN
test/fixtures/files/trevor.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

View File

@ -1,10 +1,8 @@
- avatars
- delete avatar
- default avatars
- discrete password page
- shared/private notes
- notifications
- Add characters to users/tables
- Character sheets/prototypes
- notifications
- chat
- maps
- add expiration, invalidation to tokens