Skip to content

Commit

Permalink
Add avatar file size validation (max 5 MB)
Browse files Browse the repository at this point in the history
  • Loading branch information
markets committed Jun 15, 2021
1 parent 1e8fb13 commit b8d557a
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 32 deletions.
8 changes: 4 additions & 4 deletions app/assets/javascripts/application/avatar.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ $(function () {

// on submit take the parameters of the box to crop the avatar
$('#form_photo').on("submit", () => {
let total_width = parseInt(getComputedStyle(document.getElementById("containerCrop")).width);
let photo_width = parseInt(getComputedStyle(document.getElementById("foto")).width);
let total_width = parseInt(getComputedStyle(document.getElementById("container_crop")).width);
let photo_width = parseInt(getComputedStyle(document.getElementById("original_img")).width);
let left_displacement = total_width - photo_width;

$('#height_offset').val(parseInt(panel.css('top')) - 15);
$('#width_offset').val(parseInt(panel.css('left')) - 15 - (left_displacement/2));
$('#height_width').val(parseInt(panel.css('width')));
$('#original_width').val($('#foto').width());
$('#original_width').val($('#original_img').width());
});

function resize(e) {
Expand Down Expand Up @@ -93,7 +93,7 @@ $(function () {
}

function preview_image_modal() {
var preview = document.querySelector('#foto');
var preview = document.querySelector('#original_img');
var file = document.querySelector('#avatar-js').files[0];
var reader = new FileReader();

Expand Down
8 changes: 4 additions & 4 deletions app/assets/stylesheets/application/avatar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

#crop_panel {
position: absolute;
width: 140px;
height: 140px;
width: 200px;
height: 200px;
border-left: 4px dashed black;
cursor: move;
touch-action: none;
Expand All @@ -21,7 +21,7 @@
right: 0;
width: 16px;
height: 100%;
cursor: w-resize;
cursor: ew-resize;
}

#crop_panel::after {
Expand All @@ -32,5 +32,5 @@
bottom: 0;
width: 100%;
height: 16px;
cursor: n-resize;
cursor: ns-resize;
}
20 changes: 15 additions & 5 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ def update

def update_avatar
avatar = params[:avatar]
errors = validate_avatar(avatar)

if avatar && content_type_permitted(avatar.content_type)
if errors.blank?
current_user.avatar.purge if current_user.avatar.attached?

crop_image_and_save(current_user, avatar)
else
flash[:error] = t 'users.show.invalid_format'
flash[:error] = errors.join("<br>")
end

redirect_to current_user
Expand Down Expand Up @@ -151,7 +151,17 @@ def crop_image_and_save(user, avatar)
)
end

def content_type_permitted(avatar_content_type)
%w[image/jpeg image/pjpeg image/png image/x-png].include? avatar_content_type
def validate_avatar(file)
errors = []

if User::AVATAR_CONTENT_TYPES.exclude?(file.content_type)
errors << t("users.show.invalid_format")
end

if file.size.to_f > User::AVATAR_MAX_SIZE.megabytes
errors << t("users.avatar.max_size_warning", size: User::AVATAR_MAX_SIZE)
end

errors
end
end
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class User < ApplicationRecord
:timeoutable
]

AVATAR_MAX_SIZE = 5
AVATAR_CONTENT_TYPES = %w[image/jpeg image/pjpeg image/png image/x-png]
GENDERS = %w(
female
male
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/_messages.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<button type="button" class="close" data-dismiss="alert">x</button>
<ul>
<li>
<%= value %>
<%= value.html_safe %>
</li>
</ul>
</div>
Expand Down
17 changes: 8 additions & 9 deletions app/views/users/_avatar.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,24 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
<%= t ".crop_the_image" %>
</h4>
<h4 class="modal-title"><%= t ".crop_the_image" %></h4>
</div>
<div class="modal-body">
<div id="containerCrop" class="col-12">
<div id="container_crop" class="col-12">
<div id="crop_panel"></div>
<img id="foto" alt="" />
<img id="original_img">
</div>
</div>
<div class="modal-footer">
<div class="form-actions">
<button type="button" class="btn btn-default" data-dismiss="modal">
<%= t 'users.new.cancel' %>
</button>
<%= f.hidden_field :height_width, value: 140 %>
<%= f.hidden_field :height_width, value: 200 %>
<%= f.hidden_field :width_offset, value: 1 %>
<%= f.hidden_field :height_offset, value: 1 %>
<%= f.hidden_field :original_width, value: 1 %>
<%= f.button :submit, class: "btn btn-default", data: { dismiss: "modal" } do %>
<%= t("users.new.cancel") %>
<% end %>
<%= f.button :submit, class: "btn btn-primary" do %>
<%= t("global.save") %>
<% end %>
Expand Down
1 change: 1 addition & 0 deletions config/locales/ca.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ ca:
avatar:
change_your_image: Canvia la teva imatge
crop_the_image: Retalla la imatge
max_size_warning: La imatge és massa gran, el màxim permès és de %{size}MB
edit:
edit_user: Canviar usuari
form:
Expand Down
7 changes: 4 additions & 3 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,10 @@ en:
new:
error_amount: Time must be greater than 0
users:
avatar:
change_your_image: Change your image
crop_the_image: Crop the image
max_size_warning: Image is too big, max allowed is %{size}MB
edit:
edit_user: Update user
form:
Expand All @@ -526,9 +530,6 @@ en:
create_more_users_button: Create and add another user
new_user: New user
user_created_add: User %{uid} %{name} saved, now create next one
avatar:
change_your_image: Change your image
crop_the_image: Crop the image
show:
account: Last transactions
accounts: Accounts
Expand Down
1 change: 1 addition & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ es:
avatar:
change_your_image: Cambia tu imagen
crop_the_image: Recortar la imagen
max_size_warning: La imagen es demasiado grande, el máximo permitido es %{size}MB
edit:
edit_user: Cambiar usuario
form:
Expand Down
1 change: 1 addition & 0 deletions config/locales/eu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ eu:
avatar:
change_your_image:
crop_the_image:
max_size_warning:
edit:
edit_user: Erabiltzailea aldatu
form:
Expand Down
1 change: 1 addition & 0 deletions config/locales/gl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ gl:
avatar:
change_your_image:
crop_the_image:
max_size_warning:
edit:
edit_user: Actualizar persoa usuaria
form:
Expand Down
1 change: 1 addition & 0 deletions config/locales/pt-BR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ pt-BR:
avatar:
change_your_image:
crop_the_image:
max_size_warning:
edit:
edit_user: Trocar usuário
form:
Expand Down
25 changes: 19 additions & 6 deletions spec/controllers/users_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -409,18 +409,31 @@
context "with a normal logged user" do
before { login(user) }

it "change the photo attached @user" do
path = Rails.root.join("docs/images/ofertas.png")
uploaded_file = Rack::Test::UploadedFile.new(path, "image/png")
let(:uploaded_file) do
Rack::Test::UploadedFile.new(
Rails.root.join("docs/images/ofertas.png"),
"image/png"
)
end

it "change the photo attached @user" do
put :update_avatar, params: { avatar: uploaded_file, original_width: 500, height_width: 140 }

expect(user.avatar.attached?).to eq true
end

it "don't change the photo attached if the format isn't valid" do
path = Rails.root.join("spec/controllers/users_controller_spec.rb")
uploaded_file = Rack::Test::UploadedFile.new(path)
it "don't change the photo attached if the mime_type isn't valid" do
uploaded_file = Rack::Test::UploadedFile.new(
Rails.root.join("spec/controllers/users_controller_spec.rb")
)

put :update_avatar, params: { avatar: uploaded_file }

expect(flash[:error]).not_to be_empty
end

it "don't change the photo attached if the file size it too big" do
allow_any_instance_of(ActionDispatch::Http::UploadedFile).to receive(:size) { User::AVATAR_MAX_SIZE.megabytes + 1.megabyte }

put :update_avatar, params: { avatar: uploaded_file }

Expand Down

0 comments on commit b8d557a

Please sign in to comment.