Skip to content

Commit

Permalink
Merge pull request #735 from CamKem/fix/image-security
Browse files Browse the repository at this point in the history
Fix: image security
  • Loading branch information
nunomaduro authored Nov 18, 2024
2 parents 2a970f7 + 27d2793 commit c5438ab
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 44 deletions.
80 changes: 42 additions & 38 deletions app/Livewire/Questions/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,35 +263,6 @@ public function store(Request $request): void
}
}

/**
* Handle the image uploads.
*/
public function uploadImages(): void
{
collect($this->images)->each(function (UploadedFile $image): void {
$today = now()->format('Y-m-d');

/** @var string $path */
$path = $image->store("images/{$today}", 'public');
$this->optimizeImage($path);

if ($path) {
session()->push('images', $path);

$this->dispatch(
'image.uploaded',
path: Storage::url($path),
originalName: $image->getClientOriginalName()
);
} else { // @codeCoverageIgnoreStart
$this->addError('images', 'The image could not be uploaded.');
$this->dispatch('notification.created', message: 'The image could not be uploaded.');
} // @codeCoverageIgnoreEnd
});

$this->reset('images');
}

/**
* Optimize the images.
*/
Expand Down Expand Up @@ -322,15 +293,6 @@ public function optimizeImage(string $path): void
$imagick->destroy();
}

/**
* Handle the image deletes.
*/
public function deleteImage(string $path): void
{
Storage::disk('public')->delete($path);
$this->cleanSession($path);
}

/**
* Render the component.
*/
Expand All @@ -347,6 +309,48 @@ public function render(): View
]);
}

/**
* Handle the image deletes.
*/
private function deleteImage(string $path): void
{
if (! str_starts_with($path, 'images/')) {
return;
}

Storage::disk('public')->delete($path);
$this->cleanSession($path);
}

/**
* Handle the image uploads.
*/
private function uploadImages(): void
{
collect($this->images)->each(function (UploadedFile $image): void {
$today = now()->format('Y-m-d');

/** @var string $path */
$path = $image->store("images/{$today}", 'public');
$this->optimizeImage($path);

if ($path) {
session()->push('images', $path);

$this->dispatch(
'image.uploaded',
path: Storage::url($path),
originalName: $image->getClientOriginalName()
);
} else { // @codeCoverageIgnoreStart
$this->addError('images', 'The image could not be uploaded.');
$this->dispatch('notification.created', message: 'The image could not be uploaded.');
} // @codeCoverageIgnoreEnd
});

$this->reset('images');
}

/**
* Clean the session of the given image path.
*/
Expand Down
26 changes: 20 additions & 6 deletions tests/Unit/Livewire/Questions/CreateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,10 @@
$component = Livewire::actingAs($user)->test(Create::class);

$component->set('images', [$file]);
$component->invade()->updated('images');

$method = new ReflectionMethod(Create::class, 'uploadImages');
$method->setAccessible(true);
$method->invoke($component->instance());

expect(session('images'))->toBeArray()
->and(session('images'))->toContain($path);
Expand All @@ -431,7 +434,10 @@
'toId' => $user->id,
]);
$component->set('images', [$file]);
$component->call('uploadImages');

$method = new ReflectionMethod(Create::class, 'uploadImages');
$method->setAccessible(true);
$method->invoke($component->instance());

Storage::disk('public')->assertExists($path);

Expand Down Expand Up @@ -484,12 +490,14 @@

Storage::disk('public')->assertExists($path);

$component->call('deleteImage', $path);
$method = new ReflectionMethod(Create::class, 'deleteImage');
$method->setAccessible(true);
$method->invoke($component->instance(), $path);

$pathAgain = $file->store('images', 'public');
Storage::disk('public')->assertExists($pathAgain);

$component->call('deleteImage', $pathAgain);
$method->invoke($component->instance(), $pathAgain);

Storage::disk('public')->assertMissing($pathAgain);
});
Expand Down Expand Up @@ -598,7 +606,10 @@
]);

$component->set('images', [UploadedFile::fake()->image('test.jpg')]);
$component->call('uploadImages');

$method = new ReflectionMethod(Create::class, 'uploadImages');
$method->setAccessible(true);
$method->invoke($component->instance());

$component->assertHasNoErrors();
});
Expand All @@ -613,7 +624,10 @@
]);

$component->set('images', [UploadedFile::fake()->image('test.jpg')]);
$component->call('uploadImages');

$method = new ReflectionMethod(Create::class, 'uploadImages');
$method->setAccessible(true);
$method->invoke($component->instance());

$component->assertHasNoErrors();
});
Expand Down

0 comments on commit c5438ab

Please sign in to comment.