From b8741439f5f0cd408d1cd429eca386ab9e90dacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Carodej?= Date: Thu, 12 May 2022 10:42:08 +0200 Subject: [PATCH] api refactoring part 2 --- .env.testing | 2 +- public/mix-manifest.json | 12 ++-- .../RemoteUpload/RemoteUploadPopup.vue | 2 +- .../Subscription/UserBillingAlerts.vue | 6 +- .../CreateUploadRequestPopup.vue | 2 +- resources/js/store/modules/fileBrowser.js | 2 +- resources/js/store/modules/fileFunctions.js | 10 ++-- resources/js/store/modules/uploadRequest.js | 6 +- routes/api.php | 9 ++- .../{upload-request.php => file-request.php} | 4 +- src/App/Providers/RouteServiceProvider.php | 6 +- ...enticateAndReturnBearerTokenController.php | 39 +++++++++++++ .../DestroyActiveBearerTokenController.php | 33 +++++++++++ src/App/Users/Requests/LoginUserRequest.php | 30 ++++++++++ .../Homepage/Controllers/IndexController.php | 5 +- ...ilesRemotelyForUploadRequestController.php | 31 ++-------- .../Settings/Actions/GetConfigAction.php | 15 +++-- .../Controllers/GetConfigController.php | 11 ++-- .../CreateUploadRequestRootFolderAction.php | 32 +++++++++++ .../Controllers/CreateFolderController.php | 18 ++++-- .../DeleteFileOrFolderController.php | 14 ++++- .../MoveItemInUploadRequestController.php | 10 +++- .../SetUploadRequestAsFilledController.php | 12 ++-- ...adFileChunksForUploadRequestController.php | 33 ++--------- .../UploadFileForUploadRequestController.php | 56 +++++++++++++++++++ .../Middleware/ProtectUploadRequestRoutes.php | 5 +- .../UploadRequestBrowsingTest.php | 6 +- .../UploadRequestEditingTest.php | 22 ++++---- .../UploadRequest/UploadRequestTest.php | 24 ++++---- 29 files changed, 313 insertions(+), 144 deletions(-) rename routes/{upload-request.php => file-request.php} (92%) create mode 100644 src/App/Users/Controllers/Authentication/AuthenticateAndReturnBearerTokenController.php create mode 100644 src/App/Users/Controllers/Authentication/DestroyActiveBearerTokenController.php create mode 100644 src/App/Users/Requests/LoginUserRequest.php create mode 100644 src/Domain/UploadRequest/Actions/CreateUploadRequestRootFolderAction.php create mode 100644 src/Domain/UploadRequest/Controllers/UploadFileForUploadRequestController.php diff --git a/.env.testing b/.env.testing index c38bbe3c..cdfbecfa 100644 --- a/.env.testing +++ b/.env.testing @@ -1,6 +1,6 @@ APP_NAME=Laravel APP_ENV=local -APP_KEY=base64:8yxp90qaG22isu7sxy8zfiuGvkXoAzJBtdr3/ztuH7w= +APP_KEY=base64:qO2rFS9MzY3SKl6AqwV1jMAshl9jiaC02VNjXMhrMpo= APP_DEBUG=true APP_URL=http://localhost APP_DEMO=false diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 7bf68508..3595196d 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,6 +1,6 @@ { "/js/main.js": "/js/main.js", - "/chunks/request.js": "/chunks/request.js?id=f5c1db9739c4c1c0", + "/chunks/request.js": "/chunks/request.js?id=4f2f083839a7f102", "/chunks/request-upload.js": "/chunks/request-upload.js?id=1201e261c848a844", "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=19a0784e59d768ec", "/chunks/status-check.js": "/chunks/status-check.js?id=a5ba5fb895af7040", @@ -9,13 +9,13 @@ "/chunks/environment.js": "/chunks/environment.js?id=e4fdb87ff173d48a", "/chunks/app-setup.js": "/chunks/app-setup.js?id=cbe7bfed06400736", "/chunks/admin-account.js": "/chunks/admin-account.js?id=78d257775f5fc485", - "/chunks/shared.js": "/chunks/shared.js?id=2fba310a3f0823f9", + "/chunks/shared.js": "/chunks/shared.js?id=54c3bc26f2aab8d6", "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=ebf193e6828917dc", "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=e1ca697ccf4363dc", "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=b5519d193bce2339", "/chunks/not-found.js": "/chunks/not-found.js?id=d31bd699138cf828", "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=26798085f527d955", - "/chunks/admin.js": "/chunks/admin.js?id=1eece624920f98df", + "/chunks/admin.js": "/chunks/admin.js?id=60aa9e8508a842a1", "/chunks/dashboard.js": "/chunks/dashboard.js?id=5ab55a12214433c8", "/chunks/invoices.js": "/chunks/invoices.js?id=799928609f57ca10", "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=a0c4f59d0ec4aee0", @@ -57,12 +57,12 @@ "/chunks/sign-up.js": "/chunks/sign-up.js?id=2af6073efe54c560", "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=ff8954243e86c1e1", "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=2f0401ee2fc148c4", - "/chunks/settings.js": "/chunks/settings.js?id=83d20f90399191b9", + "/chunks/settings.js": "/chunks/settings.js?id=2f6576332da7cad2", "/chunks/profile.js": "/chunks/profile.js?id=3e24bb5e1f52d4bb", "/chunks/settings-password.js": "/chunks/settings-password.js?id=d00bf503d8126dc4", "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=ecfee7f7e98204f8", - "/chunks/billing.js": "/chunks/billing.js?id=a21fc7e052c60acd", - "/chunks/platform.js": "/chunks/platform.js?id=4c28a2760f5cd8ea", + "/chunks/billing.js": "/chunks/billing.js?id=dd217d680baafb84", + "/chunks/platform.js": "/chunks/platform.js?id=220943bcb1e9f3ca", "/chunks/files.js": "/chunks/files.js?id=5f29f35c280e680b", "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=6f43aea38e0927bc", "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=6e819ffe88a0fd1d", diff --git a/resources/js/components/RemoteUpload/RemoteUploadPopup.vue b/resources/js/components/RemoteUpload/RemoteUploadPopup.vue index 02d9fa26..28b0ac74 100644 --- a/resources/js/components/RemoteUpload/RemoteUploadPopup.vue +++ b/resources/js/components/RemoteUpload/RemoteUploadPopup.vue @@ -105,7 +105,7 @@ export default { // Get route let route = { - RequestUpload: `/api/upload-request/${this.$router.currentRoute.params.token}/upload/remote`, + RequestUpload: `/api/file-request/${this.$router.currentRoute.params.token}/upload/remote`, Public: `/api/editor/upload/remote/${this.$router.currentRoute.params.token}`, }[this.$router.currentRoute.name] || '/api/upload/remote' diff --git a/resources/js/components/Subscription/UserBillingAlerts.vue b/resources/js/components/Subscription/UserBillingAlerts.vue index e6866783..341e5498 100644 --- a/resources/js/components/Subscription/UserBillingAlerts.vue +++ b/resources/js/components/Subscription/UserBillingAlerts.vue @@ -152,7 +152,7 @@ export default { this.isSendingBillingAlert = true axios - .patch(`/api/subscriptions/billing-alerts/${this.user.data.relationships.alert.data.id}`, { + .put('/api/subscriptions/billing-alert', { amount: this.billingAlertAmount, }) .then(() => { @@ -184,7 +184,7 @@ export default { this.isSendingBillingAlert = true axios - .post('/api/subscriptions/billing-alerts', { + .post('/api/subscriptions/billing-alert', { amount: this.billingAlertAmount, }) .then(() => { @@ -222,7 +222,7 @@ export default { events.$on('action:confirmed', (data) => { if (data.operation === 'delete-billing-alert') axios - .delete(`/api/subscriptions/billing-alerts/${this.user.data.relationships.alert.data.id}`) + .delete('/api/subscriptions/billing-alert') .then(() => { this.$store.dispatch('getAppData') diff --git a/resources/js/components/UploadRequest/CreateUploadRequestPopup.vue b/resources/js/components/UploadRequest/CreateUploadRequestPopup.vue index 51b06b85..89d20ba5 100644 --- a/resources/js/components/UploadRequest/CreateUploadRequestPopup.vue +++ b/resources/js/components/UploadRequest/CreateUploadRequestPopup.vue @@ -164,7 +164,7 @@ export default { // Send request to get share link axios - .post(`/api/upload-request`, this.form) + .post(`/api/file-request`, this.form) .then((response) => { this.generatedUploadRequest = response.data }) diff --git a/resources/js/store/modules/fileBrowser.js b/resources/js/store/modules/fileBrowser.js index b590e993..0220cd64 100644 --- a/resources/js/store/modules/fileBrowser.js +++ b/resources/js/store/modules/fileBrowser.js @@ -104,7 +104,7 @@ const actions = { return new Promise((resolve, reject) => { // Get route let route = { - RequestUpload: `/api/upload-request/${router.currentRoute.params.token}/navigation`, + RequestUpload: `/api/file-request/${router.currentRoute.params.token}/navigation`, Public: `/api/browse/navigation/${router.currentRoute.params.token}`, }[router.currentRoute.name] || '/api/browse/navigation' diff --git a/resources/js/store/modules/fileFunctions.js b/resources/js/store/modules/fileFunctions.js index fc874a2a..536ee25a 100644 --- a/resources/js/store/modules/fileFunctions.js +++ b/resources/js/store/modules/fileFunctions.js @@ -59,7 +59,7 @@ const actions = { // Get route let route = { - RequestUpload: `/api/upload-request/${router.currentRoute.params.token}/move`, + RequestUpload: `/api/file-request/${router.currentRoute.params.token}/move`, Public: `/api/editor/move/${router.currentRoute.params.token}`, }[router.currentRoute.name] || '/api/move' @@ -87,7 +87,7 @@ const actions = { createFolder: ({ commit, getters, dispatch }, folder) => { // Get route let route = { - RequestUpload: `/api/upload-request/${router.currentRoute.params.token}/create-folder`, + RequestUpload: `/api/file-request/${router.currentRoute.params.token}/create-folder`, Public: `/api/editor/create-folder/${router.currentRoute.params.token}`, }[router.currentRoute.name] || '/api/create-folder' @@ -126,7 +126,7 @@ const actions = { // Get route let route = { - RequestUpload: `/api/upload-request/${router.currentRoute.params.token}/rename/${data.id}`, + RequestUpload: `/api/file-request/${router.currentRoute.params.token}/rename/${data.id}`, Public: `/api/editor/rename/${data.id}/${router.currentRoute.params.token}`, }[router.currentRoute.name] || `/api/rename/${data.id}` @@ -149,7 +149,7 @@ const actions = { return new Promise((resolve, reject) => { // Get route let route = { - RequestUpload: `/api/upload-request/${router.currentRoute.params.token}/upload/chunks`, + RequestUpload: `/api/file-request/${router.currentRoute.params.token}/upload/chunks`, Public: `/api/editor/upload/chunks/${router.currentRoute.params.token}`, }[router.currentRoute.name] || '/api/upload/chunks' @@ -319,7 +319,7 @@ const actions = { // Get route let route = { - RequestUpload: `/api/upload-request/${router.currentRoute.params.token}/remove`, + RequestUpload: `/api/file-request/${router.currentRoute.params.token}/remove`, Public: `/api/editor/remove/${router.currentRoute.params.token}`, }[router.currentRoute.name] || '/api/remove' diff --git a/resources/js/store/modules/uploadRequest.js b/resources/js/store/modules/uploadRequest.js index d9ed24d3..ace431e0 100644 --- a/resources/js/store/modules/uploadRequest.js +++ b/resources/js/store/modules/uploadRequest.js @@ -13,7 +13,7 @@ const actions = { return new Promise((resolve, reject) => { axios - .get(`/api/upload-request/${router.currentRoute.params.token}/browse/${id || 'all'}${getters.sorting.URI}`) + .get(`/api/file-request/${router.currentRoute.params.token}/browse/${id || 'all'}${getters.sorting.URI}`) .then((response) => { let folders = response.data.folders.data let files = response.data.files.data @@ -37,7 +37,7 @@ const actions = { }, getUploadRequestDetail: ({ commit }) => { return new Promise((resolve, reject) => { - axios.get(`/api/upload-request/${router.currentRoute.params.token}`) + axios.get(`/api/file-request/${router.currentRoute.params.token}`) .then((response) => { resolve(response) @@ -56,7 +56,7 @@ const actions = { }, closeUploadRequest: ({ commit }) => { axios - .delete(`/api/upload-request/${router.currentRoute.params.token}`) + .delete(`/api/file-request/${router.currentRoute.params.token}`) .then((response) => { commit('LOADING_STATE', { loading: false, data: [] }) commit('SET_UPLOAD_REQUEST', response.data) diff --git a/routes/api.php b/routes/api.php index 3c0c0363..527e07aa 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,6 +1,5 @@ middleware('throttle:login'); +Route::post('/logout', DestroyActiveBearerTokenController::class); // Socialite Route::get('/socialite/{provider}/redirect', SocialiteRedirectController::class); diff --git a/routes/upload-request.php b/routes/file-request.php similarity index 92% rename from routes/upload-request.php rename to routes/file-request.php index 9ece16b6..9cd32d45 100644 --- a/routes/upload-request.php +++ b/routes/file-request.php @@ -8,6 +8,7 @@ use Domain\UploadRequest\Controllers\BrowseUploadRequestController; use Domain\UploadRequest\Controllers\CreateUploadRequestController; use Domain\UploadRequest\Controllers\MoveItemInUploadRequestController; use Domain\UploadRequest\Controllers\SetUploadRequestAsFilledController; +use Domain\UploadRequest\Controllers\UploadFileForUploadRequestController; use Domain\UploadRequest\Controllers\GetFolderTreeForUploadRequestController; use Domain\UploadRequest\Controllers\UploadFileChunksForUploadRequestController; use Domain\RemoteUpload\Controllers\UploadFilesRemotelyForUploadRequestController; @@ -22,6 +23,8 @@ Route::group(['middleware' => 'upload-request'], function () { // Edit Route::post('/{uploadRequest}/upload/remote', UploadFilesRemotelyForUploadRequestController::class); Route::post('/{uploadRequest}/upload/chunks', UploadFileChunksForUploadRequestController::class); + Route::post('/{uploadRequest}/upload', UploadFileForUploadRequestController::class); + Route::post('/{uploadRequest}/move', MoveItemInUploadRequestController::class); Route::patch('/{uploadRequest}/rename/{id}', RenameFileOrFolderController::class); Route::post('/{uploadRequest}/create-folder', CreateFolderController::class); @@ -30,7 +33,6 @@ Route::group(['middleware' => 'upload-request'], function () { // Browsing Route::get('/{uploadRequest}/navigation', GetFolderTreeForUploadRequestController::class); Route::get('/{uploadRequest}/browse/{folder?}', BrowseUploadRequestController::class); - Route::post('/{uploadRequest}/move', MoveItemInUploadRequestController::class); }); // User functionality diff --git a/src/App/Providers/RouteServiceProvider.php b/src/App/Providers/RouteServiceProvider.php index eb2742e2..b68870d9 100644 --- a/src/App/Providers/RouteServiceProvider.php +++ b/src/App/Providers/RouteServiceProvider.php @@ -43,9 +43,9 @@ class RouteServiceProvider extends ServiceProvider ->middleware('api') ->group(base_path('routes/share.php')); - Route::prefix('api/upload-request') + Route::prefix('api/file-request') ->middleware('api') - ->group(base_path('routes/upload-request.php')); + ->group(base_path('routes/file-request.php')); Route::prefix('api/admin') ->middleware(['api', 'auth:sanctum', 'admin']) @@ -85,5 +85,7 @@ class RouteServiceProvider extends ServiceProvider ? Limit::perMinute(1000)->by($request->user()->id) : Limit::perMinute(100)->by($request->ip()); }); + + RateLimiter::for('login', fn (Request $request) => Limit::perMinute(5)->by($request->ip())); } } diff --git a/src/App/Users/Controllers/Authentication/AuthenticateAndReturnBearerTokenController.php b/src/App/Users/Controllers/Authentication/AuthenticateAndReturnBearerTokenController.php new file mode 100644 index 00000000..12b88b27 --- /dev/null +++ b/src/App/Users/Controllers/Authentication/AuthenticateAndReturnBearerTokenController.php @@ -0,0 +1,39 @@ +input('email')) + ->firstOrFail(); + + // Check the credentials + if (! Hash::check($request->input('password'), $user->password)) { + throw ValidationException::withMessages(['email' => ['The provided credentials are incorrect.'], ]); + } + + // Create access token + $token = $user->createToken('login'); + + // Return token + return response()->json([ + 'type' => 'success', + 'message' => 'You were successfully authenticated', + 'data' => [ + 'token' => $token->plainTextToken, + ], + ]); + } +} diff --git a/src/App/Users/Controllers/Authentication/DestroyActiveBearerTokenController.php b/src/App/Users/Controllers/Authentication/DestroyActiveBearerTokenController.php new file mode 100644 index 00000000..c41245e9 --- /dev/null +++ b/src/App/Users/Controllers/Authentication/DestroyActiveBearerTokenController.php @@ -0,0 +1,33 @@ +bearerToken(), 2); + + // Get token + $instance = PersonalAccessToken::findOrFail($id); + + // Check the correct token + if (hash_equals($instance->token, hash('sha256', $token))) { + // Delete token + $instance->delete(); + + return response()->json([ + 'type' => 'success', + 'message' => 'You were successfully logged out', + ]); + } + + return response()->json([ + 'type' => 'error', + 'message' => 'You are not authorized', + ], 401); + } +} diff --git a/src/App/Users/Requests/LoginUserRequest.php b/src/App/Users/Requests/LoginUserRequest.php new file mode 100644 index 00000000..c23bd2fc --- /dev/null +++ b/src/App/Users/Requests/LoginUserRequest.php @@ -0,0 +1,30 @@ + 'required|email', + 'password' => 'required|string', + ]; + } +} diff --git a/src/Domain/Homepage/Controllers/IndexController.php b/src/Domain/Homepage/Controllers/IndexController.php index e62882a3..8e318c92 100644 --- a/src/Domain/Homepage/Controllers/IndexController.php +++ b/src/Domain/Homepage/Controllers/IndexController.php @@ -1,14 +1,15 @@ doesntExist()) { - $this->createFolder($uploadRequest); + ($this->createUploadRequestRootFolder)($uploadRequest); } // Set default parent_id for uploaded file @@ -54,28 +55,4 @@ class UploadFilesRemotelyForUploadRequestController 'message' => 'Files were successfully added to the upload queue.', ], 201); } - - /** - * Create root Upload Request folder - */ - private function createFolder(UploadRequest $uploadRequest): void - { - // Format timestamp - $timestamp = format_date($uploadRequest->created_at, 'd. M. Y'); - - // Create folder - DB::table('folders')->insert([ - 'id' => $uploadRequest->id, - 'parent_id' => $uploadRequest->folder_id ?? null, - 'user_id' => $uploadRequest->user_id, - 'name' => $uploadRequest->name ?? __t('upload_request_default_folder', ['timestamp' => $timestamp]), - 'created_at' => now(), - 'updated_at' => now(), - ]); - - // Update upload request status - $uploadRequest->update([ - 'status' => 'filling', - ]); - } } diff --git a/src/Domain/Settings/Actions/GetConfigAction.php b/src/Domain/Settings/Actions/GetConfigAction.php index 10404ba1..dd217f00 100644 --- a/src/Domain/Settings/Actions/GetConfigAction.php +++ b/src/Domain/Settings/Actions/GetConfigAction.php @@ -1,21 +1,21 @@ upload_limit) ? toMegabytes($settings->upload_limit) : null; - } catch (MissingExtensionException $e) { $storageDefaultSpaceFormatted = '5GB'; $uploadLimit = 'undefined'; @@ -190,4 +189,4 @@ class GetConfigAction 'legal' => $pages ? json_encode($pages) : 'undefined', ]; } -} \ No newline at end of file +} diff --git a/src/Domain/Settings/Controllers/GetConfigController.php b/src/Domain/Settings/Controllers/GetConfigController.php index badcd4e7..9380af8d 100644 --- a/src/Domain/Settings/Controllers/GetConfigController.php +++ b/src/Domain/Settings/Controllers/GetConfigController.php @@ -1,20 +1,19 @@ json(($this->getConfigAction)()); } -} \ No newline at end of file +} diff --git a/src/Domain/UploadRequest/Actions/CreateUploadRequestRootFolderAction.php b/src/Domain/UploadRequest/Actions/CreateUploadRequestRootFolderAction.php new file mode 100644 index 00000000..8cf44084 --- /dev/null +++ b/src/Domain/UploadRequest/Actions/CreateUploadRequestRootFolderAction.php @@ -0,0 +1,32 @@ +created_at, 'd. M. Y'); + + // Create folder + DB::table('folders')->insert([ + 'id' => $uploadRequest->id, + 'parent_id' => $uploadRequest->folder_id ?? null, + 'user_id' => $uploadRequest->user_id, + 'name' => $uploadRequest->name ?? __t('upload_request_default_folder', ['timestamp' => $timestamp]), + 'created_at' => now(), + 'updated_at' => now(), + ]); + + // Update upload request status + $uploadRequest->update([ + 'status' => 'filling', + ]); + } +} diff --git a/src/Domain/UploadRequest/Controllers/CreateFolderController.php b/src/Domain/UploadRequest/Controllers/CreateFolderController.php index 3422b995..02c633f7 100644 --- a/src/Domain/UploadRequest/Controllers/CreateFolderController.php +++ b/src/Domain/UploadRequest/Controllers/CreateFolderController.php @@ -2,6 +2,7 @@ namespace Domain\UploadRequest\Controllers; use Domain\Folders\Models\Folder; +use Illuminate\Http\JsonResponse; use Domain\Folders\Resources\FolderResource; use Domain\Folders\Actions\CreateFolderAction; use Domain\UploadRequest\Models\UploadRequest; @@ -16,16 +17,21 @@ class CreateFolderController ) { } - public function __invoke(CreateFolderRequest $request, UploadRequest $uploadRequest) - { + public function __invoke( + CreateFolderRequest $request, + UploadRequest $uploadRequest, + ): JsonResponse { // Check privileges - if (! in_array($request->input('parent_id'), getChildrenFolderIds($uploadRequest->id))) { - return response('Access Denied', 403); + if ($request->has('parent_id') && ! in_array($request->input('parent_id'), getChildrenFolderIds($uploadRequest->id))) { + return response()->json([ + 'type' => 'error', + 'message' => "You don't have privileges to create folder here", + ], 403); } // Create new folder $folder = Folder::create([ - 'parent_id' => $request->input('parent_id'), + 'parent_id' => $request->input('parent_id') ?? $uploadRequest->id, 'name' => $request->input('name'), 'color' => $request->input('color') ?? null, 'emoji' => $request->input('emoji') ?? null, @@ -35,6 +41,6 @@ class CreateFolderController ]); // Return new folder - return response(new FolderResource($folder), 201); + return response()->json(new FolderResource($folder), 201); } } diff --git a/src/Domain/UploadRequest/Controllers/DeleteFileOrFolderController.php b/src/Domain/UploadRequest/Controllers/DeleteFileOrFolderController.php index d0c31222..6947834d 100644 --- a/src/Domain/UploadRequest/Controllers/DeleteFileOrFolderController.php +++ b/src/Domain/UploadRequest/Controllers/DeleteFileOrFolderController.php @@ -4,14 +4,22 @@ namespace Domain\UploadRequest\Controllers; use Illuminate\Support\Arr; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; +use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Storage; use Domain\Items\Requests\DeleteItemRequest; use Domain\UploadRequest\Models\UploadRequest; class DeleteFileOrFolderController { - public function __invoke(DeleteItemRequest $request, UploadRequest $uploadRequest) - { + public function __invoke( + DeleteItemRequest $request, + UploadRequest $uploadRequest + ): JsonResponse { + $successMessage = [ + 'type' => 'success', + 'message' => 'Items was successfully deleted.', + ]; + foreach ($request->input('items') as $file) { // Get file or folder item $item = get_item($file['type'], $file['id']); @@ -27,7 +35,7 @@ class DeleteFileOrFolderController } } - return response('Done', 204); + return response()->json($successMessage); } private function destroyFile(File $file): void diff --git a/src/Domain/UploadRequest/Controllers/MoveItemInUploadRequestController.php b/src/Domain/UploadRequest/Controllers/MoveItemInUploadRequestController.php index b7224353..493e1ea3 100644 --- a/src/Domain/UploadRequest/Controllers/MoveItemInUploadRequestController.php +++ b/src/Domain/UploadRequest/Controllers/MoveItemInUploadRequestController.php @@ -4,24 +4,28 @@ namespace Domain\UploadRequest\Controllers; use App\Http\Controllers\Controller; use Domain\Items\Requests\MoveItemRequest; use Domain\UploadRequest\Models\UploadRequest; +use Symfony\Component\HttpFoundation\JsonResponse; class MoveItemInUploadRequestController extends Controller { public function __invoke( MoveItemRequest $request, UploadRequest $uploadRequest, - ) { + ): JsonResponse { foreach ($request->input('items') as $item) { $item = get_item($item['type'], $item['id']); // Check privileges if (! in_array($item['parent_id'], getChildrenFolderIds($uploadRequest->id))) { - return response('Access Denied', 403); + return response()->json(accessDeniedError(), 403); } $item->update(['parent_id' => $request->input('to_id') ?? $uploadRequest->id]); } - return response('Done.', 204); + return response()->json([ + 'type' => 'success', + 'message' => 'Items was successfully moved.', + ]); } } diff --git a/src/Domain/UploadRequest/Controllers/SetUploadRequestAsFilledController.php b/src/Domain/UploadRequest/Controllers/SetUploadRequestAsFilledController.php index 505a3012..755ef227 100644 --- a/src/Domain/UploadRequest/Controllers/SetUploadRequestAsFilledController.php +++ b/src/Domain/UploadRequest/Controllers/SetUploadRequestAsFilledController.php @@ -1,16 +1,13 @@ update([ 'status' => 'filled', @@ -21,6 +18,9 @@ class SetUploadRequestAsFilledController $uploadRequest->user->notify(new UploadRequestFulfilledNotification($uploadRequest)); } - return response(new UploadRequestResource($uploadRequest), 201); + return response()->json([ + 'type' => 'success', + 'message' => 'File request was successfully set as filled', + ]); } } diff --git a/src/Domain/UploadRequest/Controllers/UploadFileChunksForUploadRequestController.php b/src/Domain/UploadRequest/Controllers/UploadFileChunksForUploadRequestController.php index 28b787ea..a3ceb0e9 100644 --- a/src/Domain/UploadRequest/Controllers/UploadFileChunksForUploadRequestController.php +++ b/src/Domain/UploadRequest/Controllers/UploadFileChunksForUploadRequestController.php @@ -1,7 +1,6 @@ doesntExist()) { - $this->createFolder($uploadRequest); + ($this->createUploadRequestRootFolder)($uploadRequest); } // Set default parent_id for uploaded file @@ -61,28 +62,4 @@ class UploadFileChunksForUploadRequestController return response(new FileResource($file), 201); } } - - /** - * Create root Upload Request folder - */ - private function createFolder(UploadRequest $uploadRequest): void - { - // Format timestamp - $timestamp = format_date($uploadRequest->created_at, 'd. M. Y'); - - // Create folder - DB::table('folders')->insert([ - 'id' => $uploadRequest->id, - 'parent_id' => $uploadRequest->folder_id ?? null, - 'user_id' => $uploadRequest->user_id, - 'name' => $uploadRequest->name ?? __t('upload_request_default_folder', ['timestamp' => $timestamp]), - 'created_at' => now(), - 'updated_at' => now(), - ]); - - // Update upload request status - $uploadRequest->update([ - 'status' => 'filling', - ]); - } } diff --git a/src/Domain/UploadRequest/Controllers/UploadFileForUploadRequestController.php b/src/Domain/UploadRequest/Controllers/UploadFileForUploadRequestController.php new file mode 100644 index 00000000..14b5a192 --- /dev/null +++ b/src/Domain/UploadRequest/Controllers/UploadFileForUploadRequestController.php @@ -0,0 +1,56 @@ +id); + + // Create folder if it doesn't exist + if ($folder->doesntExist()) { + ($this->createUploadRequestRootFolder)($uploadRequest); + } + + // Set default parent_id for uploaded file + if (is_null($request->input('parent_id'))) { + $request->merge(['parent_id' => $uploadRequest->id]); + } + + // Get file name + $name = Str::uuid() . '.' . $request->input('extension'); + + // Move file to user directory + Storage::disk('local')->put("files/{$uploadRequest->user->id}/$name", $request->file('file')->get()); + + // Process file + $file = ($this->processFie)($request, $uploadRequest->user, $name); + + // Set public access url + $file->setUploadRequestPublicUrl($uploadRequest->id); + + // Set timestamp for auto filling + cache()->set("auto-filling.$uploadRequest->id", now()->toString()); + + return response()->json(new FileResource($file), 201); + } +} diff --git a/src/Domain/UploadRequest/Middleware/ProtectUploadRequestRoutes.php b/src/Domain/UploadRequest/Middleware/ProtectUploadRequestRoutes.php index c75e8efd..47ac8152 100644 --- a/src/Domain/UploadRequest/Middleware/ProtectUploadRequestRoutes.php +++ b/src/Domain/UploadRequest/Middleware/ProtectUploadRequestRoutes.php @@ -16,7 +16,10 @@ class ProtectUploadRequestRoutes // Check if upload request is active if (! in_array($uploadRequest->status, ['active', 'filling'])) { - return response('Gone', 410); + return response()->json([ + 'type' => 'gone', + 'message' => 'The file request is not active anymore', + ], 410); } return $next($request); diff --git a/tests/Domain/UploadRequest/UploadRequestBrowsingTest.php b/tests/Domain/UploadRequest/UploadRequestBrowsingTest.php index 1a905ea5..c912c4a4 100644 --- a/tests/Domain/UploadRequest/UploadRequestBrowsingTest.php +++ b/tests/Domain/UploadRequest/UploadRequestBrowsingTest.php @@ -47,7 +47,7 @@ class UploadRequestBrowsingTest extends TestCase $this ->actingAs($user) - ->getJson("/api/upload-request/$uploadRequest->id/navigation") + ->getJson("/api/file-request/$uploadRequest->id/navigation") ->assertStatus(200) ->assertExactJson([ [ @@ -115,7 +115,7 @@ class UploadRequestBrowsingTest extends TestCase $this ->actingAs($user) - ->getJson("/api/upload-request/$uploadRequest->id/browse/$root->id") + ->getJson("/api/file-request/$uploadRequest->id/browse/$root->id") ->assertStatus(200) ->assertJsonFragment([ 'id' => $root->id, @@ -165,7 +165,7 @@ class UploadRequestBrowsingTest extends TestCase $this ->actingAs($user) - ->getJson("/api/upload-request/$uploadRequest->id/browse/$root->id") + ->getJson("/api/file-request/$uploadRequest->id/browse/$root->id") ->assertStatus(200) ->assertJsonFragment([ 'id' => $root->id, diff --git a/tests/Domain/UploadRequest/UploadRequestEditingTest.php b/tests/Domain/UploadRequest/UploadRequestEditingTest.php index e6c34d15..ed543d3f 100644 --- a/tests/Domain/UploadRequest/UploadRequestEditingTest.php +++ b/tests/Domain/UploadRequest/UploadRequestEditingTest.php @@ -34,7 +34,7 @@ class UploadRequestEditingTest extends TestCase $this ->actingAs($user) - ->patchJson("/api/upload-request/$uploadRequest->id/rename/$folder->id", [ + ->patchJson("/api/file-request/$uploadRequest->id/rename/$folder->id", [ 'name' => 'Renamed Folder', 'type' => 'folder', ]) @@ -71,7 +71,7 @@ class UploadRequestEditingTest extends TestCase $this ->actingAs($user) - ->patchJson("/api/upload-request/$uploadRequest->id/rename/$file->id", [ + ->patchJson("/api/file-request/$uploadRequest->id/rename/$file->id", [ 'name' => 'Renamed File', 'type' => 'file', ]) @@ -102,7 +102,7 @@ class UploadRequestEditingTest extends TestCase $this ->actingAs($user) - ->postJson("/api/upload-request/$uploadRequest->id/create-folder", [ + ->postJson("/api/file-request/$uploadRequest->id/create-folder", [ 'name' => 'New Folder', 'parent_id' => $uploadRequest->id, ]) @@ -162,7 +162,7 @@ class UploadRequestEditingTest extends TestCase }); $this - ->postJson("/api/upload-request/$uploadRequest->id/remove", [ + ->postJson("/api/file-request/$uploadRequest->id/remove", [ 'items' => [ [ 'id' => $image->id, @@ -170,7 +170,7 @@ class UploadRequestEditingTest extends TestCase 'force_delete' => true, ], ], - ])->assertStatus(204); + ])->assertStatus(200); // Assert primary file was deleted Storage::assertMissing("files/$user->id/fake-image.jpeg"); @@ -209,7 +209,7 @@ class UploadRequestEditingTest extends TestCase Storage::putFileAs("files/$user->id", $fakeFile, $fakeFile->name); $this - ->postJson("/api/upload-request/$uploadRequest->id/remove", [ + ->postJson("/api/file-request/$uploadRequest->id/remove", [ 'items' => [ [ 'id' => $file->id, @@ -217,7 +217,7 @@ class UploadRequestEditingTest extends TestCase 'force_delete' => true, ], ], - ])->assertStatus(204); + ])->assertStatus(200); // Assert primary file was deleted Storage::assertMissing("files/$user->id/fake-file.pdf"); @@ -264,7 +264,7 @@ class UploadRequestEditingTest extends TestCase Storage::putFileAs("files/$user->id", $fakeFile, $fakeFile->name); $this - ->postJson("/api/upload-request/$uploadRequest->id/remove", [ + ->postJson("/api/file-request/$uploadRequest->id/remove", [ 'items' => [ [ 'id' => $folder->id, @@ -272,7 +272,7 @@ class UploadRequestEditingTest extends TestCase 'force_delete' => true, ], ], - ])->assertStatus(204); + ])->assertStatus(200); $this ->assertDatabaseMissing('folders', [ @@ -317,7 +317,7 @@ class UploadRequestEditingTest extends TestCase ]); $this - ->postJson("/api/upload-request/$uploadRequest->id/move", [ + ->postJson("/api/file-request/$uploadRequest->id/move", [ 'to_id' => $folder->id, 'items' => [ [ @@ -325,7 +325,7 @@ class UploadRequestEditingTest extends TestCase 'id' => $file->id, ], ], - ])->assertStatus(204); + ])->assertStatus(200); $this->assertDatabaseHas('files', [ 'id' => $file->id, diff --git a/tests/Domain/UploadRequest/UploadRequestTest.php b/tests/Domain/UploadRequest/UploadRequestTest.php index 61c91664..c7a229d9 100644 --- a/tests/Domain/UploadRequest/UploadRequestTest.php +++ b/tests/Domain/UploadRequest/UploadRequestTest.php @@ -42,7 +42,7 @@ class UploadRequestTest extends TestCase $this ->actingAs($user) - ->postJson('/api/upload-request', [ + ->postJson('/api/file-request', [ 'folder_id' => $folder->id, 'email' => 'howdy@hi5ve.digital', 'notes' => 'Please send me your files...', @@ -74,7 +74,7 @@ class UploadRequestTest extends TestCase $this ->actingAs($user) - ->postJson('/api/upload-request', [ + ->postJson('/api/file-request', [ 'folder_id' => $folder->id, 'notes' => 'Please send me your files...', ]) @@ -105,7 +105,7 @@ class UploadRequestTest extends TestCase $this ->actingAs($user) - ->postJson('/api/upload-request', [ + ->postJson('/api/file-request', [ 'folder_id' => $folder->id, 'notes' => 'Please send me your files...', 'name' => 'My name', @@ -137,7 +137,7 @@ class UploadRequestTest extends TestCase 'user_id' => $user->id, ]); - $this->getJson("/api/upload-request/$uploadRequest->id") + $this->getJson("/api/file-request/$uploadRequest->id") ->assertOk() ->assertJsonFragment([ 'id' => $uploadRequest->id, @@ -165,7 +165,7 @@ class UploadRequestTest extends TestCase ->create('fake-file.pdf', 12000000, 'application/pdf'); $this - ->postJson("/api/upload-request/$uploadRequest->id/upload/chunks", [ + ->postJson("/api/file-request/$uploadRequest->id/upload/chunks", [ 'name' => $file->name, 'extension' => 'pdf', 'chunk' => $file, @@ -209,7 +209,7 @@ class UploadRequestTest extends TestCase ->create('fake-file.pdf', 12000000, 'application/pdf'); $this - ->postJson("/api/upload-request/$uploadRequest->id/upload/chunks", [ + ->postJson("/api/file-request/$uploadRequest->id/upload/chunks", [ 'name' => $file->name, 'extension' => 'pdf', 'chunk' => $file, @@ -252,7 +252,7 @@ class UploadRequestTest extends TestCase ->create('fake-file.pdf', 12000000, 'application/pdf'); $this - ->postJson("/api/upload-request/$uploadRequest->id/upload/chunks", [ + ->postJson("/api/file-request/$uploadRequest->id/upload/chunks", [ 'name' => $file->name, 'file' => $file, 'is_last_chunk' => 1, @@ -275,12 +275,8 @@ class UploadRequestTest extends TestCase ]); $this - ->deleteJson("/api/upload-request/$uploadRequest->id") - ->assertStatus(201) - ->assertJsonFragment([ - 'id' => $uploadRequest->id, - 'status' => 'filled', - ]); + ->deleteJson("/api/file-request/$uploadRequest->id") + ->assertStatus(200); Notification::assertSentTo($user, UploadRequestFulfilledNotification::class); } @@ -323,7 +319,7 @@ class UploadRequestTest extends TestCase ->create('fake-file.pdf', 12000000, 'application/pdf'); $this - ->postJson("/api/upload-request/$uploadRequest->id/upload/chunks", [ + ->postJson("/api/file-request/$uploadRequest->id/upload/chunks", [ 'name' => $file->name, 'extension' => 'pdf', 'chunk' => $file,