diff --git a/.env.testing b/.env.testing
index b9f884b9..39a04a99 100644
--- a/.env.testing
+++ b/.env.testing
@@ -1,6 +1,6 @@
APP_NAME=Laravel
APP_ENV=local
-APP_KEY=base64:H+C6Ovly2gudhK4Zyn0EOED/ZOKNXthKIr6fv6bXJUM=
+APP_KEY=base64:k5FduZ4Vu5ONvcJysN6xZYlix606oNocewyXSyOEspQ=
APP_DEBUG=true
APP_URL=http://localhost
APP_DEMO=false
diff --git a/config/filesystems.php b/config/filesystems.php
index e0e8b953..25ee0e1d 100644
--- a/config/filesystems.php
+++ b/config/filesystems.php
@@ -47,19 +47,19 @@ return [
'endpoint' => env('S3_URL'),
],
'ftp' => [
- 'driver' => 'ftp',
- 'host' => env('FTP_HOST'),
+ 'driver' => 'ftp',
+ 'host' => env('FTP_HOST'),
'username' => env('FTP_USERNAME'),
'password' => env('FTP_PASSWORD'),
],
'azure' => [
- 'driver' => 'azure',
- 'name' => env('AZURE_STORAGE_NAME'),
- 'key' => env('AZURE_STORAGE_KEY'),
- 'container' => env('AZURE_STORAGE_CONTAINER'),
- 'url' => env('AZURE_STORAGE_URL'),
- 'prefix' => null,
- 'connection_string' => env('AZURE_STORAGE_CONNECTION_STRING') // optional, will override default endpoint builder
+ 'driver' => 'azure',
+ 'name' => env('AZURE_STORAGE_NAME'),
+ 'key' => env('AZURE_STORAGE_KEY'),
+ 'container' => env('AZURE_STORAGE_CONTAINER'),
+ 'url' => env('AZURE_STORAGE_URL'),
+ 'prefix' => null,
+ 'connection_string' => env('AZURE_STORAGE_CONNECTION_STRING'), // optional, will override default endpoint builder
],
],
];
diff --git a/config/language-translations.php b/config/language-translations.php
index 1e5c8d67..f6b809f4 100644
--- a/config/language-translations.php
+++ b/config/language-translations.php
@@ -942,5 +942,12 @@ return [
'paste_code_from_2fa_app' => 'Paste the latest code from 2fa app...',
'zero_for_unlimited_members' => 'Type -1 to set unlimited team members.',
'max_team_members' => 'Max Team Members',
+ 'remote_upload' => 'Remote Upload',
+ 'upload_files_remotely' => 'Upload Files Remotely',
+ 'remote_links' => 'Remote Links',
+ 'remote_links_help' => 'For every line paste one link',
+ 'paste_remote_links_here' => 'Paste your remote links here...',
+ 'remote_download_submitted' => 'Your links will be downloaded as soon as possible',
+ 'remote_download_processed' => 'Your links were processed successfully',
],
];
diff --git a/public/mix-manifest.json b/public/mix-manifest.json
index fde75b9d..d042daed 100644
--- a/public/mix-manifest.json
+++ b/public/mix-manifest.json
@@ -1,27 +1,27 @@
{
"/js/main.js": "/js/main.js",
- "/chunks/request.js": "/chunks/request.js?id=6770484e564115b3",
- "/chunks/request-upload.js": "/chunks/request-upload.js?id=eb234dacadd33d8b",
+ "/chunks/request.js": "/chunks/request.js?id=b493de3b8cf4a8f2",
+ "/chunks/request-upload.js": "/chunks/request-upload.js?id=efb89edeaed37404",
"/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=19a0784e59d768ec",
- "/chunks/status-check.js": "/chunks/status-check.js?id=9239a586761b912d",
+ "/chunks/status-check.js": "/chunks/status-check.js?id=f40938d1fb43820f",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=ba76b9a8adbfdc0b",
"/chunks/database.js": "/chunks/database.js?id=5113b0d4284f764f",
- "/chunks/environment.js": "/chunks/environment.js?id=e4fdb87ff173d48a",
+ "/chunks/environment.js": "/chunks/environment.js?id=784c2442268b36dc",
"/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=c0fa346721760ad2",
- "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=6020e9e778bd00e5",
+ "/chunks/shared.js": "/chunks/shared.js?id=54733651dfb0af9f",
+ "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=d2fff07a2bc7af3f",
"/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=a6063bed9be75a09",
"/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=a881c02da23d7112",
+ "/chunks/admin.js": "/chunks/admin.js?id=780ebe14261335f6",
"/chunks/dashboard.js": "/chunks/dashboard.js?id=5ab55a12214433c8",
"/chunks/invoices.js": "/chunks/invoices.js?id=799928609f57ca10",
"/chunks/subscriptions.js": "/chunks/subscriptions.js?id=a0c4f59d0ec4aee0",
"/chunks/pages.js": "/chunks/pages.js?id=bb5cc8327ca846a3",
"/chunks/page-edit.js": "/chunks/page-edit.js?id=0bdc8a5935fd2197",
- "/chunks/plans.js": "/chunks/plans.js?id=76398906ad873fc3",
+ "/chunks/plans.js": "/chunks/plans.js?id=1d04fbdca84afd42",
"/chunks/users.js": "/chunks/users.js?id=b6629338e26b8313",
"/chunks/user-create.js": "/chunks/user-create.js?id=40254ae98547761e",
"/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=18f9d1ab17996507",
@@ -42,7 +42,7 @@
"/chunks/app-settings.js": "/chunks/app-settings.js?id=b0d1082fdcbbd17c",
"/chunks/app-appearance.js": "/chunks/app-appearance.js?id=8ba3feb2cc81a2c3",
"/chunks/app-index.js": "/chunks/app-index.js?id=0c50096e8de09288",
- "/chunks/app-environment.js": "/chunks/app-environment.js?id=3436286fd625f8b7",
+ "/chunks/app-environment.js": "/chunks/app-environment.js?id=f5cdd68ebc6a6b54",
"/chunks/app-others.js": "/chunks/app-others.js?id=dd23507db4551d0a",
"/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=f79027ce1f1f4c4b",
"/chunks/app-adsense.js": "/chunks/app-adsense.js?id=c7e7dc2975317062",
@@ -53,22 +53,22 @@
"/chunks/contact-us.js": "/chunks/contact-us.js?id=ea99d85aa3500595",
"/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=c26cb144101e7c79",
"/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=170d814982e1c475",
- "/chunks/sign-in.js": "/chunks/sign-in.js?id=c648cb698176a993",
- "/chunks/sign-up.js": "/chunks/sign-up.js?id=3d7559511768cd0e",
+ "/chunks/sign-in.js": "/chunks/sign-in.js?id=5f7111f8ee7639bf",
+ "/chunks/sign-up.js": "/chunks/sign-up.js?id=80da89f329c514fc",
"/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=27cda9364b6593d8",
"/chunks/create-new-password.js": "/chunks/create-new-password.js?id=2f0401ee2fc148c4",
- "/chunks/settings.js": "/chunks/settings.js?id=13f38ad770e862c6",
+ "/chunks/settings.js": "/chunks/settings.js?id=c8a4915f96c762d4",
"/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=092e324aad54656b",
"/chunks/billing.js": "/chunks/billing.js?id=115c25478cee576d",
- "/chunks/platform.js": "/chunks/platform.js?id=622fe102512635e6",
- "/chunks/files.js": "/chunks/files.js?id=e91e9fa66c979280",
- "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=bc93b317f1ddc35a",
- "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=dc31d8d4dd8220bb",
- "/chunks/trash.js": "/chunks/trash.js?id=dff5da6dd52cf85a",
- "/chunks/team-folders.js": "/chunks/team-folders.js?id=8926350140fe5aa2",
- "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=b9dcedcf37d523b5",
+ "/chunks/platform.js": "/chunks/platform.js?id=907e530c6cc415bc",
+ "/chunks/files.js": "/chunks/files.js?id=aaea9173f7697d6e",
+ "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=4bab41df721a6fc6",
+ "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=c62bc3eb07de20df",
+ "/chunks/trash.js": "/chunks/trash.js?id=31e826373e0d01f8",
+ "/chunks/team-folders.js": "/chunks/team-folders.js?id=4babe7db8a9a3a16",
+ "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=cfb073052d66d07c",
"/chunks/invitation.js": "/chunks/invitation.js?id=424b2783d9785a09",
"/css/tailwind.css": "/css/tailwind.css",
"/css/app.css": "/css/app.css"
diff --git a/resources/js/components/FilePreview/FilePreviewToolbar.vue b/resources/js/components/FilePreview/FilePreviewToolbar.vue
index a48a1691..d4a00434 100644
--- a/resources/js/components/FilePreview/FilePreviewToolbar.vue
+++ b/resources/js/components/FilePreview/FilePreviewToolbar.vue
@@ -10,7 +10,7 @@
{{ currentFile.data.attributes.name }}
diff --git a/resources/js/components/Layout/Toolbars/DesktopSharepageToolbar.vue b/resources/js/components/Layout/Toolbars/DesktopSharepageToolbar.vue
index 22ddbfd9..1acbbf55 100644
--- a/resources/js/components/Layout/Toolbars/DesktopSharepageToolbar.vue
+++ b/resources/js/components/Layout/Toolbars/DesktopSharepageToolbar.vue
@@ -12,17 +12,22 @@
:action="$t('create_something')"
/>
-
+
-
-
-
+
+
+
+
diff --git a/resources/js/components/Layout/Toolbars/DesktopToolbar.vue b/resources/js/components/Layout/Toolbars/DesktopToolbar.vue
index 66880a1a..afa65460 100644
--- a/resources/js/components/Layout/Toolbars/DesktopToolbar.vue
+++ b/resources/js/components/Layout/Toolbars/DesktopToolbar.vue
@@ -39,6 +39,11 @@
:title="$t('upload_folder')"
type="folder"
/>
+
-
+
-
-
-
+
+
+
+
diff --git a/resources/js/components/Layout/Toolbars/NavigationBar.vue b/resources/js/components/Layout/Toolbars/NavigationBar.vue
index f77d5a29..36d2f492 100644
--- a/resources/js/components/Layout/Toolbars/NavigationBar.vue
+++ b/resources/js/components/Layout/Toolbars/NavigationBar.vue
@@ -3,7 +3,7 @@
diff --git a/resources/js/components/Menus/Components/Option.vue b/resources/js/components/Menus/Components/Option.vue
index 4bc8d1cc..1fe21043 100644
--- a/resources/js/components/Menus/Components/Option.vue
+++ b/resources/js/components/Menus/Components/Option.vue
@@ -119,6 +119,12 @@
class="vue-feather group-hover-text-theme"
:class="{ 'text-theme': isActive }"
/>
+
import AlphabetIcon from '../../Icons/AlphabetIcon'
import {
+ Link2Icon,
UserMinusIcon,
UserCheckIcon,
UserPlusIcon,
@@ -287,6 +294,7 @@ export default {
name: 'Option',
props: ['isHoverDisabled', 'isActive', 'title', 'arrow', 'icon'],
components: {
+ Link2Icon,
UserMinusIcon,
UserCheckIcon,
UserPlusIcon,
diff --git a/resources/js/components/Popups/Components/PopupHeader.vue b/resources/js/components/Popups/Components/PopupHeader.vue
index 58dc4a10..cc1c4a3c 100644
--- a/resources/js/components/Popups/Components/PopupHeader.vue
+++ b/resources/js/components/Popups/Components/PopupHeader.vue
@@ -2,6 +2,7 @@
+
@@ -25,6 +26,7 @@
diff --git a/resources/js/components/Spotlight/Spotlight.vue b/resources/js/components/Spotlight/Spotlight.vue
index 653299b6..1cd174fb 100644
--- a/resources/js/components/Spotlight/Spotlight.vue
+++ b/resources/js/components/Spotlight/Spotlight.vue
@@ -139,6 +139,11 @@
size="18"
class="vue-feather text-theme"
/>
+
+
@@ -86,6 +87,7 @@ import { mapGetters } from 'vuex'
import CreateUploadRequestPopup from "../components/UploadRequest/CreateUploadRequestPopup";
import CreateTeamFolderPopup from "../components/Teams/CreateTeamFolderPopup";
import NotificationsPopup from "../components/Notifications/NotificationsPopup";
+import RemoteUploadPopup from "../components/RemoteUpload/RemoteUploadPopup";
export default {
name: 'Admin',
@@ -190,6 +192,7 @@ export default {
},
},
components: {
+ RemoteUploadPopup,
NotificationsPopup,
CreateTeamFolderPopup,
CreateUploadRequestPopup,
diff --git a/resources/js/views/FileView/Files.vue b/resources/js/views/FileView/Files.vue
index e0744bfc..06bfe741 100644
--- a/resources/js/views/FileView/Files.vue
+++ b/resources/js/views/FileView/Files.vue
@@ -46,6 +46,11 @@
/>
+
+
+
+
diff --git a/resources/js/views/FileView/TeamFolders.vue b/resources/js/views/FileView/TeamFolders.vue
index d8556677..2b41cbae 100644
--- a/resources/js/views/FileView/TeamFolders.vue
+++ b/resources/js/views/FileView/TeamFolders.vue
@@ -43,6 +43,12 @@
/>
+
-
+
-
-
-
+
+
+
+
diff --git a/resources/js/views/Platform.vue b/resources/js/views/Platform.vue
index d3cd15cf..8df23fd8 100644
--- a/resources/js/views/Platform.vue
+++ b/resources/js/views/Platform.vue
@@ -16,6 +16,7 @@
+
@@ -79,10 +80,12 @@ import { events } from '../bus'
import { mapGetters } from 'vuex'
import CreateUploadRequestPopup from "../components/UploadRequest/CreateUploadRequestPopup";
import NotificationsPopup from "../components/Notifications/NotificationsPopup";
+import RemoteUploadPopup from "../components/RemoteUpload/RemoteUploadPopup";
export default {
name: 'Platform',
components: {
+ RemoteUploadPopup,
NotificationsPopup,
CreateUploadRequestPopup,
CreateTeamFolderPopup,
diff --git a/resources/js/views/Profile.vue b/resources/js/views/Profile.vue
index 6ab65687..de09c86b 100644
--- a/resources/js/views/Profile.vue
+++ b/resources/js/views/Profile.vue
@@ -8,6 +8,7 @@
+
@@ -94,10 +95,12 @@ import CreateUploadRequestPopup from "../components/UploadRequest/CreateUploadRe
import CreateTeamFolderPopup from "../components/Teams/CreateTeamFolderPopup";
import ChangeSubscriptionPopup from "../components/Subscription/Popups/ChangeSubscriptionPopup";
import NotificationsPopup from "../components/Notifications/NotificationsPopup";
+import RemoteUploadPopup from "../components/RemoteUpload/RemoteUploadPopup";
export default {
name: 'Settings',
components: {
+ RemoteUploadPopup,
NotificationsPopup,
ChangeSubscriptionPopup,
CreateTeamFolderPopup,
diff --git a/resources/js/views/Shared.vue b/resources/js/views/Shared.vue
index 5964998e..c6a8ee5b 100644
--- a/resources/js/views/Shared.vue
+++ b/resources/js/views/Shared.vue
@@ -7,6 +7,7 @@
+
@@ -61,12 +62,13 @@ import DragUI from '../components/UI/Others/DragUI'
import Alert from '../components/Popups/Alert'
import { mapGetters } from 'vuex'
import { events } from '../bus'
-import router from '../router'
import DesktopSharepageToolbar from '../components/Layout/Toolbars/DesktopSharepageToolbar'
+import RemoteUploadPopup from "../components/RemoteUpload/RemoteUploadPopup";
export default {
name: 'Shared',
components: {
+ RemoteUploadPopup,
DesktopSharepageToolbar,
MobileToolbar,
InfoSidebar,
diff --git a/resources/js/views/UploadRequest.vue b/resources/js/views/UploadRequest.vue
index 5cdaad49..6e493801 100644
--- a/resources/js/views/UploadRequest.vue
+++ b/resources/js/views/UploadRequest.vue
@@ -8,6 +8,7 @@
+
@@ -54,10 +55,12 @@ import Spotlight from '../components/Spotlight/Spotlight'
import DragUI from '../components/UI/Others/DragUI'
import { mapGetters } from 'vuex'
import { events } from '../bus'
+import RemoteUploadPopup from "../components/RemoteUpload/RemoteUploadPopup";
export default {
name: 'UploadRequest',
components: {
+ RemoteUploadPopup,
DesktopUploadRequestToolbar,
MobileUploadRequestToolBar,
InfoSidebarUploadRequest,
diff --git a/routes/api.php b/routes/api.php
index 761b9e9f..21dbd1e8 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -12,6 +12,7 @@ use Domain\SetupWizard\Controllers\PingAPIController;
use Domain\Folders\Controllers\CreateFolderController;
use Domain\Browsing\Controllers\BrowseFolderController;
use Domain\Sharing\Controllers\ShareViaEmailController;
+use Domain\Files\Controllers\RemoteUploadFileController;
use Domain\Folders\Controllers\NavigationTreeController;
use Domain\Items\Controllers\MoveFileOrFolderController;
use App\Socialite\Controllers\SocialiteRedirectController;
@@ -78,6 +79,7 @@ Route::group(['middleware' => ['auth:sanctum']], function () {
// User master,editor routes
Route::group(['middleware' => ['auth:sanctum']], function () {
+ Route::post('/upload/remote', RemoteUploadFileController::class);
Route::post('/create-folder', CreateFolderController::class);
Route::post('/upload', UploadFileController::class);
diff --git a/routes/share.php b/routes/share.php
index eb02f9ae..df07f5c6 100644
--- a/routes/share.php
+++ b/routes/share.php
@@ -7,6 +7,7 @@ use Domain\Files\Controllers\VisitorUploadFileController;
use Domain\Folders\Controllers\VisitorCreateFolderController;
use Domain\Sharing\Controllers\WebCrawlerOpenGraphController;
use Domain\Browsing\Controllers\VisitorBrowseFolderController;
+use Domain\Files\Controllers\VisitorRemoteUploadFileController;
use Domain\Items\Controllers\VisitorMoveFileOrFolderController;
use Domain\Items\Controllers\VisitorDeleteFileOrFolderController;
use Domain\Items\Controllers\VisitorRenameFileOrFolderController;
@@ -16,6 +17,7 @@ use Domain\Browsing\Controllers\VisitorSearchFilesAndFoldersController;
// Browse functions
Route::group(['prefix' => 'editor'], function () {
+ Route::post('/upload/remote/{shared}', VisitorRemoteUploadFileController::class);
Route::post('/create-folder/{shared}', VisitorCreateFolderController::class);
Route::post('/upload/{shared}', VisitorUploadFileController::class);
diff --git a/routes/upload-request.php b/routes/upload-request.php
index 4dfd8f48..9912ae62 100644
--- a/routes/upload-request.php
+++ b/routes/upload-request.php
@@ -10,6 +10,7 @@ use Domain\UploadRequest\Controllers\MoveItemInUploadRequestController;
use Domain\UploadRequest\Controllers\SetUploadRequestAsFilledController;
use Domain\UploadRequest\Controllers\UploadFilesForUploadRequestController;
use Domain\UploadRequest\Controllers\GetFolderTreeForUploadRequestController;
+use Domain\UploadRequest\Controllers\UploadFilesRemotelyForUploadRequestController;
Route::get('/{uploadRequest}', GetUploadRequestController::class);
@@ -19,6 +20,7 @@ Route::group(['middleware' => 'upload-request'], function () {
Route::delete('/{uploadRequest}', SetUploadRequestAsFilledController::class);
// Edit
+ Route::post('/{uploadRequest}/upload/remote', UploadFilesRemotelyForUploadRequestController::class);
Route::post('/{uploadRequest}/upload', UploadFilesForUploadRequestController::class);
Route::patch('/{uploadRequest}/rename/{id}', RenameFileOrFolderController::class);
Route::post('/{uploadRequest}/create-folder', CreateFolderController::class);
diff --git a/src/App/Users/Models/User.php b/src/App/Users/Models/User.php
index fe197b7f..ec7f9403 100644
--- a/src/App/Users/Models/User.php
+++ b/src/App/Users/Models/User.php
@@ -38,6 +38,7 @@ use VueFileManager\Subscription\App\User\Traits\Billable;
* @method static where(string $string, string $string1)
* @method static create(array $array)
* @method static find(mixed $email)
+ * @method canUpload(int $size)
*/
class User extends Authenticatable implements MustVerifyEmail
{
diff --git a/src/Domain/Files/Actions/GetContentFromExternalSource.php b/src/Domain/Files/Actions/GetContentFromExternalSource.php
new file mode 100644
index 00000000..6672f0bb
--- /dev/null
+++ b/src/Domain/Files/Actions/GetContentFromExternalSource.php
@@ -0,0 +1,102 @@
+checkDisabledMimetypes($extension);
+
+ // Get file basename
+ $basename = Str::uuid() . ".$extension";
+
+ // Get file name
+ $name = array_key_exists('filename', pathinfo($url))
+ ? explode('?', pathinfo($url)['filename'])[0]
+ : Str::uuid();
+
+ // Get file path
+ $path = "files/$user->id/$basename";
+
+ // Store file to main storage disk
+ $localDisk->put($path, $response->getBody());
+
+ // Create multiple image thumbnails
+ ($this->createImageThumbnail)($basename, $user->id);
+
+ // Create new file
+ $file = File::create([
+ 'mimetype' => $extension,
+ 'type' => getFileType($localDisk->mimeType($path)),
+ 'parent_id' => $payload['parent_id'] ?? null,
+ 'name' => $name ?? $basename,
+ 'basename' => $basename,
+ 'filesize' => $localDisk->size($path),
+ 'user_id' => $user->id,
+ 'creator_id' => auth()->id(),
+ ]);
+
+ // Store file exif information
+ ($this->storeExifMetadata)($file);
+
+ // Move file to external storage
+ match (config('filesystems.default')) {
+ 's3' => ($this->moveFileToExternalStorage)($basename, $user->id),
+ 'ftp', 'azure' => ($this->moveFileToFTPStorage)($basename, $user->id),
+ default => null
+ };
+ } catch (ErrorException | Error $e) {
+ Log::error("Remote upload failed as {$e->getMessage()}");
+ Log::error($e->getTraceAsString());
+ }
+ }
+ }
+
+ /**
+ * @param string|null $extension
+ */
+ protected function checkDisabledMimetypes(?string $extension): void
+ {
+ $mimetypeBlacklist = explode(',', get_settings('mimetypes_blacklist')) ?? null;
+
+ // If is extension in mimetype blacklist, Abort!
+ if ($extension && array_intersect([str_replace('.', '', ".$extension")], $mimetypeBlacklist)) {
+ abort(422);
+ }
+ }
+}
diff --git a/src/Domain/Files/Actions/MoveFileToFTPStorageAction.php b/src/Domain/Files/Actions/MoveFileToFTPStorageAction.php
index f7eea3b5..2c95c040 100644
--- a/src/Domain/Files/Actions/MoveFileToFTPStorageAction.php
+++ b/src/Domain/Files/Actions/MoveFileToFTPStorageAction.php
@@ -12,7 +12,6 @@ class MoveFileToFTPStorageAction
string $file,
string $userId
): void {
-
// Stream file object to ftp
Storage::putFileAs("files/$userId", config('filesystems.disks.local.root') . "/files/$userId/$file", $file, 'private');
diff --git a/src/Domain/Files/Actions/ProcessFileAction.php b/src/Domain/Files/Actions/ProcessFileAction.php
new file mode 100644
index 00000000..74418399
--- /dev/null
+++ b/src/Domain/Files/Actions/ProcessFileAction.php
@@ -0,0 +1,93 @@
+size($chunkPath);
+ $mimetype = $localDisk->mimeType($chunkPath);
+ $name = Str::uuid() . '.' . $request->input('extension');
+
+ // Get upload limit
+ $uploadLimit = get_settings('upload_limit');
+
+ // File size handling
+ if ($uploadLimit && $size > format_bytes($uploadLimit)) {
+ abort(413);
+ }
+
+ // Check if user has enough space to upload file
+ if (! $user->canUpload($size)) {
+ // Delete file from chunk directory
+ $localDisk->delete($chunkPath);
+
+ // Set up response
+ $response = response([
+ 'type' => 'error',
+ 'message' => __t('user_action_not_allowed'),
+ ], 401);
+
+ // Abort code
+ abort($response);
+ }
+
+ // Move file to user directory
+ $localDisk->move($chunkPath, "files/$user->id/$name");
+
+ // Create multiple image thumbnails
+ ($this->createImageThumbnail)($name, $user->id);
+
+ // Move file to external storage
+ match (config('filesystems.default')) {
+ 's3' => ($this->moveFileToExternalStorage)($name, $user->id),
+ 'ftp', 'azure' => ($this->moveFileToFTPStorage)($name, $user->id),
+ default => null
+ };
+
+ // Create new file
+ $file = File::create([
+ 'mimetype' => $request->input('extension'),
+ 'type' => getFileType($mimetype),
+ 'parent_id' => ($this->getFileParentId)($request, $user->id),
+ 'name' => $request->input('name'),
+ 'basename' => $name,
+ 'filesize' => $size,
+ 'user_id' => $user->id,
+ 'creator_id' => auth()->check() ? auth()->id() : $user->id,
+ ]);
+
+ // Store file exif data
+ ($this->storeExifMetadata)($file);
+
+ // Return new file
+ return $file;
+ }
+}
diff --git a/src/Domain/Files/Actions/ProcessImageThumbnailAction.php b/src/Domain/Files/Actions/ProcessImageThumbnailAction.php
index 533d79e0..a58006d5 100644
--- a/src/Domain/Files/Actions/ProcessImageThumbnailAction.php
+++ b/src/Domain/Files/Actions/ProcessImageThumbnailAction.php
@@ -22,28 +22,33 @@ class ProcessImageThumbnailAction
* Create image thumbnail from uploaded image
*/
public function __invoke(
- string $fileName,
- $file,
- string $userId
+ string $name,
+ string $userId,
): void {
- // Create thumbnail from image
- if (in_array($file->getClientMimeType(), $this->availableFormats)) {
- // Make copy of file for the thumbnail generation
- Storage::disk('local')->copy("files/$userId/{$fileName}", "temp/$userId/{$fileName}");
+ // Get local disk instance
+ $disk = Storage::disk('local');
- // Create thumbnails instantly
- ($this->generateImageThumbnail)(
- fileName: $fileName,
- userId: $userId,
- execution: 'immediately'
- );
+ if (! in_array($disk->mimeType("files/$userId/$name"), $this->availableFormats)) {
+ return;
+ }
- // Create thumbnails later
- ($this->generateImageThumbnail)->onQueue('high')->execute(
- fileName: $fileName,
+ // Make copy of file for the thumbnail generation
+ $disk->copy("files/$userId/$name", "temp/$userId/$name");
+
+ // Create thumbnails instantly
+ ($this->generateImageThumbnail)(
+ fileName: $name,
+ userId: $userId,
+ execution: 'immediately'
+ );
+
+ // Create thumbnails later
+ ($this->generateImageThumbnail)
+ ->onQueue('high')
+ ->execute(
+ fileName: $name,
userId: $userId,
execution: 'later'
);
- }
}
}
diff --git a/src/Domain/Files/Actions/StoreFileChunksAction.php b/src/Domain/Files/Actions/StoreFileChunksAction.php
new file mode 100644
index 00000000..413a6fd0
--- /dev/null
+++ b/src/Domain/Files/Actions/StoreFileChunksAction.php
@@ -0,0 +1,33 @@
+file('file');
+
+ // Get chunk name
+ $name = $file->getClientOriginalName();
+
+ // Get chunk file path
+ $path = Storage::disk('local')->path("chunks/$name");
+
+ // Build the file
+ File::append($path, $file->get());
+
+ // If last chunk, then return file path
+ if ($request->boolean('is_last')) {
+ return "chunks/$name";
+ }
+ }
+}
diff --git a/src/Domain/Files/Actions/StoreFileExifMetadataAction.php b/src/Domain/Files/Actions/StoreFileExifMetadataAction.php
index 758d1c52..979bad8b 100644
--- a/src/Domain/Files/Actions/StoreFileExifMetadataAction.php
+++ b/src/Domain/Files/Actions/StoreFileExifMetadataAction.php
@@ -1,18 +1,22 @@
user_id/$file->basename");
- if ($exif_data) {
- // Convert array to collection
- $data = json_decode(json_encode($exif_data));
+ if (is_null($data)) {
+ return;
+ }
- $item->exif()->create([
+ $file
+ ->exif()
+ ->create([
'date_time_original' => $data->DateTimeOriginal ?? null,
'artist' => $data->OwnerName ?? null,
'width' => $data->COMPUTED->Width ?? null,
@@ -33,6 +37,5 @@ class StoreFileExifMetadataAction
'longitude_ref' => $data->GPSLongitudeRef ?? null,
'latitude_ref' => $data->GPSLatitudeRef ?? null,
]);
- }
}
}
diff --git a/src/Domain/Files/Actions/UploadFileAction.php b/src/Domain/Files/Actions/UploadFileAction.php
deleted file mode 100644
index 6fd8f7e5..00000000
--- a/src/Domain/Files/Actions/UploadFileAction.php
+++ /dev/null
@@ -1,111 +0,0 @@
-file('file');
-
- $chunkName = $file->getClientOriginalName();
-
- // File Path
- $filePath = Storage::disk('local')->path('chunks/' . $chunkName);
-
- // Generate file
- File::append($filePath, $file->get());
-
- // Size of file
- $fileSize = File::size($filePath);
-
- // Size of limit
- $uploadLimit = get_settings('upload_limit');
-
- // File size handling
- if ($uploadLimit && $fileSize > format_bytes($uploadLimit)) {
- abort(413);
- }
-
- // If last then process file
- if ($request->boolean('is_last')) {
- $disk_local = Storage::disk('local');
-
- // File name
- $fileName = Str::uuid() . '.' . $request->input('extension');
-
- // Get user
- $user = $request->filled('parent_id')
- ? Folder::find($request->input('parent_id'))->getLatestParent()->user
- : auth()->user();
-
- // File Info
- $fileSize = $disk_local->size("chunks/$chunkName");
- $fileMimetype = $disk_local->mimeType("chunks/$chunkName");
-
- // Check if user has enough space to upload file
- if (! $user->canUpload($fileSize)) {
- Storage::disk('local')->delete("chunks/$chunkName");
-
- throw new InvalidUserActionException();
- }
-
- // Move finished file from chunk to file-manager directory
- $disk_local->move("chunks/$chunkName", "files/$user->id/$fileName");
-
- // Create multiple image thumbnails
- ($this->createImageThumbnail)($fileName, $file, $user->id);
-
- // Move files to external storage
- match (config('filesystems.default')) {
- 's3' => ($this->moveFileToExternalStorage)($fileName, $user->id),
- 'ftp', 'azure' => ($this->moveFileToFTPStorage)($fileName, $user->id),
- default => null
- };
-
- // Create new file
- $item = UserFile::create([
- 'mimetype' => $request->input('extension'),
- 'type' => get_file_type($fileMimetype),
- 'parent_id' => ($this->getFileParentId)($request, $user->id),
- 'name' => $request->input('filename'),
- 'basename' => $fileName,
- 'filesize' => $fileSize,
- 'user_id' => $user->id,
- 'creator_id' => auth()->id(),
- ]);
-
- // Store exif metadata for files
- ($this->storeExifMetadata)($item, $file);
-
- // Return new file
- return $item;
- }
- }
-}
diff --git a/src/Domain/Files/Controllers/RemoteUploadFileController.php b/src/Domain/Files/Controllers/RemoteUploadFileController.php
new file mode 100644
index 00000000..98460c5a
--- /dev/null
+++ b/src/Domain/Files/Controllers/RemoteUploadFileController.php
@@ -0,0 +1,36 @@
+filled('parent_id')
+ ? Folder::find($request->input('parent_id'))
+ ->getLatestParent()
+ ->user
+ : auth()->user();
+
+ // Execute job for get content from url and save
+ ($this->getContentFromExternalSource)($request->all(), $user);
+
+ return response('Files were successfully added to the upload queue', 201);
+ }
+}
diff --git a/src/Domain/Files/Controllers/UploadFileController.php b/src/Domain/Files/Controllers/UploadFileController.php
index 1e3d7b6c..ceb79c87 100644
--- a/src/Domain/Files/Controllers/UploadFileController.php
+++ b/src/Domain/Files/Controllers/UploadFileController.php
@@ -1,24 +1,28 @@
fakeUploadFile)($request);
}
- try {
- // Upload and store file record
- if (! $request->boolean('is_last')) {
- return ($this->uploadFiles)($request);
- }
+ // Store file chunks
+ $chunkPath = ($this->storeFileChunks)($request);
- $file = ($this->uploadFiles)($request);
+ // Proceed after last chunk
+ if ($request->boolean('is_last')) {
+ // Get user
+ $user = $request->filled('parent_id')
+ ? Folder::find($request->input('parent_id'))
+ ->getLatestParent()
+ ->user
+ : auth()->user();
+
+ // Process file
+ $file = ($this->processFie)($request, $user, $chunkPath);
return response(new FileResource($file), 201);
- } catch (InvalidUserActionException $e) {
- return response([
- 'type' => 'error',
- 'message' => $e->getMessage(),
- ], 401);
}
}
}
diff --git a/src/Domain/Files/Controllers/VisitorRemoteUploadFileController.php b/src/Domain/Files/Controllers/VisitorRemoteUploadFileController.php
new file mode 100644
index 00000000..0c051659
--- /dev/null
+++ b/src/Domain/Files/Controllers/VisitorRemoteUploadFileController.php
@@ -0,0 +1,39 @@
+protectShareRecord)($shared);
+
+ // Check shared permission
+ if (is_visitor($shared)) {
+ abort(403, "You don't have access to this item");
+ }
+
+ // Check access to requested directory
+ ($this->verifyAccessToItem)($request->input('parent_id'), $shared);
+
+ // Execute job for get content from url and save
+ ($this->getContentFromExternalSource)($request->all(), $shared->user);
+
+ return response('Files were successfully added to the upload queue', 201);
+ }
+}
diff --git a/src/Domain/Files/Controllers/VisitorUploadFileController.php b/src/Domain/Files/Controllers/VisitorUploadFileController.php
index dfef2645..c709b285 100644
--- a/src/Domain/Files/Controllers/VisitorUploadFileController.php
+++ b/src/Domain/Files/Controllers/VisitorUploadFileController.php
@@ -1,14 +1,13 @@
fakeUploadFile)($request);
}
@@ -48,19 +48,18 @@ class VisitorUploadFileController extends Controller
// Check access to requested directory
($this->verifyAccessToItem)($request->input('parent_id'), $shared);
- try {
- // Return new uploaded file
- $file = ($this->uploadFile)($request, $shared->user_id);
+ // Store file chunks
+ $chunkPath = ($this->storeFileChunks)($request);
+
+ // Proceed after last chunk
+ if ($request->boolean('is_last')) {
+ // Process file
+ $file = ($this->processFie)($request, $shared->user, $chunkPath);
// Set public access url
$file->setSharedPublicUrl($shared->token);
return response(new FileResource($file), 201);
- } catch (InvalidUserActionException $e) {
- return response([
- 'type' => 'error',
- 'message' => $e->getMessage(),
- ], 401);
}
}
}
diff --git a/src/Domain/Files/Requests/RemoteUploadRequest.php b/src/Domain/Files/Requests/RemoteUploadRequest.php
new file mode 100644
index 00000000..24426059
--- /dev/null
+++ b/src/Domain/Files/Requests/RemoteUploadRequest.php
@@ -0,0 +1,30 @@
+ 'required|url',
+ 'parent_id' => 'nullable|uuid',
+ ];
+ }
+}
diff --git a/src/Domain/Files/Requests/UploadRequest.php b/src/Domain/Files/Requests/UploadRequest.php
index b4c01645..7224374d 100644
--- a/src/Domain/Files/Requests/UploadRequest.php
+++ b/src/Domain/Files/Requests/UploadRequest.php
@@ -24,9 +24,9 @@ class UploadRequest extends FormRequest
public function rules()
{
return [
- 'filename' => 'required|string',
+ 'name' => 'required|string',
'parent_id' => 'nullable|uuid',
- 'path' => 'required|string',
+ 'path' => 'sometimes|string',
'is_last' => 'sometimes|string',
'extension' => 'sometimes|string|nullable',
'file' => ['required', 'file', new DisabledMimetypes],
diff --git a/src/Domain/Settings/Actions/TestFTPConnectionAction.php b/src/Domain/Settings/Actions/TestFTPConnectionAction.php
index c6a5ef1a..b61304a7 100644
--- a/src/Domain/Settings/Actions/TestFTPConnectionAction.php
+++ b/src/Domain/Settings/Actions/TestFTPConnectionAction.php
@@ -1,11 +1,10 @@
input('storage.driver')) {
's3', 'storj', 'spaces', 'wasabi', 'backblaze', 'oss', 'other' => 's3',
'local' => 'local',
- 'ftp' => 'ftp',
+ 'ftp' => 'ftp',
};
if (! app()->runningUnitTests()) {
-
// Test driver connection
match ($driver) {
's3' => ($this->testS3Connection)(
diff --git a/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php b/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php
index db529335..dac40a0d 100644
--- a/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php
+++ b/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php
@@ -2,11 +2,11 @@
namespace Domain\SetupWizard\Controllers;
use Artisan;
-use Domain\Settings\Actions\TestFTPConnectionAction;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Domain\Settings\DTO\S3CredentialsData;
use Domain\Settings\Actions\TestS3ConnectionAction;
+use Domain\Settings\Actions\TestFTPConnectionAction;
use Domain\Settings\Actions\TestSESConnectionAction;
use Domain\Settings\Actions\TestSMTPConnectionAction;
use Domain\Settings\Actions\TestMailgunConnectionAction;
@@ -22,7 +22,8 @@ class StoreEnvironmentSettingsController extends Controller
private TestSMTPConnectionAction $testSMTPConnection,
private TestMailgunConnectionAction $testMailgunConnection,
private TestPostmarkConnectionAction $testPostmarkConnection,
- ) {}
+ ) {
+ }
/**
* Store environment setup
@@ -35,7 +36,7 @@ class StoreEnvironmentSettingsController extends Controller
$StorageDriver = match ($request->input('storage.driver')) {
's3', 'storj', 'spaces', 'wasabi', 'backblaze', 'oss', 'other' => 's3',
'local' => 'local',
- 'ftp' => 'ftp',
+ 'ftp' => 'ftp',
};
// Test driver connection
diff --git a/src/Domain/UploadRequest/Controllers/UploadFilesForUploadRequestController.php b/src/Domain/UploadRequest/Controllers/UploadFilesForUploadRequestController.php
index 164aa6d9..67df3b18 100644
--- a/src/Domain/UploadRequest/Controllers/UploadFilesForUploadRequestController.php
+++ b/src/Domain/UploadRequest/Controllers/UploadFilesForUploadRequestController.php
@@ -4,15 +4,16 @@ namespace Domain\UploadRequest\Controllers;
use DB;
use Domain\Folders\Models\Folder;
use Domain\Files\Resources\FileResource;
-use Domain\Files\Actions\UploadFileAction;
+use Domain\Files\Actions\ProcessFileAction;
use Domain\UploadRequest\Models\UploadRequest;
-use App\Users\Exceptions\InvalidUserActionException;
+use Domain\Files\Actions\StoreFileChunksAction;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
class UploadFilesForUploadRequestController
{
public function __construct(
- private UploadFileAction $uploadFile,
+ private ProcessFileAction $processFie,
+ private StoreFileChunksAction $storeFileChunks,
) {
}
@@ -29,14 +30,18 @@ class UploadFilesForUploadRequestController
$this->createFolder($uploadRequest);
}
- try {
- // Set default parent_id for uploaded file
- if (is_null($request->input('parent_id'))) {
- $request->merge(['parent_id' => $uploadRequest->id]);
- }
+ // Set default parent_id for uploaded file
+ if (is_null($request->input('parent_id'))) {
+ $request->merge(['parent_id' => $uploadRequest->id]);
+ }
- // Upload file
- $file = ($this->uploadFile)($request, $uploadRequest->user_id);
+ // Store file chunks
+ $chunkPath = ($this->storeFileChunks)($request);
+
+ // Proceed after last chunk
+ if ($request->boolean('is_last')) {
+ // Process file
+ $file = ($this->processFie)($request, $uploadRequest->user, $chunkPath);
// Set public access url
$file->setUploadRequestPublicUrl($uploadRequest->id);
@@ -44,13 +49,7 @@ class UploadFilesForUploadRequestController
// Set timestamp for auto filling
cache()->set("auto-filling.$uploadRequest->id", now()->toString());
- // Return new uploaded file
return response(new FileResource($file), 201);
- } catch (InvalidUserActionException $e) {
- return response([
- 'type' => 'error',
- 'message' => $e->getMessage(),
- ], 401);
}
}
diff --git a/src/Domain/UploadRequest/Controllers/UploadFilesRemotelyForUploadRequestController.php b/src/Domain/UploadRequest/Controllers/UploadFilesRemotelyForUploadRequestController.php
new file mode 100644
index 00000000..2688fe9a
--- /dev/null
+++ b/src/Domain/UploadRequest/Controllers/UploadFilesRemotelyForUploadRequestController.php
@@ -0,0 +1,68 @@
+id);
+
+ // Create folder if not exist
+ if ($folder->doesntExist()) {
+ $this->createFolder($uploadRequest);
+ }
+
+ // Set default parent_id for uploaded file
+ if (is_null($request->input('parent_id'))) {
+ $request->merge(['parent_id' => $uploadRequest->id]);
+ }
+
+ // Execute job for get content from url and save
+ ($this->getContentFromExternalSource)($request->all(), $uploadRequest->user);
+
+ // Set timestamp for auto filling
+ cache()->set("auto-filling.$uploadRequest->id", now()->toString());
+
+ return response('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/Support/Demo/Actions/FakeUploadFileAction.php b/src/Support/Demo/Actions/FakeUploadFileAction.php
index 48f33cb4..e9ad06a6 100644
--- a/src/Support/Demo/Actions/FakeUploadFileAction.php
+++ b/src/Support/Demo/Actions/FakeUploadFileAction.php
@@ -19,7 +19,7 @@ class FakeUploadFileAction
return [
'data' => [
'id' => Str::uuid(),
- 'type' => get_file_type($file->getMimeType()),
+ 'type' => getFileType($file->getMimeType()),
'attributes' => [
'filesize' => Metric::bytes($file->getSize())->format(),
'name' => $request->input('filename'),
diff --git a/src/Support/errors.php b/src/Support/errors.php
index 5eb7db27..1e9595d6 100644
--- a/src/Support/errors.php
+++ b/src/Support/errors.php
@@ -1,17 +1,17 @@
'error',
- 'message' => 'Access Denied',
- ];
-}
+ function accessDeniedError(): array
+ {
+ return [
+ 'type' => 'error',
+ 'message' => 'Access Denied',
+ ];
+ }
-function userActionNotAllowedError(): array
-{
- return [
- 'type' => 'error',
- 'message' => 'This user action is not allowed.',
- ];
-}
+ function userActionNotAllowedError(): array
+ {
+ return [
+ 'type' => 'error',
+ 'message' => 'This user action is not allowed.',
+ ];
+ }
diff --git a/src/Support/helpers.php b/src/Support/helpers.php
index 59d1e9bb..1a1dc13e 100644
--- a/src/Support/helpers.php
+++ b/src/Support/helpers.php
@@ -210,7 +210,6 @@ if (! function_exists('setEnvironmentValue')) {
if (count($values) > 0) {
foreach ($values as $envKey => $envValue) {
-
$str .= "\n"; // In case the searched variable is in the last line without \n
$keyPosition = strpos($str, "{$envKey}=");
@@ -640,7 +639,7 @@ if (! function_exists('get_file_type')) {
/**
* Get file type from mimetype
*/
- function get_file_type(string $fileMimetype): string
+ function getFileType(string $fileMimetype): string
{
// Get mimetype from file
$mimetype = explode('/', $fileMimetype);
@@ -747,22 +746,32 @@ if (! function_exists('getPrettyName')) {
}
}
-if (! function_exists('get_image_meta_data')) {
+if (! function_exists('readExifData')) {
/**
* Get exif data from jpeg image
- *
- * @param $file
- * @return array|null
*/
- function get_image_meta_data($file)
+ function readExifData(string $file): object|null
{
- if (get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') {
- try {
- // Try to get the exif data
- return mb_convert_encoding(Image::make($file->getRealPath())->exif(), 'UTF8', 'UTF8');
- } catch (\Exception $e) {
- return null;
- }
+ $disk = Storage::disk('local');
+
+ $type = get_file_type_from_mimetype(
+ $disk->mimeType($file)
+ );
+
+ if ($type !== 'jpeg') {
+ return null;
+ }
+
+ try {
+ // Try to get the exif data
+ $data = Image::make($disk->path($file))->exif();
+
+ // Encode data
+ $encodedData = mb_convert_encoding($data, 'UTF8', 'UTF8');
+
+ return json_decode(json_encode($encodedData));
+ } catch (Exception $e) {
+ return null;
}
}
}
@@ -1148,4 +1157,39 @@ if (! function_exists('replace_occurrence')) {
return "{$degrees}°$minutes'$seconds\"$ref";
}
}
+
+ if (! function_exists('extractExtensionFromUrl')) {
+ /**
+ * Extract extension from the url
+ *
+ * TODO: make unit test
+ */
+ function extractExtensionFromUrl($url, $response): string|null
+ {
+ $extension = null;
+
+ if (array_key_exists('extension', pathinfo($url))) {
+ // Break attributes
+ $string = str_replace(['&'], '?', pathinfo($url)['extension']);
+
+ // Get extension from url path
+ $extension = explode('?', $string)[0];
+ }
+
+ // Return pure extension
+ if ($extension) {
+ return $extension;
+ }
+
+ // Prepare header for extracting content-type line
+ $header = array_change_key_case($response->headers(), CASE_LOWER);
+
+ // Get extension
+ if (array_key_exists('content-type', $header)) {
+ return explode('/', $header['content-type'][0])[1];
+ }
+
+ return null;
+ }
+ }
}
diff --git a/tests/Domain/Admin/AdminTest.php b/tests/Domain/Admin/AdminTest.php
index 6d6fac97..aaf7deeb 100644
--- a/tests/Domain/Admin/AdminTest.php
+++ b/tests/Domain/Admin/AdminTest.php
@@ -279,7 +279,8 @@ class AdminTest extends TestCase
->create("fake-file-$index.pdf", 1200, 'application/pdf');
$this->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
diff --git a/tests/Domain/Files/FileTest.php b/tests/Domain/Files/FileTest.php
index b5c9c557..c4d88935 100644
--- a/tests/Domain/Files/FileTest.php
+++ b/tests/Domain/Files/FileTest.php
@@ -9,6 +9,7 @@ use Domain\Files\Models\File;
use Domain\Folders\Models\Folder;
use Illuminate\Http\UploadedFile;
use Domain\Settings\Models\Setting;
+use Illuminate\Support\Facades\Http;
class FileTest extends TestCase
{
@@ -40,7 +41,8 @@ class FileTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => '.jpg',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -80,7 +82,8 @@ class FileTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -100,6 +103,54 @@ class FileTest extends TestCase
);
}
+ /**
+ * @test
+ */
+ public function it_remotely_upload_new_file()
+ {
+ $user = User::factory()
+ ->hasSettings()
+ ->create();
+
+ $folder = Folder::factory()
+ ->create([
+ 'user_id' => $user->id,
+ ]);
+
+ $fakeFile = UploadedFile::fake()
+ ->create('top-secret-document.pdf', 12000000, 'application/pdf');
+
+ Http::fake([
+ 'https://fake.com/top-secret-document.pdf' => Http::response($fakeFile->getContent()),
+ 'https://fake.com/another-secret-document.pdf' => Http::response($fakeFile->getContent()),
+ ]);
+
+ $this
+ ->actingAs($user)
+ ->postJson('/api/upload/remote', [
+ 'urls' => [
+ 'https://fake.com/top-secret-document.pdf',
+ 'https://fake.com/another-secret-document.pdf',
+ ],
+ 'parent_id' => $folder->id,
+ ])->assertStatus(201);
+
+ $this
+ ->assertDatabaseHas('files', [
+ 'user_id' => $user->id,
+ 'name' => 'top-secret-document',
+ 'parent_id' => $folder->id,
+ ])
+ ->assertDatabaseHas('files', [
+ 'name' => 'another-secret-document',
+ ]);
+
+ File::all()
+ ->each(function ($file) {
+ Storage::assertExists("files/$file->user_id/$file->basename");
+ });
+ }
+
/**
* @test
*/
@@ -125,7 +176,8 @@ class FileTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'jpeg',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -158,6 +210,7 @@ class FileTest extends TestCase
->actingAs($user)
->postJson('/api/upload', [
'file' => $file,
+ 'extension' => 'pdf',
'parent_id' => null,
'path' => "/$file->name",
'is_last' => 'true',
@@ -233,7 +286,7 @@ class FileTest extends TestCase
'parent_id' => $folder->id,
]);
}
-
+
/**
* @test
*/
@@ -348,7 +401,8 @@ class FileTest extends TestCase
->create("fake-file-$index.pdf", 1200, 'application/pdf');
$this->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -387,8 +441,8 @@ class FileTest extends TestCase
}
/**
- * @test
- */
+ * @test
+ */
public function it_store_file_exif_data_after_file_upload()
{
$file = UploadedFile::fake()
@@ -401,7 +455,8 @@ class FileTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'jpg',
'file' => $file,
'parent_id' => null,
'path' => '/' . $file->name,
diff --git a/tests/Domain/Folders/FolderTest.php b/tests/Domain/Folders/FolderTest.php
index b58213fc..0507aa76 100644
--- a/tests/Domain/Folders/FolderTest.php
+++ b/tests/Domain/Folders/FolderTest.php
@@ -371,7 +371,8 @@ class FolderTest extends TestCase
->create("fake-file-$index.pdf", 1200, 'application/pdf');
$this->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",
diff --git a/tests/Domain/Folders/FolderUploadTest.php b/tests/Domain/Folders/FolderUploadTest.php
index 0b5c8941..c6466b9f 100644
--- a/tests/Domain/Folders/FolderUploadTest.php
+++ b/tests/Domain/Folders/FolderUploadTest.php
@@ -30,7 +30,8 @@ class FolderUploadTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'path' => '/',
'parent_id' => $folder->id,
@@ -59,7 +60,8 @@ class FolderUploadTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'path' => "/level_1/level_2/level_3/$file->name",
'parent_id' => null,
@@ -69,7 +71,8 @@ class FolderUploadTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'path' => "/level_1/level_2/level_3/$file->name",
'parent_id' => null,
@@ -127,7 +130,8 @@ class FolderUploadTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'path' => "/another_folder/level_2/level_3/$file->name",
'parent_id' => null,
@@ -163,7 +167,8 @@ class FolderUploadTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $brother->name,
+ 'name' => $brother->name,
+ 'extension' => 'pdf',
'file' => $brother,
'path' => "/Folder/Brother/$brother->name",
'parent_id' => null,
@@ -173,7 +178,8 @@ class FolderUploadTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $sister->name,
+ 'name' => $sister->name,
+ 'extension' => 'pdf',
'file' => $sister,
'path' => "/Folder/Sister/$sister->name",
'parent_id' => null,
diff --git a/tests/Domain/Sharing/VisitorManipulatingTest.php b/tests/Domain/Sharing/VisitorManipulatingTest.php
index ea5df238..d4dc1ee2 100644
--- a/tests/Domain/Sharing/VisitorManipulatingTest.php
+++ b/tests/Domain/Sharing/VisitorManipulatingTest.php
@@ -330,7 +330,8 @@ class VisitorManipulatingTest extends TestCase
$this
->withUnencryptedCookies($cookie)
->post("/api/editor/upload/$share->token", [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",
@@ -341,7 +342,8 @@ class VisitorManipulatingTest extends TestCase
// Check public shared item
if (! $is_protected) {
$this->postJson("/api/editor/upload/$share->token", [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",
diff --git a/tests/Domain/Teams/TeamFileAccessTest.php b/tests/Domain/Teams/TeamFileAccessTest.php
index a23e9d52..bfbf087c 100644
--- a/tests/Domain/Teams/TeamFileAccessTest.php
+++ b/tests/Domain/Teams/TeamFileAccessTest.php
@@ -32,7 +32,8 @@ class TeamFileAccessTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",
@@ -80,7 +81,8 @@ class TeamFileAccessTest extends TestCase
$this
->actingAs($user)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",
diff --git a/tests/Domain/Teams/TeamsTest.php b/tests/Domain/Teams/TeamsTest.php
index f87c1a15..e1257852 100644
--- a/tests/Domain/Teams/TeamsTest.php
+++ b/tests/Domain/Teams/TeamsTest.php
@@ -283,7 +283,8 @@ class TeamsTest extends TestCase
$this
->actingAs($member)
->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",
diff --git a/tests/Domain/Traffic/TrafficTest.php b/tests/Domain/Traffic/TrafficTest.php
index f5e4df3f..48572845 100644
--- a/tests/Domain/Traffic/TrafficTest.php
+++ b/tests/Domain/Traffic/TrafficTest.php
@@ -37,7 +37,7 @@ class TrafficTest extends TestCase
$this
->actingAs($this->user)
->postJson('/api/upload', [
- 'filename' => $this->file->name,
+ 'name' => $this->file->name,
'file' => $this->file,
'parent_id' => null,
'path' => '/' . $this->file->name,
@@ -58,7 +58,7 @@ class TrafficTest extends TestCase
$this
->actingAs($this->user)
->postJson('/api/upload', [
- 'filename' => $this->file->name,
+ 'name' => $this->file->name,
'file' => $this->file,
'parent_id' => null,
'path' => '/' . $this->file->name,
@@ -79,7 +79,7 @@ class TrafficTest extends TestCase
$this
->actingAs($this->user)
->postJson('/api/upload', [
- 'filename' => $secondFile->name,
+ 'name' => $secondFile->name,
'file' => $secondFile,
'parent_id' => null,
'path' => '/' . $secondFile->name,
@@ -117,7 +117,7 @@ class TrafficTest extends TestCase
// Check public shared item
$this->postJson("/api/editor/upload/$share->token", [
- 'filename' => $this->file->name,
+ 'name' => $this->file->name,
'file' => $this->file,
'parent_id' => $folder->id,
'path' => '/' . $this->file->name,
diff --git a/tests/Domain/Trash/TrashTest.php b/tests/Domain/Trash/TrashTest.php
index a691c5a3..007d91f0 100644
--- a/tests/Domain/Trash/TrashTest.php
+++ b/tests/Domain/Trash/TrashTest.php
@@ -75,7 +75,7 @@ class TrashTest extends TestCase
->image('fake-image.jpg');
$this->postJson('/api/upload', [
- 'filename' => $image->name,
+ 'name' => $image->name,
'file' => $image,
'parent_id' => null,
'path' => '/' . $image->name,
diff --git a/tests/Domain/UploadRequest/UploadRequestTest.php b/tests/Domain/UploadRequest/UploadRequestTest.php
index a0459a6e..e71345f4 100644
--- a/tests/Domain/UploadRequest/UploadRequestTest.php
+++ b/tests/Domain/UploadRequest/UploadRequestTest.php
@@ -150,7 +150,8 @@ class UploadRequestTest extends TestCase
$this
->postJson("/api/upload-request/$uploadRequest->id/upload", [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -195,7 +196,8 @@ class UploadRequestTest extends TestCase
$this
->postJson("/api/upload-request/$uploadRequest->id/upload", [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -239,7 +241,7 @@ class UploadRequestTest extends TestCase
$this
->postJson("/api/upload-request/$uploadRequest->id/upload", [
- 'filename' => $file->name,
+ 'name' => $file->name,
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -312,7 +314,8 @@ class UploadRequestTest extends TestCase
$this
->postJson("/api/upload-request/$uploadRequest->id/upload", [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
diff --git a/tests/Domain/Zip/UserZippingTest.php b/tests/Domain/Zip/UserZippingTest.php
index 9f42014a..dd095a87 100644
--- a/tests/Domain/Zip/UserZippingTest.php
+++ b/tests/Domain/Zip/UserZippingTest.php
@@ -32,7 +32,8 @@ class UserZippingTest extends TestCase
->create("fake-inner-file-$index.pdf", 1200, 'application/pdf');
$this->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",
@@ -46,7 +47,8 @@ class UserZippingTest extends TestCase
->create("fake-file-$index.pdf", 1200, 'application/pdf');
$this->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => null,
'path' => "/$file->name",
@@ -87,7 +89,8 @@ class UserZippingTest extends TestCase
->create("fake-file-$index.pdf", 1200, 'application/pdf');
$this->postJson('/api/upload', [
- 'filename' => $file->name,
+ 'name' => $file->name,
+ 'extension' => 'pdf',
'file' => $file,
'parent_id' => $folder->id,
'path' => "/$file->name",