From c2ec2af33cdd33a698b0646ee72855af43fdade6 Mon Sep 17 00:00:00 2001 From: ak Date: Wed, 18 Oct 2023 21:20:47 -0700 Subject: [PATCH] removed old boilerplate, implemented S3 uploading. --- README.md | 1 + app/Http/Controllers/FileController.php | 8 +- app/Jobs/UploadToS3.php | 61 ++++ app/Models/File.php | 2 +- composer.json | 2 + composer.lock | 327 ++++++++++++++++-- ...23_10_19_033004_add_s3_column_to_files.php | 30 ++ resources/js/Components/Dropdown.vue | 37 +- resources/js/Components/DropdownLink.vue | 4 +- resources/js/Components/InputError.vue | 2 +- resources/js/Components/InputLabel.vue | 2 +- resources/js/Components/NavLink.vue | 4 +- resources/js/Components/ResponsiveNavLink.vue | 2 +- resources/js/Components/TextInput.vue | 2 +- .../js/Components/custom/NewDropdown.vue | 4 +- .../js/Components/custom/UploadFiles.vue | 2 +- .../js/Components/custom/UploadFolder.vue | 2 +- .../js/Components/custom/UserDropdown.vue | 4 +- resources/js/Layouts/GuestLayout.vue | 12 + resources/js/Layouts/old.vue | 182 ---------- resources/js/Pages/Auth/ConfirmPassword.vue | 50 --- resources/js/Pages/Auth/ForgotPassword.vue | 32 +- resources/js/Pages/Auth/Login.vue | 17 +- resources/js/Pages/Auth/Register.vue | 5 +- resources/js/Pages/Auth/VerifyEmail.vue | 38 +- resources/js/Pages/Profile/Edit.vue | 22 +- .../Pages/Profile/Partials/DeleteUserForm.vue | 57 +-- .../Profile/Partials/UpdatePasswordForm.vue | 59 ++-- .../Partials/UpdateProfileInformationForm.vue | 40 ++- 29 files changed, 615 insertions(+), 395 deletions(-) create mode 100644 app/Jobs/UploadToS3.php create mode 100644 database/migrations/2023_10_19_033004_add_s3_column_to_files.php delete mode 100644 resources/js/Layouts/old.vue delete mode 100644 resources/js/Pages/Auth/ConfirmPassword.vue diff --git a/README.md b/README.md index fcbbe01..c52a06f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # laravel-vue-file-share Dropbox/Google Drive-esque file sharing application implemented in Laravel, PHP, Inertia, Vue, Headless-UI and Tailwind CSS. Uses Mitt for firing events and passing data. +Uses S3 for storing and retrieving files. diff --git a/app/Http/Controllers/FileController.php b/app/Http/Controllers/FileController.php index 62da08e..06ccd55 100644 --- a/app/Http/Controllers/FileController.php +++ b/app/Http/Controllers/FileController.php @@ -12,6 +12,8 @@ use App\Http\Requests\SharedFiles; use App\Http\Resources\FileResource; +use App\Jobs\UploadToS3; + use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -827,12 +829,16 @@ class FileController extends Controller // loop over files, make and upload each one foreach ($files as $userFile) { $file = new File(); - $file->stored_at = $userFile->store('/files/'.Auth::id()); + $file->stored_at = $userFile->store('/files/' . Auth::id(), 'local'); $file->is_folder = false; $file->name = $userFile->getClientOriginalName(); $file->mimetype = $userFile->getMimeType(); $file->size = $userFile->getSize(); + $file->s3 = 0; // file has NOT been uploaded to s3 $parent->appendNode($file); + + // upload file to S3 + UploadToS3::dispatch($file); } } diff --git a/app/Jobs/UploadToS3.php b/app/Jobs/UploadToS3.php new file mode 100644 index 0000000..ff581e4 --- /dev/null +++ b/app/Jobs/UploadToS3.php @@ -0,0 +1,61 @@ +file; + + // if the file has not been uploaded to S3 + if (!$file->s3) { + $localPath = Storage::disk('local')->path($file->stored_at); + Log::debug("File at " . $localPath . " being uploaded to S3"); + + // upload file to S3 + try { + // upload to S3 with the "stored_at" path. get file from 'local' disk at the "stored_at" path. + $stored = Storage::put($file->stored_at, Storage::disk('local')->get($file->stored_at)); + // if storing is successful, change DB and output log message + if ($stored) { + Log::debug("File uploaded to S3"); + $file->s3 = 1; + $file->save(); + } + // else file storing on S3 was not successful. + else { + Log::error("File upload to S3 was unsuccessful"); + } + } + catch (\Exception $exception) { + Log::error($exception->getMessage()); + } + } + // else do nothing + } +} diff --git a/app/Models/File.php b/app/Models/File.php index 9137673..59287cb 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -88,7 +88,7 @@ class File extends Model else $model->path = ''; // append current file or folder name to path name - $model->path = $model->path . Str::slug($model->name); + $model->path = $model->path . $model->name; }); // define delete function diff --git a/composer.json b/composer.json index 482bdcf..f09e294 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,8 @@ "laravel/framework": "^10.10", "laravel/sanctum": "^3.2", "laravel/tinker": "^2.8", + "league/flysystem-aws-s3-v3": "^3.0", + "psr/http-message": "^1.0", "tightenco/ziggy": "^1.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index b486fde..81e855a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,157 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6befa31489c527cc8174c05d5165886a", + "content-hash": "edbfbe62b4cb8f6882359a6168f6d6e6", "packages": [ + { + "name": "aws/aws-crt-php", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "2f1dc7b7eda080498be96a4a6d683a41583030e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/2f1dc7b7eda080498be96a4a6d683a41583030e9", + "reference": "2f1dc7b7eda080498be96a4a6d683a41583030e9", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "support": { + "issues": "https://github.com/awslabs/aws-crt-php/issues", + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.2" + }, + "time": "2023-07-20T16:49:55+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.283.7", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "54cbb4253c6add698ec429bfb6ff2168c2fd7092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/54cbb4253c6add698ec429bfb6ff2168c2fd7092", + "reference": "54cbb4253c6add698ec429bfb6ff2168c2fd7092", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.0.4", + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", + "guzzlehttp/promises": "^1.4.0 || ^2.0", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "mtdowling/jmespath.php": "^2.6", + "php": ">=7.2.5", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "composer/composer": "^1.10.22", + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "nette/neon": "^2.3", + "paragonie/random_compat": ">= 2", + "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "sebastian/comparator": "^1.2.3 || ^4.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "support": { + "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", + "issues": "https://github.com/aws/aws-sdk-php/issues", + "source": "https://github.com/aws/aws-sdk-php/tree/3.283.7" + }, + "time": "2023-10-18T20:16:37+00:00" + }, { "name": "brick/math", "version": "0.11.0", @@ -1815,16 +1964,16 @@ }, { "name": "league/flysystem", - "version": "3.16.0", + "version": "3.17.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729" + "reference": "bd4c9b26849d82364119c68429541f1631fba94b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4fdf372ca6b63c6e281b1c01a624349ccb757729", - "reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/bd4c9b26849d82364119c68429541f1631fba94b", + "reference": "bd4c9b26849d82364119c68429541f1631fba94b", "shasum": "" }, "require": { @@ -1842,8 +1991,8 @@ "symfony/http-client": "<5.2" }, "require-dev": { - "async-aws/s3": "^1.5", - "async-aws/simple-s3": "^1.1", + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", "aws/aws-sdk-php": "^3.220.0", "composer/semver": "^3.0", "ext-fileinfo": "*", @@ -1889,7 +2038,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.16.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.17.0" }, "funding": [ { @@ -1901,7 +2050,73 @@ "type": "github" } ], - "time": "2023-09-07T19:22:17+00:00" + "time": "2023-10-05T20:15:05+00:00" + }, + { + "name": "league/flysystem-aws-s3-v3", + "version": "3.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", + "reference": "ded9ba346bb01cb9cc4cc7f2743c2c0e14d18e1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/ded9ba346bb01cb9cc4cc7f2743c2c0e14d18e1c", + "reference": "ded9ba346bb01cb9cc4cc7f2743c2c0e14d18e1c", + "shasum": "" + }, + "require": { + "aws/aws-sdk-php": "^3.220.0", + "league/flysystem": "^3.10.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\AwsS3V3\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "AWS S3 filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "aws", + "file", + "files", + "filesystem", + "s3", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues", + "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.16.0" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2023-08-30T10:14:57+00:00" }, { "name": "league/flysystem-local", @@ -1965,16 +2180,16 @@ }, { "name": "league/mime-type-detection", - "version": "1.13.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "a6dfb1194a2946fcdc1f38219445234f65b35c96" + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/a6dfb1194a2946fcdc1f38219445234f65b35c96", - "reference": "a6dfb1194a2946fcdc1f38219445234f65b35c96", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b6a5854368533df0295c5761a0253656a2e52d9e", + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e", "shasum": "" }, "require": { @@ -2005,7 +2220,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.13.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.14.0" }, "funding": [ { @@ -2017,7 +2232,7 @@ "type": "tidelift" } ], - "time": "2023-08-05T12:09:49+00:00" + "time": "2023-10-17T14:13:20+00:00" }, { "name": "monolog/monolog", @@ -2120,6 +2335,72 @@ ], "time": "2023-06-21T08:46:11+00:00" }, + { + "name": "mtdowling/jmespath.php", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/bbb69a935c2cbb0c03d7f481a238027430f6440b", + "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.33" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.7.0" + }, + "time": "2023-08-25T10:54:48+00:00" + }, { "name": "nesbot/carbon", "version": "2.71.0", @@ -2851,16 +3132,16 @@ }, { "name": "psr/http-message", - "version": "2.0", + "version": "1.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", "shasum": "" }, "require": { @@ -2869,7 +3150,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -2884,7 +3165,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -2898,9 +3179,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" + "source": "https://github.com/php-fig/http-message/tree/1.1" }, - "time": "2023-04-04T09:54:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { "name": "psr/log", diff --git a/database/migrations/2023_10_19_033004_add_s3_column_to_files.php b/database/migrations/2023_10_19_033004_add_s3_column_to_files.php new file mode 100644 index 0000000..3f63f9e --- /dev/null +++ b/database/migrations/2023_10_19_033004_add_s3_column_to_files.php @@ -0,0 +1,30 @@ +boolean('s3')->default(0)->after('stored_at'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('files', function (Blueprint $table) { + // reverse everything done above + $table->dropColumn('s3'); + }); + } +}; diff --git a/resources/js/Components/Dropdown.vue b/resources/js/Components/Dropdown.vue index 53357ac..092c396 100644 --- a/resources/js/Components/Dropdown.vue +++ b/resources/js/Components/Dropdown.vue @@ -1,43 +1,43 @@