Skip to content

Commit dfe7095

Browse files
Merge pull request #1917 from basecamp/dont-resize-svg-avatars
Don't try to resize non-variable avatars
2 parents 2fcdd92 + 2e47749 commit dfe7095

File tree

7 files changed

+62
-9
lines changed

7 files changed

+62
-9
lines changed

app/controllers/users/avatars_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def show
1010
if @user.system?
1111
redirect_to view_context.image_path("system_user.png")
1212
elsif @user.avatar.attached?
13-
redirect_to rails_blob_url(@user.avatar.variant(:thumb), disposition: "inline")
13+
redirect_to rails_blob_url(@user.avatar_thumbnail, disposition: "inline")
1414
elsif stale? @user, cache_control: cache_control
1515
render_initials
1616
end

app/models/user.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
class User < ApplicationRecord
2-
include Accessor, Assignee, Attachable, Configurable, EmailAddressChangeable,
2+
include Accessor, Assignee, Attachable, Avatar, Configurable, EmailAddressChangeable,
33
Mentionable, Named, Notifiable, Role, Searcher, Watcher
44
include Timelined # Depends on Accessor
55

6-
has_one_attached :avatar do |attachable|
7-
attachable.variant :thumb, resize_to_fill: [ 256, 256 ]
8-
end
9-
106
belongs_to :account
117
belongs_to :identity, optional: true
128

app/models/user/avatar.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module User::Avatar
2+
extend ActiveSupport::Concern
3+
4+
ALLOWED_AVATAR_CONTENT_TYPES = %w[ image/jpeg image/png image/gif image/webp ].freeze
5+
6+
included do
7+
has_one_attached :avatar do |attachable|
8+
attachable.variant :thumb, resize_to_fill: [ 256, 256 ]
9+
end
10+
11+
validate :avatar_content_type_allowed
12+
end
13+
14+
def avatar_thumbnail
15+
avatar.variable? ? avatar.variant(:thumb) : avatar
16+
end
17+
18+
private
19+
def avatar_content_type_allowed
20+
if avatar.attached? && !ALLOWED_AVATAR_CONTENT_TYPES.include?(avatar.content_type)
21+
errors.add(:avatar, "must be a JPEG, PNG, GIF, or WebP image")
22+
end
23+
end
24+
end

app/views/users/edit.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
<label class="avatar btn btn--circle input--file txt-xx-large center fill-white">
1616
<%= image_tag user_avatar_path(@user), aria: { hidden: "true" }, class: "avatar", size: 128, data: { upload_preview_target: "image" } %>
17-
<%= form.file_field :avatar, id: "file", class: "input", accept: "image/*",
17+
<%= form.file_field :avatar, id: "file", class: "input", accept: "image/jpeg, image/png, image/gif, image/webp",
1818
data: { upload_preview_target: "input", action: "upload-preview#previewImage" } %>
1919
<span class="for-screen-reader">Profile avatar for <%= @user.name %></span>
2020
</label>

test/controllers/users/avatars_controller_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Users::AvatarsControllerTest < ActionDispatch::IntegrationTest
3232

3333
get user_avatar_path(users(:david))
3434

35-
assert_redirected_to rails_blob_url(users(:david).avatar.variant(:thumb), disposition: "inline")
35+
assert_redirected_to rails_blob_url(users(:david).avatar_thumbnail, disposition: "inline")
3636
end
3737

3838
test "show other image redirects to the blob url" do
@@ -41,7 +41,7 @@ class Users::AvatarsControllerTest < ActionDispatch::IntegrationTest
4141

4242
get user_avatar_path(users(:kevin))
4343

44-
assert_redirected_to rails_blob_url(users(:kevin).avatar.variant(:thumb), disposition: "inline")
44+
assert_redirected_to rails_blob_url(users(:kevin).avatar_thumbnail, disposition: "inline")
4545
end
4646

4747
test "delete self" do

test/fixtures/files/avatar.svg

Lines changed: 3 additions & 0 deletions
Loading

test/models/user/avatar_test.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
require "test_helper"
2+
3+
class User::AvatarTest < ActiveSupport::TestCase
4+
test "avatar_thumbnail returns variant for variable images" do
5+
users(:david).avatar.attach(io: File.open(file_fixture("moon.jpg")), filename: "moon.jpg", content_type: "image/jpeg")
6+
7+
assert users(:david).avatar.variable?
8+
assert_equal users(:david).avatar.variant(:thumb).blob, users(:david).avatar_thumbnail.blob
9+
end
10+
11+
test "avatar_thumbnail returns original blob for non-variable images" do
12+
users(:david).avatar.attach(io: File.open(file_fixture("avatar.svg")), filename: "avatar.svg", content_type: "image/svg+xml")
13+
14+
assert_not users(:david).avatar.variable?
15+
assert_equal users(:david).avatar.blob, users(:david).avatar_thumbnail.blob
16+
end
17+
18+
test "allows valid image content types" do
19+
users(:david).avatar.attach(io: File.open(file_fixture("moon.jpg")), filename: "test.jpg")
20+
21+
assert users(:david).valid?
22+
end
23+
24+
test "rejects SVG uploads" do
25+
users(:david).avatar.attach(io: File.open(file_fixture("avatar.svg")), filename: "avatar.svg")
26+
27+
assert_not users(:david).valid?
28+
assert_includes users(:david).errors[:avatar], "must be a JPEG, PNG, GIF, or WebP image"
29+
end
30+
end

0 commit comments

Comments
 (0)