diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/Http/Controllers/FileController.php | 5 | ||||
| -rw-r--r-- | app/Http/Middleware/LogVisitors.php | 29 | ||||
| -rw-r--r-- | app/Http/Requests/FileUploadRequest.php | 34 | ||||
| -rw-r--r-- | app/Models/File.php | 2 | ||||
| -rw-r--r-- | app/Providers/AppServiceProvider.php | 6 |
5 files changed, 66 insertions, 10 deletions
diff --git a/app/Http/Controllers/FileController.php b/app/Http/Controllers/FileController.php index 5d0f09a..2c25d7a 100644 --- a/app/Http/Controllers/FileController.php +++ b/app/Http/Controllers/FileController.php @@ -32,11 +32,12 @@ class FileController extends Controller */ public function upload(FileUploadRequest $request) { + Log::info('uploading'); try { $uploadedFiles = []; $urls = []; - foreach ($request->file('files') as $uploadedFile) { + foreach ($request->file('f') as $uploadedFile) { $file = $this->storeFile($uploadedFile, $request); $uploadedFiles[] = $file; $urls[] = $file->download_url; @@ -102,6 +103,7 @@ class FileController extends Controller /** * Handle individual chunk upload + * returns json or htmx, depending on value of request->input('response_type') */ public function uploadChunk(Request $request) { @@ -173,6 +175,7 @@ class FileController extends Controller */ public function completeChunkedUpload(Request $request) { + Log::info('uploading chunked'); $request->validate([ 'upload_id' => 'required|string', 'original_filename' => 'required|string', diff --git a/app/Http/Middleware/LogVisitors.php b/app/Http/Middleware/LogVisitors.php new file mode 100644 index 0000000..bb95c8c --- /dev/null +++ b/app/Http/Middleware/LogVisitors.php @@ -0,0 +1,29 @@ +<?php + +namespace App\Http\Middleware; + +use Closure; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Log; +use Symfony\Component\HttpFoundation\Response; + +class LogVisitors +{ + /** + * Handle an incoming request. + * + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + */ + public function handle(Request $request, Closure $next): Response + { + // Log visitor information to dedicated channel + Log::channel('visitors')->info('', [ + 'ip' => $request->ip(), + 'time' => now()->toDateTimeString(), + 'route' => $request->path(), + 'method' => $request->method(), + ]); + + return $next($request); + } +} diff --git a/app/Http/Requests/FileUploadRequest.php b/app/Http/Requests/FileUploadRequest.php index f4302b8..6b326b3 100644 --- a/app/Http/Requests/FileUploadRequest.php +++ b/app/Http/Requests/FileUploadRequest.php @@ -4,6 +4,9 @@ namespace App\Http\Requests; use App\Rules\MimeTypeRule; use Illuminate\Foundation\Http\FormRequest; +use Illuminate\Support\Facades\Log; +use Illuminate\Contracts\Validation\Validator; +use Illuminate\Http\Exceptions\HttpResponseException; class FileUploadRequest extends FormRequest { @@ -26,12 +29,12 @@ class FileUploadRequest extends FormRequest $config = config('fileupload'); return [ - 'files' => [ + 'f' => [ 'required', 'array', 'max:' . $config['max_files_per_upload'], ], - 'files.*' => [ + 'f.*' => [ 'required', 'file', 'max:' . $config['max_file_size'], // in KB @@ -48,12 +51,27 @@ class FileUploadRequest extends FormRequest $config = config('fileupload'); return [ - 'files.required' => 'Please select at least one file to upload.', - 'files.array' => 'Invalid file upload format.', - 'files.max' => 'You can upload a maximum of ' . $config['max_files_per_upload'] . ' files at once.', - 'files.*.required' => 'One or more files are missing.', - 'files.*.file' => 'One or more uploads are not valid files.', - 'files.*.max' => 'One or more files exceed the maximum size of ' . $config['max_file_size'] . 'KB.', + 'f.required' => 'Please select at least one file to upload.', + 'f.array' => 'Invalid file upload format.', + 'f.max' => 'You can upload a maximum of ' . $config['max_files_per_upload'] . ' files at once.', + 'f.*.required' => 'One or more files are missing.', + 'f.*.file' => 'One or more uploads are not valid files.', + 'f.*.max' => 'One or more files exceed the maximum size of ' . $config['max_file_size'] . 'KB.', ]; } + + /** + * Handle a failed validation attempt. + */ + protected function failedValidation(Validator $validator) + { + Log::warning('File upload validation failed', [ + 'ip' => $this->ip(), + 'errors' => $validator->errors()->toArray(), + 'has_files' => $this->hasFile('files'), + 'all_input' => array_keys($this->all()), + ]); + + parent::failedValidation($validator); + } } diff --git a/app/Models/File.php b/app/Models/File.php index a5a14e3..887333a 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -90,7 +90,7 @@ class File extends Model $days = $days ?? config('fileupload.expiration_days'); if (config('fileupload.expiration_enabled')) { - $this->expires_at = now()->addDays($days); + $this->expires_at = now()->addDays((int) $days); $this->save(); } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 0b1ef2f..6fd3a15 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -29,6 +29,12 @@ class AppServiceProvider extends ServiceProvider return Limit::perMinute($config['max_attempts']) ->by($request->ip()) ->response(function (Request $request, array $headers) { + \Log::warning('Rate limit exceeded', [ + 'ip' => $request->ip(), + 'url' => $request->fullUrl(), + 'retry_after' => $headers['Retry-After'] ?? 60 + ]); + return response()->json([ 'error' => 'Too many upload attempts. Please try again later.', 'retry_after' => $headers['Retry-After'] ?? 60 |
