diff --git a/_ide_helper.php b/_ide_helper.php index fe5197ec..099bb772 100644 --- a/_ide_helper.php +++ b/_ide_helper.php @@ -3,7 +3,7 @@ /** * A helper file for Laravel, to provide autocomplete information to your IDE - * Generated for Laravel 6.18.3 on 2020-04-27 09:19:35. + * Generated for Laravel 6.18.3 on 2020-04-28 07:53:27. * * This file should not be included in your code, only analyzed by your IDE! * diff --git a/app/Http/Controllers/FileBrowser/BrowseController.php b/app/Http/Controllers/FileBrowser/BrowseController.php index ffbfa4dc..3964132e 100644 --- a/app/Http/Controllers/FileBrowser/BrowseController.php +++ b/app/Http/Controllers/FileBrowser/BrowseController.php @@ -131,7 +131,7 @@ class BrowseController extends Controller * * @return array */ - public function folder_tree() { + public function navigation_tree() { $folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name') ->where('parent_id', 0) diff --git a/app/Http/Controllers/FileFunctions/EditItemsController.php b/app/Http/Controllers/FileFunctions/EditItemsController.php index 0c85006f..7324be1e 100644 --- a/app/Http/Controllers/FileFunctions/EditItemsController.php +++ b/app/Http/Controllers/FileFunctions/EditItemsController.php @@ -2,387 +2,327 @@ namespace App\Http\Controllers\FileFunctions; -use App\Share; -use Illuminate\Support\Arr; +use App\Http\Requests\FileFunctions\CreateFolderRequest; +use App\Http\Requests\FileFunctions\DeleteItemRequest; +use App\Http\Requests\FileFunctions\RenameItemRequest; +use App\Http\Requests\FileFunctions\MoveItemRequest; +use App\Http\Requests\FileFunctions\UploadRequest; +use Illuminate\Contracts\Routing\ResponseFactory; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\DB; -use Intervention\Image\ImageManagerStatic as Image; -use Illuminate\Support\Facades\Validator; -use Illuminate\Support\Facades\Storage; use App\Http\Controllers\Controller; -use Illuminate\Http\Request; -use Illuminate\Support\Str; +use App\Http\Tools\Guardian; +use App\Http\Tools\Editor; use App\FileManagerFolder; use App\FileManagerFile; -use Response; +use Exception; class EditItemsController extends Controller { /** - * Create new folder + * Create new folder for authenticated master|editor user * - * @param Request $request - * @return array + * @param CreateFolderRequest $request + * @return FileManagerFolder|Model */ - public function create_folder(Request $request) + public function user_create_folder(CreateFolderRequest $request) { - // Check permission to create folder for authenticated public editor - if ( ! $request->user()->tokenCan('master') ) { - $this->check_access($request, $request->parent_id); + // Check permission to create folder for authenticated editor + if ($request->user()->tokenCan('editor')) { + + // check if shared_token cookie exist + if (!$request->hasCookie('shared_token')) abort('401'); + + // Get shared token + $shared = get_shared($request->cookie('shared_token')); + + // Check access to requested directory + Guardian::check_item_access($request->parent_id, $shared); } - // Validate request - $validator = Validator::make($request->all(), [ - 'parent_id' => 'required|integer', - 'name' => 'string', - ]); + // Create new folder + return Editor::create_folder($request); + } - // Return error - if ($validator->fails()) abort(400, 'Bad input'); + /** + * Create new folder for guest user with edit permission + * + * @param CreateFolderRequest $request + * @param $token + * @return FileManagerFolder|Model + */ + public function guest_create_folder(CreateFolderRequest $request, $token) + { + // Get shared record + $shared = get_shared($token); - // Get parent_id from request - $parent_id = $request->parent_id === 0 ? 0 : $request->parent_id; + // Check shared permission + if (!is_editor($shared)) abort(403); + + // Check access to requested directory + Guardian::check_item_access($request->parent_id, $shared); // Create folder - $folder = FileManagerFolder::create([ - 'user_id' => Auth::id(), - 'parent_id' => $parent_id, - 'name' => $request->has('name') ? $request->input('name') : 'New Folder', - 'type' => 'folder', - 'unique_id' => $this->get_unique_id(), - 'user_scope' => $request->user()->token()->scopes[0], - ]); - - // Return new folder - return $folder; + return Editor::create_folder($request, $shared); } /** - * Rename item name + * Rename item for authenticated master|editor user * - * @param Request $request + * @param RenameItemRequest $request + * @param $unique_id * @return mixed */ - public function rename_item(Request $request, $unique_id) + public function user_rename_item(RenameItemRequest $request, $unique_id) { - // Validate request - $validator = Validator::make($request->all(), [ - 'name' => 'required|string', - 'type' => 'required|string', - ]); + // Check permission to rename item for authenticated editor + if ($request->user()->tokenCan('editor')) { - // Return error - if ($validator->fails()) abort(400, 'Bad input'); + // check if shared_token cookie exist + if (!$request->hasCookie('shared_token')) abort('401'); - // Get user id - $user_id = Auth::id(); + // Get shared token + $shared = get_shared($request->cookie('shared_token')); - // Update folder name - if ($request->type === 'folder') { + // Get file|folder item + $item = get_item($request->type, $unique_id, Auth::id()); - $item = FileManagerFolder::where('unique_id', $unique_id) - ->where('user_id', $user_id) - ->firstOrFail(); - - // Check permission to rename for authenticated public editor - if ( ! $request->user()->tokenCan('master') ) { - $this->check_access($request, $item->unique_id); + // Check access to requested directory + if ($request->type === 'folder') { + Guardian::check_item_access($item->unique_id, $shared); + } else { + Guardian::check_item_access($item->folder_id, $shared); } - - $item->name = $request->name; - $item->save(); - - } else { - - $item = FileManagerFile::where('unique_id', $unique_id) - ->where('user_id', $user_id) - ->firstOrFail(); - - // Check permission to rename for authenticated public editor - if ( ! $request->user()->tokenCan('master') ) { - $this->check_access($request, $item->folder_id); - } - - $item->name = $request->name; - $item->save(); } - // Return updated item - return $item; + // Rename Item + return Editor::rename_item($request, $unique_id); } /** - * Delete item + * Rename item for guest user with edit permission * - * @param Request $request + * @param RenameItemRequest $request * @param $unique_id - * @throws \Exception + * @param $token + * @return mixed */ - public function delete_item(Request $request, $unique_id) + public function guest_rename_item(RenameItemRequest $request, $unique_id, $token) { - // Validate request - $validator = Validator::make($request->all(), [ - 'type' => 'required|string', - 'force_delete' => 'required|boolean', - ]); + // Get shared record + $shared = get_shared($token); - // Return error - if ($validator->fails()) abort(400, 'Bad input'); + // Check shared permission + if (!is_editor($shared)) abort(403); - // Get user id - $user = Auth::user(); + // Get file|folder item + $item = get_item($request->type, $unique_id, $shared->user_id); - // Delete folder + // Check access to requested item if ($request->type === 'folder') { - - // Get folder - $folder = FileManagerFolder::withTrashed() - ->with(['folders']) - ->where('user_id', $user->id) - ->where('unique_id', $unique_id) - ->first(); - - // Check permission to delete for authenticated public editor - if ( ! $request->user()->tokenCan('master') ) { - $this->check_access($request, $folder->unique_id); - } - - // Force delete children files - if ($request->force_delete) { - - // Get children folder ids - $child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id'); - - // Get children files - $files = FileManagerFile::onlyTrashed() - ->where('user_id', $user->id) - ->whereIn('folder_id', Arr::flatten([$unique_id, $child_folders])) - ->get(); - - // Remove all children files - foreach ($files as $file) { - - // Delete file - Storage::disk('local')->delete('/file-manager/' . $file->basename); - - // Delete thumbnail if exist - if (!is_null($file->thumbnail)) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail')); - - // Delete file permanently - $file->forceDelete(); - } - - // Delete folder record - $folder->forceDelete(); - - } else { - - // Remove folder from user favourites - $user->favourites()->detach($unique_id); - - // Soft delete folder record - $folder->delete(); - } + Guardian::check_item_access($item->unique_id, $shared); } else { - - $file = FileManagerFile::withTrashed() - ->where('user_id', $user->id) - ->where('unique_id', $unique_id) - ->first(); - - // Check permission to delete for authenticated public editor - if ( ! $request->user()->tokenCan('master') ) { - $this->check_access($request, $file->folder_id); - } - - if ($request->force_delete) { - - // Delete file - Storage::disk('local')->delete('/file-manager/' . $file->basename); - - // Delete thumbnail if exist - if ($file->thumbnail) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail')); - - // Delete file permanently - $file->forceDelete(); - } else { - - // Soft delete file - $file->delete(); - } + Guardian::check_item_access($item->folder_id, $shared); } + + // Rename item + return Editor::rename_item($request, $unique_id, $shared); } /** - * Upload items + * Delete item for authenticated master|editor user * - * @param Request $request - * @return array + * @param DeleteItemRequest $request + * @param $unique_id + * @return ResponseFactory|\Illuminate\Http\Response + * @throws Exception */ - public function upload_item(Request $request) + public function user_delete_item(DeleteItemRequest $request, $unique_id) { - // Check permission to upload for authenticated public editor - if ( ! $request->user()->tokenCan('master') ) { - $this->check_access($request, $request->parent_id); + // Check permission to delete item for authenticated editor + if ($request->user()->tokenCan('editor')) { + + // Prevent force delete for non-master users + if ($request->force_delete) abort('401'); + + // check if shared_token cookie exist + if (!$request->hasCookie('shared_token')) abort('401'); + + // Get shared token + $shared = get_shared($request->cookie('shared_token')); + + // Get file|folder item + $item = get_item($request->type, $unique_id, Auth::id()); + + // Check access to requested directory + if ($request->type === 'folder') { + Guardian::check_item_access($item->unique_id, $shared); + } else { + Guardian::check_item_access($item->folder_id, $shared); + } } + // Delete item + Editor::delete_item($request, $unique_id); + + // Return response + return response(null, 204); + } + + /** + * Delete item for guest user with edit permission + * + * @param DeleteItemRequest $request + * @param $unique_id + * @param $token + * @return ResponseFactory|\Illuminate\Http\Response + * @throws Exception + */ + public function guest_delete_item(DeleteItemRequest $request, $unique_id, $token) + { + // Get shared record + $shared = get_shared($token); + + // Check shared permission + if (!is_editor($shared)) abort(403); + + // Get file|folder item + $item = get_item($request->type, $unique_id, $shared->user_id); + + // Check access to requested item + if ($request->type === 'folder') { + Guardian::check_item_access($item->unique_id, $shared); + } else { + Guardian::check_item_access($item->folder_id, $shared); + } + + // Delete item + Editor::delete_item($request, $unique_id, $shared); + + // Return response + return response(null, 204); + } + + /** + * Delete file for authenticated master|editor user + * + * @param UploadRequest $request + * @return FileManagerFile|Model + */ + public function user_upload(UploadRequest $request) + { // Check if user can upload if (config('vuefilemanager.limit_storage_by_capacity') && user_storage_percentage() >= 100) { abort(423, 'You exceed your storage limit!'); } - // Validate request - $validator = Validator::make($request->all(), [ - 'parent_id' => 'required|integer', - 'file' => 'required|file', - ]); + // Check permission to upload for authenticated editor + if ($request->user()->tokenCan('editor')) { - // Return error - if ($validator->fails()) abort(400, 'Bad input'); + // check if shared_token cookie exist + if (!$request->hasCookie('shared_token')) abort('401'); - // Get parent_id from request - $folder_id = $request->parent_id === 0 ? 0 : $request->parent_id; - $file = $request->file('file'); + // Get shared token + $shared = get_shared($request->cookie('shared_token')); - // File - $filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName()); - $filetype = get_file_type($file); - $thumbnail = null; - $filesize = $file->getSize(); - $directory = 'file-manager'; - - // create directory if not exist - if (!Storage::disk('local')->exists($directory)) { - Storage::disk('local')->makeDirectory($directory); + // Check access to requested directory + Guardian::check_item_access($request->parent_id, $shared); } - // Store to disk - Storage::disk('local')->putFileAs($directory, $file, $filename, 'public'); + // Return new uploaded file + return Editor::upload($request); + } - // Create image thumbnail - if ($filetype == 'image') { + /** + * Delete file for guest user with edit permission + * + * @param UploadRequest $request + * @param $token + * @return FileManagerFile|Model + */ + public function guest_upload(UploadRequest $request, $token) + { + // Get shared record + $shared = get_shared($token); - $thumbnail = 'thumbnail-' . $filename; + // Check shared permission + if (!is_editor($shared)) abort(403); - // Create intervention image - $image = Image::make($file->getRealPath())->orientate(); + // Check access to requested directory + Guardian::check_item_access($request->parent_id, $shared); - $image->resize(256, null, function ($constraint) { - $constraint->aspectRatio(); - })->stream(); + // Return new uploaded file + $new_file = Editor::upload($request, $shared); - // Store thumbnail to s3 - Storage::disk('local')->put($directory . '/' . $thumbnail, $image); - } - - // Store file - $new_file = FileManagerFile::create([ - 'user_id' => Auth::id(), - 'name' => pathinfo($file->getClientOriginalName())['filename'], - 'basename' => $filename, - 'folder_id' => $folder_id, - 'mimetype' => $file->getClientOriginalExtension(), - 'filesize' => $filesize, - 'type' => $filetype, - 'thumbnail' => $thumbnail, - 'unique_id' => $this->get_unique_id(), - 'user_scope' => $request->user()->token()->scopes[0], - ]); + // Set public access url + $new_file->setPublicUrl($token); return $new_file; } /** - * Move item + * Move item for authenticated master|editor user * - * @param Request $request + * @param MoveItemRequest $request * @param $unique_id - * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response + * @return ResponseFactory|\Illuminate\Http\Response */ - public function move_item(Request $request, $unique_id) + public function user_move(MoveItemRequest $request, $unique_id) { - // Validate request - $validator = Validator::make($request->all(), [ - 'to_unique_id' => 'required|integer', - 'from_type' => 'required|string', - ]); + // Check permission to upload for authenticated editor + if ($request->user()->tokenCan('editor')) { - // Return error - if ($validator->fails()) abort(400, 'Bad input'); + // check if shared_token cookie exist + if (!$request->hasCookie('shared_token')) abort('401'); - // Get user id - $user_id = Auth::id(); + // Get shared token + $shared = get_shared($request->cookie('shared_token')); - if ($request->from_type === 'folder') { - - // Move folder - $item = FileManagerFolder::where('user_id', $user_id) - ->where('unique_id', $unique_id) - ->firstOrFail(); - - $item->parent_id = $request->to_unique_id; - - } else { - - // Move file under new folder - $item = FileManagerFile::where('user_id', $user_id) - ->where('unique_id', $unique_id) - ->firstOrFail(); - - $item->folder_id = $request->to_unique_id; + // Check access to requested directory + Guardian::check_item_access($request->to_unique_id, $shared); } - $item->update(); + // Move item + Editor::move($request, $unique_id); return response('Done!', 204); } /** - * Get unique id + * Move item for guest user with edit permission * - * @return int + * @param MoveItemRequest $request + * @param $unique_id + * @param $token + * @return ResponseFactory|\Illuminate\Http\Response */ - private function get_unique_id(): int + public function guest_move(MoveItemRequest $request, $unique_id, $token) { - // Get files and folders - $folders = FileManagerFolder::withTrashed()->get(); - $files = FileManagerFile::withTrashed()->get(); + // Get shared record + $shared = get_shared($token); - // Get last ids - $folders_unique = $folders->isEmpty() ? 0 : $folders->last()->unique_id; - $files_unique = $files->isEmpty() ? 0 : $files->last()->unique_id; + // Check shared permission + if (!is_editor($shared)) abort(403); - // Count new unique id - $unique_id = $folders_unique > $files_unique ? $folders_unique + 1 : $files_unique + 1; + $moving_unique_id = $unique_id; - return $unique_id; - } + if ($request->from_type !== 'folder') { + $file = FileManagerFile::where('unique_id', $unique_id) + ->where('user_id', $shared->user_id) + ->firstOrFail(); - /** - * Check if user has access to requested folder - * - * @param $request - */ - protected function check_access($request, $parent_id): void - { - // check if shared_token cookie exist - if (! $request->hasCookie('shared_token')) abort('401'); + $moving_unique_id = $file->folder_id; + } - // Get shared token - $shared = Share::where(DB::raw('BINARY `token`'), $request->cookie('shared_token')) - ->firstOrFail(); + // Check access to requested item + Guardian::check_item_access([ + $request->to_unique_id, $moving_unique_id + ], $shared); - // Get all children folders - $foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name') - ->where('user_id', $shared->user_id) - ->where('parent_id', $shared->item_id) - ->get(); + // Move item + Editor::move($request, $unique_id, $shared); - // Get all authorized parent folders by shared folder as root of tree - $accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]); - - // Check user access - if (!in_array($parent_id, $accessible_folder_ids)) abort(403); + return response('Done!', 204); } } \ No newline at end of file diff --git a/app/Http/Controllers/FileFunctions/ShareController.php b/app/Http/Controllers/FileFunctions/ShareController.php index 9ea3ffe9..bb99d672 100644 --- a/app/Http/Controllers/FileFunctions/ShareController.php +++ b/app/Http/Controllers/FileFunctions/ShareController.php @@ -89,6 +89,7 @@ class ShareController extends Controller * * @param $token * @return ResponseFactory|\Illuminate\Http\Response + * @throws \Exception */ public function destroy($token) { diff --git a/app/Http/Controllers/Sharing/FileSharingController.php b/app/Http/Controllers/Sharing/FileSharingController.php index 44506550..d6feb602 100644 --- a/app/Http/Controllers/Sharing/FileSharingController.php +++ b/app/Http/Controllers/Sharing/FileSharingController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Sharing; use App\Http\Controllers\Controller; use App\Http\Requests\Share\AuthenticateShareRequest; use App\Http\Resources\ShareResource; +use App\Http\Tools\Guardian; use Illuminate\Contracts\View\Factory; use Illuminate\Support\Facades\Cookie; use Illuminate\Support\Facades\DB; @@ -91,7 +92,7 @@ class FileSharingController extends Controller $shared = Share::where('token', $request->cookie('shared_token'))->firstOrFail(); // Check if user can get directory - $this->check_folder_access($unique_id, $shared); + Guardian::check_item_access($unique_id, $shared); // Get files and folders list($folders, $files) = $this->get_items($unique_id, $shared); @@ -117,7 +118,7 @@ class FileSharingController extends Controller } // Check if user can get directory - $this->check_folder_access($unique_id, $shared); + Guardian::check_item_access($unique_id, $shared); // Get files and folders list($folders, $files) = $this->get_items($unique_id, $shared); @@ -177,24 +178,64 @@ class FileSharingController extends Controller } /** - * Check if user has access to requested folder + * Get navigation tree * - * @param $folder_unique_id - * @param $shared + * @param Request $request + * @return array */ - protected function check_folder_access($unique_id, $shared): void + public function get_private_navigation_tree(Request $request) { - // Get all children folders - $foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name') - ->where('user_id', $shared->user_id) + // Get sharing record + $shared = Share::where('token', $request->cookie('shared_token'))->firstOrFail(); + + // Check if user can get directory + Guardian::check_item_access($shared->item_id, $shared); + + // Get folders + $folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name') ->where('parent_id', $shared->item_id) - ->get(); + ->where('user_id', $shared->user_id) + ->get(['id', 'parent_id', 'unique_id', 'name']); - // Get all authorized parent folders by shared folder as root of tree - $accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]); + // Return folder tree + return [ + [ + 'unique_id' => $shared->item_id, + 'name' => __('vuefilemanager.home'), + 'location' => 'public', + 'folders' => $folders, + ] + ]; + } - // Check user access - if (!in_array($unique_id, $accessible_folder_ids)) abort(401); + /** + * Get navigation tree + * + * @return array + */ + public function get_public_navigation_tree($token) + { + // Get sharing record + $shared = Share::where('token', $token)->firstOrFail(); + + // Check if user can get directory + Guardian::check_item_access($shared->item_id, $shared); + + // Get folders + $folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name') + ->where('parent_id', $shared->item_id) + ->where('user_id', $shared->user_id) + ->get(['id', 'parent_id', 'unique_id', 'name']); + + // Return folder tree + return [ + [ + 'unique_id' => $shared->item_id, + 'name' => __('vuefilemanager.home'), + 'location' => 'public', + 'folders' => $folders, + ] + ]; } /** diff --git a/app/Http/Requests/FileFunctions/CreateFolderRequest.php b/app/Http/Requests/FileFunctions/CreateFolderRequest.php new file mode 100644 index 00000000..272697d0 --- /dev/null +++ b/app/Http/Requests/FileFunctions/CreateFolderRequest.php @@ -0,0 +1,32 @@ + 'required|integer', + 'name' => 'string', + ]; + } +} diff --git a/app/Http/Requests/FileFunctions/DeleteItemRequest.php b/app/Http/Requests/FileFunctions/DeleteItemRequest.php new file mode 100644 index 00000000..032767ec --- /dev/null +++ b/app/Http/Requests/FileFunctions/DeleteItemRequest.php @@ -0,0 +1,32 @@ + 'required|string', + 'force_delete' => 'required|boolean', + ]; + } +} diff --git a/app/Http/Requests/FileFunctions/MoveItemRequest.php b/app/Http/Requests/FileFunctions/MoveItemRequest.php new file mode 100644 index 00000000..407f4cb3 --- /dev/null +++ b/app/Http/Requests/FileFunctions/MoveItemRequest.php @@ -0,0 +1,32 @@ + 'required|integer', + 'from_type' => 'required|string', + ]; + } +} diff --git a/app/Http/Requests/FileFunctions/RenameItemRequest.php b/app/Http/Requests/FileFunctions/RenameItemRequest.php new file mode 100644 index 00000000..865fda41 --- /dev/null +++ b/app/Http/Requests/FileFunctions/RenameItemRequest.php @@ -0,0 +1,32 @@ + 'required|string', + 'type' => 'required|string', + ]; + } +} diff --git a/app/Http/Requests/FileFunctions/UploadRequest.php b/app/Http/Requests/FileFunctions/UploadRequest.php new file mode 100644 index 00000000..da425a6a --- /dev/null +++ b/app/Http/Requests/FileFunctions/UploadRequest.php @@ -0,0 +1,32 @@ + 'required|integer', + 'file' => 'required|file', + ]; + } +} diff --git a/app/Http/Tools/Editor.php b/app/Http/Tools/Editor.php new file mode 100644 index 00000000..3f6b75fc --- /dev/null +++ b/app/Http/Tools/Editor.php @@ -0,0 +1,272 @@ +user()->token()->scopes[0] : 'editor'; + $name = $request->has('name') ? $request->input('name') : 'New Folder'; + $user_id = is_null($shared) ? Auth::id() : $shared->user_id; + + // Create folder + $folder = FileManagerFolder::create([ + 'parent_id' => $request->parent_id, + 'unique_id' => get_unique_id(), + 'user_scope' => $user_scope, + 'user_id' => $user_id, + 'type' => 'folder', + 'name' => $name, + ]); + + // Return new folder + return $folder; + } + + /** + * Rename item name + * + * @param RenameItemRequest $request + * @param $unique_id + * @return mixed + */ + public static function rename_item($request, $unique_id, $shared = null) + { + // Get user id + $user_id = is_null($shared) ? Auth::id() : $shared->user_id; + + // Get item + $item = get_item($request->type, $unique_id, $user_id); + + // Rename item + $item->update([ + 'name' => $request->name + ]); + + // Return updated item + return $item; + } + + /** + * Delete file or folder + * + * @param $request + * @param $unique_id + * @param null $shared + * @throws \Exception + */ + public static function delete_item($request, $unique_id, $shared = null) + { + // Get user id + $user = is_null($shared) ? Auth::user() : User::findOrFail($shared->user_id); + + // Delete folder + if ($request->type === 'folder') { + + // Get folder + $folder = FileManagerFolder::withTrashed() + ->with(['folders']) + ->where('user_id', $user->id) + ->where('unique_id', $unique_id) + ->first(); + + // TODO: delete folder shared record + + // Force delete children files + if ($request->force_delete) { + + // Get children folder ids + $child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id'); + + // Get children files + $files = FileManagerFile::onlyTrashed() + ->where('user_id', $user->id) + ->whereIn('folder_id', Arr::flatten([$unique_id, $child_folders])) + ->get(); + + // Remove all children files + foreach ($files as $file) { + + // Delete file + Storage::disk('local')->delete('/file-manager/' . $file->basename); + + // Delete thumbnail if exist + if (!is_null($file->thumbnail)) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail')); + + // Delete file permanently + $file->forceDelete(); + } + + // Delete folder record + $folder->forceDelete(); + } + + // Soft delete items + if (!$request->force_delete) { + + // Remove folder from user favourites + $user->favourites()->detach($unique_id); + + // Soft delete folder record + $folder->delete(); + } + } + + // Delete item + if ($request->type !== 'folder') { + + // Get file + $file = FileManagerFile::withTrashed() + ->where('user_id', $user->id) + ->where('unique_id', $unique_id) + ->first(); + + // TODO: delete file shared record + + // Force delete file + if ($request->force_delete) { + + // Delete file + Storage::disk('local')->delete('/file-manager/' . $file->basename); + + // Delete thumbnail if exist + if ($file->thumbnail) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail')); + + // Delete file permanently + $file->forceDelete(); + } + + // Soft delete file + if (!$request->force_delete) { + + // Soft delete file + $file->delete(); + } + } + } + + /** + * Upload file + * + * @param $request + * @param $unique_id + * @param null $shared + * @return FileManagerFile|\Illuminate\Database\Eloquent\Model + */ + public static function upload($request, $shared = null) + { + // Get user data + $user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor'; + $user_id = is_null($shared) ? Auth::id() : $shared->user_id; + + // Get parent_id from request + $folder_id = $request->parent_id === 0 ? 0 : $request->parent_id; + $file = $request->file('file'); + + // File + $filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName()); + $filetype = get_file_type($file); + $filesize = $file->getSize(); + $directory = 'file-manager'; + $thumbnail = null; + + // create directory if not exist + if (!Storage::disk('local')->exists($directory)) { + Storage::disk('local')->makeDirectory($directory); + } + + // Store to disk + Storage::disk('local')->putFileAs($directory, $file, $filename, 'public'); + + // Create image thumbnail + if ($filetype == 'image') { + + // Get thumbnail name + $thumbnail = 'thumbnail-' . $filename; + + // Create intervention image + $image = Image::make($file->getRealPath())->orientate(); + + // Resize image + $image->resize(256, null, function ($constraint) { + $constraint->aspectRatio(); + })->stream(); + + // Store thumbnail to disk + Storage::disk('local')->put($directory . '/' . $thumbnail, $image); + } + + // Store file + $options = [ + 'name' => pathinfo($file->getClientOriginalName())['filename'], + 'mimetype' => $file->getClientOriginalExtension(), + 'unique_id' => get_unique_id(), + 'user_scope' => $user_scope, + 'folder_id' => $folder_id, + 'thumbnail' => $thumbnail, + 'basename' => $filename, + 'filesize' => $filesize, + 'type' => $filetype, + 'user_id' => $user_id, + ]; + + // Return new file + return FileManagerFile::create($options); + } + + /** + * Move folder or file to new location + * + * @param $request + * @param $unique_id + * @param null $shared + */ + public static function move($request, $unique_id, $shared = null) + { + // Get user id + $user_id = is_null($shared) ? Auth::id() : $shared->user_id; + + if ($request->from_type === 'folder') { + + // Move folder + $item = FileManagerFolder::where('user_id', $user_id) + ->where('unique_id', $unique_id) + ->firstOrFail(); + + $item->update([ + 'parent_id' => $request->to_unique_id + ]); + + } else { + + // Move file under new folder + $item = FileManagerFile::where('user_id', $user_id) + ->where('unique_id', $unique_id) + ->firstOrFail(); + + $item->update([ + 'folder_id' => $request->to_unique_id + ]); + } + } +} \ No newline at end of file diff --git a/app/Http/Tools/Guardian.php b/app/Http/Tools/Guardian.php new file mode 100644 index 00000000..0cef6609 --- /dev/null +++ b/app/Http/Tools/Guardian.php @@ -0,0 +1,42 @@ +where('user_id', $shared->user_id) + ->where('parent_id', $shared->item_id) + ->get(); + + // Get all authorized parent folders by shared folder as root of tree + $accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]); + + // Check user access + if ( is_array($requested_id) ) { + foreach ($requested_id as $id) { + if (!in_array($id, $accessible_folder_ids)) + abort(403); + } + } + + if (! is_array($requested_id)) { + if (! in_array($requested_id, $accessible_folder_ids)) + abort(403); + } + } +} \ No newline at end of file diff --git a/app/Http/helpers.php b/app/Http/helpers.php index cd6d7550..fc8a0772 100644 --- a/app/Http/helpers.php +++ b/app/Http/helpers.php @@ -1,11 +1,83 @@ where('user_id', $user_id) + ->firstOrFail(); + } + + // Return file item + return FileManagerFile::where('unique_id', $unique_id) + ->where('user_id', $user_id) + ->firstOrFail(); +} + +/** + * Get shared token + * + * @param $token + * @return \Illuminate\Database\Eloquent\Builder|Model + */ +function get_shared($token) { + + return Share::where(DB::raw('BINARY `token`'), $token) + ->firstOrFail(); +} + +/** + * Check if shared permission is editor + * + * @param $shared + * @return bool + */ +function is_editor($shared) { + + return $shared->permission === 'editor'; +} + +/** + * Get unique id + * + * @return int + */ +function get_unique_id(): int +{ + // Get files and folders + $folders = FileManagerFolder::withTrashed()->get(); + $files = FileManagerFile::withTrashed()->get(); + + // Get last ids + $folders_unique = $folders->isEmpty() ? 0 : $folders->last()->unique_id; + $files_unique = $files->isEmpty() ? 0 : $files->last()->unique_id; + + // Count new unique id + $unique_id = $folders_unique > $files_unique ? $folders_unique + 1 : $files_unique + 1; + + return $unique_id; +} /** * Store user avatar to storage @@ -102,8 +174,7 @@ function get_storage_fill_percentage($used, $capacity) */ function user_storage_percentage() { - - $user = \Illuminate\Support\Facades\Auth::user(); + $user = Auth::user(); return get_storage_fill_percentage($user->used_capacity, config('vuefilemanager.user_storage_capacity')); } diff --git a/public/mix-manifest.json b/public/mix-manifest.json index bee9b7da..0366fde9 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,5 +1,97 @@ { "/js/main.js": "/js/main.js", "/css/app.css": "/css/app.css", - "/js/main.9a27394a2df24ee693e3.hot-update.js": "/js/main.9a27394a2df24ee693e3.hot-update.js" + "/js/main.9a27394a2df24ee693e3.hot-update.js": "/js/main.9a27394a2df24ee693e3.hot-update.js", + "/js/main.26f701f7b52599858cce.hot-update.js": "/js/main.26f701f7b52599858cce.hot-update.js", + "/js/main.5121a1dc87cc3f3442cd.hot-update.js": "/js/main.5121a1dc87cc3f3442cd.hot-update.js", + "/js/main.8b54f2c597a60d415870.hot-update.js": "/js/main.8b54f2c597a60d415870.hot-update.js", + "/js/main.53935909cecacef877d0.hot-update.js": "/js/main.53935909cecacef877d0.hot-update.js", + "/js/main.6e0d2ac0add6c3e6dc84.hot-update.js": "/js/main.6e0d2ac0add6c3e6dc84.hot-update.js", + "/js/main.bcef9d636d3dfe572ecc.hot-update.js": "/js/main.bcef9d636d3dfe572ecc.hot-update.js", + "/js/main.07de0a9dbfed267ff7b2.hot-update.js": "/js/main.07de0a9dbfed267ff7b2.hot-update.js", + "/js/main.549012c4fffc95472aa6.hot-update.js": "/js/main.549012c4fffc95472aa6.hot-update.js", + "/js/main.ea575a8d60a5a25453e4.hot-update.js": "/js/main.ea575a8d60a5a25453e4.hot-update.js", + "/js/main.880f1e5ff9834e6633ec.hot-update.js": "/js/main.880f1e5ff9834e6633ec.hot-update.js", + "/js/main.9cd0cd846091e6779623.hot-update.js": "/js/main.9cd0cd846091e6779623.hot-update.js", + "/js/main.435761e62a7eba7f7511.hot-update.js": "/js/main.435761e62a7eba7f7511.hot-update.js", + "/js/main.8ef42b97a65fa42e754c.hot-update.js": "/js/main.8ef42b97a65fa42e754c.hot-update.js", + "/js/main.801802ad6742f1431b33.hot-update.js": "/js/main.801802ad6742f1431b33.hot-update.js", + "/js/main.712419afb068ad058a73.hot-update.js": "/js/main.712419afb068ad058a73.hot-update.js", + "/js/main.559f1d43ac058be060f7.hot-update.js": "/js/main.559f1d43ac058be060f7.hot-update.js", + "/js/main.d8b716639ab25f3dc50a.hot-update.js": "/js/main.d8b716639ab25f3dc50a.hot-update.js", + "/js/main.efd3e8d2d7598c6c5ad5.hot-update.js": "/js/main.efd3e8d2d7598c6c5ad5.hot-update.js", + "/js/main.a337a75d4abd0a14c156.hot-update.js": "/js/main.a337a75d4abd0a14c156.hot-update.js", + "/js/main.40d1dab8fa1b64701590.hot-update.js": "/js/main.40d1dab8fa1b64701590.hot-update.js", + "/js/main.7fc88aadbaf4dddd1177.hot-update.js": "/js/main.7fc88aadbaf4dddd1177.hot-update.js", + "/js/main.68350763e369b5ff2093.hot-update.js": "/js/main.68350763e369b5ff2093.hot-update.js", + "/js/main.6284a84d480e86837360.hot-update.js": "/js/main.6284a84d480e86837360.hot-update.js", + "/js/main.25ee0aa3ee03e3e8b38f.hot-update.js": "/js/main.25ee0aa3ee03e3e8b38f.hot-update.js", + "/js/main.2e26a22377d42ebff156.hot-update.js": "/js/main.2e26a22377d42ebff156.hot-update.js", + "/js/main.b59bbae58419a6b486cf.hot-update.js": "/js/main.b59bbae58419a6b486cf.hot-update.js", + "/js/main.d2355590570597337ecf.hot-update.js": "/js/main.d2355590570597337ecf.hot-update.js", + "/js/main.60d4eefa65e064d28377.hot-update.js": "/js/main.60d4eefa65e064d28377.hot-update.js", + "/js/main.4167e6ccc3b10d70c878.hot-update.js": "/js/main.4167e6ccc3b10d70c878.hot-update.js", + "/js/main.1d8dd28c32fe1ebb0f90.hot-update.js": "/js/main.1d8dd28c32fe1ebb0f90.hot-update.js", + "/js/main.ad773a1236560dfa16b9.hot-update.js": "/js/main.ad773a1236560dfa16b9.hot-update.js", + "/js/main.34c776e9045fb0e219c3.hot-update.js": "/js/main.34c776e9045fb0e219c3.hot-update.js", + "/js/main.092895cf0d85296ec513.hot-update.js": "/js/main.092895cf0d85296ec513.hot-update.js", + "/js/main.a46dde16305495525978.hot-update.js": "/js/main.a46dde16305495525978.hot-update.js", + "/js/main.b9df9d4300e51d62c760.hot-update.js": "/js/main.b9df9d4300e51d62c760.hot-update.js", + "/js/main.ef40152e201f13bc6b7b.hot-update.js": "/js/main.ef40152e201f13bc6b7b.hot-update.js", + "/js/main.03e94dd396114f5ce51f.hot-update.js": "/js/main.03e94dd396114f5ce51f.hot-update.js", + "/js/main.ae8691214086a1aafe6d.hot-update.js": "/js/main.ae8691214086a1aafe6d.hot-update.js", + "/js/main.42070d8db8abc6c57f08.hot-update.js": "/js/main.42070d8db8abc6c57f08.hot-update.js", + "/js/main.ff4a9feafb80b24156ea.hot-update.js": "/js/main.ff4a9feafb80b24156ea.hot-update.js", + "/js/main.a75b114c09bd29e14d0c.hot-update.js": "/js/main.a75b114c09bd29e14d0c.hot-update.js", + "/js/main.3c80fdca8d8a4151fec5.hot-update.js": "/js/main.3c80fdca8d8a4151fec5.hot-update.js", + "/js/main.ce2a2b97c841955d6004.hot-update.js": "/js/main.ce2a2b97c841955d6004.hot-update.js", + "/js/main.32b5fdecf37fed13cd9a.hot-update.js": "/js/main.32b5fdecf37fed13cd9a.hot-update.js", + "/js/main.7a89ccb6115f0faacdfb.hot-update.js": "/js/main.7a89ccb6115f0faacdfb.hot-update.js", + "/js/main.92699644dc4433d69518.hot-update.js": "/js/main.92699644dc4433d69518.hot-update.js", + "/js/main.95ab80867410adfb44d4.hot-update.js": "/js/main.95ab80867410adfb44d4.hot-update.js", + "/js/main.15ec5d8a6721629ca107.hot-update.js": "/js/main.15ec5d8a6721629ca107.hot-update.js", + "/js/main.7c08936d73cc17d9f314.hot-update.js": "/js/main.7c08936d73cc17d9f314.hot-update.js", + "/js/main.3d44fb777bb96f9cfdb7.hot-update.js": "/js/main.3d44fb777bb96f9cfdb7.hot-update.js", + "/js/main.98249452457878999097.hot-update.js": "/js/main.98249452457878999097.hot-update.js", + "/js/main.254701868eb16ecc7ceb.hot-update.js": "/js/main.254701868eb16ecc7ceb.hot-update.js", + "/js/main.73bb5ad5ec65301443bd.hot-update.js": "/js/main.73bb5ad5ec65301443bd.hot-update.js", + "/js/main.d3e2774f2e315b7c16b5.hot-update.js": "/js/main.d3e2774f2e315b7c16b5.hot-update.js", + "/js/main.e1c6df6a9c86ceb0f997.hot-update.js": "/js/main.e1c6df6a9c86ceb0f997.hot-update.js", + "/js/main.84e6dd621e31be103cb9.hot-update.js": "/js/main.84e6dd621e31be103cb9.hot-update.js", + "/js/main.f9b77ba27f8c37a3cab6.hot-update.js": "/js/main.f9b77ba27f8c37a3cab6.hot-update.js", + "/js/main.4568b1ac1065ffb6734b.hot-update.js": "/js/main.4568b1ac1065ffb6734b.hot-update.js", + "/js/main.34dd57888d1ba88b8b51.hot-update.js": "/js/main.34dd57888d1ba88b8b51.hot-update.js", + "/js/main.427a9203ec38e951d238.hot-update.js": "/js/main.427a9203ec38e951d238.hot-update.js", + "/js/main.c0ef7695de0e2fb4df8f.hot-update.js": "/js/main.c0ef7695de0e2fb4df8f.hot-update.js", + "/js/main.d1ac8bf7abe8c3cab86f.hot-update.js": "/js/main.d1ac8bf7abe8c3cab86f.hot-update.js", + "/js/main.89cd5452893cfa0c4306.hot-update.js": "/js/main.89cd5452893cfa0c4306.hot-update.js", + "/js/main.9efa7621633482f41475.hot-update.js": "/js/main.9efa7621633482f41475.hot-update.js", + "/js/main.64f6c551250c31f1a04f.hot-update.js": "/js/main.64f6c551250c31f1a04f.hot-update.js", + "/js/main.afa8179642bbf412e95a.hot-update.js": "/js/main.afa8179642bbf412e95a.hot-update.js", + "/js/main.5c4a761e3d1b8ae3e586.hot-update.js": "/js/main.5c4a761e3d1b8ae3e586.hot-update.js", + "/js/main.0ceed72f1427b5958022.hot-update.js": "/js/main.0ceed72f1427b5958022.hot-update.js", + "/js/main.6131813f3daf3dbf18df.hot-update.js": "/js/main.6131813f3daf3dbf18df.hot-update.js", + "/js/main.1d7089edabf59ca7143b.hot-update.js": "/js/main.1d7089edabf59ca7143b.hot-update.js", + "/js/main.835a0e8499a6e9ce3eb6.hot-update.js": "/js/main.835a0e8499a6e9ce3eb6.hot-update.js", + "/js/main.34ca6eeac2f66555a259.hot-update.js": "/js/main.34ca6eeac2f66555a259.hot-update.js", + "/js/main.b103b99817043bcec0ee.hot-update.js": "/js/main.b103b99817043bcec0ee.hot-update.js", + "/js/main.2f39160d1e959ee8065e.hot-update.js": "/js/main.2f39160d1e959ee8065e.hot-update.js", + "/js/main.9ebf2fb72f11bfa290af.hot-update.js": "/js/main.9ebf2fb72f11bfa290af.hot-update.js", + "/js/main.a55c90d56d628ca5983b.hot-update.js": "/js/main.a55c90d56d628ca5983b.hot-update.js", + "/js/main.c77fe61a6e467daa6312.hot-update.js": "/js/main.c77fe61a6e467daa6312.hot-update.js", + "/js/main.2b72fda2d2b42a05b446.hot-update.js": "/js/main.2b72fda2d2b42a05b446.hot-update.js", + "/js/main.ae606d26a4b1b2344ca2.hot-update.js": "/js/main.ae606d26a4b1b2344ca2.hot-update.js", + "/js/main.5bd37eed26fa598948d5.hot-update.js": "/js/main.5bd37eed26fa598948d5.hot-update.js", + "/js/main.130254a5160e0ef992a1.hot-update.js": "/js/main.130254a5160e0ef992a1.hot-update.js", + "/js/main.5fa2ead36e925d546d3d.hot-update.js": "/js/main.5fa2ead36e925d546d3d.hot-update.js", + "/js/main.dba558d979b0090f27dd.hot-update.js": "/js/main.dba558d979b0090f27dd.hot-update.js", + "/js/main.44e728d411a734bc1a30.hot-update.js": "/js/main.44e728d411a734bc1a30.hot-update.js", + "/js/main.9301a0253ea88d48eaec.hot-update.js": "/js/main.9301a0253ea88d48eaec.hot-update.js", + "/js/main.c32533dd170b4ad36995.hot-update.js": "/js/main.c32533dd170b4ad36995.hot-update.js", + "/js/main.70d54b5f4ad55603282c.hot-update.js": "/js/main.70d54b5f4ad55603282c.hot-update.js", + "/js/main.ae3ebc3222124628f432.hot-update.js": "/js/main.ae3ebc3222124628f432.hot-update.js", + "/js/main.cd30cc7c96f7330f1e28.hot-update.js": "/js/main.cd30cc7c96f7330f1e28.hot-update.js", + "/js/main.6d71eff38004e48494e6.hot-update.js": "/js/main.6d71eff38004e48494e6.hot-update.js", + "/js/main.e0368145878abbdceab2.hot-update.js": "/js/main.e0368145878abbdceab2.hot-update.js", + "/js/main.63bc86c9bdf936a03d56.hot-update.js": "/js/main.63bc86c9bdf936a03d56.hot-update.js" } diff --git a/resources/js/App.vue b/resources/js/App.vue index 68932ae3..d7e8cec4 100644 --- a/resources/js/App.vue +++ b/resources/js/App.vue @@ -31,13 +31,13 @@ - - diff --git a/routes/api.php b/routes/api.php index ba5972f7..6261b694 100644 --- a/routes/api.php +++ b/routes/api.php @@ -19,6 +19,20 @@ // Public routes Route::group(['middleware' => ['api']], function () { + // Edit Functions + Route::delete('/remove-item/{unique_id}/public/{token}', 'FileFunctions\EditItemsController@guest_delete_item'); + Route::patch('/rename-item/{unique_id}/public/{token}', 'FileFunctions\EditItemsController@guest_rename_item'); + Route::post('/create-folder/public/{token}', 'FileFunctions\EditItemsController@guest_create_folder'); + Route::patch('/move/{unique_id}/public/{token}', 'FileFunctions\EditItemsController@guest_move'); + Route::post('/upload/public/{token}', 'FileFunctions\EditItemsController@guest_upload'); + + // Sharing page browsing + Route::get('/folders/{unique_id}/public/{token}', 'Sharing\FileSharingController@get_public_folders'); + Route::get('/navigation/public/{token}', 'Sharing\FileSharingController@get_public_navigation_tree'); + Route::post('/shared/authenticate/{token}', 'Sharing\FileSharingController@authenticate'); + Route::get('/files/{token}/public', 'Sharing\FileSharingController@file_public'); + Route::get('/shared/{token}', 'FileFunctions\ShareController@show'); + // User reset password Route::post('/password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail'); Route::post('/password/reset', 'Auth\ResetPasswordController@reset'); @@ -27,12 +41,6 @@ Route::group(['middleware' => ['api']], function () { Route::post('/user/check', 'Auth\AuthController@check_account'); Route::post('/user/register', 'Auth\AuthController@register'); Route::post('/user/login', 'Auth\AuthController@login'); - - // Sharing - Route::get('/folders/{unique_id}/public/{token}', 'Sharing\FileSharingController@get_public_folders'); - Route::post('/shared/authenticate/{token}', 'Sharing\FileSharingController@authenticate'); - Route::get('/files/{token}/public', 'Sharing\FileSharingController@file_public'); - Route::get('/shared/{token}', 'FileFunctions\ShareController@show'); }); // User master Routes @@ -45,15 +53,12 @@ Route::group(['middleware' => ['auth:api', 'auth.cookie', 'scope:master']], func // Browse Route::get('/file-detail/{unique_id}', 'FileBrowser\BrowseController@file_detail'); + Route::get('/navigation', 'FileBrowser\BrowseController@navigation_tree'); Route::get('/folders/{unique_id}', 'FileBrowser\BrowseController@folder'); - Route::get('/folder-tree', 'FileBrowser\BrowseController@folder_tree'); Route::get('/shared-all', 'FileBrowser\BrowseController@shared'); Route::get('/search', 'FileBrowser\BrowseController@search'); Route::get('/trash', 'FileBrowser\BrowseController@trash'); - // Edit functions - Route::patch('/move-item/{unique_id}', 'FileFunctions\EditItemsController@move_item'); - // Trash Route::patch('/restore-item/{unique_id}', 'FileFunctions\TrashController@restore'); Route::delete('/empty-trash', 'FileFunctions\TrashController@clear'); @@ -76,6 +81,7 @@ Route::group(['middleware' => ['auth:api', 'auth.cookie', 'scope:visitor,editor' // Browse folders & files Route::get('/folders/{unique_id}/private', 'Sharing\FileSharingController@get_private_folders'); + Route::get('/navigation/private', 'Sharing\FileSharingController@get_private_navigation_tree'); Route::get('/files/private', 'Sharing\FileSharingController@file_private'); }); @@ -83,8 +89,9 @@ Route::group(['middleware' => ['auth:api', 'auth.cookie', 'scope:visitor,editor' Route::group(['middleware' => ['auth:api', 'auth.cookie', 'scope:master,editor']], function () { // Edit items - Route::delete('/remove-item/{unique_id}', 'FileFunctions\EditItemsController@delete_item'); - Route::patch('/rename-item/{unique_id}', 'FileFunctions\EditItemsController@rename_item'); - Route::post('/create-folder', 'FileFunctions\EditItemsController@create_folder'); - Route::post('/upload-file', 'FileFunctions\EditItemsController@upload_item'); + Route::delete('/remove-item/{unique_id}', 'FileFunctions\EditItemsController@user_delete_item'); + Route::patch('/rename-item/{unique_id}', 'FileFunctions\EditItemsController@user_rename_item'); + Route::post('/create-folder', 'FileFunctions\EditItemsController@user_create_folder'); + Route::patch('/move/{unique_id}', 'FileFunctions\EditItemsController@user_move'); + Route::post('/upload', 'FileFunctions\EditItemsController@user_upload'); });