Improve avatar upload experience (#3181)

Fixes https://github.com/flarum/core/issues/3055

- On the frontend, accept only image types as a hint to the OS file picker.
- On the backend, add more robust validation to ensure only valid images make it through. This isn't necessary for security, but results in less confusing error mesages.
This commit is contained in:
Alexander Skvortsov 2021-12-01 15:16:45 -05:00 committed by GitHub
parent 2b87f10738
commit c522657212
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 2 deletions

View File

@ -149,7 +149,7 @@ export default class AvatarEditor extends Component {
// Create a hidden HTML input element and click on it so the user can select // Create a hidden HTML input element and click on it so the user can select
// an avatar file. Once they have, we will upload it via the API. // an avatar file. Once they have, we will upload it via the API.
const $input = $('<input type="file">'); const $input = $('<input type="file" accept=".jpg, .jpeg, .png, .bmp, .gif">');
$input $input
.appendTo('body') .appendTo('body')

View File

@ -11,6 +11,8 @@ namespace Flarum\User;
use Flarum\Foundation\AbstractValidator; use Flarum\Foundation\AbstractValidator;
use Flarum\Foundation\ValidationException; use Flarum\Foundation\ValidationException;
use Intervention\Image\Exception\NotReadableException;
use Intervention\Image\ImageManager;
use Psr\Http\Message\UploadedFileInterface; use Psr\Http\Message\UploadedFileInterface;
use Symfony\Component\Mime\MimeTypes; use Symfony\Component\Mime\MimeTypes;
@ -69,6 +71,12 @@ class AvatarValidator extends AbstractValidator
if (! in_array($guessedExtension, $allowedTypes)) { if (! in_array($guessedExtension, $allowedTypes)) {
$this->raise('mimes', [':values' => implode(', ', $allowedTypes)]); $this->raise('mimes', [':values' => implode(', ', $allowedTypes)]);
} }
try {
(new ImageManager)->make($file->getStream());
} catch (NotReadableException $_e) {
$this->raise('image');
}
} }
protected function assertFileSize(UploadedFileInterface $file) protected function assertFileSize(UploadedFileInterface $file)
@ -103,6 +111,6 @@ class AvatarValidator extends AbstractValidator
protected function getAllowedTypes() protected function getAllowedTypes()
{ {
return ['jpg', 'png', 'bmp', 'gif']; return ['jpeg', 'jpg', 'png', 'bmp', 'gif'];
} }
} }