Merge remote-tracking branch 'origin/zipstream'

This commit is contained in:
Peter Papp
2021-07-29 16:11:02 +02:00
78 changed files with 1200 additions and 1476 deletions
+4 -31
View File
@@ -41,37 +41,10 @@ MAIL_ENCRYPTION=
MAIL_FROM_ADDRESS="${MAIL_USERNAME}"
MAIL_FROM_NAME="${MAIL_USERNAME}"
OSS_ACCESS_KEY_ID=
OSS_SECRET_ACCESS_KEY=
OSS_REGION=
OSS_BUCKET=
OSS_ENDPOINT=
OSS_URL=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=
DO_SPACES_KEY=
DO_SPACES_SECRET=
DO_SPACES_ENDPOINT=
DO_SPACES_REGION=
DO_SPACES_BUCKET=
WASABI_KEY=
WASABI_SECRET=
WASABI_ENDPOINT=
WASABI_REGION=
WASABI_BUCKET=
BACKBLAZE_KEY=
BACKBLAZE_SECRET=
BACKBLAZE_ENDPOINT=
BACKBLAZE_REGION=
BACKBLAZE_BUCKET=
APP_DEPLOY_SECRET=
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_DEFAULT_REGION=
S3_BUCKET=
CASHIER_LOGGER=stack
CASHIER_CURRENCY=
+4 -4
View File
@@ -34,10 +34,10 @@ MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_DEFAULT_REGION=us-east-1
S3_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
+2 -2
View File
@@ -28,17 +28,17 @@
"laravel/ui": "^3.2.0",
"league/flysystem-aws-s3-v3": "^1.0.29",
"league/flysystem-cached-adapter": "^1.1.0",
"madnest/madzipper": "^1.1.0",
"spatie/laravel-backup": "^6.16.1",
"spatie/laravel-query-builder": "^3.5",
"spatie/laravel-queueable-action": "^2.12",
"spatie/laravel-tail": "^4.3.3",
"stechstudio/laravel-zipstream": "^4.4",
"teamtnt/laravel-scout-tntsearch-driver": "^11.5.0.0",
"vimeo/psalm": "^4.8.1"
},
"require-dev": {
"ext-json": "*",
"friendsofphp/php-cs-fixer": "^3.0",
"friendsofphp/php-cs-fixer": "^3.0.0",
"barryvdh/laravel-ide-helper": "^2.10",
"facade/ignition": "^2.11.0",
"fakerphp/faker": "^1.15.0",
Generated
+671 -220
View File
File diff suppressed because it is too large Load Diff
+8 -18
View File
@@ -162,7 +162,6 @@ return [
TeamTNT\Scout\TNTSearchScoutServiceProvider::class,
Intervention\Image\ImageServiceProvider::class,
Madnest\Madzipper\MadzipperServiceProvider::class,
App\Providers\FortifyServiceProvider::class,
/*
@@ -229,36 +228,27 @@ return [
'Image' => Intervention\Image\Facades\Image::class,
'Stripe' => Cartalyst\Stripe\Laravel\Facades\Stripe::class,
'Crawler' => Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect::class,
//'Madzipper' => Madnest\Madzipper\Madzipper::class,
],
'deploy_secret' => env('APP_DEPLOY_SECRET'),
'deploy_branch' => env('APP_DEPLOY_BRANCH'),
'deploy_secret' => env('APP_DEPLOY_SECRET'),
'deploy_branch' => env('APP_DEPLOY_BRANCH'),
'debug_blacklist' => [
'_ENV' => [
'_ENV' => [
'APP_KEY',
'DB_USERNAME',
'DB_PASSWORD',
'REDIS_PASSWORD',
'MAIL_PASSWORD',
'PUSHER_APP_KEY',
'PUSHER_APP_SECRET',
'PASSPORT_CLIENT_ID',
'PASSPORT_CLIENT_SECRET',
'AWS_SECRET_ACCESS_KEY',
'AWS_ACCESS_KEY_ID',
'S3_SECRET_ACCESS_KEY',
'S3_ACCESS_KEY_ID',
'DO_SPACES_KEY',
'DO_SPACES_SECRET',
'WASABI_KEY',
'WASABI_SECRET',
'BACKBLAZE_KEY',
'BACKBLAZE_SECRET',
],
@@ -276,8 +266,8 @@ return [
'PASSPORT_CLIENT_ID',
'PASSPORT_CLIENT_SECRET',
'AWS_SECRET_ACCESS_KEY',
'AWS_ACCESS_KEY_ID',
'S3_SECRET_ACCESS_KEY',
'S3_ACCESS_KEY_ID',
'DO_SPACES_KEY',
'DO_SPACES_SECRET',
@@ -288,7 +278,7 @@ return [
'BACKBLAZE_KEY',
'BACKBLAZE_SECRET',
],
'_POST' => [
'_POST' => [
'password',
],
],
+3 -3
View File
@@ -76,9 +76,9 @@ return [
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'key' => env('S3_ACCESS_KEY_ID'),
'secret' => env('S3_SECRET_ACCESS_KEY'),
'region' => env('S3_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
],
+5 -44
View File
@@ -45,58 +45,19 @@ return [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'oss' => [
'driver' => 's3',
'key' => env('OSS_ACCESS_KEY_ID'),
'secret' => env('OSS_SECRET_ACCESS_KEY'),
'region' => env('OSS_REGION'),
'bucket' => env('OSS_BUCKET'),
'endpoint' => env('OSS_ENDPOINT'),
'url' => env('OSS_URL'),
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'endpoint' => env('AWS_URL'),
],
'spaces' => [
'driver' => 's3',
'key' => env('DO_SPACES_KEY'),
'secret' => env('DO_SPACES_SECRET'),
'endpoint' => env('DO_SPACES_ENDPOINT'),
'region' => env('DO_SPACES_REGION'),
'bucket' => env('DO_SPACES_BUCKET'),
],
'wasabi' => [
'driver' => 's3',
'key' => env('WASABI_KEY'),
'secret' => env('WASABI_SECRET'),
'endpoint' => env('WASABI_ENDPOINT'),
'region' => env('WASABI_REGION'),
'bucket' => env('WASABI_BUCKET'),
],
'backblaze' => [
'driver' => 's3',
'key' => env('BACKBLAZE_KEY'),
'secret' => env('BACKBLAZE_SECRET'),
'endpoint' => env('BACKBLAZE_ENDPOINT'),
'region' => env('BACKBLAZE_REGION'),
'bucket' => env('BACKBLAZE_BUCKET'),
'key' => env('S3_ACCESS_KEY_ID'),
'secret' => env('S3_SECRET_ACCESS_KEY'),
'region' => env('S3_DEFAULT_REGION'),
'bucket' => env('S3_BUCKET'),
'endpoint' => env('S3_URL'),
],
],
];
-1
View File
@@ -338,7 +338,6 @@ return [
'context_menu.share_cancel' => 'Cancel Sharing',
'context_menu.share_edit' => 'Edit Sharing',
'context_menu.upload' => 'Upload',
'context_menu.zip_folder' => 'Zip and Download',
'cookie_disclaimer.button' => 'cookies policy',
'cookie_disclaimer.description' => 'By browsing this website you are agreeing to our {0}.',
'datatable.paginate_info' => 'Showing 1 - {visible} from {total} records',
+3 -3
View File
@@ -49,11 +49,11 @@ return [
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'key' => env('S3_ACCESS_KEY_ID'),
'secret' => env('S3_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'region' => env('S3_DEFAULT_REGION', 'us-east-1'),
],
'redis' => [
+3 -3
View File
@@ -24,9 +24,9 @@ return [
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'key' => env('S3_ACCESS_KEY_ID'),
'secret' => env('S3_SECRET_ACCESS_KEY'),
'region' => env('S3_DEFAULT_REGION', 'us-east-1'),
],
'passport' => [
+33
View File
@@ -0,0 +1,33 @@
<?php
/*
* You can place your custom package configuration in here.
*/
return [
// Default options for our archives
'archive' => [
'predict' => env('ZIPSTREAM_PREDICT_SIZE', true),
],
// Default options for files added
'file' => [
'method' => env('ZIPSTREAM_FILE_METHOD', 'store'),
'deflate' => env('ZIPSTREAM_FILE_DEFLATE'),
],
// Configs for S3 files
'aws' => [
'credentials' => [
'key' => env('S3_ACCESS_KEY_ID'),
'secret' => env('S3_SECRET_ACCESS_KEY'),
],
'version' => 'latest',
'endpoint' => env('S3_URL'),
'use_path_style_endpoint' => env('ZIPSTREAM_S3_PATH_STYLE_ENDPOINT', false),
'region' => env('ZIPSTREAM_S3_REGION', env('S3_DEFAULT_REGION', 'us-east-1')),
],
// https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials_anonymous.html
'aws_anonymous_client' => env('S3_ANONYMOUS', false),
];
-32
View File
@@ -1,32 +0,0 @@
<?php
namespace Database\Factories;
use Domain\Zip\Models\Zip;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ZipFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Zip::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'id' => $this->faker->uuid,
'user_id' => $this->faker->uuid,
'shared_token' => Str::random(16),
'basename' => $this->faker->word,
];
}
}
+4 -4
View File
@@ -34,10 +34,10 @@ MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="${MAIL_USERNAME}"
MAIL_FROM_NAME="${MAIL_USERNAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_DEFAULT_REGION=
S3_BUCKET=
DO_SPACES_KEY=
DO_SPACES_SECRET=
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{oBQg:function(e,t,r){"use strict";r.r(t);var n=r("L2JU");function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var i={name:"SetupWizard",computed:function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}({},Object(n.b)(["config"])),mounted:function(){"setup-done"===this.config.installation&&this.$router.push({name:"SignIn"})}},u=r("KHd+"),p=Object(u.a)(i,(function(){var e=this.$createElement;return(this._self._c||e)("router-view")}),[],!1,null,null,null);t.default=p.exports}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{oBQg:function(e,t,r){"use strict";r.r(t);var n=r("L2JU");function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var i={name:"SetupWizard",computed:function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}({},Object(n.b)(["config"])),mounted:function(){var e=this.$root.$data.config.installation;e&&"setup-done"===e&&this.$router.push({name:"SignIn"})}},u=r("KHd+"),a=Object(u.a)(i,(function(){var e=this.$createElement;return(this._self._c||e)("router-view")}),[],!1,null,null,null);t.default=a.exports}}]);
+1 -1
View File
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+11 -210
View File
@@ -4,8 +4,8 @@
"/chunks/admin.js": "/chunks/admin.js?id=f48be89654bdd5857619",
"/chunks/admin-account.js": "/chunks/admin-account.js?id=e96160a07e0045280e2c",
"/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~c7a13fb0.js": "/chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chu~c7a13fb0.js?id=91adf6625e49f0b93731",
"/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~a7b1c983.js": "/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~a7b1c983.js?id=66c2c205086f658115d7",
"/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~eeab5771.js": "/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~eeab5771.js?id=1afc2a786d4a7222405e",
"/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~39825672.js": "/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~39825672.js?id=6c16b40191c43d6bd8ee",
"/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~3e4fdd8b.js": "/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~3e4fdd8b.js?id=f580c1668c202a4542d2",
"/chunks/admin~chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser.js": "/chunks/admin~chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser.js?id=5b0057f770c45f0ffd92",
"/chunks/admin~chunks/files~chunks/settings~chunks/shared/file-browser.js": "/chunks/admin~chunks/files~chunks/settings~chunks/shared/file-browser.js?id=d5c9e6104890d4a17143",
"/chunks/admin~chunks/platform.js": "/chunks/admin~chunks/platform.js?id=2f834ba9277e999fee7a",
@@ -40,7 +40,7 @@
"/chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser.js": "/chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser.js?id=8a06b7d864acff647f8c",
"/chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser~chunks/shared/single-file.js": "/chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser~chunks/shared/single-file.js?id=0de0b81edf0bb5d4617d",
"/chunks/files~chunks/settings-subscription~chunks/shared/file-browser~chunks/user-subscription.js": "/chunks/files~chunks/settings-subscription~chunks/shared/file-browser~chunks/user-subscription.js?id=c5ec9502bcfad35c502e",
"/chunks/files~chunks/shared/file-browser.js": "/chunks/files~chunks/shared/file-browser.js?id=5c31a056cb557ade51c2",
"/chunks/files~chunks/shared/file-browser.js": "/chunks/files~chunks/shared/file-browser.js?id=89464ac77e762367486b",
"/chunks/files~chunks/shared/file-browser~chunks/shared/single-file.js": "/chunks/files~chunks/shared/file-browser~chunks/shared/single-file.js?id=ad09e3f973e4db0411f1",
"/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=8871529af0da8193d3a3",
"/chunks/homepage.js": "/chunks/homepage.js?id=d29b9f09d08d673dff75",
@@ -56,7 +56,7 @@
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=320263fdc9aef3a3be60",
"/chunks/plans.js": "/chunks/plans.js?id=0533e61243eeb87b3e8e",
"/chunks/platform.js": "/chunks/platform.js?id=721cb528aaff1d69d58f",
"/chunks/platform~chunks/shared.js": "/chunks/platform~chunks/shared.js?id=e5dcf772403613fce36c",
"/chunks/platform~chunks/shared.js": "/chunks/platform~chunks/shared.js?id=f7ea7a882f169ecc2c31",
"/chunks/profile.js": "/chunks/profile.js?id=7186e04a6f0f5b6bf470",
"/chunks/profile~chunks/settings-password.js": "/chunks/profile~chunks/settings-password.js?id=ddb7be518c092ed392ca",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=85217c42d79948008ed1",
@@ -70,11 +70,12 @@
"/chunks/settings~chunks/settings-password.js": "/chunks/settings~chunks/settings-password.js?id=680f99e2021f19ff1af8",
"/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=8a499266af9527039582",
"/chunks/shared.js": "/chunks/shared.js?id=7524b7a783d4aed23794",
"/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=888919dfd3b48bf68608",
"/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=0285afcb460b8fc6fe9d",
"/chunks/shared/file-browser.js": "/chunks/shared/file-browser.js?id=0f6c34512740fca7e007",
"/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=7886247bb35deada28a2",
"/chunks/sign-in.js": "/chunks/sign-in.js?id=6e5c9d01fd2214d21de2",
"/chunks/sign-up.js": "/chunks/sign-up.js?id=0838eae8d5c33f41789c",
"/chunks/status-check.js": "/chunks/status-check.js?id=635d75468141b45bf14c",
"/chunks/stripe-credentials.js": "/chunks/stripe-credentials.js?id=fc62992171c9d72c3f4c",
"/chunks/subscription-plans.js": "/chunks/subscription-plans.js?id=1f3df9ae55ca315928d4",
"/chunks/subscription-service.js": "/chunks/subscription-service.js?id=1abfefb47d2e34107b64",
@@ -90,211 +91,11 @@
"/chunks/user-storage.js": "/chunks/user-storage.js?id=2ec04730d677842c8d10",
"/chunks/user-subscription.js": "/chunks/user-subscription.js?id=fc7ddaca95c26ec5c217",
"/chunks/users.js": "/chunks/users.js?id=720f418eef0585bdb419",
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~6c99cc74.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~6c99cc74.js?id=0a6998f62a162c08a48f",
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~cfac0ed6.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~cfac0ed6.js?id=f66c7653a087fe1f3320",
"/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser~chunks/shared/single-file.js": "/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser~chunks/shared/single-file.js?id=9d10953d3b088324dfe3",
"/vendors~chunks/platform~chunks/shared.js": "/vendors~chunks/platform~chunks/shared.js?id=7d09e0b0658e140a7ffa",
"/chunks/platform.2fb97113768ec6ac8cf4.hot-update.js": "/chunks/platform.2fb97113768ec6ac8cf4.hot-update.js",
"/chunks/platform.269c296529f1e0bebfbc.hot-update.js": "/chunks/platform.269c296529f1e0bebfbc.hot-update.js",
"/js/main.fbb839974ed1b2dceb01.hot-update.js": "/js/main.fbb839974ed1b2dceb01.hot-update.js",
"/js/main.a16169bc4e06eb7f5dc9.hot-update.js": "/js/main.a16169bc4e06eb7f5dc9.hot-update.js",
"/js/main.fb460478cb691bafeaf9.hot-update.js": "/js/main.fb460478cb691bafeaf9.hot-update.js",
"/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~39825672.js": "/chunks/admin-account~chunks/app-setup~chunks/billings-detail~chunks/create-new-password~chunks/datab~39825672.js?id=6c16b40191c43d6bd8ee",
"/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~3e4fdd8b.js": "/chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/~3e4fdd8b.js?id=f580c1668c202a4542d2",
"/chunks/status-check.js": "/chunks/status-check.js?id=635d75468141b45bf14c",
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~25aaad73.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~25aaad73.js?id=0de519ac9b2c2754e0c2",
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~81c8aec0.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~81c8aec0.js?id=ca3b57f70682c1c315f7",
"/js/main.c2ea1287545920d2d1d7.hot-update.js": "/js/main.c2ea1287545920d2d1d7.hot-update.js",
"/chunks/status-check.63fa29d966c15c677ded.hot-update.js": "/chunks/status-check.63fa29d966c15c677ded.hot-update.js",
"/chunks/status-check.56f7ef8040cf10183052.hot-update.js": "/chunks/status-check.56f7ef8040cf10183052.hot-update.js",
"/chunks/status-check.8eac1daf25a1315057b5.hot-update.js": "/chunks/status-check.8eac1daf25a1315057b5.hot-update.js",
"/chunks/status-check.e69a44900306402e2575.hot-update.js": "/chunks/status-check.e69a44900306402e2575.hot-update.js",
"/chunks/status-check.0335abb595171fb8febd.hot-update.js": "/chunks/status-check.0335abb595171fb8febd.hot-update.js",
"/chunks/status-check.925d2eb52c3b6f1092fc.hot-update.js": "/chunks/status-check.925d2eb52c3b6f1092fc.hot-update.js",
"/chunks/status-check.fa734d0ff0501d95d78a.hot-update.js": "/chunks/status-check.fa734d0ff0501d95d78a.hot-update.js",
"/chunks/status-check.b52a65d0854eba152db0.hot-update.js": "/chunks/status-check.b52a65d0854eba152db0.hot-update.js",
"/chunks/status-check.94a238343d32a3593730.hot-update.js": "/chunks/status-check.94a238343d32a3593730.hot-update.js",
"/chunks/status-check.d26d16eb0f805934099e.hot-update.js": "/chunks/status-check.d26d16eb0f805934099e.hot-update.js",
"/chunks/status-check.817d38d76d20d9b6b999.hot-update.js": "/chunks/status-check.817d38d76d20d9b6b999.hot-update.js",
"/chunks/status-check.b23cf9da9024262c156c.hot-update.js": "/chunks/status-check.b23cf9da9024262c156c.hot-update.js",
"/chunks/status-check.3caf4f948b9fb43bbe84.hot-update.js": "/chunks/status-check.3caf4f948b9fb43bbe84.hot-update.js",
"/chunks/status-check.fd48ccab164693fcdea5.hot-update.js": "/chunks/status-check.fd48ccab164693fcdea5.hot-update.js",
"/chunks/status-check.344bf3c13a2e36441be0.hot-update.js": "/chunks/status-check.344bf3c13a2e36441be0.hot-update.js",
"/chunks/status-check.ea968d6ece69aae07f08.hot-update.js": "/chunks/status-check.ea968d6ece69aae07f08.hot-update.js",
"/chunks/status-check.743a142fe4730f6d72af.hot-update.js": "/chunks/status-check.743a142fe4730f6d72af.hot-update.js",
"/chunks/status-check.5a6d6b03ac02d0701914.hot-update.js": "/chunks/status-check.5a6d6b03ac02d0701914.hot-update.js",
"/chunks/status-check.82222dc83f1b97faa180.hot-update.js": "/chunks/status-check.82222dc83f1b97faa180.hot-update.js",
"/chunks/status-check.12a7818cafb4f559e3ca.hot-update.js": "/chunks/status-check.12a7818cafb4f559e3ca.hot-update.js",
"/chunks/status-check.4f234d9cc5aa1f7383d6.hot-update.js": "/chunks/status-check.4f234d9cc5aa1f7383d6.hot-update.js",
"/chunks/status-check.a003a3da687f128f1e7e.hot-update.js": "/chunks/status-check.a003a3da687f128f1e7e.hot-update.js",
"/chunks/status-check.153b00e47876739069e3.hot-update.js": "/chunks/status-check.153b00e47876739069e3.hot-update.js",
"/chunks/status-check.2bae6095b187aef98c4a.hot-update.js": "/chunks/status-check.2bae6095b187aef98c4a.hot-update.js",
"/chunks/status-check.117479536341a6383292.hot-update.js": "/chunks/status-check.117479536341a6383292.hot-update.js",
"/chunks/status-check.2b4d86d0cae4f430abca.hot-update.js": "/chunks/status-check.2b4d86d0cae4f430abca.hot-update.js",
"/chunks/status-check.21ec11073ec3500f7ba1.hot-update.js": "/chunks/status-check.21ec11073ec3500f7ba1.hot-update.js",
"/chunks/status-check.2f86dfe4fe2abec46c5e.hot-update.js": "/chunks/status-check.2f86dfe4fe2abec46c5e.hot-update.js",
"/chunks/status-check.5773c30fb2fcb9d05689.hot-update.js": "/chunks/status-check.5773c30fb2fcb9d05689.hot-update.js",
"/chunks/status-check.03a83305772f7918d123.hot-update.js": "/chunks/status-check.03a83305772f7918d123.hot-update.js",
"/chunks/status-check.21bdb0e4207c0a40f7f6.hot-update.js": "/chunks/status-check.21bdb0e4207c0a40f7f6.hot-update.js",
"/chunks/status-check.656aa08d4bae5f1c3df3.hot-update.js": "/chunks/status-check.656aa08d4bae5f1c3df3.hot-update.js",
"/chunks/status-check.5211425a983b819363c7.hot-update.js": "/chunks/status-check.5211425a983b819363c7.hot-update.js",
"/chunks/status-check.859628c5c6992d3bb018.hot-update.js": "/chunks/status-check.859628c5c6992d3bb018.hot-update.js",
"/chunks/status-check.78422de75fed79be3951.hot-update.js": "/chunks/status-check.78422de75fed79be3951.hot-update.js",
"/chunks/status-check.908af3c7f8f9a7b1ae21.hot-update.js": "/chunks/status-check.908af3c7f8f9a7b1ae21.hot-update.js",
"/chunks/status-check.cbdef22c5c6001f2d227.hot-update.js": "/chunks/status-check.cbdef22c5c6001f2d227.hot-update.js",
"/chunks/status-check.62eafd6d519bd018414b.hot-update.js": "/chunks/status-check.62eafd6d519bd018414b.hot-update.js",
"/chunks/status-check.4083ee0f0450741e34b3.hot-update.js": "/chunks/status-check.4083ee0f0450741e34b3.hot-update.js",
"/chunks/status-check.c5fc51f63061817cc012.hot-update.js": "/chunks/status-check.c5fc51f63061817cc012.hot-update.js",
"/chunks/status-check.6367aec2f0f20b55910e.hot-update.js": "/chunks/status-check.6367aec2f0f20b55910e.hot-update.js",
"/chunks/status-check.0332955397de443c048f.hot-update.js": "/chunks/status-check.0332955397de443c048f.hot-update.js",
"/chunks/status-check.27d85b5ebb3b6e946930.hot-update.js": "/chunks/status-check.27d85b5ebb3b6e946930.hot-update.js",
"/chunks/status-check.4de407b5ef2da57f3d29.hot-update.js": "/chunks/status-check.4de407b5ef2da57f3d29.hot-update.js",
"/chunks/status-check.24f6388ea8eb94ebe753.hot-update.js": "/chunks/status-check.24f6388ea8eb94ebe753.hot-update.js",
"/chunks/status-check.6e32f854037eb3962c05.hot-update.js": "/chunks/status-check.6e32f854037eb3962c05.hot-update.js",
"/chunks/status-check.beab2f037dc3451bd183.hot-update.js": "/chunks/status-check.beab2f037dc3451bd183.hot-update.js",
"/chunks/status-check.8d938d248630f003d0f0.hot-update.js": "/chunks/status-check.8d938d248630f003d0f0.hot-update.js",
"/chunks/status-check.6e64aab3299cb4187df4.hot-update.js": "/chunks/status-check.6e64aab3299cb4187df4.hot-update.js",
"/chunks/status-check.f02f451b6a39b1505420.hot-update.js": "/chunks/status-check.f02f451b6a39b1505420.hot-update.js",
"/chunks/status-check.41a0d8d8ff82a12822d5.hot-update.js": "/chunks/status-check.41a0d8d8ff82a12822d5.hot-update.js",
"/chunks/status-check.9e5c61113daf0ef6e8a7.hot-update.js": "/chunks/status-check.9e5c61113daf0ef6e8a7.hot-update.js",
"/chunks/status-check.04b816923d6220da8bcd.hot-update.js": "/chunks/status-check.04b816923d6220da8bcd.hot-update.js",
"/chunks/status-check.3d05edacfae90f309828.hot-update.js": "/chunks/status-check.3d05edacfae90f309828.hot-update.js",
"/chunks/status-check.aaebee1463c6323bbc6a.hot-update.js": "/chunks/status-check.aaebee1463c6323bbc6a.hot-update.js",
"/chunks/status-check.70cbffa431377a3150be.hot-update.js": "/chunks/status-check.70cbffa431377a3150be.hot-update.js",
"/chunks/status-check.71df47da915040cf2118.hot-update.js": "/chunks/status-check.71df47da915040cf2118.hot-update.js",
"/chunks/status-check.818828709ad87794fbe9.hot-update.js": "/chunks/status-check.818828709ad87794fbe9.hot-update.js",
"/chunks/status-check.133fe71e1cb3f84ee1e4.hot-update.js": "/chunks/status-check.133fe71e1cb3f84ee1e4.hot-update.js",
"/chunks/status-check.5f3da43accc8be3d1a2b.hot-update.js": "/chunks/status-check.5f3da43accc8be3d1a2b.hot-update.js",
"/chunks/status-check.028c5b059149a81f7787.hot-update.js": "/chunks/status-check.028c5b059149a81f7787.hot-update.js",
"/chunks/status-check.17d9938802d2e0de939e.hot-update.js": "/chunks/status-check.17d9938802d2e0de939e.hot-update.js",
"/chunks/status-check.55864bdb9120e9c5dec2.hot-update.js": "/chunks/status-check.55864bdb9120e9c5dec2.hot-update.js",
"/chunks/status-check.89f667b0b909a3f26fdc.hot-update.js": "/chunks/status-check.89f667b0b909a3f26fdc.hot-update.js",
"/chunks/status-check.046ee03118743db52823.hot-update.js": "/chunks/status-check.046ee03118743db52823.hot-update.js",
"/chunks/status-check.369a05557ff60fd9dc18.hot-update.js": "/chunks/status-check.369a05557ff60fd9dc18.hot-update.js",
"/chunks/status-check.75d1417fa31fbbcfda5c.hot-update.js": "/chunks/status-check.75d1417fa31fbbcfda5c.hot-update.js",
"/chunks/status-check.2556456bff5ae93f32ed.hot-update.js": "/chunks/status-check.2556456bff5ae93f32ed.hot-update.js",
"/chunks/status-check.83ba79669c740c10b6ee.hot-update.js": "/chunks/status-check.83ba79669c740c10b6ee.hot-update.js",
"/chunks/status-check.09bab771f6e1f18dab46.hot-update.js": "/chunks/status-check.09bab771f6e1f18dab46.hot-update.js",
"/chunks/status-check.02c1726eaaded87b4c41.hot-update.js": "/chunks/status-check.02c1726eaaded87b4c41.hot-update.js",
"/chunks/status-check.a8adf92deeeda8925b60.hot-update.js": "/chunks/status-check.a8adf92deeeda8925b60.hot-update.js",
"/chunks/status-check.2deadcd44fb48105d730.hot-update.js": "/chunks/status-check.2deadcd44fb48105d730.hot-update.js",
"/chunks/status-check.839642e4f10111e58a22.hot-update.js": "/chunks/status-check.839642e4f10111e58a22.hot-update.js",
"/chunks/status-check.6ce31ad99aa96d5b5993.hot-update.js": "/chunks/status-check.6ce31ad99aa96d5b5993.hot-update.js",
"/chunks/status-check.701cf5a929649d21713e.hot-update.js": "/chunks/status-check.701cf5a929649d21713e.hot-update.js",
"/chunks/status-check.3e4358af3c0450adfd95.hot-update.js": "/chunks/status-check.3e4358af3c0450adfd95.hot-update.js",
"/chunks/status-check.01efdf5080444cc90af5.hot-update.js": "/chunks/status-check.01efdf5080444cc90af5.hot-update.js",
"/chunks/status-check.846f9c7f5da907550aaf.hot-update.js": "/chunks/status-check.846f9c7f5da907550aaf.hot-update.js",
"/chunks/status-check.024478ce34199ac7844b.hot-update.js": "/chunks/status-check.024478ce34199ac7844b.hot-update.js",
"/chunks/status-check.4f72acb05a725e6eca35.hot-update.js": "/chunks/status-check.4f72acb05a725e6eca35.hot-update.js",
"/chunks/status-check.3532526f22a4041a748b.hot-update.js": "/chunks/status-check.3532526f22a4041a748b.hot-update.js",
"/chunks/status-check.649a7aee2ae9580df2eb.hot-update.js": "/chunks/status-check.649a7aee2ae9580df2eb.hot-update.js",
"/chunks/status-check.4c850b632e7e0d2b61fa.hot-update.js": "/chunks/status-check.4c850b632e7e0d2b61fa.hot-update.js",
"/chunks/status-check.1c443b9b41fa0e557015.hot-update.js": "/chunks/status-check.1c443b9b41fa0e557015.hot-update.js",
"/chunks/status-check.43cd10467f8145ab8b8a.hot-update.js": "/chunks/status-check.43cd10467f8145ab8b8a.hot-update.js",
"/chunks/status-check.d481f098122f8655e168.hot-update.js": "/chunks/status-check.d481f098122f8655e168.hot-update.js",
"/chunks/status-check.a2c752fc5e7dbfc99947.hot-update.js": "/chunks/status-check.a2c752fc5e7dbfc99947.hot-update.js",
"/chunks/status-check.277b6609c757ec412ed6.hot-update.js": "/chunks/status-check.277b6609c757ec412ed6.hot-update.js",
"/chunks/status-check.5644c5af469338e1e03b.hot-update.js": "/chunks/status-check.5644c5af469338e1e03b.hot-update.js",
"/chunks/status-check.5f89e0e74f0a67dfe6ea.hot-update.js": "/chunks/status-check.5f89e0e74f0a67dfe6ea.hot-update.js",
"/chunks/status-check.5766b48d22a243437a6b.hot-update.js": "/chunks/status-check.5766b48d22a243437a6b.hot-update.js",
"/chunks/status-check.113f6b7ae77db4eac24f.hot-update.js": "/chunks/status-check.113f6b7ae77db4eac24f.hot-update.js",
"/chunks/status-check.bad00428f8bd7830ccc2.hot-update.js": "/chunks/status-check.bad00428f8bd7830ccc2.hot-update.js",
"/chunks/status-check.8e8b19f34cd29d04c28d.hot-update.js": "/chunks/status-check.8e8b19f34cd29d04c28d.hot-update.js",
"/chunks/status-check.7acf77341bdc0fd0843e.hot-update.js": "/chunks/status-check.7acf77341bdc0fd0843e.hot-update.js",
"/chunks/status-check.8959cc673db134489b96.hot-update.js": "/chunks/status-check.8959cc673db134489b96.hot-update.js",
"/chunks/status-check.0f0f5fd801d84fd294f2.hot-update.js": "/chunks/status-check.0f0f5fd801d84fd294f2.hot-update.js",
"/chunks/status-check.4a7ed4b9a955f6ef0258.hot-update.js": "/chunks/status-check.4a7ed4b9a955f6ef0258.hot-update.js",
"/chunks/status-check.42f2561f7ed01edb7b9e.hot-update.js": "/chunks/status-check.42f2561f7ed01edb7b9e.hot-update.js",
"/chunks/status-check.307cbf84fac83c53b419.hot-update.js": "/chunks/status-check.307cbf84fac83c53b419.hot-update.js",
"/chunks/status-check.f9a2880175ec95388827.hot-update.js": "/chunks/status-check.f9a2880175ec95388827.hot-update.js",
"/chunks/status-check.0c7c19c8fb32b76d9cfe.hot-update.js": "/chunks/status-check.0c7c19c8fb32b76d9cfe.hot-update.js",
"/chunks/status-check.dfa86748f8af397925a8.hot-update.js": "/chunks/status-check.dfa86748f8af397925a8.hot-update.js",
"/chunks/status-check.34bdf238910f0b66a954.hot-update.js": "/chunks/status-check.34bdf238910f0b66a954.hot-update.js",
"/chunks/status-check.21b2ade29ea985949dfa.hot-update.js": "/chunks/status-check.21b2ade29ea985949dfa.hot-update.js",
"/chunks/status-check.baa7022569488793f294.hot-update.js": "/chunks/status-check.baa7022569488793f294.hot-update.js",
"/chunks/status-check.48fe84b10d2b825983e8.hot-update.js": "/chunks/status-check.48fe84b10d2b825983e8.hot-update.js",
"/chunks/status-check.9cd90094c730296236af.hot-update.js": "/chunks/status-check.9cd90094c730296236af.hot-update.js",
"/chunks/status-check.b6ba8f66b0c827f642e0.hot-update.js": "/chunks/status-check.b6ba8f66b0c827f642e0.hot-update.js",
"/chunks/status-check.063a157f083452b8b125.hot-update.js": "/chunks/status-check.063a157f083452b8b125.hot-update.js",
"/chunks/status-check.c2ad5ae060ef91ab6871.hot-update.js": "/chunks/status-check.c2ad5ae060ef91ab6871.hot-update.js",
"/chunks/status-check.3891829a59fb48de60ce.hot-update.js": "/chunks/status-check.3891829a59fb48de60ce.hot-update.js",
"/chunks/status-check.b8524057c92cf78e2417.hot-update.js": "/chunks/status-check.b8524057c92cf78e2417.hot-update.js",
"/chunks/status-check.c2c2b27fb8e745ed8963.hot-update.js": "/chunks/status-check.c2c2b27fb8e745ed8963.hot-update.js",
"/chunks/status-check.15d6b6e8f8475864a673.hot-update.js": "/chunks/status-check.15d6b6e8f8475864a673.hot-update.js",
"/chunks/status-check.e1e749b26d87429a53a5.hot-update.js": "/chunks/status-check.e1e749b26d87429a53a5.hot-update.js",
"/chunks/status-check.342fab583e418b3ebbed.hot-update.js": "/chunks/status-check.342fab583e418b3ebbed.hot-update.js",
"/chunks/status-check.874b6be18d7aec08c953.hot-update.js": "/chunks/status-check.874b6be18d7aec08c953.hot-update.js",
"/chunks/status-check.e9174089178511cfce23.hot-update.js": "/chunks/status-check.e9174089178511cfce23.hot-update.js",
"/chunks/status-check.fd3ef69c9b6f81c92394.hot-update.js": "/chunks/status-check.fd3ef69c9b6f81c92394.hot-update.js",
"/chunks/status-check.78ba39dc0f31677098e8.hot-update.js": "/chunks/status-check.78ba39dc0f31677098e8.hot-update.js",
"/chunks/status-check.3be338b4385837e5654a.hot-update.js": "/chunks/status-check.3be338b4385837e5654a.hot-update.js",
"/chunks/status-check.2aab334f1e78b69f9dda.hot-update.js": "/chunks/status-check.2aab334f1e78b69f9dda.hot-update.js",
"/chunks/status-check.5149b186c7ce6ea2480c.hot-update.js": "/chunks/status-check.5149b186c7ce6ea2480c.hot-update.js",
"/chunks/status-check.25a5d00d0b6ac88049aa.hot-update.js": "/chunks/status-check.25a5d00d0b6ac88049aa.hot-update.js",
"/chunks/status-check.a63a1d526dfed0a76b1e.hot-update.js": "/chunks/status-check.a63a1d526dfed0a76b1e.hot-update.js",
"/chunks/status-check.57c6ee73eb5756b44f65.hot-update.js": "/chunks/status-check.57c6ee73eb5756b44f65.hot-update.js",
"/chunks/status-check.655180fb3bb8f2efd7ae.hot-update.js": "/chunks/status-check.655180fb3bb8f2efd7ae.hot-update.js",
"/chunks/status-check.29342b5167bd43d568f5.hot-update.js": "/chunks/status-check.29342b5167bd43d568f5.hot-update.js",
"/chunks/status-check.df584bec143167d59b30.hot-update.js": "/chunks/status-check.df584bec143167d59b30.hot-update.js",
"/chunks/status-check.25ff987a9d155f6a08c9.hot-update.js": "/chunks/status-check.25ff987a9d155f6a08c9.hot-update.js",
"/chunks/status-check.9ddbb495101d3b822daf.hot-update.js": "/chunks/status-check.9ddbb495101d3b822daf.hot-update.js",
"/chunks/status-check.1b4fc4962eb0a2abf3dd.hot-update.js": "/chunks/status-check.1b4fc4962eb0a2abf3dd.hot-update.js",
"/chunks/status-check.ec77ec1f605d9f475cca.hot-update.js": "/chunks/status-check.ec77ec1f605d9f475cca.hot-update.js",
"/chunks/status-check.61056a5eacdc788fdb48.hot-update.js": "/chunks/status-check.61056a5eacdc788fdb48.hot-update.js",
"/chunks/status-check.de33b68974f5a3e9343d.hot-update.js": "/chunks/status-check.de33b68974f5a3e9343d.hot-update.js",
"/chunks/status-check.6deee25c3fa2227ac05c.hot-update.js": "/chunks/status-check.6deee25c3fa2227ac05c.hot-update.js",
"/js/main.346469da6ba011c0109f.hot-update.js": "/js/main.346469da6ba011c0109f.hot-update.js",
"/chunks/status-check.346469da6ba011c0109f.hot-update.js": "/chunks/status-check.346469da6ba011c0109f.hot-update.js",
"/js/main.fed47f21bf43ddf8070d.hot-update.js": "/js/main.fed47f21bf43ddf8070d.hot-update.js",
"/chunks/status-check.fed47f21bf43ddf8070d.hot-update.js": "/chunks/status-check.fed47f21bf43ddf8070d.hot-update.js",
"/chunks/status-check.a6bbcb26f56eeb17115c.hot-update.js": "/chunks/status-check.a6bbcb26f56eeb17115c.hot-update.js",
"/chunks/status-check.2110cbfc3b787f160276.hot-update.js": "/chunks/status-check.2110cbfc3b787f160276.hot-update.js",
"/chunks/status-check.f24b656e0468f2d00b4f.hot-update.js": "/chunks/status-check.f24b656e0468f2d00b4f.hot-update.js",
"/chunks/status-check.05b0553aadf9779806cd.hot-update.js": "/chunks/status-check.05b0553aadf9779806cd.hot-update.js",
"/chunks/status-check.13342e70f59140ae74c2.hot-update.js": "/chunks/status-check.13342e70f59140ae74c2.hot-update.js",
"/chunks/status-check.87e610af0ba29a732796.hot-update.js": "/chunks/status-check.87e610af0ba29a732796.hot-update.js",
"/chunks/status-check.9e087dc2b137ef2c85cc.hot-update.js": "/chunks/status-check.9e087dc2b137ef2c85cc.hot-update.js",
"/chunks/status-check.d7e06b44ad2eb06686bb.hot-update.js": "/chunks/status-check.d7e06b44ad2eb06686bb.hot-update.js",
"/chunks/status-check.7d330409915d9d7d53e8.hot-update.js": "/chunks/status-check.7d330409915d9d7d53e8.hot-update.js",
"/chunks/admin-account.b0c3374208474353d7fe.hot-update.js": "/chunks/admin-account.b0c3374208474353d7fe.hot-update.js",
"/chunks/app-setup.b0c3374208474353d7fe.hot-update.js": "/chunks/app-setup.b0c3374208474353d7fe.hot-update.js",
"/chunks/billings-detail.b0c3374208474353d7fe.hot-update.js": "/chunks/billings-detail.b0c3374208474353d7fe.hot-update.js",
"/chunks/database.b0c3374208474353d7fe.hot-update.js": "/chunks/database.b0c3374208474353d7fe.hot-update.js",
"/chunks/environment-setup.b0c3374208474353d7fe.hot-update.js": "/chunks/environment-setup.b0c3374208474353d7fe.hot-update.js",
"/chunks/installation-disclaimer.b0c3374208474353d7fe.hot-update.js": "/chunks/installation-disclaimer.b0c3374208474353d7fe.hot-update.js",
"/chunks/purchase-code.b0c3374208474353d7fe.hot-update.js": "/chunks/purchase-code.b0c3374208474353d7fe.hot-update.js",
"/chunks/stripe-credentials.b0c3374208474353d7fe.hot-update.js": "/chunks/stripe-credentials.b0c3374208474353d7fe.hot-update.js",
"/chunks/subscription-plans.b0c3374208474353d7fe.hot-update.js": "/chunks/subscription-plans.b0c3374208474353d7fe.hot-update.js",
"/chunks/subscription-service.b0c3374208474353d7fe.hot-update.js": "/chunks/subscription-service.b0c3374208474353d7fe.hot-update.js",
"/chunks/status-check.0f14031d4868f0989dd6.hot-update.js": "/chunks/status-check.0f14031d4868f0989dd6.hot-update.js",
"/chunks/status-check.b2ac3607bcf6295b4d10.hot-update.js": "/chunks/status-check.b2ac3607bcf6295b4d10.hot-update.js",
"/chunks/status-check.f316b77b0d63454fb2b0.hot-update.js": "/chunks/status-check.f316b77b0d63454fb2b0.hot-update.js",
"/chunks/status-check.cba5e0e686d4165d0e5b.hot-update.js": "/chunks/status-check.cba5e0e686d4165d0e5b.hot-update.js",
"/chunks/status-check.875ff8ea9b5f6b427e3d.hot-update.js": "/chunks/status-check.875ff8ea9b5f6b427e3d.hot-update.js",
"/chunks/status-check.12d2c68ca5d98223766c.hot-update.js": "/chunks/status-check.12d2c68ca5d98223766c.hot-update.js",
"/chunks/status-check.7920c3c8d544ef1e8dfa.hot-update.js": "/chunks/status-check.7920c3c8d544ef1e8dfa.hot-update.js",
"/chunks/status-check.650821558473b8202711.hot-update.js": "/chunks/status-check.650821558473b8202711.hot-update.js",
"/js/main.fe5e650dee5a1bb1fc13.hot-update.js": "/js/main.fe5e650dee5a1bb1fc13.hot-update.js",
"/chunks/setup-wizard.72c41776eacb54277e7b.hot-update.js": "/chunks/setup-wizard.72c41776eacb54277e7b.hot-update.js",
"/js/main.1a7a79423134ff81c39e.hot-update.js": "/js/main.1a7a79423134ff81c39e.hot-update.js",
"/chunks/status-check.43c5e2ea66b5c644abaa.hot-update.js": "/chunks/status-check.43c5e2ea66b5c644abaa.hot-update.js",
"/chunks/status-check.0407d7cadd6459a2005a.hot-update.js": "/chunks/status-check.0407d7cadd6459a2005a.hot-update.js",
"/chunks/status-check.7a654201d619492b9376.hot-update.js": "/chunks/status-check.7a654201d619492b9376.hot-update.js",
"/chunks/status-check.031b18740a152e7a4afe.hot-update.js": "/chunks/status-check.031b18740a152e7a4afe.hot-update.js",
"/chunks/status-check.7eb7825dea3966215cac.hot-update.js": "/chunks/status-check.7eb7825dea3966215cac.hot-update.js",
"/chunks/status-check.20d5dcc79d3a534cb81f.hot-update.js": "/chunks/status-check.20d5dcc79d3a534cb81f.hot-update.js",
"/chunks/status-check.46c1ceffd07c9cd4efd7.hot-update.js": "/chunks/status-check.46c1ceffd07c9cd4efd7.hot-update.js",
"/chunks/status-check.2c09dddbdc08be3cff85.hot-update.js": "/chunks/status-check.2c09dddbdc08be3cff85.hot-update.js",
"/chunks/status-check.cfd5dfab739238654232.hot-update.js": "/chunks/status-check.cfd5dfab739238654232.hot-update.js",
"/chunks/status-check.4545d2bb3a274c9d33e6.hot-update.js": "/chunks/status-check.4545d2bb3a274c9d33e6.hot-update.js",
"/chunks/status-check.3059fc882bb7470ea906.hot-update.js": "/chunks/status-check.3059fc882bb7470ea906.hot-update.js",
"/chunks/status-check.fabc216483cd1a46178f.hot-update.js": "/chunks/status-check.fabc216483cd1a46178f.hot-update.js",
"/chunks/status-check.2173dc6d5f4e6a54ee7c.hot-update.js": "/chunks/status-check.2173dc6d5f4e6a54ee7c.hot-update.js",
"/chunks/status-check.98c68242f87b96f7722c.hot-update.js": "/chunks/status-check.98c68242f87b96f7722c.hot-update.js",
"/chunks/status-check.4b98c68a29333a6337cc.hot-update.js": "/chunks/status-check.4b98c68a29333a6337cc.hot-update.js",
"/chunks/status-check.7178131f4e152a536f0e.hot-update.js": "/chunks/status-check.7178131f4e152a536f0e.hot-update.js",
"/chunks/status-check.807b117afc2ff10989b5.hot-update.js": "/chunks/status-check.807b117afc2ff10989b5.hot-update.js",
"/chunks/status-check.d6a3ce2c20f008057804.hot-update.js": "/chunks/status-check.d6a3ce2c20f008057804.hot-update.js",
"/chunks/status-check.8d8bf142eb151aa57a29.hot-update.js": "/chunks/status-check.8d8bf142eb151aa57a29.hot-update.js",
"/chunks/status-check.362d9498a4fd7f2a55c8.hot-update.js": "/chunks/status-check.362d9498a4fd7f2a55c8.hot-update.js"
"/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser~chunks/shared/single-file.js": "/vendors~chunks/files~chunks/platform~chunks/shared~chunks/shared/file-browser~chunks/shared/single-file.js?id=9d10953d3b088324dfe3",
"/vendors~chunks/platform~chunks/shared.js": "/vendors~chunks/platform~chunks/shared.js?id=7d09e0b0658e140a7ffa",
"/chunks/shared/authenticate.485b9d7c84b7f0b5d3a8.hot-update.js": "/chunks/shared/authenticate.485b9d7c84b7f0b5d3a8.hot-update.js",
"/chunks/shared/authenticate.380d5d03b67c56ca9dc5.hot-update.js": "/chunks/shared/authenticate.380d5d03b67c56ca9dc5.hot-update.js",
"/chunks/shared/authenticate.19c93dcbd7fd68271075.hot-update.js": "/chunks/shared/authenticate.19c93dcbd7fd68271075.hot-update.js"
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
/**
* vee-validate v3.4.5
* (c) 2020 Abdelrahman Awad
* @license MIT
*/
@@ -13,7 +13,7 @@
<OptionGroup v-if="item && isMultiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail" />
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
<!-- Multi options -->
@@ -46,8 +46,7 @@
<OptionGroup v-if="item && isMultiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail" />
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
<!-- Multi options -->
@@ -89,8 +88,7 @@
<OptionGroup v-if="item && isMultiSelectContextMenu ">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail" />
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
<!-- Multi options -->
@@ -103,7 +101,7 @@
<Option @click.native="$deleteFileOrFolder(item)" :title="$t('context_menu.delete')" icon="trash" />
</OptionGroup>
<OptionGroup v-if="item && !isMultiSelectContextMenu && !hasFolder">
<OptionGroup v-if="item && !isMultiSelectContextMenu">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
@@ -125,8 +123,7 @@
<OptionGroup v-if="item && isMultiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail" />
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
<!-- Multi options -->
@@ -135,7 +132,7 @@
<Option @click.native="$deleteFileOrFolder(item)" :title="$t('context_menu.delete')" icon="trash" />
</OptionGroup>
<OptionGroup v-if="item && !isMultiSelectContextMenu && !hasFolder">
<OptionGroup v-if="item && !isMultiSelectContextMenu">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
@@ -146,8 +143,7 @@
<!-- Single options -->
<OptionGroup v-if="item && isMultiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail" />
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
<!-- Multi options -->
@@ -220,9 +216,6 @@ export default {
}
},
methods: {
downloadFolder() {
this.$store.dispatch('downloadFolder', this.item)
},
emptyTrash() {
this.$store.dispatch('emptyTrash')
},
@@ -249,8 +242,8 @@ export default {
}
},
downloadItem() {
if (this.clipboard.length > 1)
this.$store.dispatch('downloadFiles')
if (this.clipboard.length > 1 || (this.clipboard.length === 1 && this.clipboard[0].type === 'folder'))
this.$store.dispatch('downloadZip')
else {
this.$downloadFile(this.item.file_url, this.item.name + '.' + this.item.mimetype)
}
@@ -10,8 +10,7 @@
</OptionGroup>
<OptionGroup>
<Option v-if="!isFolder" @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
<Option v-if="isFolder" @click.native="downloadFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</MenuMobileGroup>
@@ -28,8 +27,7 @@
</OptionGroup>
<OptionGroup>
<Option v-if="!isFolder" @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
<Option v-if="isFolder" @click.native="downloadFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</MenuMobileGroup>
@@ -47,8 +45,7 @@
</OptionGroup>
<OptionGroup>
<Option v-if="!isFolder" @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
<Option v-if="isFolder" @click.native="downloadFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</MenuMobileGroup>
@@ -61,16 +58,14 @@
</OptionGroup>
<OptionGroup>
<Option v-if="!isFolder" @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
<Option v-if="isFolder" @click.native="downloadFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</MenuMobileGroup>
<!--Base location for guest with visit permission-->
<MenuMobileGroup v-if="$isThisLocation(['base', 'public']) && $checkPermission('visitor')">
<OptionGroup>
<Option v-if="!isFolder" @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
<Option v-if="isFolder" @click.native="downloadFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</MenuMobileGroup>
</MenuMobile>
@@ -126,9 +121,6 @@ export default {
}
},
methods: {
downloadFolder() {
this.$store.dispatch('downloadFolder', this.clipboard[0])
},
addToFavourites() {
if (this.favourites && !this.favourites.find(el => el.id === this.clipboard[0].id)) {
this.$store.dispatch('addToFavourites', this.clipboard[0])
@@ -136,12 +128,13 @@ export default {
this.$store.dispatch('removeFromFavourites', this.clipboard[0])
}
},
downloadItem() {
this.$downloadFile(
this.clipboard[0].file_url,
this.clipboard[0].name + '.' + this.clipboard[0].mimetype
)
}
downloadItem() {
if (this.clipboard.length > 1 || (this.clipboard.length === 1 && this.clipboard[0].type === 'folder'))
this.$store.dispatch('downloadZip')
else {
this.$downloadFile(this.clipboard[0].file_url, this.clipboard[0].name + '.' + this.clipboard[0].mimetype)
}
},
}
}
</script>
@@ -5,7 +5,7 @@
<ToolbarButton class="action-btn" v-if="!$isThisLocation(['shared']) && $checkPermission('master') || $checkPermission('editor')" source="trash" :class="{'is-inactive' : clipboard.length < 1}" :action="$t('actions.delete')" @click.native="deleteItem" />
<ToolbarButton class="action-btn" v-if="!$isThisLocation(['shared'])" source="download" :class="{'is-inactive': canDownloadItems}" :action="$t('actions.delete')" @click.native="downloadItem" />
<ToolbarButton class="action-btn" v-if="!$isThisLocation(['shared'])" source="download" :action="$t('actions.delete')" @click.native="downloadItem" />
<ToolbarButton class="action-btn" source="shared-off" @click.native="shareCancel" v-if="$isThisLocation(['shared'])" />
@@ -16,17 +16,18 @@
<script>
import ToolbarButton from '@/components/FilesView/ToolbarButton'
import {events} from '@/bus'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
export default {
name: 'MultiSelectToolbarMobile',
components: {ToolbarButton},
components: {
ToolbarButton
},
computed: {
...mapGetters(['clipboard']),
canDownloadItems() {
return this.clipboard.filter(item => item.type === 'folder').length !== 0
}
...mapGetters([
'clipboard'
]),
},
data() {
return {
@@ -42,8 +43,8 @@ export default {
events.$emit('mobileSelecting:stop')
},
downloadItem() {
if (this.clipboard.length > 1)
this.$store.dispatch('downloadFiles')
if (this.clipboard.length > 1 || (this.clipboard.length === 1 && this.clipboard[0].type === 'folder'))
this.$store.dispatch('downloadZip')
else {
this.$downloadFile(this.clipboard[0].file_url, this.clipboard[0].name + '.' + this.clipboard[0].mimetype)
}
@@ -54,23 +55,14 @@ export default {
events.$emit('popup:open', {name: 'move', item: [this.clipboard[0]]})
},
deleteItem() {
//Delete items
this.$store.dispatch('deleteItem')
this.closeSelecting()
}
},
created() {
events.$on('mobileSelecting:start', () => {
this.mobileMultiSelect = true
})
events.$on('mobileSelecting:stop', () => {
this.mobileMultiSelect = false
})
events.$on('mobileSelecting:start', () => this.mobileMultiSelect = true)
events.$on('mobileSelecting:stop', () => this.mobileMultiSelect = false)
}
}
</script>
+13 -43
View File
@@ -15,56 +15,26 @@ const defaultState = {
}
const actions = {
downloadFolder: ({commit, getters}, folder) => {
commit('PROCESSING_POPUP', {
title: i18n.t('popup_zipping.title'),
message: i18n.t('popup_zipping.message')
})
let route = getters.sharedDetail
? `/api/zip/folder/${folder.id}/${router.currentRoute.params.token}`
: `/api/zip/folder/${folder.id}`
axios.get(route)
.then(response => {
Vue.prototype.$downloadFile(response.data.url, response.data.name)
})
.catch(() => {
Vue.prototype.$isSomethingWrong()
})
.finally(() => {
commit('PROCESSING_POPUP', undefined)
})
},
downloadFiles: ({commit, getters}) => {
downloadZip: ({getters}) => {
let files = []
// get ids of selected files
getters.clipboard.forEach(file => files.push(file.id))
getters.clipboard.forEach(file => {
let type = file.type === 'folder'
? 'folder'
: 'file'
files.push(file.id + '|' + type)
})
let items = files.join(',')
// Get route
let route = getters.sharedDetail
? `/api/zip/files/${router.currentRoute.params.token}`
: '/api/zip/files'
? `/api/zip/${router.currentRoute.params.token}?items=${items}`
: `/api/zip?items=${items}`
commit('PROCESSING_POPUP', {
title: i18n.t('popup_zipping.title'),
message: i18n.t('popup_zipping.message'),
})
axios.post(route, {
items: files
})
.then(response => {
Vue.prototype.$downloadFile(response.data.url, response.data.name)
})
.catch(() => {
Vue.prototype.$isSomethingWrong()
})
.finally(() => {
commit('PROCESSING_POPUP', undefined)
})
Vue.prototype.$downloadFile(route, 'files.zip')
},
moveItem: ({commit, getters, dispatch}, {to_item, noSelectedItem}) => {
@@ -76,9 +76,9 @@
})
.catch(error => {
if (error.response.status == 401)
if (error.response.status === 401)
this.$refs.authenticateProtected.setErrors({
'Password': [error.response.data.message]
'Password': [error.response.data]
});
})
.finally(() => {
+2 -4
View File
@@ -2,9 +2,8 @@
use App\Users\Actions\CreateNewUserAction;
use Domain\Pages\Controllers\PagesController;
use Domain\Zip\Controllers\ZipFilesController;
use Domain\Zip\Controllers\ZipController;
use Domain\Sharing\Controllers\ShareController;
use Domain\Zip\Controllers\ZipFolderController;
use Domain\Trash\Controllers\DumpTrashController;
use App\Users\Controllers\ResetPasswordController;
use Domain\Files\Controllers\UploadFileController;
@@ -80,6 +79,5 @@ Route::group(['middleware' => ['auth:sanctum']], function () {
Route::post('/remove', DeleteFileOrFolderController::class);
Route::post('/move', MoveFileOrFolderController::class);
Route::get('/zip/folder/{id}', ZipFolderController::class);
Route::post('/zip/files', ZipFilesController::class);
Route::get('/zip', ZipController::class);
});
-4
View File
@@ -1,9 +1,7 @@
<?php
// Get avatars and system images
use Domain\Zip\Controllers\GetZipController;
use App\Users\Controllers\GetAvatarController;
use Domain\Zip\Controllers\VisitorGetZipController;
use Domain\Settings\Controllers\GetAppImageController;
use Domain\Files\Controllers\FileAccess\GetFileController;
use Domain\Files\Controllers\FileAccess\GetThumbnailController;
@@ -15,12 +13,10 @@ Route::get('/system/{image}', GetAppImageController::class);
// Get public thumbnails and files
Route::get('/thumbnail/{name}/{shared}', VisitorGetThumbnailController::class);
Route::get('/zip/{id}/public/{token}', VisitorGetZipController::class);
Route::get('/file/{name}/{shared}', VisitorGetFileController::class);
// User master,editor,visitor access to image thumbnails and file downloads
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::get('/thumbnail/{name}', GetThumbnailController::class)->name('thumbnail');
Route::get('/file/{name}', GetFileController::class)->name('file');
Route::get('/zip/{id}', GetZipController::class)->name('zip');
});
+3 -7
View File
@@ -1,8 +1,7 @@
<?php
use Domain\Sharing\Controllers\ShareController;
use Domain\Zip\Controllers\VisitorZipFilesController;
use Domain\Zip\Controllers\VisitorZipFolderController;
use Domain\Zip\Controllers\VisitorZipController;
use Domain\Files\Controllers\VisitorShowFileController;
use Domain\Files\Controllers\VisitorUploadFileController;
use Domain\Folders\Controllers\VisitorCreateFolderController;
@@ -26,15 +25,12 @@ Route::group(['prefix' => 'editor'], function () {
});
// Zip shared items
Route::group(['prefix' => 'zip'], function () {
Route::get('/folder/{id}/{shared}', VisitorZipFolderController::class);
Route::post('/files/{shared}', VisitorZipFilesController::class);
});
Route::get('/zip/{shared}', VisitorZipController::class);
// Browse share content
Route::group(['prefix' => 'browse'], function () {
Route::post('/authenticate/{shared}', VisitorUnlockLockedShareController::class);
Route::get('/folders/{id}/{shared}', VisitorBrowseFolderContentController::class);
Route::post('/authenticate/{shared}', VisitorUnlockLockedShareController::class);
Route::get('/navigation/{shared}', VisitorNavigationFolderTreeController::class);
Route::get('/search/{shared}', VisitorSearchFilesAndFoldersController::class);
Route::get('/file/{shared}', VisitorShowFileController::class);
+9 -11
View File
@@ -1,10 +1,10 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use App\Console\Commands\SetupDevEnvironment;
use App\Console\Commands\SetupProdEnvironment;
use Support\Scheduler\Actions\DeleteOldZipsAction;
use Support\Scheduler\Actions\DeleteFailedFilesAction;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Support\Scheduler\Actions\DeleteUnverifiedUsersAction;
@@ -27,22 +27,20 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule): void
{
if (!is_storage_driver(['local'])) {
$schedule->call(
fn() => resolve(DeleteFailedFilesAction::class)()
)->everySixHours();
}
$schedule->call(
fn () => resolve(DeleteExpiredShareLinksAction::class)()
fn() => resolve(DeleteExpiredShareLinksAction::class)()
)->everyTenMinutes();
$schedule->call(
fn () => resolve(DeleteUnverifiedUsersAction::class)()
fn() => resolve(DeleteUnverifiedUsersAction::class)()
)->daily();
$schedule->call(function () {
resolve(DeleteOldZipsAction::class)();
if (! is_storage_driver(['local'])) {
resolve(DeleteFailedFilesAction::class)();
}
})->everySixHours();
// Run queue jobs every minute
$schedule->command('queue:work --stop-when-empty')
->everyMinute()
@@ -26,7 +26,7 @@ class UploadFileAction
public function __invoke(
UploadRequest $request,
?Share $shared = null,
): UserFile {
) {
// Get parent_id from request
$file = $request->file('file');
@@ -20,7 +20,7 @@ class UploadFileController extends Controller
*/
public function __invoke(
UploadRequest $request,
): File | array {
) {
if (is_demo_account('howdy@hi5ve.digital')) {
return ($this->fakeUploadFile)($request);
}
@@ -20,49 +20,21 @@ class StoreEnvironmentSettingsController extends Controller
'FILESYSTEM_DRIVER' => 'local',
],
's3' => [
'FILESYSTEM_DRIVER' => $request->input('storage.driver') ?? null,
'AWS_ACCESS_KEY_ID' => $request->input('storage.key') ?? null,
'AWS_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null,
'AWS_DEFAULT_REGION' => $request->input('storage.region') ?? null,
'AWS_BUCKET' => $request->input('storage.bucket') ?? null,
],
'spaces' => [
'FILESYSTEM_DRIVER' => $request->input('storage.driver') ?? null,
'DO_SPACES_KEY' => $request->input('storage.key') ?? null,
'DO_SPACES_SECRET' => $request->input('storage.secret') ?? null,
'DO_SPACES_ENDPOINT' => $request->input('storage.endpoint') ?? null,
'DO_SPACES_REGION' => $request->input('storage.region') ?? null,
'DO_SPACES_BUCKET' => $request->input('storage.bucket') ?? null,
],
'wasabi' => [
'FILESYSTEM_DRIVER' => $request->input('storage.driver') ?? null,
'WASABI_KEY' => $request->input('storage.key') ?? null,
'WASABI_SECRET' => $request->input('storage.secret') ?? null,
'WASABI_ENDPOINT' => $request->input('storage.endpoint') ?? null,
'WASABI_REGION' => $request->input('storage.region') ?? null,
'WASABI_BUCKET' => $request->input('storage.bucket') ?? null,
],
'backblaze' => [
'FILESYSTEM_DRIVER' => $request->input('storage.driver') ?? null,
'BACKBLAZE_KEY' => $request->input('storage.key') ?? null,
'BACKBLAZE_SECRET' => $request->input('storage.secret') ?? null,
'BACKBLAZE_ENDPOINT' => $request->input('storage.endpoint') ?? null,
'BACKBLAZE_REGION' => $request->input('storage.region') ?? null,
'BACKBLAZE_BUCKET' => $request->input('storage.bucket') ?? null,
],
'oss' => [
'FILESYSTEM_DRIVER' => $request->input('storage.driver') ?? null,
'OSS_ACCESS_KEY_ID' => $request->input('storage.key') ?? null,
'OSS_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null,
'OSS_ENDPOINT' => $request->input('storage.endpoint') ?? null,
'OSS_REGION' => $request->input('storage.region') ?? null,
'OSS_BUCKET' => $request->input('storage.bucket') ?? null,
'FILESYSTEM_DRIVER' => 's3',
'S3_ACCESS_KEY_ID' => $request->input('storage.key') ?? null,
'S3_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null,
'S3_DEFAULT_REGION' => $request->input('storage.region') ?? null,
'S3_BUCKET' => $request->input('storage.bucket') ?? null,
'S3_URL' => $request->input('storage.endpoint') ?? null,
],
];
// Get storage driver from request
$driver = 'local' === $request->input('storage.driver') ? 'local' : 's3';
// Storage credentials for storage
setEnvironmentValue(
$drivers[$request->input('storage.driver')]
$drivers[$driver]
);
// Store credentials for mail
@@ -5,14 +5,15 @@ use Domain\Sharing\Models\Share;
class ProtectShareRecordAction
{
private string $message = "Sorry, you don't have permission";
public function __invoke(
Share $shared
): void {
if ($shared->is_protected) {
$abort_message = "Sorry, you don't have permission";
if (! request()->hasCookie('share_session')) {
abort(403, $abort_message);
abort(403, $this->message);
}
// Get shared session
@@ -22,12 +23,12 @@ class ProtectShareRecordAction
// Check if is requested same share record
if ($share_session->token !== $shared->token) {
abort(403, $abort_message);
abort(403, $this->message);
}
// Check if share record was authenticated previously via ShareController@authenticate
if (! $share_session->authenticated) {
abort(403, $abort_message);
abort(403, $this->message);
}
}
}
@@ -83,15 +83,6 @@ class ShareController extends Controller
->where('user_id', Auth::id())
->firstOrFail()
->delete();
// Get zip record if exist
$zip = Zip::where('shared_token', $token)
->where('user_id', Auth::id())
->first();
if ($zip) {
$zip->delete();
}
}
return response('Done!', 204);
@@ -46,6 +46,7 @@ class SharePublicIndexController extends Controller
}
return view('index')
->with('status_check', [])
->with('installation', 'setup-done')
->with('settings', get_settings_in_json() ?? null);
}
@@ -0,0 +1,45 @@
<?php
namespace Domain\Zip\Actions;
use Domain\Files\Models\File;
use Domain\Folders\Models\Folder;
class GetItemsListFromUrlParamAction
{
public function __invoke(
string $user_id
): array {
$list = explode(',', request()->get('items'));
$itemList = collect($list)
->map(function ($chunk) {
$items = explode('|', $chunk);
return [
'id' => $items[0],
'type' => $items[1],
];
});
$folderIds = $itemList
->where('type', 'folder')
->pluck('id');
$fileIds = $itemList
->where('type', 'file')
->pluck('id');
$folders = Folder::whereUserId($user_id)
->whereIn('id', $folderIds)
->get();
$files = File::whereUserId($user_id)
->whereIn('id', $fileIds)
->get();
return [$folders, $files];
}
}
+92
View File
@@ -0,0 +1,92 @@
<?php
namespace Domain\Zip\Actions;
use Domain\Folders\Models\Folder;
use Domain\Sharing\Models\Share;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use STS\ZipStream\ZipStreamFacade as Zip;
use ZipStream\ZipStream;
class ZipAction
{
public function __invoke(
Collection $folders,
Collection $files,
?Share $shared = null
): ZipStream {
// Get user id
$user_id = Auth::id() ?? $shared->user_id;
// Get zip name from single requested folder
if ($files->isEmpty() && $folders->count() === 1) {
$zipName = Str::slug($folders->first()->name) . '.zip';
}
// Create zip
$zip = Zip::create($zipName ?? 'files.zip');
// Zip Files
$files->map(function ($file) use ($zip) {
// get file path
$filePath = "files/$file->user_id/$file->basename";
// Add file into zip
if (Storage::exists($filePath)) {
// local disk
if (is_storage_driver('local')) {
$zip->add(Storage::path($filePath), $file->name);
}
// s3 client
if (is_storage_driver('s3')) {
$bucketName = config('filesystems.disks.s3.bucket');
$zip->add("s3://$bucketName/$filePath", $file->name);
}
}
});
// Zip Folders
$folders->map(function ($folder) use ($zip, $user_id) {
// Get folder
$requested_folder = Folder::with(['folders.files', 'files'])
->where('id', $folder->id)
->where('user_id', $user_id)
->with('folders')
->first();
$folderFiles = get_files_for_zip($requested_folder, collect([]));
foreach ($folderFiles as $file) {
// get file path
$filePath = "files/$user_id/{$file['basename']}";
// Add file into zip
if (Storage::exists($filePath)) {
$zipDestination = "{$file['folder_path']}/{$file['name']}";
// local disk
if (is_storage_driver('local')) {
$zip->add(Storage::path($filePath), $zipDestination);
}
// s3 client
if (is_storage_driver('s3')) {
$bucketName = config('filesystems.disks.s3.bucket');
$zip->add("s3://$bucketName/$filePath", $zipDestination);
}
}
}
});
return $zip;
}
}
-70
View File
@@ -1,70 +0,0 @@
<?php
namespace Domain\Zip\Actions;
use Domain\Zip\Models\Zip;
use Illuminate\Support\Str;
use Domain\Sharing\Models\Share;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FileNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class ZipFilesAction
{
/**
* Zip selected files, store it in /zip folder and retrieve zip record
*/
public function __invoke(
File | Collection $files,
?Share $shared = null,
): Zip {
// Local storage instance
$disk_local = Storage::disk('local');
// Move file to local storage from external storage service
if (! is_storage_driver('local')) {
$files->each(function ($file) use ($disk_local) {
try {
$disk_local->put("temp/$file->basename", Storage::get("files/$file->user_id/$file->basename"));
} catch (FileNotFoundException $e) {
throw new HttpException(404, 'File not found');
}
});
}
// Get zip path
$zip_name = Str::random() . '.zip';
// Create zip
$zipper = new \Madnest\Madzipper\Madzipper;
$zip = $zipper->make($disk_local->path("zip/$zip_name"));
// Add files to zip
$files->each(function ($file) use ($zip, $disk_local) {
$file_path = is_storage_driver('local')
? $disk_local->path("files/$file->user_id/$file->basename")
: $disk_local->path("temp/$file->basename");
$zip->addString("$file->name.$file->mimetype", File::get($file_path));
});
// Close zip
//$zip->close();
// Delete temporary files
if (! is_storage_driver('local')) {
$files->each(function ($file) use ($disk_local) {
$disk_local->delete("temp/$file->basename");
});
}
// Store zip record
return Zip::create([
'user_id' => $shared->user_id ?? Auth::id(),
'shared_token' => $shared->token ?? null,
'basename' => $zip_name,
]);
}
}
@@ -1,81 +0,0 @@
<?php
namespace Domain\Zip\Actions;
use Domain\Zip\Models\Zip;
use Illuminate\Support\Str;
use Domain\Sharing\Models\Share;
use Domain\Folders\Models\Folder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FileNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class ZipFolderAction
{
/**
* Zip requested folder
*/
public function __invoke(
$id,
?Share $shared = null
): Zip {
// Get folder
$requested_folder = Folder::with(['folders.files', 'files'])
->where('id', $id)
->where('user_id', Auth::id() ?? $shared->user_id)
->with('folders')
->first();
$files = get_files_for_zip($requested_folder, collect([]));
// Local storage instance
$disk_local = Storage::disk('local');
// Move file to local storage from external storage service
if (! is_storage_driver('local')) {
foreach ($files as $file) {
try {
$disk_local->put("temp/{$file['basename']}", Storage::get("files/$requested_folder->user_id/{$file['basename']}"));
} catch (FileNotFoundException $e) {
throw new HttpException(404, 'File not found');
}
}
}
// Get zip path
$zip_name = Str::random(16) . '-' . Str::slug($requested_folder->name) . '.zip';
// Create zip
$zipper = new \Madnest\Madzipper\Madzipper;
$zip = $zipper->make($disk_local->path("zip/$zip_name"));
// Add files to zip
foreach ($files as $file) {
$file_path = is_storage_driver('local')
? $disk_local->path("files/$requested_folder->user_id/{$file['basename']}")
: $disk_local->path("temp/{$file['basename']}");
$zip
->folder($file['folder_path'])
->addString("{$file['name']}.{$file['mimetype']}", File::get($file_path));
}
// Close zip
//$zip->close();
// Delete temporary files
if (! is_storage_driver('local')) {
foreach ($files as $file) {
$disk_local->delete('temp/' . $file['basename']);
}
}
// Store zip record
return Zip::create([
'user_id' => $shared->user_id ?? Auth::id(),
'shared_token' => $shared->token ?? null,
'basename' => $zip_name,
]);
}
}
@@ -1,44 +0,0 @@
<?php
namespace Domain\Zip\Controllers;
use Domain\Zip\Models\Zip;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Domain\Traffic\Actions\RecordDownloadAction;
use Symfony\Component\HttpFoundation\StreamedResponse;
class GetZipController extends Controller
{
public function __construct(
private RecordDownloadAction $recordDownload,
) {
}
/**
* Get generated zip for user
*/
public function __invoke(
string $id,
): StreamedResponse {
$disk = Storage::disk('local');
$zip = Zip::whereId($id)
->where('user_id', Auth::id())
->firstOrFail();
// Store user download size
($this->recordDownload)(
file_size: $disk->size("zip/$zip->basename"),
user_id: $zip->user_id,
);
return $disk->download("zip/$zip->basename", $zip->basename, [
'Content-Type' => 'application/zip',
'Content-Length' => $disk->size("zip/$zip->basename"),
'Accept-Ranges' => 'bytes',
'Content-Range' => 'bytes 0-600/' . $disk->size("zip/$zip->basename"),
'Content-Disposition' => "attachment; filename=$zip->basename",
]);
}
}
@@ -1,44 +0,0 @@
<?php
namespace Domain\Zip\Controllers;
use Domain\Zip\Models\Zip;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use Domain\Traffic\Actions\RecordDownloadAction;
use Symfony\Component\HttpFoundation\StreamedResponse;
class VisitorGetZipController extends Controller
{
public function __construct(
private RecordDownloadAction $recordDownload,
) {
}
/**
* Get generated zip for visitor
*/
public function __invoke(
$id,
$token,
): StreamedResponse {
$disk = Storage::disk('local');
$zip = Zip::where('id', $id)
->where('shared_token', $token)
->first();
// Store user download size
($this->recordDownload)(
file_size: $disk->size("zip/$zip->basename"),
user_id: $zip->user_id,
);
return $disk->download("zip/$zip->basename", $zip->basename, [
'Content-Type' => 'application/zip',
'Content-Length' => $disk->size("zip/$zip->basename"),
'Accept-Ranges' => 'bytes',
'Content-Range' => 'bytes 0-600/' . $disk->size("zip/$zip->basename"),
'Content-Disposition' => 'attachment; filename=' . $zip->basename,
]);
}
}
@@ -0,0 +1,68 @@
<?php
namespace Domain\Zip\Controllers;
use App\Http\Controllers\Controller;
use Domain\Files\Models\File;
use Domain\Sharing\Actions\ProtectShareRecordAction;
use Domain\Sharing\Actions\VerifyAccessToItemAction;
use Domain\Sharing\Models\Share;
use Domain\Traffic\Actions\RecordDownloadAction;
use Domain\Zip\Actions\GetItemsListFromUrlParamAction;
use Domain\Zip\Actions\ZipAction;
use Illuminate\Http\Request;
use ZipStream\ZipStream;
class VisitorZipController extends Controller
{
public function __construct(
public GetItemsListFromUrlParamAction $getItemsListFromUrlParam,
public ProtectShareRecordAction $protectShareRecord,
public VerifyAccessToItemAction $verifyAccessToItem,
public RecordDownloadAction $recordDownload,
public ZipAction $zip,
) {}
public function __invoke(
Request $request,
Share $shared,
): ZipStream {
// Check ability to access protected share record
($this->protectShareRecord)($shared);
list($folders, $files) = ($this->getItemsListFromUrlParam)($shared->user_id);
// Check access to requested folders
if ($folders->isNotEmpty()) {
$folders->each(
fn ($folder) => ($this->verifyAccessToItem)($folder->id, $shared)
);
}
// Check access to requested files
if ($files->isNotEmpty()) {
$file_parent_folders = File::whereUserId($shared->user_id)
->whereIn('id', $files->pluck('id'))
->get()
->pluck('folder_id')
->toArray();
// Check access to requested directory
($this->verifyAccessToItem)($file_parent_folders, $shared);
}
// Zip items
$zip = ($this->zip)($folders, $files, $shared);
($this->recordDownload)(
file_size: $zip->predictZipSize(),
user_id: $shared->user_id,
);
return $zip;
}
}
@@ -1,55 +0,0 @@
<?php
namespace Domain\Zip\Controllers;
use Illuminate\Http\Request;
use Domain\Files\Models\File;
use Illuminate\Http\Response;
use Domain\Sharing\Models\Share;
use App\Http\Controllers\Controller;
use Domain\Zip\Actions\ZipFilesAction;
use Domain\Sharing\Actions\ProtectShareRecordAction;
use Domain\Sharing\Actions\VerifyAccessToItemAction;
/**
* Guest download multiple files via zip
*/
class VisitorZipFilesController extends Controller
{
public function __construct(
private ProtectShareRecordAction $protectShareRecord,
private VerifyAccessToItemAction $verifyAccessToItem,
private ZipFilesAction $zipFiles,
) {
}
public function __invoke(
Request $request,
Share $shared,
): Response {
// Check ability to access protected share record
($this->protectShareRecord)($shared);
$file_parent_folders = File::whereUserId($shared->user_id)
->whereIn('id', $request->items)
->get()
->pluck('folder_id')
->toArray();
// Check access to requested directory
($this->verifyAccessToItem)($file_parent_folders, $shared);
// Get requested files
$files = File::whereUserId($shared->user_id)
->whereIn('id', $request->items)
->get();
// Create zip
$zip = ($this->zipFiles)($files, $shared);
// Get file
return response([
'url' => url("/zip/{$zip->id}/public/{$shared->token}"),
'name' => $zip->basename,
], 201);
}
}
@@ -1,51 +0,0 @@
<?php
namespace Domain\Zip\Controllers;
use Illuminate\Http\Response;
use Domain\Sharing\Models\Share;
use Domain\Folders\Models\Folder;
use App\Http\Controllers\Controller;
use Domain\Zip\Actions\ZipFolderAction;
use Domain\Sharing\Actions\ProtectShareRecordAction;
use Domain\Sharing\Actions\VerifyAccessToItemAction;
/**
* Guest download folder via zip
*/
class VisitorZipFolderController extends Controller
{
public function __construct(
private ProtectShareRecordAction $protectShareRecord,
private VerifyAccessToItemAction $verifyAccessToItem,
private ZipFolderAction $zipFolder,
) {
}
public function __invoke(
string $id,
Share $shared,
): Response {
// Check ability to access protected share record
($this->protectShareRecord)($shared);
// Check access to requested folder
($this->verifyAccessToItem)($id, $shared);
// Get folder
$folder = Folder::whereUserId($shared->user_id)
->where('id', $id);
if (! $folder->exists()) {
abort(404, 'Requested folder doesn\'t exists.');
}
// Create zip
$zip = ($this->zipFolder)($id, $shared);
// Get file
return response([
'url' => url("/zip/{$zip->id}/public/{$shared->token}"),
'name' => $zip->basename,
], 201);
}
}
@@ -0,0 +1,41 @@
<?php
namespace Domain\Zip\Controllers;
use App\Http\Controllers\Controller;
use Domain\Traffic\Actions\RecordDownloadAction;
use Domain\Zip\Actions\GetItemsListFromUrlParamAction;
use Domain\Zip\Actions\ZipAction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use STS\ZipStream\ZipStream;
class ZipController extends Controller
{
public function __construct(
public ZipAction $zip,
public RecordDownloadAction $recordDownload,
public GetItemsListFromUrlParamAction $getItemsListFromUrlParam,
) {}
public function __invoke(
Request $request,
): ZipStream {
$user_id = Auth::id();
// Get list of folders and files from requested url parameter
list($folders, $files) = ($this->getItemsListFromUrlParam)($user_id);
// Zip items
$zip = ($this->zip)($folders, $files);
($this->recordDownload)(
file_size: $zip->predictZipSize(),
user_id: $user_id,
);
return $zip;
}
}
@@ -1,32 +0,0 @@
<?php
namespace Domain\Zip\Controllers;
use Illuminate\Http\Request;
use Domain\Files\Models\File;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Domain\Zip\Actions\ZipFilesAction;
class ZipFilesController extends Controller
{
public function __construct(
private ZipFilesAction $zipFiles,
) {
}
public function __invoke(
Request $request,
): Response {
$files = File::whereUserId(Auth::id())
->whereIn('id', $request->input('items'))
->get();
$zip = ($this->zipFiles)($files);
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 201);
}
}
@@ -1,34 +0,0 @@
<?php
namespace Domain\Zip\Controllers;
use Illuminate\Http\Response;
use Domain\Folders\Models\Folder;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Domain\Zip\Actions\ZipFolderAction;
class ZipFolderController extends Controller
{
public function __construct(
private ZipFolderAction $zipFolder,
) {
}
public function __invoke(
string $id,
): Response {
$folder = Folder::whereUserId(Auth::id())
->where('id', $id);
if (! $folder->exists()) {
abort(404, "Requested folder doesn't exists.");
}
$zip = ($this->zipFolder)($id);
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 201);
}
}
-48
View File
@@ -1,48 +0,0 @@
<?php
namespace Domain\Zip\Models;
use App\Users\Models\User;
use Illuminate\Support\Str;
use Database\Factories\ZipFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @property string basename
* @property string shared_token
* @property string id
* @property string user_id
* @property string created_at
* @property string updated_at
* @method static where(string $string, string $string1, string $toDateTimeString)
*/
class Zip extends Model
{
use HasFactory;
protected $guarded = ['id'];
public $incrementing = false;
protected $keyType = 'string';
protected static function newFactory(): ZipFactory
{
return ZipFactory::new();
}
public function user(): HasOne
{
return $this->hasOne(User::class, 'id', 'user_id');
}
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->id = (string) Str::uuid();
});
}
}
@@ -1,24 +0,0 @@
<?php
namespace Support\Scheduler\Actions;
use Domain\Zip\Models\Zip;
use Illuminate\Support\Facades\Storage;
class DeleteOldZipsAction
{
/**
* Delete old zips
*/
public function __invoke(): void
{
Zip::where('created_at', '<=', now()->subDay()->toDateTimeString())
->get()
->each(function ($zip) {
// Delete zip file
Storage::disk('local')->delete("zip/$zip->basename");
// Delete zip record
$zip->delete();
});
}
}
-9
View File
@@ -264,11 +264,6 @@ class AdminTest extends TestCase
$user->favouriteFolders()->attach($folder->id);
});
// Create zips
Zip::factory(Zip::class)
->count(2)
->create(['user_id' => $user->id]);
// Create shares
Share::factory(Share::class)
->count(2)
@@ -334,10 +329,6 @@ class AdminTest extends TestCase
'user_id' => $user->id,
]);
$this->assertDatabaseMissing('zips', [
'user_id' => $user->id,
]);
$file_ids
->each(function ($id, $index) use ($user) {
Storage::disk('local')
-56
View File
@@ -97,30 +97,6 @@ class ContentAccessTest extends TestCase
->assertStatus(200);
}
/**
* @test
*/
public function it_get_private_user_zip()
{
$user = User::factory(User::class)
->create();
$file = UploadedFile::fake()
->create('archive.zip', 2000, 'application/zip');
Storage::putFileAs('zip', $file, 'EHWKcuvKzA4Gv29v-archive.zip');
$zip = Zip::factory(Zip::class)->create([
'basename' => 'EHWKcuvKzA4Gv29v-archive.zip',
'user_id' => $user->id,
]);
$this
->actingAs($user)
->get("zip/$zip->id")
->assertOk();
}
/**
* @test
*/
@@ -175,29 +151,6 @@ class ContentAccessTest extends TestCase
->assertStatus(404);
}
/**
* @test
*/
public function logged_user_try_to_get_another_private_user_zip()
{
$user = User::factory(User::class)
->create();
$file = UploadedFile::fake()
->create('archive.zip', 2000, 'application/zip');
Storage::putFileAs('zip', $file, 'EHWKcuvKzA4Gv29v-archive.zip');
$zip = Zip::factory(Zip::class)->create([
'basename' => 'EHWKcuvKzA4Gv29v-archive.zip',
]);
$this
->actingAs($user)
->get("zip/$zip->id")
->assertNotFound();
}
/**
* @test
*/
@@ -207,15 +160,6 @@ class ContentAccessTest extends TestCase
->assertRedirect();
}
/**
* @test
*/
public function guest_try_to_get_private_user_zip()
{
$this->get('zip/EHWKcuvKzA4Gv29v-archive.zip')
->assertRedirect();
}
/**
* @test
*/
@@ -186,57 +186,4 @@ class VisitorAccessToItemsTest extends TestCase
]);
});
}
/**
* @test
*/
public function it_download_publicly_zipped_files()
{
collect([true, false])
->each(function ($is_protected) {
$user = User::factory(User::class)
->create();
$share = Share::factory(Share::class)
->create([
'user_id' => $user->id,
'type' => 'folder',
'is_protected' => $is_protected,
]);
$zip = Zip::factory(Zip::class)->create([
'basename' => 'EHWKcuvKzA4Gv29v-archive.zip',
'user_id' => $user->id,
'shared_token' => $share->token,
]);
$file = UploadedFile::fake()
->create($zip->basename, 1000, 'application/zip');
Storage::putFileAs('zip', $file, $file->name);
if ($is_protected) {
$cookie = [
'share_session' => json_encode([
'token' => $share->token,
'authenticated' => true,
]),
];
$this->withCookies($cookie)
->get("/zip/$zip->id/$share->token")
->assertStatus(200);
}
if (! $is_protected) {
$this->get("/zip/$zip->id/$share->token")
->assertStatus(200);
}
$this->assertDatabaseMissing('traffic', [
'user_id' => $user->id,
'download' => null,
]);
});
}
}
@@ -1,10 +1,10 @@
<?php
namespace Tests\Domain\Zip;
use Storage;
use Tests\TestCase;
use App\Users\Models\User;
use Domain\Zip\Models\Zip;
use Illuminate\Support\Str;
use Domain\Files\Models\File;
use Domain\Sharing\Models\Share;
@@ -24,15 +24,21 @@ class SharedZippingTest extends TestCase
$user = User::factory(User::class)
->create();
$folder = Folder::factory(Folder::class)
$sharedFolder = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
]);
$folder = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $sharedFolder->id,
]);
collect([0, 1])
->each(function ($index) use ($folder, $user) {
$file = UploadedFile::fake()
->create(Str::random() . "-fake-file-$index.pdf", 1000, 'application/pdf');
->create("fake-inner-file-$index.pdf", 1200, 'application/pdf');
Storage::putFileAs("files/$user->id", $file, $file->name);
@@ -46,14 +52,35 @@ class SharedZippingTest extends TestCase
]);
});
collect([0, 1])
->each(function ($index) use ($sharedFolder, $user) {
$file = UploadedFile::fake()
->create(Str::random() . "-fake-file-$index.pdf", 1000, 'application/pdf');
Storage::putFileAs("files/$user->id", $file, $file->name);
File::factory(File::class)
->create([
'filesize' => $file->getSize(),
'folder_id' => $sharedFolder->id,
'user_id' => $user->id,
'basename' => $file->name,
'name' => "fake-file-$index.pdf",
]);
});
$share = Share::factory(Share::class)
->create([
'item_id' => $folder->id,
'item_id' => $sharedFolder->id,
'user_id' => $user->id,
'type' => 'folder',
'is_protected' => $is_protected,
]);
$files = File::all()
->pluck('id')
->toArray();
// Check shared item protected by password
if ($is_protected) {
$cookie = ['share_session' => json_encode([
@@ -63,24 +90,18 @@ class SharedZippingTest extends TestCase
$this
->withUnencryptedCookies($cookie)
->post("/api/zip/files/$share->token", [
'items' => File::all()->pluck('id'),
])->assertStatus(201);
->get("/api/zip/{$share->token}?items=$files[0]|file,$files[1]|file,$folder->id|folder")
->assertStatus(200)
->assertHeader('content-type', 'application/x-zip');
}
// Check public shared item
if (! $is_protected) {
$this->postJson("/api/zip/files/$share->token", [
'items' => File::all()->pluck('id'),
])->assertStatus(201);
if (!$is_protected) {
$this
->get("/api/zip/{$share->token}?items=$files[0]|file,$files[1]|file,$folder->id|folder")
->assertStatus(200)
->assertHeader('content-type', 'application/x-zip');
}
$this->assertDatabaseHas('zips', [
'user_id' => $user->id,
'shared_token' => $share->token,
]);
Storage::assertExists('zip/' . Zip::first()->basename);
});
}
@@ -119,6 +140,10 @@ class SharedZippingTest extends TestCase
'is_protected' => $is_protected,
]);
$files = File::all()
->pluck('id')
->toArray();
// Check shared item protected by password
if ($is_protected) {
$cookie = ['share_session' => json_encode([
@@ -128,17 +153,18 @@ class SharedZippingTest extends TestCase
$this
->withUnencryptedCookies($cookie)
->post("/api/zip/files/$share->token", [
'items' => File::all()->pluck('id'),
])->assertStatus(403);
->get("/api/zip/$share->token?items=$files[0]|file,$files[1]|file")
->assertStatus(403);
}
// Check public shared item
if (! $is_protected) {
$this->postJson("/api/zip/files/$share->token", [
'items' => File::all()->pluck('id'),
])->assertStatus(403);
if (!$is_protected) {
$this
->get("/api/zip/$share->token?items=$files[0]|file,$files[1]|file")
->assertStatus(403);
}
File::all()->each(fn ($file) => $file->delete());
});
}
@@ -198,25 +224,15 @@ class SharedZippingTest extends TestCase
$this
->withUnencryptedCookies($cookie)
->get("/api/zip/folder/$children->id/$share->token")
->assertStatus(201);
->get("/api/zip/$share->token?items=$children->id|folder")
->assertStatus(200);
}
// Check public shared item
if (! $is_protected) {
$this->getJson("/api/zip/folder/$children->id/$share->token")
->assertStatus(201);
if (!$is_protected) {
$this->getJson("/api/zip/$share->token?items=$children->id|folder")
->assertStatus(200);
}
$this->assertDatabaseHas('zips', [
'user_id' => $user->id,
'shared_token' => $share->token,
]);
Zip::all()
->each(function ($zip) {
Storage::assertExists("zip/$zip->basename");
});
});
}
@@ -252,13 +268,13 @@ class SharedZippingTest extends TestCase
$this
->withUnencryptedCookies($cookie)
->get("/api/zip/folder/$folder->id/$share->token")
->get("/api/zip/$share->token?items=$folder->id|folder")
->assertStatus(403);
}
// Check public shared item
if (! $is_protected) {
$this->getJson("/api/zip/folder/$folder->id/$share->token")
if (!$is_protected) {
$this->getJson("/api/zip/$share->token?items=$folder->id|folder")
->assertStatus(403);
}
});
@@ -1,10 +1,10 @@
<?php
namespace Tests\Domain\Zip;
use Storage;
use Tests\TestCase;
use App\Users\Models\User;
use Domain\Zip\Models\Zip;
use Laravel\Sanctum\Sanctum;
use Domain\Files\Models\File;
use Domain\Folders\Models\Folder;
@@ -22,6 +22,24 @@ class UserZippingTest extends TestCase
Sanctum::actingAs($user);
$folder = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
]);
collect([0, 1])
->each(function ($index) use ($folder) {
$file = UploadedFile::fake()
->create("fake-inner-file-$index.pdf", 1200, 'application/pdf');
$this->postJson('/api/upload', [
'filename' => $file->name,
'file' => $file,
'folder_id' => $folder->id,
'is_last' => 'true',
])->assertStatus(201);
});
collect([0, 1])
->each(function ($index) {
$file = UploadedFile::fake()
@@ -35,20 +53,15 @@ class UserZippingTest extends TestCase
])->assertStatus(201);
});
$file_ids = File::all()->pluck('id');
$files = File::all()
->where('folder_id', null)
->pluck('id')
->toArray();
$this->postJson('/api/zip/files', [
'items' => $file_ids,
])->assertStatus(201);
$this->assertDatabaseHas('zips', [
'user_id' => $user->id,
]);
Storage::disk('local')
->assertExists(
'zip/' . Zip::first()->basename
);
$this
->getJson("/api/zip?items=$files[0]|file,$files[1]|file,$folder->id|folder")
->assertStatus(200)
->assertHeader('content-type', 'application/x-zip');
}
/**
@@ -79,16 +92,8 @@ class UserZippingTest extends TestCase
])->assertStatus(201);
});
$this->getJson("/api/zip/folder/$folder->id")
->assertStatus(201);
$this->assertDatabaseHas('zips', [
'user_id' => $user->id,
]);
Storage::disk('local')
->assertExists(
'zip/' . Zip::first()->basename
);
$this->getJson("/api/zip?items=$folder->id|folder")
->assertStatus(200)
->assertHeader('content-type', 'application/x-zip');
}
}
-27
View File
@@ -4,10 +4,8 @@ namespace Tests\Support\Scheduler;
use Storage;
use Tests\TestCase;
use App\Users\Models\User;
use Domain\Zip\Models\Zip;
use Domain\Sharing\Models\Share;
use Illuminate\Http\UploadedFile;
use Support\Scheduler\Actions\DeleteOldZipsAction;
use Support\Scheduler\Actions\DeleteFailedFilesAction;
use Support\Scheduler\Actions\DeleteUnverifiedUsersAction;
use Support\Scheduler\Actions\DeleteExpiredShareLinksAction;
@@ -32,31 +30,6 @@ class SchedulerTest extends TestCase
]);
}
/**
* @test
*/
public function it_delete_zips_older_than_one_day()
{
$file = UploadedFile::fake()
->create('archive.zip', 2000, 'application/zip');
Storage::putFileAs('zip', $file, 'EHWKcuvKzA4Gv29v-archive.zip');
$zip = Zip::factory(Zip::class)->create([
'basename' => 'EHWKcuvKzA4Gv29v-archive.zip',
'created_at' => now()->subDay(),
]);
resolve(DeleteOldZipsAction::class)();
$this->assertDatabaseMissing('zips', [
'id' => $zip->id,
]);
Storage::disk('local')
->assertMissing('zip/EHWKcuvKzA4Gv29v-archive.zip');
}
/**
* @test
*/