media: PM-Medien privat ausliefern + Vorschau-Signatur (M4, M5, Fix#4/#5)

- Neue PM-Bilder/Anhänge liegen auf der privaten local-Disk; Auslieferung
  über kontrollierte Media-Routen mit gemeinsamer Zugriffslogik
  (AuthorizesPressReleaseMediaAccess). Öffentliche Medien werden aus den
  geladenen Modellen ermittelt (weniger Queries) und länger gecacht.
- Anonyme Token-Vorschau lädt Bilder über temporär signierte URLs (Fix#5).
- API-Resource baut Variant-URLs über die Media-Route statt /storage
  (Fix#4). Storage-Schicht prüft zusätzlich den serverseitigen MIME-Type (M5).
- press-releases:privatize-media migriert Bestandsmedien.

Deployment: einmalig `php artisan press-releases:privatize-media` ausführen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-14 13:48:06 +00:00
parent 6e84266f90
commit 6250b0bab4
21 changed files with 588 additions and 70 deletions

View file

@ -15,8 +15,8 @@ use Livewire\WithFileUploads;
* delete. Authorisation is delegated to the `update` ability on the
* PressReleasePolicy so the component is safe for admins and customers.
*
* Storage uses the `public` disk with path obscurity (UUID prefix). Embargo
* / unpublished-state guards live at the PressRelease level.
* Storage uses the private disk. Downloads run through a controller that
* checks publication state or the PressRelease policy.
*/
new class extends Component
{

View file

@ -235,7 +235,7 @@ new class extends Component {
$pressRelease->images()->update(['is_preview' => false]);
$pressRelease->images()->create([
'disk' => 'public',
'disk' => $stored['disk'],
'path' => $stored['path'],
'variants' => $stored['variants'],
'title' => $this->newTitle ?: null,