@@ -129,24 +129,52 @@ defmodule MindwendelWeb.IdeaLive.FormComponent do
129129 end
130130
131131 defp prepare_attachments ( socket ) do
132- files =
133- consume_uploaded_entries ( socket , :attachment , fn % { path: path } , entry ->
134- # The tmp uploaded file will be deleted directly after this function ends.
135- # Copy it to a tmp folder first so the attachment changeset can process it.
136- # See also this discussion https://github.com/elixir-waffle/waffle/issues/71
137- filename = "#{ entry . uuid } .#{ mime_ext ( entry . client_type ) } "
138- dest = "#{ Path . dirname ( path ) } /#{ filename } "
139- File . cp! ( path , dest )
140- { :ok , % { path: dest , name: entry . client_name , file_type: entry . client_type } }
141- end )
142-
143- files
132+ consume_uploaded_entries ( socket , :attachment , fn % { path: path } , entry ->
133+ # The tmp uploaded file will be deleted directly after this function ends.
134+ # Copy it to a tmp folder first so the attachment changeset can process it.
135+ # See also this discussion https://github.com/elixir-waffle/waffle/issues/71
136+ case detect_mime_type ( path ) do
137+ nil ->
138+ { :ok , :rejected }
139+
140+ file_type ->
141+ filename = "#{ entry . uuid } .#{ mime_ext ( file_type ) } "
142+ dest = "#{ Path . dirname ( path ) } /#{ filename } "
143+ File . cp! ( path , dest )
144+ { :ok , % { path: dest , name: entry . client_name , file_type: file_type } }
145+ end
146+ end )
147+ |> Enum . reject ( & ( & 1 == :rejected ) )
144148 end
145149
146150 defp remove_tmp_attachments ( tmp_attachments ) do
147151 Enum . each ( tmp_attachments , fn tmp_attachment -> File . rm ( tmp_attachment . path ) end )
148152 end
149153
154+ @ doc false
155+ def detect_mime_type ( path ) do
156+ case File . open ( path , [ :read , :binary ] ) do
157+ { :ok , fd } ->
158+ result =
159+ case IO . binread ( fd , 4 ) do
160+ data when is_binary ( data ) -> match_magic_bytes ( data )
161+ _ -> nil
162+ end
163+
164+ File . close ( fd )
165+ result
166+
167+ _ ->
168+ nil
169+ end
170+ end
171+
172+ defp match_magic_bytes ( << 0xFF , 0xD8 , 0xFF , _ >> ) , do: "image/jpeg"
173+ defp match_magic_bytes ( << 0x89 , 0x50 , 0x4E , 0x47 >> ) , do: "image/png"
174+ defp match_magic_bytes ( << 0x47 , 0x49 , 0x46 , 0x38 >> ) , do: "image/gif"
175+ defp match_magic_bytes ( << 0x25 , 0x50 , 0x44 , 0x46 >> ) , do: "application/pdf"
176+ defp match_magic_bytes ( _ ) , do: nil
177+
150178 defp mime_ext ( client_type ) do
151179 List . first ( MIME . extensions ( client_type ) )
152180 end
0 commit comments