route('databaseUuid'); $resource = getResourceByUuid($databaseIdentifier, data_get(auth()->user()->currentTeam(), 'id')); if (is_null($resource)) { return response()->json(['error' => 'You do not have permission for this database'], 500); } $chunk = $request->file('file'); $originalName = $chunk instanceof UploadedFile ? $chunk->getClientOriginalName() : null; if (blank($originalName) || ! self::hasAllowedExtension($originalName)) { return response()->json([ 'error' => 'Unsupported file type. Allowed extensions: '.implode(', ', self::ALLOWED_EXTENSIONS), ], 422); } $declaredTotalSize = (int) $request->input('dzTotalFilesize', 0); if ($declaredTotalSize > self::MAX_BYTES) { return response()->json([ 'error' => 'File exceeds maximum allowed size of '.self::formatMaxSize().'.', ], 422); } $receiver = new FileReceiver('file', $request, HandlerFactory::classFromRequest($request)); if ($receiver->isUploaded() === false) { throw new UploadMissingFileException; } $save = $receiver->receive(); if ($save->isFinished()) { // Use the original identifier from the route to maintain path consistency // For ServiceDatabase: {name}-{service_uuid} // For standalone databases: {uuid} return $this->saveFile($save->getFile(), $databaseIdentifier); } $handler = $save->handler(); return response()->json([ 'done' => $handler->getPercentageDone(), 'status' => true, ]); } protected function saveFile(UploadedFile $file, string $resourceIdentifier) { $originalName = $file->getClientOriginalName(); $size = $file->getSize(); if (! self::hasAllowedExtension($originalName) || $size === false || $size > self::MAX_BYTES) { @unlink($file->getPathname()); return response()->json([ 'error' => 'Uploaded file failed validation.', ], 422); } $mime = str_replace('/', '-', $file->getMimeType()); $filePath = "upload/{$resourceIdentifier}"; $finalPath = storage_path('app/'.$filePath); $file->move($finalPath, 'restore'); return response()->json([ 'mime_type' => $mime, ]); } private static function hasAllowedExtension(string $name): bool { $lower = strtolower($name); $suffixes = array_map(fn ($ext) => '.'.$ext, self::ALLOWED_EXTENSIONS); usort($suffixes, fn ($a, $b) => strlen($b) <=> strlen($a)); foreach ($suffixes as $suffix) { if (! str_ends_with($lower, $suffix)) { continue; } $stem = substr($lower, 0, -strlen($suffix)); if ($stem !== '' && ! str_ends_with($stem, '.')) { return true; } return false; } return false; } private static function formatMaxSize(): string { return (self::MAX_BYTES / (1024 * 1024 * 1024)).' GiB'; } }