fix: acceso público a imágenes de storage para WhatsApp y navegador

- Mueve la ruta /storage/{path} fuera del middleware de auth para que
  sea pública; necesario para que los servidores de WhatsApp y el navegador
  puedan cargar imágenes de promociones sin autenticación
- Dockerfile: agrega 'rm -rf public/storage' antes de storage:link para
  evitar que COPY copie la junction de Windows y deje el symlink roto en el contenedor
- Crea .dockerignore: excluye public/storage, .git, .env y artefactos de
  build del contexto de Docker para builds más limpios y seguros

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-28 21:06:08 -06:00
parent a0c3194e88
commit 3f48c0bc7c
3 changed files with 16 additions and 7 deletions
+8
View File
@@ -0,0 +1,8 @@
.git
.env
node_modules
public/storage
storage/framework/cache
storage/framework/sessions
storage/framework/views
storage/logs
+1 -1
View File
@@ -25,7 +25,7 @@ RUN mkdir -p storage/framework/sessions storage/framework/views storage/framewor
&& chmod -R 775 storage bootstrap/cache \ && chmod -R 775 storage bootstrap/cache \
&& chown -R nobody:nginx storage bootstrap/cache && chown -R nobody:nginx storage bootstrap/cache
RUN php artisan storage:link RUN rm -rf public/storage && php artisan storage:link
COPY nginx.conf /etc/nginx/nginx.conf COPY nginx.conf /etc/nginx/nginx.conf
COPY supervisord.conf /etc/supervisord.conf COPY supervisord.conf /etc/supervisord.conf
+7 -6
View File
@@ -58,6 +58,12 @@ Route::get('/webhook/whatsapp', [\App\Http\Controllers\WhatsAppWebhookControlle
Route::post('/webhook/whatsapp', [\App\Http\Controllers\WhatsAppWebhookController::class, 'handle']) Route::post('/webhook/whatsapp', [\App\Http\Controllers\WhatsAppWebhookController::class, 'handle'])
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]); ->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
Route::get('/storage/{path}', function (string $path) {
$fullPath = storage_path('app/public/' . $path);
abort_unless(file_exists($fullPath), 404);
return response()->file($fullPath);
})->where('path', '.*');
Route::middleware(['auth:sanctum',config('jetstream.auth_session'),'verified', Route::middleware(['auth:sanctum',config('jetstream.auth_session'),'verified',
])->group(function () { ])->group(function () {
@@ -160,12 +166,7 @@ Route::middleware(['auth:sanctum',config('jetstream.auth_session'),'verified',
Route::resource('/plantel',PlantelController::class); Route::resource('/plantel',PlantelController::class);
Route::get('/registros', [CodeController::class,'registros' ])->name('registros'); Route::get('/registros', [CodeController::class,'registros' ])->name('registros');
Route::resource('/role',RoleController::class); Route::resource('/role',RoleController::class);
Route::get('/storage/{path}', function ($path) { $fullPath = storage_path('app/public/' . $path);
if (!file_exists($fullPath)) {
abort(404);
}
return response()->file($fullPath);
})->where('path', '.*')->middleware('auth');
// Route::get('/test-chat', function () { broadcast(new MessageSent('Hola realtime ')); return 'Mensaje enviado';}); // Route::get('/test-chat', function () { broadcast(new MessageSent('Hola realtime ')); return 'Mensaje enviado';});
Route::resource('/turno',TurnoController::class); Route::resource('/turno',TurnoController::class);
Route::resource('/user',UserController::class); Route::resource('/user',UserController::class);