Compare commits

...

1001 Commits
oasis ... ads

Author SHA1 Message Date
Čarodej
ac9233ce2c ads test tag 2022-08-08 09:53:18 +02:00
Čarodej
1afa5fa48e added new adsense code 2022-08-08 09:51:14 +02:00
Čarodej
6c8a4e2186 adsense edit 2022-08-08 09:35:02 +02:00
Čarodej
b38a8f5450 Merge remote-tracking branch 'origin/master' into ads
# Conflicts:
#	package.json
#	public/9346.js
#	public/chunks/admin.js
#	public/chunks/app-environment.js
#	public/chunks/app-server.js
#	public/chunks/billing.js
#	public/chunks/forgotten-password.js
#	public/chunks/homepage.js
#	public/chunks/plan-create/metered.js
#	public/chunks/plan-settings.js
#	public/chunks/platform.js
#	public/chunks/profile.js
#	public/chunks/recent-uploads.js
#	public/chunks/request.js
#	public/chunks/settings.js
#	public/chunks/shared.js
#	public/chunks/shared/authenticate.js
#	public/chunks/shared/single-file.js
#	public/chunks/sign-in.js
#	public/css/tailwind.css
#	public/js/main.js
#	public/js/main.js.LICENSE.txt
#	public/mix-manifest.json
2022-08-08 08:50:24 +02:00
Čarodej
5505006d1b frontend build 2022-08-05 15:40:09 +02:00
Čarodej
7db1c7926f extended license restrictions removed 2022-08-05 15:24:06 +02:00
Čarodej
d1ecd33838 setup wizard update 2022-08-05 09:34:24 +02:00
Čarodej
49abb58776 updated subscription package source 2022-08-05 08:25:12 +02:00
Čarodej
d8f1f57b89 $max_execution_time adjusted 2022-07-28 19:08:28 +02:00
Čarodej
dba177d7f3 todo added 2022-07-17 14:14:23 +02:00
Čarodej
46971e0765 build 2022-07-16 11:53:02 +02:00
Čarodej
c9e1fcbd3c changelog update 2022-07-16 11:51:41 +02:00
Čarodej
f87fef13cd fixed language typo issue 2022-07-15 15:02:35 +02:00
Čarodej
1bc3164a5d updated composer lock 2022-07-15 12:50:34 +02:00
Čarodej
c323677cfa email localization fix 2022-07-15 12:19:48 +02:00
Čarodej
bc5300ad6d fixed setup wizard 2022-07-11 18:05:33 +02:00
Čarodej
04b965fd83 cron alert message updated 2022-07-06 10:37:55 +02:00
Čarodej
42ccd553d6 2.2.1 upgrade functions 2022-07-01 10:32:19 +02:00
Čarodej
b79184bee1 - vendor updates
- composer dumping fix
2022-07-01 09:10:59 +02:00
Čarodej
751cc6db1b build 2022-07-01 09:02:28 +02:00
Čarodej
245bef8d10 changelog update 2022-07-01 08:58:31 +02:00
Čarodej
132bf23a7e version change 2022-06-30 17:01:13 +02:00
Čarodej
ab970ef056 Merge branch 'fraud-prevention-mechanism'
# Conflicts:
#	public/chunks/admin.js
#	public/chunks/payments/settings.js
#	public/chunks/platform.js
#	public/chunks/settings.js
#	public/chunks/status-check.js
#	public/css/tailwind.css
#	public/js/main.js
#	public/mix-manifest.json
#	src/App/Providers/AppServiceProvider.php
#	tests/Domain/Admin/AdminTest.php
2022-06-30 10:54:13 +02:00
Čarodej
b8e97b62c1 added index and button into DunningEmailToCoverAccountUsageNotification 2022-06-30 10:49:18 +02:00
Čarodej
829e4ec789 version change 2022-06-29 12:17:35 +02:00
Čarodej
4c52b6a627 Fixed reCaptcha for the contact form 2022-06-29 12:16:06 +02:00
Čarodej
e01fc99ef4 Fixed deleted at language string in grid view browsed in trash section 2022-06-29 11:49:34 +02:00
Čarodej
1ba96f0c43 Extended login time up to 3 months 2022-06-29 11:42:05 +02:00
Čarodej
b6c603a97b changelog update 2022-06-28 16:45:38 +02:00
Čarodej
45844f26d3 version update 2022-06-28 16:35:03 +02:00
Čarodej
7b4cb694f3 return null in default in restriction engine 2022-06-28 16:33:47 +02:00
Čarodej
8bc046fc73 build 2022-06-28 08:25:39 +02:00
Čarodej
ec5ed24eaa language strings update 2022-06-28 08:23:41 +02:00
Čarodej
22e096cf24 version change 2022-06-27 19:33:06 +02:00
Čarodej
f2f18f3063 build 2022-06-27 19:31:24 +02:00
Čarodej
4cafb726df Added hint to set cron command in dashboard panel when cron is not set correctly 2022-06-27 19:29:34 +02:00
Čarodej
e274088b71 backblaze fix 2022-06-27 12:48:44 +02:00
Čarodej
178a8606b9 google analytics fix 2022-06-27 11:07:52 +02:00
Čarodej
a26684df79 - composer repository update
- paypal test fix
2022-06-24 12:15:40 +02:00
Čarodej
42390af2d5 composer update 2022-06-24 10:56:15 +02:00
Čarodej
06ee3faa1e prevention to get other user folder when folder upload is trying to recreate folder structure 2022-06-23 17:49:56 +02:00
Čarodej
74898d007f build 2022-06-23 17:16:47 +02:00
Čarodej
ba1fb5aa0b build 2022-06-23 17:16:14 +02:00
Čarodej
afe0a21a29 version change 2022-06-23 16:53:00 +02:00
Čarodej
7983195223 changelog update 2022-06-23 16:51:58 +02:00
Čarodej
13d0a5feba Fixed issue when you upload empty .txt file, it stops the upload process 2022-06-23 16:39:59 +02:00
Čarodej
7fff722377 Added spinner when pdf is loading 2022-06-23 12:25:10 +02:00
Čarodej
e412f3b88b Fixed issue where Dragged & Dropped folder from desktop didn't start uploading 2022-06-23 11:44:23 +02:00
Čarodej
0485672a47 Fixed issue where change in sorting option will duplicate the content in file view 2022-06-22 12:38:54 +02:00
Čarodej
ca89117c77 composer and changelog update 2022-06-22 11:40:51 +02:00
Čarodej
2ad5e66831 composer update 2022-06-22 11:04:39 +02:00
Čarodej
df3303b527 Fixed issue when after deleting user, the related subscription wasn't deleted 2022-06-22 10:30:39 +02:00
Čarodej
aedd6d9120 set sandbox/live mode in PayPal key configuration setup form 2022-06-22 09:56:05 +02:00
Čarodej
ad02c87f19 subscription page can now list subscriptions without users 2022-06-15 09:45:22 +02:00
Čarodej
c9c7a730f6 language editor fix 2022-06-15 09:07:44 +02:00
Čarodej
c7ccecf447 composer update 2022-06-15 08:40:12 +02:00
Čarodej
a4bdb74951 version change 2022-06-15 07:53:56 +02:00
Čarodej
dedbc85e57 readme update 2022-06-14 11:15:27 +02:00
Čarodej
aaea435eb0 restriction text implementation for the frontend 2022-06-14 10:31:55 +02:00
Čarodej
cd912945cf change logo update 2022-06-13 11:25:47 +02:00
Čarodej
447535bd26 multiple paypal load buttons fix 2022-06-13 11:23:47 +02:00
Čarodej
38854be63c - stripe redirection into checkout fix
- show Websocket connection test only when broadcasting is set
2022-06-13 11:08:03 +02:00
Čarodej
8ec2d5402b - stripe redirection into checkout fix
- show Websocket connection test only when broadcasting is set
2022-06-13 10:55:28 +02:00
Čarodej
a61d8434be changelog 2022-06-12 15:16:25 +02:00
Čarodej
918c0a6fe9 trash browsing fix 2022-06-12 15:15:25 +02:00
Čarodej
ebf1b16aa5 MeteredBillingRestrictionsEngine update with the new rule for dunning 2022-06-12 14:53:58 +02:00
Čarodej
119780317d MeteredBillingRestrictionsEngine update with the new rule for dunning 2022-06-10 11:19:45 +02:00
Čarodej
9bc8a9b27c dunning implementation of the notifications 2022-06-09 18:08:49 +02:00
Čarodej
f3bfe9a0cc dump fix 2022-06-08 08:53:59 +02:00
Čarodej
40b746fb78 build 2022-06-06 18:32:11 +02:00
Čarodej
8a943747eb subscription config 2022-06-06 18:31:03 +02:00
Čarodej
59e3f55ac3 Added Fraud Prevention Mechanism Rules form 2022-06-06 10:00:44 +02:00
Čarodej
16db8d3512 setup wizard fix 2022-06-06 07:57:37 +02:00
Čarodej
d521b237a3 app title fix 2022-06-02 08:40:56 +02:00
Čarodej
3077ec18d1 version change 2022-06-02 07:38:29 +02:00
Čarodej
8b5b9c3310 color fix 2022-06-02 07:38:03 +02:00
Čarodej
c4d7fa1e9b composer update 2022-06-01 20:01:05 +02:00
Čarodej
96afda9f7c back to php 8.0 2022-06-01 19:47:27 +02:00
Čarodej
97060092ba build 2022-06-01 11:03:25 +02:00
Čarodej
3a73e4c792 composer & npm update 2022-06-01 11:02:19 +02:00
Čarodej
2e798bd1ec - navigation bar long title is now allowed 2022-06-01 10:59:59 +02:00
Čarodej
94afb626eb - When new user was created via admin, the verification email was send
- Item name in list view type is now extended on the full page width
2022-06-01 10:09:18 +02:00
Čarodej
428b4c87a3 test fixing 2022-05-31 16:25:09 +02:00
Čarodej
c912166905 ResetPassword.php refactoring 2022-05-31 15:55:02 +02:00
Čarodej
aa9731dd13 file request url removed from http response 2022-05-31 15:46:11 +02:00
Čarodej
05f58e1468 centering auth page fix 2022-05-31 15:38:08 +02:00
Čarodej
7659cc7221 api refactoring 2022-05-31 15:12:31 +02:00
Čarodej
a4b18c26b5 avatar fix in dark mode 2022-05-30 10:15:25 +02:00
Čarodej
317d7aefc3 - spotlight refactoring
- subscription widget fix in admin
2022-05-30 10:12:35 +02:00
Čarodej
17d4bcd888 prefilling user refactoring 2022-05-30 09:47:42 +02:00
Čarodej
8dd4cf2be6 config refactoring 2022-05-30 09:41:43 +02:00
Čarodej
b8a50bb326 build 2022-05-27 09:31:34 +02:00
Čarodej
d8789a4788 helper refactoring 2022-05-27 09:25:31 +02:00
Čarodej
1d670fcb52 infinity scroller ui improvements 2022-05-26 09:22:50 +02:00
Čarodej
b9975de700 paginator refactoring and implementation into the routes 2022-05-26 07:46:15 +02:00
Čarodej
31218240ae Merge remote-tracking branch 'origin/infinite_scroll' into api
# Conflicts:
#	config/vuefilemanager.php
#	package-lock.json
#	package.json
#	public/mix-manifest.json
#	resources/js/store/modules/fileBrowser.js
#	resources/js/store/modules/sharing.js
#	resources/js/store/modules/teams.js
#	resources/js/store/modules/userAuth.js
#	src/App/Socialite/Controllers/SocialiteCallbackController.php
#	src/Domain/Browsing/Controllers/BrowseTrashContentController.php
#	src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php
#	src/Domain/Files/Controllers/UploadFileController.php
#	src/Domain/Items/Controllers/RenameFileOrFolderController.php
#	src/Support/helpers.php
2022-05-24 10:22:21 +02:00
Čarodej
36c5e51b4f refactoring 2022-05-24 10:01:07 +02:00
Čarodej
4e2f92ee7a adsense vue test 2022-05-24 07:53:13 +02:00
Čarodej
d6e9d2bd4f lowered max execution time 2022-05-20 17:01:53 +02:00
Čarodej
971ae4160e - plan sorting fix
- plan homepage visibility fix
2022-05-20 16:59:53 +02:00
Čarodej
63da860df5 test websocket connection 2022-05-20 16:48:25 +02:00
Čarodej
ab65aa8859 logout bug fixed 2022-05-18 17:39:05 +02:00
Čarodej
6bd1ec96bd - changelog update 2022-05-18 11:22:52 +02:00
Čarodej
8bab827d81 - backup issue fix 2022-05-18 11:17:12 +02:00
Čarodej
1d91d9759e - team invitation fix 2022-05-18 11:04:41 +02:00
Čarodej
127f1dc4cf - metered plan decimal extended into 3 places
- paginator fix
2022-05-18 10:45:56 +02:00
Čarodej
1e10ff32a8 triangle fix in notification center 2022-05-18 10:03:43 +02:00
Čarodej
aa30b519fa - send notification to native user when file request was sent via email
- updated mysql dump
2022-05-18 09:50:21 +02:00
Čarodej
3c28da2613 refactoring 2022-05-18 08:51:28 +02:00
Čarodej
e87e2ec4e3 routes response refactoring 2022-05-16 20:18:45 +02:00
Čarodej
f66982b3ec sharing route refactoring 2022-05-16 12:33:09 +02:00
Čarodej
68dc04963d Merge remote-tracking branch 'origin/api' into api
# Conflicts:
#	.env.testing
#	public/mix-manifest.json
#	resources/js/components/RemoteUpload/RemoteUploadPopup.vue
#	resources/js/store/modules/fileBrowser.js
#	resources/js/store/modules/fileFunctions.js
#	routes/share.php
#	src/Domain/Files/Controllers/VisitorUploadFileChunksController.php
#	tests/Domain/Sharing/VisitorManipulatingTest.php
#	tests/Domain/Traffic/TrafficTest.php
2022-05-16 11:55:22 +02:00
Čarodej
69a48e8925 share routes refactoring 2022-05-16 11:51:08 +02:00
Čarodej
c0e431b384 api refactoring 2022-05-16 11:50:51 +02:00
Čarodej
b8741439f5 api refactoring part 2 2022-05-13 10:43:45 +02:00
Čarodej
70901a2df5 api refactoring 2022-05-12 08:56:48 +02:00
Čarodej
d2371e667f Merge branch 'master' into api
# Conflicts:
#	.env.testing
#	public/mix-manifest.json
#	src/Domain/RemoteUpload/Controllers/UploadFilesRemotelyForUploadRequestController.php
2022-05-11 09:00:42 +02:00
Čarodej
000b5459f9 changelog update 2022-05-10 15:56:01 +02:00
Čarodej
ed17ed1a79 build 2022-05-10 11:17:01 +02:00
Čarodej
8c75166980 Fixed issue when you create plan with 0 team members amount 2022-05-10 10:48:05 +02:00
Čarodej
6472997cc1 fixed trash navigator issue 2022-05-10 10:25:42 +02:00
Čarodej
209667f55e fixed homepage redirection when homepage is disabled 2022-05-10 09:53:13 +02:00
Čarodej
73c84075c5 facebook authentication fix 2022-05-10 08:41:43 +02:00
Čarodej
5d7fed7de8 UnableToRetrieveMetadata error 2022-05-10 07:53:41 +02:00
Čarodej
b6cf1e2799 increase folder item count after drag in file 2022-05-10 07:09:28 +02:00
Čarodej
acfbbd56ca format code 2022-05-10 06:59:11 +02:00
Čarodej
b9a6bc05ff PayPal connection test 2022-05-10 06:58:34 +02:00
Čarodej
e3293f0b1a Stripe connection test 2022-05-09 17:38:38 +02:00
Čarodej
4eb901dae0 Paystack connection test 2022-05-09 17:32:44 +02:00
Čarodej
911f15d493 - Fixed upload issue 2022-05-09 16:58:14 +02:00
Čarodej
a43c799d59 - Fixed issue when upload doesn't start after you drag the file into empty view
- pointer cursor over file item
2022-05-09 15:06:21 +02:00
Čarodej
e9824bb807 show errors for recaptcha 2022-05-09 10:33:39 +02:00
Čarodej
2c933c65a7 added plan synchronization button 2022-05-09 09:57:25 +02:00
Čarodej
0b2d05a899 sanitizing env value before storing into the .env file 2022-05-09 08:23:38 +02:00
Čarodej
4e2ac2b890 moved subscription section in readme 2022-05-09 07:26:23 +02:00
Čarodej
6bd7456f2e bcmath in index moved into try/catch block 2022-05-09 07:25:18 +02:00
Čarodej
bbd6df4175 build 2022-05-08 10:46:13 +02:00
Čarodej
70fe106e45 - team members fix 2022-05-08 10:35:44 +02:00
Čarodej
1331409920 chunk issue 2022-05-08 10:13:22 +02:00
Čarodej
01970af8de websockets:install description redefined 2022-05-06 18:24:00 +02:00
Čarodej
63a72d6fe4 version change 2022-05-06 18:01:01 +02:00
Čarodej
9b5f8731d2 s3 private as a default 2022-05-06 17:28:00 +02:00
Čarodej
4250e58370 teams api update 2022-05-04 10:17:36 +02:00
Čarodej
f9b762de43 notifications api update 2022-05-04 09:20:48 +02:00
Čarodej
67b9f7f4dc file request api update 2022-05-04 09:03:18 +02:00
Čarodej
cf7e17e188 registration api update 2022-05-04 08:42:21 +02:00
Čarodej
137021fcdc personal access token api update 2022-05-04 08:36:32 +02:00
Čarodej
3d2e279afd user settings api update 2022-05-04 07:20:15 +02:00
Čarodej
4fc5ccd26d browsing api update 2022-05-03 16:18:44 +02:00
Čarodej
89e4ae6737 search api update 2022-05-03 16:11:00 +02:00
Čarodej
8b3f76d1d0 share records api update 2022-05-03 15:54:31 +02:00
Čarodej
37cc94aeda added demo page with button redirection 2022-05-03 10:48:31 +02:00
Čarodej
664f8d8e53 create share api update 2022-05-03 09:57:56 +02:00
Čarodej
b1fd046084 zip api update 2022-05-03 09:18:07 +02:00
Čarodej
e8fb5b6865 move api update 2022-05-03 08:30:41 +02:00
Čarodej
9ed2eec092 delete api update 2022-05-03 08:27:14 +02:00
Čarodej
257de10cc8 create folder api update 2022-05-03 08:14:47 +02:00
Čarodej
2e61cee49c remote upload api update 2 2022-05-03 08:10:50 +02:00
Čarodej
aca289b5a6 remote upload api update 2022-05-03 07:55:48 +02:00
Čarodej
0f42704980 trash api update 2022-05-03 07:47:54 +02:00
Čarodej
4f9fb3991c favourites api update 2022-05-03 06:59:31 +02:00
Milos Holba
f75c20e5a7 added test for getRecordsCount, format code 2022-05-02 18:21:20 +02:00
Čarodej
c2d53479e8 api enhancements 2022-05-02 17:19:37 +02:00
Čarodej
89689816ad exif fix 2022-05-02 07:00:26 +02:00
Čarodej
ba58e76d3b setup wizard database password as optional 2022-05-01 12:44:34 +02:00
Čarodej
12d7b3e92b mimetype fix 2022-04-29 09:09:53 +02:00
Čarodej
c8ebb5db9f refactoring 2022-04-29 08:24:35 +02:00
Čarodej
869dbd4797 build 2022-04-27 17:32:58 +02:00
Čarodej
4b8bd3be52 - creating admin fix
- fixed hamburger menu in public folder
- red cancel sharing button
2022-04-27 17:28:03 +02:00
Čarodej
a4aa329bf4 version change 2022-04-27 08:22:06 +02:00
Čarodej
97a807a5e5 deleted frontend code 2022-04-27 08:18:39 +02:00
Čarodej
92561d137d get exif data refactoring 2022-04-26 10:08:11 +02:00
Čarodej
43368c7555 added pdo_mysql into required php modules 2022-04-26 08:33:52 +02:00
Čarodej
5e9e4142d0 mimetype hotfix 2022-04-25 20:10:41 +02:00
Čarodej
7be7203b96 version change 2022-04-25 20:04:49 +02:00
Čarodej
0adc0f4fcd version change 2022-04-25 20:04:22 +02:00
Čarodej
110a22d317 mimetype reading fix 2022-04-25 20:03:55 +02:00
Čarodej
68b4722668 readme/changelog update 2022-04-25 12:44:59 +02:00
Čarodej
612298ebec queue:work command edit 2022-04-25 12:27:28 +02:00
Čarodej
48492f87be remote upload demo functionality 2022-04-25 12:18:02 +02:00
Čarodej
01735b4e1f remote upload demo functionality 2022-04-25 12:11:37 +02:00
Čarodej
e769c33af6 build 2022-04-25 11:01:35 +02:00
Čarodej
b635a17644 remote upload refactoring 2022-04-25 10:56:15 +02:00
Čarodej
954f0e3361 implemented remote upload progress counter 2022-04-25 10:13:10 +02:00
Čarodej
6a9fa9ceec readme update 2022-04-23 09:56:15 +02:00
Čarodej
20162ac366 language translation enhancement 2022-04-23 09:52:30 +02:00
Čarodej
0a9740a363 broadcast new files to the frontend after file was remotely uploaded 2022-04-23 09:44:43 +02:00
Čarodej
4b366747b6 Merge remote-tracking branch 'origin/remote-upload-merge'
# Conflicts:
#	public/mix-manifest.json
2022-04-22 16:37:07 +02:00
Čarodej
c2595a0de4 readme updated with broadcasting section 2022-04-22 16:36:29 +02:00
Čarodej
6e8714aec5 websocket allowed origins implementation 2022-04-22 09:44:40 +02:00
Čarodej
5e86799a82 vuefilemanager broadcast server enhancements 2022-04-22 08:58:00 +02:00
Čarodej
d586eb9d7e extractExtensionFromUrl refactoring 2022-04-21 18:05:34 +02:00
Čarodej
35d89e2be1 remote upload implementation into file request 2022-04-21 17:31:47 +02:00
Čarodej
409ab8c03f refactor user in upload controllers 2022-04-21 16:57:38 +02:00
Čarodej
8be0ae2a62 remote upload for shared route 2022-04-21 16:47:22 +02:00
Čarodej
d43efad45e Merge remote-tracking branch 'origin/master' 2022-04-21 09:12:58 +02:00
Čarodej
c86f93ac1e build 2022-04-21 09:12:47 +02:00
Čarodej
64b0dff8fb - The switch button in archived plans is now hidden
- updated readme.md
- Fixed upload progressbar in mobile version
- Added Viet Nam language into the language editor
2022-04-21 09:11:57 +02:00
Čarodej
ca76463fab fixed issue in backblaze connection test 2022-04-21 08:28:40 +02:00
Čarodej
e4dd9de931 reload view after remote upload was finished 2022-04-20 19:20:48 +02:00
Čarodej
dc8e3c8141 remote upload backend functionality 2022-04-20 18:19:25 +02:00
Čarodej
97ef846a44 composer lock fix 2022-04-20 17:30:05 +02:00
Čarodej
5b130d01af build 2022-04-19 19:11:53 +02:00
Čarodej
552e5e02c9 google button fix 2022-04-19 19:10:18 +02:00
Čarodej
19e29e69e0 file chunks refactoring 2022-04-19 09:40:31 +02:00
Milos Holba
ad8793ce28 change of the browsing functionality 2022-04-14 16:25:57 +02:00
Čarodej
6c3e7801da remote upload popup frontend 2022-04-14 15:16:43 +02:00
Čarodej
50eb67ac79 fixed issue with overflowing text in small screen for FilePreview 2022-04-14 11:08:51 +02:00
Čarodej
cd5af37bfe store refactoring 2022-04-13 16:26:11 +02:00
Čarodej
338f8664b7 vue components refactoring 2022-04-13 16:19:10 +02:00
Čarodej
6a4bfa8bfe readme update 2022-04-13 08:45:06 +02:00
Čarodej
b439fc1070 build 2022-04-12 11:11:31 +02:00
Čarodej
8baa466782 update for setEnvironmentValue function 2022-04-12 11:10:38 +02:00
Čarodej
8df7794484 ftp setup added 2022-04-12 10:43:23 +02:00
Čarodej
e71810a9bb mail setup refactoring 2022-04-12 08:36:10 +02:00
Čarodej
b37bbe38dc storage setup refactoring 2022-04-11 17:20:59 +02:00
Peter Papp
a051ab568d Merge pull request #14 from VueFileManager/dependabot/npm_and_yarn/follow-redirects-1.14.8
Bump follow-redirects from 1.14.7 to 1.14.8
2022-04-11 15:57:07 +02:00
Peter Papp
ab2c8b8371 Merge pull request #5 from VueFileManager/dependabot/npm_and_yarn/dns-packet-1.3.4
Bump dns-packet from 1.3.1 to 1.3.4
2022-04-11 15:56:56 +02:00
Peter Papp
b803c32b41 Merge pull request #15 from VueFileManager/dependabot/npm_and_yarn/node-forge-1.3.0
Bump node-forge from 1.2.1 to 1.3.0
2022-04-11 15:56:44 +02:00
Peter Papp
5d1d883fb1 Merge pull request #16 from VueFileManager/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-04-11 15:56:21 +02:00
Čarodej
e5f4bad9a9 azure implementation 2022-04-11 11:59:16 +02:00
Čarodej
fbc9eed30b ftp implementation 2022-04-11 09:34:25 +02:00
Čarodej
7740e1673f build 2022-04-08 10:35:00 +02:00
Čarodej
9de6c65643 Test ses connection before storing credentials into the app 2022-04-08 10:30:44 +02:00
Čarodej
9a15f2ecd8 Test postmark connection before storing credentials into the app 2022-04-08 09:44:58 +02:00
Čarodej
86090d5192 Test mailgun connection before storing credentials into the app 2022-04-08 08:00:13 +02:00
Čarodej
6ed2efcc4e default color for avatar was changed 2022-04-07 15:44:41 +02:00
Čarodej
85d4f535eb tnt search tweaked 2022-04-07 15:04:31 +02:00
Čarodej
03d78937dc replaced google icon 2022-04-07 14:48:42 +02:00
Čarodej
596fa5f95c fixed uploading in demo account 2022-04-07 14:30:28 +02:00
Čarodej
8d1ee24c7a updated language translations 2022-04-07 14:17:46 +02:00
Milos Holba
d71e598758 added possibility to return all record 2022-04-07 12:56:01 +02:00
Čarodej
18ffb24941 after cancelled shared link in SharedLinks, remove items from view 2022-04-07 12:17:49 +02:00
Čarodej
f5879c0670 fixed language tab in mobile version 2022-04-07 12:08:55 +02:00
Čarodej
60a3c46ffe added spinner into button when user accept or reject team invitation 2022-04-07 12:05:14 +02:00
Čarodej
76b32f551f responsive paginator fix 2022-04-07 11:42:14 +02:00
Čarodej
03d42bee51 - language strings fix
- scrolling fix
2022-04-07 11:31:37 +02:00
Čarodej
e240ce7736 dashboard app bar refactored 2022-04-07 11:18:47 +02:00
Čarodej
93dbaa081d iOs window height fix 2022-04-07 11:00:24 +02:00
Čarodej
eb48aa46e3 - fixed issue with centering and overflowing info sidebar 2022-04-07 10:37:11 +02:00
Čarodej
7bd1079ce9 in image share link, return s3 url address of image 2022-04-07 09:11:49 +02:00
Čarodej
ade6b05bd0 codecanyon.html updated 2022-04-07 08:19:26 +02:00
Čarodej
7e0913b363 open searched file from spotlight in FilePreview 2022-04-06 18:17:50 +02:00
Čarodej
736a809e83 open searched file from spotlight in FilePreview 2022-04-06 18:16:07 +02:00
Milos Holba
4379daa079 added infinite scroll in browsing 2022-04-06 17:40:44 +02:00
Čarodej
9a11af3b39 Move item grid to folder bug 2022-04-06 15:22:09 +02:00
Čarodej
4ae4e70fe4 Move item grid to folder bug 2022-04-06 10:55:15 +02:00
Čarodej
657248aa43 The delay after first upload in file request when the interface wasn't showing was removed 2022-04-06 10:35:13 +02:00
Čarodej
b0f1bb46d7 clear howdy file requests in demo account 2022-04-06 09:36:10 +02:00
Čarodej
490fe5a120 readme update 2022-04-06 09:24:29 +02:00
Čarodej
953e7892b7 Wasabi region list updated 2022-04-06 08:32:32 +02:00
Čarodej
34bd1d3a3c language moved 2022-04-05 17:09:34 +02:00
Čarodej
8035ea2b23 feb 2022-04-05 16:47:53 +02:00
Čarodej
993dfc8fa1 updates automatically handled on the background 2022-04-05 16:43:12 +02:00
Čarodej
3649b6b7cf update language strings action added 2022-04-05 14:25:45 +02:00
Čarodej
23fdab0f68 npm upgrade 2022-04-05 11:04:37 +02:00
Čarodej
736174fda7 readme update 2022-04-05 11:03:42 +02:00
Čarodej
4e9c40d7ed delete language transaction in 2.0.14 update 2022-04-05 10:02:24 +02:00
Čarodej
10d8b592ea confirm token in 2fa challenge 2022-04-05 09:52:49 +02:00
Čarodej
9f783fcd95 Added new app settings shortcuts findable by spotlight - Application, Login & Registration, Appearance, Adsense, Homepage, Environment, Server 2022-04-05 08:05:32 +02:00
Čarodej
d386f70be8 set default max team members in admin and setup wizard 2022-04-05 07:47:37 +02:00
Čarodej
2c86c62d7f meta infinite members fix 2022-04-05 07:06:18 +02:00
Čarodej
4e9e8c47c0 language string fix 2022-04-05 06:44:42 +02:00
Čarodej
ba308fa70a item grid sm image 2022-04-04 19:35:14 +02:00
Čarodej
e8a0c421e9 plan import fix 2022-04-04 19:11:35 +02:00
Čarodej
bf6bc17d7d auto plan synchronization 2022-04-04 19:05:02 +02:00
Čarodej
80b2371868 delete only howdy share links in demo mode 2022-04-04 17:49:18 +02:00
Čarodej
3d9272b05e - spotlight mobile fix with opening image 2022-04-04 17:38:22 +02:00
Čarodej
2fa73dc3d2 - set paypal mode in credentials setup 2022-04-04 16:52:50 +02:00
Čarodej
b219c00113 - set paypal mode in credentials setup 2022-04-04 16:48:29 +02:00
Čarodej
c1f775975d - image thumbnail fix in s3
- svg thumbnail fix
2022-04-04 12:58:07 +02:00
Čarodej
a3805b4bff removed pcntl 2022-04-02 20:31:18 +02:00
Čarodej
be37f95404 - Added status column to the fixed plan table
- Ability to delete fixed plan if there isn't any subscribed user
- Improved error handling in subscription module
2022-04-02 17:52:48 +02:00
Čarodej
086dab99cd feb 2022-04-01 17:19:51 +02:00
Čarodej
2d4c7241ef test smtp connection before set up 2022-04-01 17:18:51 +02:00
Čarodej
d4199a796d test s3 connection before set up 2022-04-01 13:01:18 +02:00
Čarodej
e4d44fc5eb Ability to set custom s3 compatible service in administration settings and setup wizard 2022-04-01 11:26:59 +02:00
Čarodej
40b13acbb9 improved email setup 2022-04-01 10:14:50 +02:00
Čarodej
b1160a1327 added pcntl extension to the required 2022-04-01 09:04:21 +02:00
Čarodej
9cfe6118a9 item popup fix 2022-03-31 17:45:03 +02:00
Čarodej
64dbcf287d spatie config notification fix 2022-03-31 17:20:24 +02:00
Čarodej
bfe4c257a2 max_execution_time fix 2022-03-31 16:56:14 +02:00
Čarodej
1615be340a added spinner into dashboard AlertBox.vue 2022-03-31 13:03:29 +02:00
Čarodej
2ce165dd65 feb 2022-03-31 12:08:06 +02:00
Čarodej
c5bfd99df7 fixed demo under envato iframe 2022-03-31 12:04:36 +02:00
Čarodej
182451515c auto delete all shared links every day in demo mode 2022-03-31 11:22:13 +02:00
Čarodej
ff476251f5 .dwg fix 2022-03-31 11:18:09 +02:00
Čarodej
ef9f654834 added chunk size edit to the admin 2022-03-31 10:41:50 +02:00
Čarodej
ab042cc4b3 readme update 2022-03-31 10:09:18 +02:00
Čarodej
3f8fc1c9ce dashboard alert box for new system upgrade 2022-03-30 18:12:41 +02:00
Čarodej
dff804153e upgrade functionality for v2.0.10 fix 2022-03-30 13:43:08 +02:00
Čarodej
d362b37cd3 upgrade functionality for v2.0.10 2022-03-30 13:36:28 +02:00
Čarodej
621f6770c5 demo generator team update 2022-03-30 12:03:31 +02:00
Čarodej
d1d58711c5 disabled moving and deleting folders from root of TeamFolders 2022-03-30 09:56:14 +02:00
Čarodej
36883d1c0d disabled moving and deleting folders from root of TeamFolders 2022-03-30 09:56:09 +02:00
Čarodej
0ca67c2348 - when member upload files or create folder in team folder, the true owner of the content is creator of team member. That means the upload bandwidth and storage go to creator responsibility 2022-03-30 09:34:25 +02:00
Čarodej
0fbb8fd8ee build 2022-03-29 12:30:39 +02:00
Čarodej
b0829c71e9 build 2022-03-29 12:29:32 +02:00
Čarodej
af3f08e728 fixed moving issue when user move folder with files into team folder 2022-03-29 12:28:22 +02:00
Čarodej
32d4873715 disabled 2fa set up in demo mode for howdy account 2022-03-29 10:49:08 +02:00
dependabot[bot]
b8a1390220 Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-29 08:27:02 +00:00
Čarodej
9d4d1ba9aa s3 bandwidth usage fix 2022-03-29 10:06:20 +02:00
Čarodej
8c59501907 - build 2022-03-28 18:40:05 +02:00
Čarodej
ed67927672 unlimited team members text fix 2022-03-28 18:03:38 +02:00
Čarodej
e604c8e4fd text logo fix on shared page 2022-03-28 17:13:41 +02:00
Čarodej
4ea76419db contact form fix 2022-03-28 17:03:30 +02:00
Čarodej
8d13d82af9 removed todo 2022-03-28 16:58:10 +02:00
Čarodej
6ee142b58c user delete fix 2022-03-28 11:49:09 +02:00
Čarodej
5964bebad2 user storage fix 2022-03-28 11:38:05 +02:00
Čarodej
6a48beb793 adsense fix 2022-03-28 10:49:15 +02:00
Čarodej
bbd8e70c9d - s3 direct download 2022-03-25 19:14:32 +01:00
Čarodej
e232543ea4 - language updates 2022-03-25 18:47:12 +01:00
Čarodej
62c6331845 - direct download link 2022-03-25 18:20:27 +01:00
Čarodej
43f2a43d6c - app logo extension fix
- redirect when user is logged in sign in/up page
2022-03-25 16:48:15 +01:00
Čarodej
c5810e962b - download/upload statistics in admin panel fix 2022-03-25 11:36:50 +01:00
Čarodej
d7d95e22ea - share by email fix 2022-03-25 11:10:35 +01:00
Čarodej
8c1e59d81a - bug in demo folder favourites fixed 2022-03-25 10:51:20 +01:00
Čarodej
3c1c6eb5b9 license upgrade function 2022-03-25 10:34:39 +01:00
Čarodej
df05eb0433 s3 configuration fix 2022-03-25 07:38:22 +01:00
Čarodej
bb1d775585 codecanyon text update 2022-03-24 19:18:30 +01:00
Čarodej
7f49ae011c readme update 2022-03-23 19:26:51 +01:00
Čarodej
a608678bb9 plan tables for fixed billing
language translation fix
2022-03-23 19:16:40 +01:00
Čarodej
aa515b5450 deleted some files 2022-03-23 16:57:09 +01:00
dependabot[bot]
87466e4596 Bump node-forge from 1.2.1 to 1.3.0
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.2.1 to 1.3.0.
- [Release notes](https://github.com/digitalbazaar/forge/releases)
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.2.1...v1.3.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-22 18:48:10 +00:00
Čarodej
3f01dd3f95 s3 multipart upload fix 2022-03-22 19:25:38 +01:00
Čarodej
5531be6640 - language fix
- move item popup fix
2022-03-21 11:56:31 +01:00
Čarodej
1d144d6c9e notification mobile fix 2022-03-21 09:38:15 +01:00
Čarodej
b043878eed chunk upload fix 2022-03-21 09:35:13 +01:00
Čarodej
a2d0b26b68 language fix 2022-03-21 08:34:59 +01:00
Čarodej
381a440c61 codecanyon images 2022-03-20 22:10:45 +01:00
Čarodej
95efdc3993 changelog 2022-03-20 21:41:55 +01:00
Čarodej
dece343d8b composer update 2022-03-20 19:20:35 +01:00
Čarodej
5d15f3da51 build 2022-03-20 19:02:34 +01:00
Čarodej
42245317f4 fixes 2022-03-20 19:00:46 +01:00
Čarodej
73ef6e6c1f backend language strings updates 2022-03-20 14:26:53 +01:00
Čarodej
881facc867 language strings updates 2022-03-20 12:12:09 +01:00
Čarodej
98d9f3ab0d language strings refactoring 2022-03-19 10:14:11 +01:00
Čarodej
7564c01fa3 removed unused language strings 2022-03-19 09:26:43 +01:00
Čarodej
1ad8fbdd57 alert icon in mobile menu 2022-03-18 07:21:33 +01:00
Čarodej
10f37e645b alert icon in mobile menu 2022-03-17 18:31:10 +01:00
Čarodej
ca883a6f93 server status fix 2022-03-17 17:54:04 +01:00
Čarodej
0d59fe5b8e composer update 2022-03-17 16:58:16 +01:00
Čarodej
fea2d839e7 fakeRenameFileOrFolder fixes 2022-03-17 16:52:58 +01:00
Čarodej
0c334f5daf fakeRenameFileOrFolder fixes 2022-03-17 14:43:46 +01:00
Čarodej
87bcd50e44 SetUploadRequestAsFilledController demo fix 2022-03-17 14:36:29 +01:00
Čarodej
01588fa06b - admin registration fixes
- alert popup refactoring
2022-03-17 12:31:09 +01:00
Čarodej
e8f59ef0a9 fixes 2022-03-17 10:06:29 +01:00
Čarodej
9c040cfe48 folder creation fix 2022-03-17 09:38:49 +01:00
Čarodej
4b899d8f29 composer fix 2022-03-16 17:25:45 +01:00
Čarodej
e8c3fd74b1 added AdminBonusAddedNotification.php and InsufficientBalanceNotification.php 2022-03-16 17:22:55 +01:00
Čarodej
1d1e6823c7 added AdminBonusAddedNotification.php and InsufficientBalanceNotification.php 2022-03-16 11:45:08 +01:00
Čarodej
bc197cbb5e added SubscriptionWasCreatedNotification 2022-03-16 11:08:57 +01:00
Čarodej
9a6abbd6e8 added BillingAlertTriggeredNotification 2022-03-16 10:37:55 +01:00
Čarodej
60407f9dce cron indicator improvement 2022-03-16 09:50:49 +01:00
Čarodej
9d955799d3 set broadcasting in admin and setup wizard 2022-03-16 09:37:17 +01:00
Čarodej
4bab179e17 feb 2022-03-15 18:04:26 +01:00
Čarodej
aa5742dafa dark mode logo 2022-03-15 18:03:28 +01:00
Čarodej
f6f4184fb2 barchart center fix 2022-03-15 16:51:33 +01:00
Čarodej
f6ea18fce2 - admin form fix
- backblaze new region
- webhook url new place
2022-03-15 16:39:17 +01:00
Čarodej
a544578b38 backspace fix 2022-03-15 11:47:32 +01:00
Čarodej
5fa205de27 Revert "removed backspace functionality for team folder and sharedwithme homepage"
This reverts commit dfeef6fd
2022-03-15 11:47:16 +01:00
Čarodej
806af9da5c space between mobilemultiselect toolbar 2022-03-15 11:40:57 +01:00
Čarodej
dfeef6fdf8 removed backspace functionality for team folder and sharedwithme homepage 2022-03-15 11:21:14 +01:00
Čarodej
d0b4b729c9 hide overlays by esc shortcut 2022-03-15 10:59:38 +01:00
Čarodej
1c4b4c6279 - fixed create menu items
- reload team folder after update team member
2022-03-15 10:39:43 +01:00
Čarodej
556f6d0813 fixed uploaded image default rotation 2022-03-15 09:08:54 +01:00
Čarodej
3f4263393e file preview fix 2022-03-15 08:35:16 +01:00
Čarodej
a51dece5ee - readme update
- command update
2022-03-14 18:16:50 +01:00
Čarodej
a7db1a22d2 installation release image 2022-03-14 11:41:43 +01:00
Čarodej
ee80f454fb readme update 2022-03-14 11:15:44 +01:00
Čarodej
2c4175b708 check write permission added into setup wizard and server status 2022-03-14 10:51:19 +01:00
Čarodej
fe3fbe7db7 UI Fixes part III. 2022-03-14 10:10:23 +01:00
Čarodej
3c35ea9a4e UI Fixes part II. 2022-03-14 09:02:40 +01:00
Čarodej
f835c6a7c2 UI Fixes 2022-03-14 08:45:26 +01:00
Čarodej
5e48af22a2 setup wizard debug 2022-03-13 18:30:03 +01:00
Čarodej
2bba6dc051 added registration bonus notification 2022-03-12 09:34:26 +01:00
Čarodej
ab03b471f7 click outside of notification center hide notification popup 2022-03-12 09:10:34 +01:00
Čarodej
9e973b89ce notification implementation into the toaster 2022-03-12 08:40:35 +01:00
Čarodej
0e45092795 pusher update 2022-03-11 12:56:18 +01:00
Čarodej
c1ace2854f pusher update 2022-03-11 09:27:56 +01:00
Čarodej
4e471cb077 pusher update 2022-03-11 09:21:15 +01:00
Čarodej
ffa4f67cbd feb 2022-03-11 09:17:53 +01:00
Čarodej
8e4fc55b23 feb 2022-03-11 09:11:20 +01:00
Čarodej
ee516fd384 added wss 2022-03-11 09:09:46 +01:00
Čarodej
da27c47d7a pusher host setup 2022-03-11 08:58:54 +01:00
Čarodej
28d99cce78 pusher host fix 2022-03-11 08:43:41 +01:00
Čarodej
0905a0660c - demo notifications generator
- frontend build
2022-03-11 08:40:32 +01:00
Čarodej
d02ca13197 - demo notifications generator
- frontend build
2022-03-10 16:45:18 +01:00
Čarodej
9ae2d54a5e team invitation notification with broadcasting 2022-03-10 16:23:13 +01:00
Čarodej
64e80d387b backend notifications implementation 2022-03-10 11:49:02 +01:00
Čarodej
70d7f2f5bd Merge remote-tracking branch 'origin/sockets'
# Conflicts:
#	composer.lock
#	public/mix-manifest.json
2022-03-10 07:14:08 +01:00
Čarodej
4315cddcb2 extended UploadRequestFulfilledNotification with array 2022-03-10 07:13:38 +01:00
Čarodej
26f7cdb80f added notification center UI 2022-03-10 06:27:04 +01:00
Čarodej
8495ed5422 websocket implementation 2022-03-09 07:40:05 +01:00
Čarodej
2a0b01e888 chunkFilename added 2022-03-08 11:50:15 +01:00
Čarodej
6ebf5dc3cb added file request MobileContextMenu 2022-03-08 11:45:36 +01:00
Čarodej
dd1f3b299d ability to download log from admin 2022-03-08 10:51:32 +01:00
Čarodej
4e2155b75a set storage driver via admin 2022-03-08 09:42:18 +01:00
Čarodej
c0ca83193f prematurely 2fa switched before 2fa was set fix 2022-03-08 08:51:31 +01:00
Čarodej
08175d4dba image changes 2022-03-07 17:43:43 +01:00
Čarodej
e6043e4530 fixed avatar 2022-03-07 16:49:34 +01:00
Čarodej
bf62c007ac Merge remote-tracking branch 'origin/master'
# Conflicts:
#	codecanyon.html
2022-03-07 16:48:28 +01:00
Čarodej
1cf50206cb demo images 2022-03-07 16:48:01 +01:00
Čarodej
9bc0ce3c3d demo images 2022-03-07 11:24:22 +01:00
Čarodej
2fa0b5cd77 extended teams demo 2022-03-07 10:31:37 +01:00
Čarodej
241190104e subscription repository update 2022-03-06 10:13:04 +01:00
Čarodej
23054c2257 dark mode revision 2022-03-06 09:25:11 +01:00
Čarodej
1e4649eec2 demo functions refactoring 2022-03-05 18:09:53 +01:00
Čarodej
81f227c5e7 added callback url to the socialite settings 2022-03-05 16:55:02 +01:00
Čarodej
5829eaacc4 removed SocialiteCallback.vue 2022-03-05 11:35:17 +01:00
Čarodej
e0e488860d socialite fix 2022-03-05 11:18:53 +01:00
Čarodej
2c90db8e04 credentials settings fix 2022-03-05 10:15:50 +01:00
Čarodej
0a30ca0b98 create new subscription if stripe was previously cancelled 2022-03-05 09:35:42 +01:00
Čarodej
ae138bb4d4 swap stripe subscription 2022-03-04 18:51:06 +01:00
Čarodej
ad5b741feb paystack refactoring 2022-03-04 13:37:28 +01:00
Čarodej
cad1a1680c paystack refactoring 2022-03-04 13:36:28 +01:00
Čarodej
0f6dd0304f auto redirect 2022-03-04 12:25:46 +01:00
Čarodej
2724fb1873 fb 2022-03-04 11:50:54 +01:00
Čarodej
0f4b80ddac upgrade subscription popup 2022-03-04 11:35:38 +01:00
Čarodej
6155173d82 fb 2022-03-03 17:32:45 +01:00
Čarodej
6ca2269c80 fixes part 6 2022-03-03 07:37:28 +01:00
Čarodej
4b751a29c2 env variables refactoring 2022-03-02 10:43:27 +01:00
Čarodej
ff9198a03e frontend build 2022-03-02 09:02:11 +01:00
Čarodej
0c0a2424b7 frontend build 2022-03-02 07:47:10 +01:00
Čarodej
a3abfd670a fixes part 5 2022-03-02 07:43:20 +01:00
Čarodej
90303458a0 fixes part 4 2022-03-01 18:04:36 +01:00
Čarodej
3f0a69a062 fixes part 3 2022-03-01 11:35:01 +01:00
Čarodej
a303ffffdc fixes part 2 2022-03-01 10:15:50 +01:00
Čarodej
64d1883f53 fixes part 1 2022-03-01 08:24:51 +01:00
Čarodej
071bdc1bcd file request language strings added 2022-02-28 18:25:18 +01:00
Čarodej
30025271c2 toggle favourites refactor 2022-02-28 17:38:18 +01:00
Čarodej
8ae24a9a6e multi email input refactoring 2022-02-28 17:06:41 +01:00
Čarodej
dee1614297 transaction date fix 2022-02-28 09:08:51 +01:00
Čarodej
c2e4b50df5 fixed missing days and sorting in traffic widget 2022-02-28 09:03:57 +01:00
Čarodej
2e80da830a file metadata refactoring 2022-02-28 07:26:35 +01:00
Čarodej
c84850e8d2 Merge remote-tracking branch 'origin/exif_metadata'
# Conflicts:
#	public/mix-manifest.json
#	resources/js/App.vue
#	resources/js/components/FilesView/ImageMetaData.vue
#	resources/js/components/FilesView/InfoSidebar.vue
#	resources/js/components/FilesView/SearchBar.vue
#	resources/js/components/Spotlight/Spotlight.vue
#	resources/js/views/Shared.vue
#	src/Domain/Files/Resources/FileResource.php
2022-02-25 18:23:08 +01:00
Čarodej
6fd8ddf680 FileResource.php refactor 2022-02-25 18:12:14 +01:00
Čarodej
ab3a307dc1 Laravel 9 upgrade 2022-02-25 17:37:17 +01:00
Čarodej
c3a6f5d703 UI enhancements for file request 2022-02-25 09:42:55 +01:00
Čarodej
293eb679fa - added file request into the spotlight
- after enter stop editing item name
2022-02-25 08:35:21 +01:00
Čarodej
45dcdcce16 added email notification about fulfilling upload request 2022-02-24 10:43:35 +01:00
Čarodej
a589ee5f7a browsing through upload request 2022-02-24 10:20:38 +01:00
Čarodej
06b28aeee3 file preview optimization for upload request 2022-02-23 16:43:20 +01:00
Čarodej
047b907c60 it move file to another folder in upload request 2022-02-23 11:13:29 +01:00
Čarodej
eb7b319ebd get navigation tree for upload request 2022-02-23 10:39:50 +01:00
Čarodej
aef715e061 delete items in file request 2022-02-23 10:05:09 +01:00
Čarodej
fdfb5f57d7 create folder in upload request 2022-02-23 08:26:16 +01:00
Čarodej
0501e3e3d5 Rename upload request item 2022-02-23 07:53:34 +01:00
Čarodej
efb0fc4734 InfoSidebarUploadRequest for upload request 2022-02-23 06:53:29 +01:00
Čarodej
f15c81d342 auto expiration after latest upload 2022-02-22 16:41:17 +01:00
Čarodej
6feadfd188 auto expiration for upload request 2022-02-22 11:53:51 +01:00
Čarodej
ee67b8050d mobile file request 2022-02-22 11:36:28 +01:00
Čarodej
c3398f0da4 finish file request 2022-02-22 09:35:06 +01:00
Čarodej
171ee5fa04 security of request upload item 2022-02-19 12:49:56 +01:00
Čarodej
1107bf66af upload file into request folder and get their thumbnails 2022-02-19 12:32:19 +01:00
Čarodej
5be55b52bd create folder after upload first file 2022-02-18 09:32:19 +01:00
Čarodej
6db8b0662a create/get upload request backend 2022-02-17 16:55:35 +01:00
Čarodej
45a3b5415b create/get upload request backend 2022-02-17 10:11:43 +01:00
Čarodej
394a7b6baf upload request prototype UI 2022-02-16 16:57:57 +01:00
Čarodej
3fafc811fe UI Fixes 4 2022-02-15 18:30:58 +01:00
Čarodej
5ee77da25f UI Fixes 2 2022-02-15 17:39:59 +01:00
Čarodej
421388b360 UI Fixes 2022-02-15 16:08:12 +01:00
dependabot[bot]
8828432e4d Bump follow-redirects from 1.14.7 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-15 10:02:43 +00:00
Čarodej
820f0b3890 latest database backups included into the admin settings 2022-02-15 10:40:59 +01:00
Čarodej
b897eaf482 server status included into the admin settings 2022-02-15 09:33:53 +01:00
Čarodej
da74a38605 invitation fix 2022-02-14 08:54:26 +01:00
Čarodej
00c6562719 handle team invitation for non registered user 2022-02-12 11:28:08 +01:00
Čarodej
4498461e70 none billing app fixes 2022-02-12 09:16:36 +01:00
Čarodej
948c7453a6 fixed billing app fixes 2022-02-11 17:25:39 +01:00
Čarodej
eb948f9000 metered billing app fixes 2022-02-11 17:02:17 +01:00
Čarodej
3fd43936e7 improved email setup in admin settings 2022-02-11 10:52:14 +01:00
Čarodej
03730b80c0 setup wizard funcionality upgrade for v2 2022-02-11 10:05:12 +01:00
Čarodej
3867c9cd67 admin creation via setup wizard refactoring 2022-02-10 09:06:47 +01:00
Čarodej
b5c00e98df email setup test 2022-02-10 08:57:47 +01:00
Čarodej
9f5172da85 added multiple email drivers into setup wizard 2022-02-09 16:17:31 +01:00
Čarodej
a6940379cb setup wizard refactoring 2022-02-09 14:04:51 +01:00
Čarodej
a9e4daed35 UI enhancements 2022-02-09 08:40:28 +01:00
Čarodej
e7d9fca9c2 contextmenu fix 2022-02-08 18:12:07 +01:00
Čarodej
638a1a9a72 video preview in shared single page 2022-02-08 17:34:07 +01:00
Čarodej
4df575f5e9 Shared pages refactoring part 3 2022-02-08 14:25:28 +01:00
Čarodej
7b0f9a19de Shared pages refactoring part 2 2022-02-08 12:58:47 +01:00
Čarodej
f04c057490 Shared pages refactoring part 1 2022-02-08 10:01:38 +01:00
Čarodej
09774b1d48 Google adsense implementation 2022-02-07 17:47:29 +01:00
Čarodej
81362fef2d pdfvuer resolve 2022-02-06 15:43:26 +01:00
Čarodej
58fae35085 drag ui refactoring 2022-02-06 14:56:11 +01:00
Čarodej
21e184f373 resolved timezones 2022-02-06 14:26:42 +01:00
Čarodej
38e86b4b8b UI fixes 2022-02-05 12:30:02 +01:00
Čarodej
6980c28c57 ad test 2022-02-04 14:25:26 +01:00
Čarodej
e794ef5c17 ad test 2022-02-04 11:20:40 +01:00
Čarodej
f8317e761b frontend build 2022-02-04 10:58:24 +01:00
Čarodej
5a28eeef1e UI improvements 3 2022-02-03 18:50:12 +01:00
Čarodej
cad8c31422 UI improvements 2 2022-02-03 18:19:10 +01:00
Čarodej
78f69ca816 UI improvements 2022-02-03 11:58:52 +01:00
Čarodej
bb9280d050 File preview refactoring 2022-02-03 10:49:14 +01:00
Čarodej
b751429dc5 UI/UX improvements 2022-02-01 16:01:57 +01:00
Milos Holba
45a46bbc65 added windows shortcut for spotlight 2022-02-01 14:21:12 +01:00
Čarodej
b38b532cbe added prettier 2022-02-01 12:21:38 +01:00
Čarodej
5ae875233b tailwind 3 upgrade part 4 2022-02-01 11:36:25 +01:00
Milos Holba
2ca42f530b addded test for save file exif metadata 2022-01-29 12:48:21 +01:00
Čarodej
dcba1e8407 tailwind 3 upgrade part 3 2022-01-28 16:32:01 +01:00
Čarodej
854ae6d8fd tailwind 3 upgrade part 2 2022-01-28 13:48:42 +01:00
Čarodej
940a2de13d tailwind 3 upgrade part 1 2022-01-28 11:41:13 +01:00
Čarodej
42c2ffc274 UI improvements part 5 2022-01-28 09:17:36 +01:00
Čarodej
0c71329dee UI improvements part 4 2022-01-28 08:15:25 +01:00
Čarodej
f74bb7cec5 UI improvements part 3 2022-01-27 17:04:12 +01:00
Čarodej
d855739bf2 UI improvements part 2 2022-01-27 13:14:57 +01:00
Čarodej
a2726ae2c5 UI improvements part 1 2022-01-27 10:40:06 +01:00
Čarodej
0b3fc946bd fixed navigation for mobile version 2022-01-26 18:28:19 +01:00
Milos Holba
d16d73680f create separated exif metadata table for files 2022-01-26 17:42:01 +01:00
Čarodej
438e930e06 create token UI refactoring 2022-01-26 16:59:36 +01:00
Čarodej
737fb7f32f login & registration settings refactoring 2022-01-26 16:35:45 +01:00
Čarodej
e22ae97a87 responsive version enhancements 2022-01-26 11:43:49 +01:00
Čarodej
fb91c1883a datatable refactoring 2022-01-26 10:39:10 +01:00
Čarodej
3652c64738 mobile toolbar implementation 2022-01-26 07:45:22 +01:00
Čarodej
3d32e8f7e0 Merge remote-tracking branch 'origin/recaptcha'
# Conflicts:
#	public/mix-manifest.json
#	src/Domain/Settings/Controllers/StoreSocialServiceCredentialsController.php
2022-01-25 16:29:37 +01:00
Čarodej
995319cfe5 updates 2022-01-25 16:27:45 +01:00
Milos Holba
1085062d10 recaptcha fix 2022-01-25 14:33:34 +01:00
Milos Holba
8b1a3f0476 implemented reCaptcha 2022-01-25 14:28:22 +01:00
Čarodej
630cefee41 Folder buttons UI refactoring 2022-01-25 13:39:21 +01:00
Čarodej
5725753052 CreateFolderStructureAction refactoring 2022-01-25 10:55:48 +01:00
Čarodej
ec92295fbf CreateFolderStructureAction refactoring 2022-01-24 11:20:47 +01:00
Čarodej
87dbcbceb8 test refactoring 2022-01-24 09:25:32 +01:00
Čarodej
3677e51c8f merge fixes 2022-01-24 08:35:58 +01:00
Čarodej
4396965d4d Merge remote-tracking branch 'origin/folders_upload' into folder_upload_v2
# Conflicts:
#	composer.lock
#	config/language-translations.php
#	public/mix-manifest.json
#	resources/js/components/FilesView/DesktopToolbar.vue
#	resources/js/helpers.js
#	resources/js/store/modules/fileFunctions.js
#	src/Domain/Files/Actions/UploadFileAction.php
#	src/Domain/Files/Requests/UploadRequest.php
#	tests/Domain/Admin/AdminTest.php
#	tests/Domain/Files/FileTest.php
#	tests/Domain/Folders/FolderTest.php
#	tests/Domain/Sharing/VisitorManipulatingTest.php
#	tests/Domain/Traffic/TrafficTest.php
#	tests/Domain/Trash/TrashTest.php
#	tests/Domain/Zip/UserZippingTest.php
2022-01-24 08:05:04 +01:00
Čarodej
4319533873 refactoring 2022-01-24 07:25:38 +01:00
Čarodej
1c16f0001c MobileActionButton refactoring 2022-01-23 11:05:53 +01:00
Čarodej
1f48abae0f mobile navigation refactoring 2022-01-22 14:27:21 +01:00
Čarodej
a7fd410a68 popup header refactoring 2022-01-22 14:05:22 +01:00
Čarodej
f5e45126db confirmation popup refactoring 2022-01-22 13:43:24 +01:00
Čarodej
fc74682e62 contextmenu refactoring 2022-01-22 13:23:57 +01:00
Čarodej
26bf65af88 info sidebar refactoring 2022-01-22 12:31:27 +01:00
Čarodej
ba05cdde83 Sidebar desktop navigation refactoring 2022-01-21 18:23:27 +01:00
Čarodej
e2cfdd5345 Folder tree dynamic navigator 2022-01-21 16:46:17 +01:00
Čarodej
6cb2a1bb9a popover over bar chart 2022-01-21 10:48:57 +01:00
Čarodej
aa28118d75 refactoring 2022-01-21 09:55:11 +01:00
Čarodej
c2667ab481 confirm password when 2fa setup refactored 2022-01-21 09:43:11 +01:00
Čarodej
03e4f98ad6 confirm password to get recovery codes 2022-01-21 09:23:18 +01:00
Čarodej
4fc61afc11 added current password to the password changing form 2022-01-21 07:41:26 +01:00
Čarodej
6b71eabfa2 UI setup for emojis and theme mode 2022-01-20 17:05:48 +01:00
Čarodej
bb4f66f159 account settings refactoring 2022-01-20 10:51:24 +01:00
Čarodej
7f33df62a5 toggle emoji via spotlight 2022-01-20 10:08:30 +01:00
Čarodej
e1de316774 emoji component refactoring 2022-01-20 09:19:14 +01:00
Čarodej
34fcbdc55c create folder emoji picker refactoring 2022-01-19 15:45:59 +01:00
Čarodej
24edb85b24 Merge remote-tracking branch 'origin/master' 2022-01-19 14:04:38 +01:00
Čarodej
1342dfa20f emoji picker refactoring 2022-01-19 14:04:29 +01:00
MakingCG
5adf9bd2be Fix backend code styling 2022-01-19 08:01:36 +00:00
Čarodej
ea59624091 Merge remote-tracking branch 'origin/master' 2022-01-19 09:01:05 +01:00
Čarodej
89e886b40c qr code generator 2022-01-19 09:00:54 +01:00
Čarodej
09449539fa Popups refactoring 2022-01-19 08:21:32 +01:00
Čarodej
c711150793 ShareEditPopup refactoring 2022-01-19 08:05:33 +01:00
Čarodej
509fb32c81 update shared item fix 2022-01-18 16:56:28 +01:00
MakingCG
763e63db55 Fix backend code styling 2022-01-18 15:46:38 +00:00
Čarodej
b456a562a0 sing up forms refactoring 2022-01-18 16:43:50 +01:00
Čarodej
148f5982a9 sing in forms refactoring 2022-01-18 11:18:33 +01:00
Čarodej
59414a1e31 paginator refactor 2022-01-18 09:18:59 +01:00
Čarodej
ffebe7fecc Invoice page 2022-01-18 08:28:58 +01:00
Čarodej
2403f89ca3 show transaction usage history detail 2022-01-17 13:30:44 +01:00
Čarodej
97b429f8d1 readme update 2022-01-17 10:17:46 +01:00
Čarodej
ec83c0e018 added WidgetLatestTransactions 2022-01-14 17:39:42 +01:00
Čarodej
51701214a2 toggle paypal sandbox/live 2022-01-14 11:55:14 +01:00
Čarodej
7dd116a769 splitted user name 2022-01-14 11:17:00 +01:00
Čarodej
7e9e9ee25b Allow user pay only more than their debt 2022-01-14 10:18:51 +01:00
Čarodej
662ba988a0 build 2022-01-14 09:30:59 +01:00
Čarodej
5c59296724 fixes & UI improvements 3 2022-01-14 09:28:27 +01:00
Čarodej
703a49711c fixes & UI improvements 2 2022-01-14 09:10:41 +01:00
Čarodej
1d0ba4d679 fixes & UI improvements 2022-01-14 08:50:59 +01:00
Čarodej
ceba8f5cc1 fixes 2022-01-13 18:55:10 +01:00
Čarodej
8eff3969d3 empty states for pages 2022-01-13 18:13:34 +01:00
Čarodej
7b3bd1135c UI fixes 2022-01-13 17:32:33 +01:00
Čarodej
e77e0cda03 set webhook secret for payment services 2022-01-13 16:16:39 +01:00
Čarodej
8d67d089bf create plan fix 2022-01-13 12:25:50 +01:00
Čarodej
d4220254db frontend production 2022-01-13 12:22:40 +01:00
Čarodej
4fa93512b5 frontend production 2022-01-13 11:43:04 +01:00
Čarodej
66de377657 test refactoring 2022-01-13 11:41:40 +01:00
Čarodej
6cf7e5d26d refactor 2022-01-13 11:17:31 +01:00
Čarodej
3b34dc43ce refactor 2022-01-12 18:32:39 +01:00
Čarodej
d498446911 admin bar chart fix 2022-01-12 16:11:51 +01:00
Čarodej
4feba76f57 admin dashboard refactoring 2022-01-12 13:58:51 +01:00
Čarodej
e1bb4b2cbe mobile admin menu refactoring 2022-01-12 08:28:12 +01:00
Čarodej
53a2950dd3 Admin menu refactored 2022-01-12 07:45:33 +01:00
Čarodej
68563b9e10 Plan settings refactoring 2022-01-11 15:20:33 +01:00
Čarodej
1c188081b3 - set social login credentials
- disallow registration refactoring
2022-01-11 13:22:25 +01:00
Čarodej
62cbcd14ed ghost bar chart 2022-01-11 08:27:07 +01:00
Čarodej
9dbc3ab969 UI improvements 2022-01-11 07:27:15 +01:00
Čarodej
ca48d430bb added subscription demo generators 2022-01-10 16:29:44 +01:00
Čarodej
08139c8f96 - usage metric fix
- ui fix
- index:usage artisan command
- demo payment settings
2022-01-10 15:43:55 +01:00
Čarodej
5de2b8b0e0 credit bonus after user registration 2022-01-10 11:20:34 +01:00
Čarodej
26aa8b46df it_register_user_when_metered_billing_is_active 2022-01-10 10:20:13 +01:00
Čarodej
0d8f1b64a7 login refactor 2022-01-10 09:09:20 +01:00
Čarodej
ead4f65e1a refactor 2022-01-10 08:31:44 +01:00
Čarodej
8a64fe070b Merge remote-tracking branch 'origin/social_authentication' into subscription
# Conflicts:
#	.env.example
#	composer.lock
#	public/mix-manifest.json
#	resources/js/views/User/Password.vue
#	routes/api.php
#	src/App/Users/Actions/CreateNewUserAction.php
#	tests/App/Users/UserAccountTest.php
2022-01-10 07:38:56 +01:00
Milos Holba
f017be476f refactoring v1 2022-01-08 14:36:57 +01:00
Čarodej
0b5fcfe676 payment logo implementation 2022-01-07 17:36:39 +01:00
Čarodej
a2e6a3bd2f subscription Type Change via admin 2022-01-07 16:51:08 +01:00
Čarodej
e823e57c71 CopyShareLink.vue refactoring dark mode 2022-01-07 16:32:37 +01:00
Čarodej
a113fffbf0 CopyShareLink.vue refactoring 2022-01-07 16:26:54 +01:00
Čarodej
10c25cf9d5 CopyInput.vue refactoring 2022-01-07 13:49:00 +01:00
Čarodej
6a957fa9fc Payment setting frontend part 3 - added paypal 2022-01-07 13:29:06 +01:00
Čarodej
5d2071ea91 Payment setting frontend part 3 - added paystack 2022-01-07 13:06:54 +01:00
Čarodej
e892e0e94f Payment setting frontend part 2 - payment setup front/backend 2022-01-07 12:42:47 +01:00
Čarodej
8b7a80e10d Payment setting frontend part 1 2022-01-07 09:53:59 +01:00
Čarodej
86dac75071 added Toggle Grid/List View into the spotlight 2022-01-06 15:05:45 +01:00
Čarodej
31ec9b4fda context menu fix 2022-01-06 14:35:11 +01:00
Čarodej
21b838eda4 popover fix 2022-01-06 14:17:20 +01:00
Čarodej
e5e713659e Frontend upload restrict consolidation 2022-01-06 12:24:27 +01:00
Čarodej
8d53ed1531 - Frontend restriction shared page 2022-01-06 11:05:49 +01:00
Čarodej
05f6023053 - Frontend restriction alerts 2022-01-05 18:57:02 +01:00
Čarodej
29a954e21b - Refactoring
- Download restriction
2022-01-05 18:29:07 +01:00
Čarodej
ec29764c3f - Restrictions for team folders 2022-01-05 17:52:08 +01:00
Čarodej
b4887cea0e - Restriction UI warning
- create folder restriction
- fixed UI bugs
2022-01-05 12:48:07 +01:00
Čarodej
c7c11fe5b9 Limitation API skelet with can upload tests 2022-01-05 11:20:57 +01:00
Čarodej
49c6f25acb UI improvements 3 2022-01-04 06:47:59 +01:00
Čarodej
3b4085f0ca UI improvements 2 2022-01-03 17:27:39 +01:00
Čarodej
09d8b84870 Subscription UI refactoring 2022-01-03 16:18:36 +01:00
Čarodej
9d189b3d12 upgrade plan UI improvements 2022-01-03 11:14:27 +01:00
Čarodej
2363592dcd full screen mode 2021-12-31 14:11:10 +01:00
Čarodej
22733619d1 Socialite callback test 2021-12-31 12:23:44 +01:00
Čarodej
4ab5e17068 translation update 2021-12-30 16:05:18 +01:00
Čarodej
50abdc3266 transaction UI refactoring 2021-12-30 15:42:09 +01:00
Čarodej
6f5b3c05ad List failed payments 2021-12-30 15:25:34 +01:00
Čarodej
aa8851aacb refactoring 2021-12-30 11:03:57 +01:00
Čarodej
0cc3285ee9 delete credit card 2021-12-29 11:19:27 +01:00
Čarodej
6ec3c88690 list credit card in metered billing 2021-12-29 10:24:49 +01:00
Čarodej
88948af6d9 - credit/card refactoring 2021-12-28 19:06:16 +01:00
Čarodej
da69898051 - set payment card frontend 2021-12-28 17:08:10 +01:00
Čarodej
47e834c368 - register stripe payment method 2021-12-28 16:26:12 +01:00
Čarodej
0194e546fd - transaction type for metered billing in transaction tables 2021-12-23 17:12:51 +01:00
Čarodej
f88ed999c5 - process single charge 2021-12-23 13:07:41 +01:00
Čarodej
606765561d - charge members 2021-12-22 18:45:07 +01:00
Čarodej
b1cb7be678 - Create/Update metered billing plan 2021-12-22 09:05:15 +01:00
Čarodej
6bb7789232 - Flat fee implementation
- Fixed/Metered plan pages
2021-12-21 17:28:17 +01:00
Čarodej
60b34e53a3 - Storage, users page refactoring 2021-12-21 13:49:37 +01:00
Čarodej
f5e182baf6 format 2021-12-21 10:34:15 +01:00
Čarodej
dc0dedffea Merge remote-tracking branch 'origin/thumbnails_queue' into subscription
# Conflicts:
#	public/mix-manifest.json
#	src/Domain/Files/Models/File.php
#	webpack.mix.js
2021-12-21 10:33:05 +01:00
Čarodej
56a5bfd483 refactoring 2021-12-21 10:26:45 +01:00
Čarodej
534d474307 fixes 2021-12-21 09:15:47 +01:00
Milos Holba
22ae148a22 added socialite provider for the user 2021-12-20 15:15:05 +01:00
Čarodej
e5a2be112b update/delete billing alert 2021-12-18 16:52:11 +01:00
Čarodej
401b511b40 showing storage size refactoring 2021-12-17 11:23:02 +01:00
Čarodej
afb8323541 set/update/delete billing alert 2021-12-17 10:44:50 +01:00
Čarodej
04e46b7fcb tests fix 2021-12-17 08:36:32 +01:00
Milos Holba
f37c4f62b7 create Socialite Login/Register 2021-12-16 14:07:33 +01:00
Čarodej
27753f30ad format usage estimates refactoring & test 2021-12-16 13:44:36 +01:00
Čarodej
b4dfbd1623 Balance & Estimates backend implementation 2021-12-15 17:52:01 +01:00
Čarodej
b368d56bbc - balance implementation
- invoice refactoring
2021-12-15 11:24:41 +01:00
Čarodej
6cb3503870 metered subscription page 2021-12-15 10:53:59 +01:00
Čarodej
bb7831f717 credit usage fe implementation mobile 2021-12-15 08:54:48 +01:00
Čarodej
43738bf8db - SidebarNavigation refactored
- credit usage fe implementation
2021-12-15 08:38:44 +01:00
Čarodej
d8a33703ab filter suggestions 2021-12-14 17:59:22 +01:00
Čarodej
86eee2f533 spotlight functions indexing 2021-12-14 17:14:02 +01:00
Čarodej
342d07126a spotlight page indexing 2021-12-14 16:02:50 +01:00
Čarodej
5439ba1aae spotlight tweaks 2021-12-14 13:54:01 +01:00
Čarodej
42487d43f1 actions implementation for spotlight 2021-12-14 12:00:25 +01:00
Čarodej
9275487cfa record daily usage 2021-12-10 16:37:00 +01:00
Čarodej
26f367031e updated transaction tables 2021-12-10 11:00:30 +01:00
Milos Holba
e645eebc4d move create folder structure to new action 2021-12-09 12:49:38 +01:00
Milos Holba
5382da0b1f add image width variable to generation thumbnail queue action 2021-12-08 18:50:27 +01:00
Milos Holba
c6b4a767da fix thumbnail generation mutated data 2021-12-08 12:25:20 +01:00
Čarodej
78a6cf0c92 update payments constraints for UI 2021-12-07 08:09:52 +01:00
Čarodej
9e4de3657e spotlight action concept 2021-12-06 06:50:31 +01:00
Čarodej
2d0a166ad7 spotlight action concept 2021-12-06 06:33:32 +01:00
Čarodej
17a40ea808 stripe checkout button 2021-12-05 14:22:01 +01:00
Čarodej
0179dcb068 stripe logo added 2021-12-02 16:14:23 +01:00
Milos Holba
7d685fa166 thumbnail generation refectoring 2021-12-01 22:25:58 +01:00
Čarodej
8242ba860f traffic sorting 2021-12-01 15:13:02 +01:00
Čarodej
dd3e477593 added search button for users admin page 2021-12-01 09:42:47 +01:00
Čarodej
b08662b307 spotlight ability to search users with 'u ' keyword 2021-12-01 09:19:51 +01:00
Čarodej
de047f7dd8 record daily traffic instead of monthly 2021-11-30 17:57:00 +01:00
Čarodej
ca257ae113 - set default_max_team_member
- generate traffic for all users
2021-11-30 17:46:21 +01:00
Čarodej
c7c81dda34 get data from dataabse and upload/download storage chart 2021-11-30 17:32:25 +01:00
Milos Holba
e5322d6c2e delete from TrashTest old thumbnail test 2021-11-30 16:23:06 +01:00
Milos Holba
067c123aa8 make queue for thumbnails generation 2021-11-30 15:49:33 +01:00
Čarodej
751ebcb7eb upload/download storage chart 2021-11-30 10:53:09 +01:00
Čarodej
69e167a337 update payments method for subscription 2021-11-30 09:01:47 +01:00
Čarodej
7f0d00017f feb 2021-11-29 10:34:02 +01:00
Čarodej
d80fa81f36 feb 2021-11-29 10:25:51 +01:00
Čarodej
fa3cb93b19 sorting datatables 2021-11-29 08:01:12 +01:00
Čarodej
5d4486a4ad progress line refactoring 2021-11-29 06:49:31 +01:00
Čarodej
8456aaf01e frontend validation of team members limitation 2021-11-26 16:44:23 +01:00
Čarodej
459087337c team members limitation frontend/backend 2021-11-26 10:53:30 +01:00
Čarodej
5626a054da refactoring 2021-11-26 07:48:38 +01:00
Čarodej
64e8bccb31 - user subscribe deletion
- fixes
2021-11-26 06:57:16 +01:00
Čarodej
16823b9566 routes refactoring 2021-11-25 15:51:46 +01:00
Čarodej
13287ce6b0 paystack dark mode logo 2021-11-25 14:25:19 +01:00
Čarodej
7f6598238e create plan page refactoring 2021-11-25 14:19:04 +01:00
Čarodej
3bfca2ac83 implemented subscription page 2021-11-25 10:11:50 +01:00
Čarodej
03ddb61d33 plan details refactoring 2021-11-25 09:47:26 +01:00
Čarodej
d8f1f396d5 plan pages refactoring 2021-11-25 09:35:12 +01:00
Čarodej
936af4497b plan list refactoring 2021-11-25 07:41:09 +01:00
Čarodej
2fb3cff98b admin menu refactoring 2021-11-25 07:09:16 +01:00
Čarodej
4e069b98f6 added logo to the transaction service 2021-11-25 07:03:01 +01:00
Čarodej
9503ecbd79 labels fix 2021-11-24 18:06:11 +01:00
Čarodej
f71a31ab78 dark mode improvements 2021-11-24 17:59:05 +01:00
Čarodej
be04715f8b added user into transaction list 2021-11-24 17:13:12 +01:00
Čarodej
8ff3b408cc invoice admin page 2021-11-24 16:57:03 +01:00
Čarodej
b447d2ea83 cancel subscription 2021-11-24 16:11:13 +01:00
Čarodej
7fe576ba26 subscription detail page 2021-11-24 10:31:37 +01:00
Čarodej
913bdf70ad tables refactoring 2021-11-24 07:03:41 +01:00
Čarodej
f711ec7d89 tables refactoring 2021-11-23 16:26:38 +01:00
Čarodej
946dfa7d99 storage page refactoring 2021-11-23 15:53:18 +01:00
Čarodej
c5aadd3c6e refactoring 2021-11-23 10:39:44 +01:00
Čarodej
884c36a5a3 card navigation refactoring 2021-11-23 10:31:45 +01:00
Čarodej
b6c77a6685 popups form refactoring 2021-11-23 09:23:25 +01:00
Čarodej
21d75678c0 pages refactoring 2021-11-23 08:24:56 +01:00
Čarodej
78541c1c3c language editor refactoring 2021-11-23 08:01:43 +01:00
Čarodej
0ad8afcfe2 admin settings inputs refactoring 2021-11-23 07:09:03 +01:00
Čarodej
d958da933d users inputs refactoring 2021-11-23 06:51:18 +01:00
Čarodej
d039700b90 user inputs refactoring 2021-11-22 19:22:59 +01:00
Čarodej
4ea46f5e81 page inputs refactoring 2021-11-22 18:01:30 +01:00
Čarodej
88234d5748 user profile inputs refactoring 2021-11-22 17:55:49 +01:00
Čarodej
6dd40df7d5 settings inputs refactoring 2021-11-22 17:41:46 +01:00
Čarodej
79281e80f6 language editor refactor 2021-11-22 16:37:11 +01:00
Čarodej
67bbc79f20 pages refactor 2021-11-22 16:00:44 +01:00
Čarodej
d798f06d36 users page refactor part 2 2021-11-22 15:54:25 +01:00
Čarodej
9cece789a0 users page refactor 2021-11-22 14:50:00 +01:00
Čarodej
054c0eb32c user profile page refactor 2021-11-22 14:39:57 +01:00
Čarodej
a2e0c1810d user admin page refactor 2021-11-22 11:17:14 +01:00
Čarodej
d16a37f2ed settings page refactor 2021-11-22 10:47:24 +01:00
Čarodej
0a4d5dea8a searchbar tweaks 2021-11-22 08:33:48 +01:00
Čarodej
8faa865fb7 handle SubscriptionWasCreated, SubscriptionWasExpired, SubscriptionWasUpdated on VueFileManager backend 2021-11-19 19:53:16 +01:00
Čarodej
6ca84d9041 implementation of user limits and refactoring 2021-11-19 18:44:46 +01:00
Čarodej
4851fb5eab append subscription to the UserResource.php 2021-11-19 17:40:57 +01:00
Čarodej
7c5cb79677 event implementation 2021-11-19 17:08:49 +01:00
Čarodej
496a6ea5a7 composer update 2021-11-19 16:21:50 +01:00
Čarodej
f402141bfb removed old subscription backend 2021-11-19 16:18:27 +01:00
Čarodej
34eaf3e411 - currency computes removed
- billable namespace update
2021-11-18 16:06:14 +01:00
Čarodej
6514102df2 feb 2021-11-16 17:21:03 +01:00
Čarodej
c7dab4b268 - get plans via api
- subscribe to plan at the frontend
2021-11-11 14:57:53 +01:00
Čarodej
8387467ee7 paypal test 2021-11-11 06:53:25 +01:00
Čarodej
9744344146 set storage in event handleSubscriptionWasCreated 2021-11-10 06:55:56 +01:00
Čarodej
a5b8744082 receive events from subscription package 2021-11-09 08:31:09 +01:00
Čarodej
eb22f25b07 receive events from subscription package 2021-11-08 15:54:38 +01:00
Čarodej
0cc39f8575 FEB 2021-11-08 10:19:59 +01:00
Čarodej
9d52da4e3a - paystack test
- FEB
2021-11-08 09:27:50 +01:00
Čarodej
18ff8a6dc7 - test refactoring
- removed laravel/cashier
2021-11-06 16:07:31 +01:00
Čarodej
1f5f0a7fbb subscription installation 2021-11-06 15:55:04 +01:00
MakingCG
73cd950054 Fix backend code styling 2021-11-05 06:02:23 +00:00
Čarodej
5c12334d92 Merge remote-tracking branch 'origin/master' 2021-11-05 07:01:53 +01:00
Čarodej
8b5e5fecfb Transfer Content Ownership To Team Folder Owner after member was deleted by author of team folder 2021-11-05 07:01:44 +01:00
MakingCG
77d14a9d80 Fix backend code styling 2021-11-04 16:38:21 +00:00
Čarodej
02582f2ae3 Merge remote-tracking branch 'origin/master' 2021-11-04 17:37:47 +01:00
Čarodej
d600ee7830 Transfer Content Ownership To Team Folder Owner 2021-11-04 17:37:25 +01:00
Čarodej
8d8fdbf9ba action:confirmed fix in leaving shared folder 2021-11-04 10:45:27 +01:00
MakingCG
de9d91da62 Fix backend code styling 2021-11-04 09:21:28 +00:00
Čarodej
29cb889283 Merge remote-tracking branch 'origin/teams'
# Conflicts:
#	public/chunks/admin-account.js
#	public/chunks/admin.js
#	public/chunks/app-appearance.js
#	public/chunks/app-billings.js
#	public/chunks/app-email.js
#	public/chunks/app-index.js
#	public/chunks/app-language.js
#	public/chunks/app-others.js
#	public/chunks/app-payments.js
#	public/chunks/app-setup.js
#	public/chunks/billings-detail.js
#	public/chunks/contact-us.js
#	public/chunks/database.js
#	public/chunks/environment-setup.js
#	public/chunks/installation-disclaimer.js
#	public/chunks/page-edit.js
#	public/chunks/plan-create.js
#	public/chunks/plan-delete.js
#	public/chunks/plan-settings.js
#	public/chunks/plan-subscribers.js
#	public/chunks/platform.js
#	public/chunks/profile.js
#	public/chunks/settings-create-payment-methods.js
#	public/chunks/settings-invoices.js
#	public/chunks/settings-password.js
#	public/chunks/settings-payment-methods.js
#	public/chunks/settings.js
#	public/chunks/shared.js
#	public/chunks/shared/single-file.js
#	public/chunks/status-check.js
#	public/chunks/stripe-credentials.js
#	public/chunks/subscription-plans.js
#	public/chunks/upgrade-billing.js
#	public/chunks/upgrade-plan.js
#	public/chunks/user-create.js
#	public/chunks/user-delete.js
#	public/chunks/user-detail.js
#	public/chunks/user-invoices.js
#	public/chunks/user-password.js
#	public/chunks/user-storage.js
#	public/js/main.js
#	public/mix-manifest.json
2021-11-04 10:20:33 +01:00
Čarodej
ee86fbbe66 - convert folders into teams folders in convert/delete events
- composer update
2021-11-04 10:05:29 +01:00
Čarodej
aec5b98313 - mark folder as team folder after folder was created
- show members in spotlight search
2021-11-04 09:14:12 +01:00
Čarodej
5a9f2985c9 search team folder contents 2021-11-04 08:06:37 +01:00
Čarodej
cdaad931bb format 2021-11-03 17:34:46 +01:00
Čarodej
98823504ba Generate thumbnails for demo data fix 2021-11-03 17:24:30 +01:00
Čarodej
6203581893 Generate thumbnails for demo data 2021-11-03 17:10:23 +01:00
Čarodej
f139dbae08 Generate multiple avatar sizes for better performance loading and frugal traffic 2021-11-03 16:28:14 +01:00
Čarodej
dc8ec5f20b Generate multiple avatar sizes 2021-11-02 16:11:53 +01:00
Čarodej
9b2dbe06c7 - filebrowser contextmenu fix 2021-11-02 10:06:18 +01:00
Čarodej
23602f5e4f - border fix in share popup
- folder icon fix
2021-11-02 09:29:12 +01:00
Čarodej
b232701783 file filter icon change 2021-11-02 08:29:59 +01:00
Čarodej
54167ae366 Move item popup refactoring 2021-11-02 08:13:09 +01:00
Čarodej
ffbf809b1e team list debugging 2021-11-01 18:24:05 +01:00
Čarodej
bf4d860bb8 - add button to email input in team popup 2021-11-01 16:20:14 +01:00
Čarodej
4e86e7dd4b - toaster fix
- go back animation in location title
2021-11-01 15:58:56 +01:00
Čarodej
60a2a88805 spotlight to tailwind refactoring 2021-11-01 13:05:17 +01:00
Čarodej
e6133d6071 Fixes:
- [x] Ipad landscape in teams missing heads widget
- [x] Ipad portrait (sm) full screen mode
- [x] Ipad landscape add file handler button
- [x] In recent upload, shared items and trash is search instead spotlight text button
- [x] Dissapearing mobile context menu animation is buggy
- [x] Fileitemgrid in single shared item refactoring
- [x] Ipad landscape add eye icon to show info details list/grid
2021-11-01 11:22:23 +01:00
Čarodej
1e515ede88 - dark mode fixes
- sort reloading
2021-10-29 17:54:34 +02:00
Čarodej
57506fc34f text fixes 2021-10-29 17:25:50 +02:00
Čarodej
06bb51989e empty page fix
grid fix
auth page fix
2021-10-29 17:22:33 +02:00
Čarodej
b1a6fc3bf2 spotlight fix 2021-10-29 16:38:52 +02:00
Čarodej
351d57b103 UI fixes & refactoring 2021-10-29 15:58:54 +02:00
Čarodej
2d7b6e4e05 $showMobileMenu helper implementation 2021-10-29 11:51:46 +02:00
Čarodej
ce846cc076 Teams mobile implementation 2021-10-29 11:43:55 +02:00
Čarodej
0f08d9fe38 ui fixes 2021-10-29 09:59:26 +02:00
Čarodej
d018dcba06 - search UI icon in desktop implemented
- spotlight refactoring
2021-10-28 15:44:54 +02:00
Čarodej
ceb1e5c9dd grid enhancement 2021-10-28 15:23:52 +02:00
Čarodej
b53d9fb93a grid view implementation 2021-10-28 14:49:12 +02:00
Čarodej
240880e2ad file browser refactoring 2021-10-28 09:18:55 +02:00
Čarodej
3dfee77042 mobile fixes 2021-10-28 08:49:35 +02:00
Čarodej
9c26c764bd File icons refactoring 2021-10-28 07:45:55 +02:00
Čarodej
407f2d2874 File item refactoring 2021-10-27 16:48:43 +02:00
Čarodej
cd44274690 EmptyFilePage fix 2021-10-27 10:14:02 +02:00
Čarodej
265cc393e1 EmptyFilePage refactoring 2021-10-27 10:04:36 +02:00
Čarodej
21d6410f76 file view refactoring 2021-10-27 09:53:59 +02:00
Čarodej
e3ddf27023 optimized browsing 2021-10-26 10:14:33 +02:00
Čarodej
15e154176d - ability leave team folder
- refactoring
2021-10-26 09:05:08 +02:00
Čarodej
6ef50978d5 fixes 2021-10-26 07:56:57 +02:00
Čarodej
54af098148 TeamMembersButton.vue tailwind refactoring 2021-10-26 07:06:45 +02:00
Čarodej
fda82d6dbf dark mode for teams 2021-10-26 06:57:40 +02:00
Čarodej
d4990d8d5f Team member preview refactoring 2021-10-25 18:03:43 +02:00
Čarodej
524791f251 invitation page implementation 2021-10-25 17:14:27 +02:00
Čarodej
b45662942d headline refactoring in auth pages 2021-10-25 10:33:14 +02:00
Čarodej
3f93373f60 issue fixing 2021-10-25 09:53:24 +02:00
Čarodej
018b973c0f tailwind refactoring 2021-10-25 09:09:46 +02:00
Čarodej
133dd5285d tailwind implementation 2021-10-25 09:02:00 +02:00
Čarodej
3ec5166936 added file owner into file detail panel 2021-10-25 08:30:41 +02:00
Čarodej
69fccfeaad show owner in team members information 2021-10-25 08:06:51 +02:00
Čarodej
c9631a9727 author thumbnail in file 2021-10-22 17:48:42 +02:00
Čarodej
841c1db54a implemented navigation tree controller for teams 2021-10-22 16:39:53 +02:00
Čarodej
705281325f DesktopToolbar.vue team members widget resolving 2021-10-22 10:53:04 +02:00
Čarodej
cea881ce38 clear SharedWithMe.vue view 2021-10-22 09:50:27 +02:00
Čarodej
3fee035e9e clear SharedWithMe.vue view 2021-10-22 08:43:19 +02:00
Čarodej
2aac3fc966 - protect edition of team folder from team member
- zip migration deleted
2021-10-22 08:08:56 +02:00
Čarodej
07b249346b get and browse team folders shared with me 2021-09-24 16:56:18 +02:00
Čarodej
37cad85a86 TeamFoldersController@show refactored 2021-09-24 11:32:32 +02:00
Čarodej
19cc01131b - gate implementation
- protected shared view fix
2021-09-24 10:52:19 +02:00
Čarodej
d40108f6a9 addded new folder icon 2021-09-22 17:58:10 +02:00
Čarodej
f715cd897f - moving files fix 2021-09-22 16:41:55 +02:00
Čarodej
a9556896ca encoding troubleshooting 2021-09-08 18:18:36 +02:00
Peter Papp
1db153aeef unit test fixes 2021-08-31 16:09:11 +02:00
Peter Papp
6f9b6835a7 TeamFolders.vue refactoring 2021-08-31 15:36:44 +02:00
Peter Papp
d1cb1a378b desktop toolbar refactoring 2021-08-31 15:14:55 +02:00
Peter Papp
c916916a4d navigation after created team folder 2021-08-31 14:36:40 +02:00
Peter Papp
a3516769de team folder browsing with static team folder details 2021-08-31 14:08:47 +02:00
Peter Papp
f44e262d6e TypedAvatar.vue colored background 2021-08-31 09:52:22 +02:00
Peter Papp
ac62a432fe added TypedAvatar.vue component 2021-08-30 15:06:26 +02:00
Peter Papp
2bfdf5c311 TeamMembersPreview refactoring 2021-08-30 14:43:52 +02:00
Peter Papp
e751a6bc90 team folder generator 2021-08-30 09:16:48 +02:00
Peter Papp
eb38ca8c9a api resource refactoring part 6 2021-08-27 16:42:13 +02:00
Peter Papp
4304fb1ddb api resource refactoring part 5 2021-08-27 13:02:28 +02:00
Peter Papp
7984ce3ef1 api resource refactoring part 4 2021-08-27 11:23:17 +02:00
Peter Papp
d299183ecd api resource refactoring part 3 2021-08-27 11:01:44 +02:00
Peter Papp
174f2a2c1f api resource refactoring part 2 2021-08-27 10:05:20 +02:00
Peter Papp
e0e060e5a1 api resource refactoring 2021-08-27 09:41:14 +02:00
Peter Papp
5c6a873b02 - added file resource
- frontend refactoring
2021-08-26 18:01:57 +02:00
Peter Papp
f5f2179145 added folder resource 2021-08-26 15:06:39 +02:00
Peter Papp
bee7352b28 team folders page 2021-08-26 12:20:36 +02:00
Peter Papp
7020720392 added request validators 2021-08-25 17:53:15 +02:00
Peter Papp
8282defbe3 updating team members/invitations 2021-08-25 17:37:07 +02:00
Peter Papp
49c147f609 - it_update_member_permission_in_team_folder
- it_remove_member_from_team_folder
- it_add_member_into_team_folder
2021-08-24 18:38:43 +02:00
Peter Papp
dfa82535eb - it_update_member_permission_in_team_folder
- it_remove_member_from_team_folder
- it_add_member_into_team_folder
2021-08-24 18:28:20 +02:00
Peter Papp
bcfe813e1e it_get_team_folders_shared_with_another_user 2021-08-24 17:24:36 +02:00
Peter Papp
78bf913d92 it_get_content_of_team_folder 2021-08-24 17:04:11 +02:00
Peter Papp
0c6621494e it_get_all_team_folders 2021-08-24 16:54:05 +02:00
Peter Papp
e0ecfce382 it_dissolve_team_folder 2021-08-24 14:25:10 +02:00
Peter Papp
80a86bbddd it_convert_folder_into_team_folder 2021-08-24 14:05:32 +02:00
Peter Papp
60f0f3c329 it_reject_team_folder_invite 2021-08-24 13:39:05 +02:00
Peter Papp
d53a4964ae it_accept_team_folder_invite 2021-08-24 13:29:45 +02:00
Peter Papp
ca1d037975 create team folder 2021-08-24 10:58:03 +02:00
Peter Papp
fdd9c5a591 team folders test skelet 2021-08-24 09:12:57 +02:00
Peter Papp
d4e3957598 refactoring part 6 2021-08-24 09:03:42 +02:00
Peter Papp
f24d57d88d refactoring part 5 2021-08-23 17:55:38 +02:00
Peter Papp
fd313e3d83 refactoring part 4 2021-08-23 17:49:28 +02:00
Peter Papp
527a0790e3 refactoring part 3 2021-08-23 16:31:25 +02:00
Peter Papp
42210233dc refactoring part 2 2021-08-23 15:22:43 +02:00
Peter Papp
cc0436b8f3 refactoring part 1 2021-08-23 09:32:21 +02:00
Peter Papp
a926545146 navigation through public folders 2021-08-23 09:16:01 +02:00
Peter Papp
26e3194f21 public share navigation 2021-08-23 08:30:34 +02:00
Peter Papp
882b5543f0 team UI dark mode 2021-08-23 07:02:24 +02:00
Peter Papp
1f529ae7e0 MultiSelectToolbar.vue refactoring 2021-08-21 11:19:03 +02:00
Peter Papp
a6e60d2efa MobileContextMenu.vue refactoring 2021-08-21 10:53:56 +02:00
Peter Papp
d71dbea246 create list mobile refactoring 2021-08-21 09:47:30 +02:00
Peter Papp
5ac786fb4c mobile filter refactoring 2021-08-21 09:41:34 +02:00
Peter Papp
8cf6b6ea78 FileActionsMobile.vue refactoring 2021-08-21 09:21:36 +02:00
Peter Papp
a99cbc2841 panel navigator refactoring 2021-08-20 18:07:26 +02:00
Peter Papp
b23259309c empty page refactored 2021-08-20 17:51:58 +02:00
Peter Papp
b5a8fe8b1a current folder functionality 2021-08-20 17:36:46 +02:00
Peter Papp
c697f8a451 vue routes refactoring 2021-08-20 17:00:35 +02:00
Peter Papp
fb6dfbe7b4 DesktopToolbar.vue refactoring 2021-08-20 16:49:51 +02:00
Peter Papp
15fba236d7 - added recent uploads
- added my shared items
- added trash
2021-08-20 11:08:50 +02:00
Peter Papp
99e9c0086e contextmenu refactoring 2021-08-20 09:54:00 +02:00
Peter Papp
c57a244ae1 reorganization of FileView 2021-08-20 09:04:56 +02:00
Peter Papp
e13a2cd18f UI changes for team folders 2021-08-19 18:14:38 +02:00
Peter Papp
58b7e6d584 added CreateTeamFolderPopup.vue 2021-08-19 10:42:46 +02:00
Peter Papp
1d569f13c2 added team into DesktopToolbar.vue 2021-08-19 07:55:52 +02:00
MakingCG
a521f88859 Application Build 2021-08-19 04:37:21 +00:00
Peter Papp
a824e4d78e delete index.html 2021-08-19 06:35:16 +02:00
Milos Holba
3d491c7e58 added FolderUploadIcon 2021-08-18 18:51:25 +02:00
Peter Papp
52842c61e5 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	public/mix-manifest.json
2021-08-18 18:50:33 +02:00
Milos Holba
4e3e63ba00 new test for folders upload 2021-08-18 18:50:32 +02:00
Peter Papp
0c7a416cb5 generate iframe from shared link 2021-08-18 18:50:22 +02:00
Peter Papp
63b4aa0e1d Create share record popup changes 2021-08-18 16:58:52 +02:00
Milos Holba
09dfaaa34a fix upload progress count 2021-08-17 17:41:56 +02:00
Milos Holba
a4231ea30a added folder upload via Upload Folder button 2021-08-17 15:08:13 +02:00
Milos Holba
387c824647 Merge remote-tracking branch 'origin/master' into folders_upload 2021-08-11 17:46:57 +02:00
Milos Holba
ec2a10e32f fixed upload files in the nested levels of folders 2021-08-11 17:15:02 +02:00
MakingCG
34a1f31f96 Application Build 2021-08-11 07:22:32 +00:00
Peter Papp
20b26ce57d Merge remote-tracking branch 'origin/spotlight'
# Conflicts:
#	public/mix-manifest.json
2021-08-11 09:18:47 +02:00
Milos Holba
717f28608f folder upload 2021-08-10 17:50:08 +02:00
Peter Papp
dc60ba972f frontend refactoring 2021-08-10 17:49:22 +02:00
Peter Papp
98688b81c0 file preview refactoring 2021-08-10 11:43:05 +02:00
Peter Papp
843a1bc690 single file preview in spotlight 2021-08-10 11:14:04 +02:00
Peter Papp
8b360edb2b mobile spotlight fix 2021-08-10 10:24:16 +02:00
Peter Papp
1175724e43 mobile spotlight 2021-08-10 10:19:10 +02:00
Peter Papp
79295e77b6 spotlight optimizing UI 2021-08-10 08:38:57 +02:00
Peter Papp
f78cedbc0c spotlight desktop UI 2021-08-10 08:16:34 +02:00
MakingCG
cea889d912 Application Build 2021-08-09 08:17:14 +00:00
Peter Papp
98691dcdd4 desktop searchbar restyle 2021-08-09 10:15:30 +02:00
Peter Papp
6a6e05f035 - mobile create menu 2021-08-09 10:03:58 +02:00
Peter Papp
60337934cb - removed participant upload 2021-08-09 09:38:08 +02:00
Peter Papp
9a80c044fc added create icon into desktopToolbar 2021-08-09 09:23:10 +02:00
MakingCG
5341fbedc6 Fix backend code styling 2021-07-29 14:12:15 +00:00
Peter Papp
53f667372d Merge remote-tracking branch 'origin/zipstream' 2021-07-29 16:11:02 +02:00
Peter Papp
cd39606905 shared page password error fix 2021-07-29 16:10:21 +02:00
Peter Papp
2d6f375c8b setup wizard StoreEnvironmentSettingsController.php tweaks 2021-07-29 16:04:27 +02:00
Peter Papp
46dcdc5e94 s3 template in .env.example 2021-07-29 13:41:25 +02:00
Peter Papp
79826a3601 comments 2021-07-29 13:38:26 +02:00
Peter Papp
826e90c087 single folder zip name 2021-07-29 13:34:43 +02:00
Peter Papp
087b6e77cc upload chunk fix 2021-07-29 13:22:39 +02:00
Peter Papp
94f30e5c9f fe build 2021-07-29 13:08:40 +02:00
Peter Papp
1f1f646f62 visitor zipping 2021-07-29 13:01:25 +02:00
Peter Papp
0ea7447901 user zipping 2021-07-29 10:51:58 +02:00
Peter Papp
1b893d59ea zip unit testing 2021-07-29 09:29:02 +02:00
Peter Papp
6a805b03fa deleted old files 2021-07-28 18:33:13 +02:00
Peter Papp
71a1eb8e7c Zipping on the fly 2021-07-28 18:16:20 +02:00
MakingCG
3823fb22d9 Fix backend code styling 2021-07-24 09:35:00 +00:00
Peter Papp
8810880616 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	public/mix-manifest.json
2021-07-24 11:34:11 +02:00
Peter Papp
cb496281b7 Implemented setup wizard server check functionality 2021-07-24 11:33:58 +02:00
MakingCG
a65ec6e8c7 Application Build 2021-07-23 16:15:56 +00:00
Peter Papp
7576904587 Merge remote-tracking branch 'origin/master' 2021-07-23 18:14:05 +02:00
Peter Papp
f8cb879e42 queueable email sharing 2021-07-23 18:13:58 +02:00
MakingCG
5f4fa23a68 Fix backend code styling 2021-07-23 15:54:00 +00:00
Peter Papp
c2771be913 Merge remote-tracking branch 'origin/master' 2021-07-23 17:53:28 +02:00
Peter Papp
7a85a03fea added user_with_full_storage_capacity_try_to_upload_new_file 2021-07-23 17:53:17 +02:00
Peter Papp
5c848f75a6 set default charset and collation into db migrations 2021-07-23 17:41:42 +02:00
Peter Papp
7b65d868c4 - added it_test_user_timezone
- refactored set_time_by_user_timezone
2021-07-23 17:36:05 +02:00
MakingCG
35fefdc383 Fix backend code styling 2021-07-23 15:17:30 +00:00
Peter Papp
32d54fa50e Dark mode switcher 2021-07-23 17:16:42 +02:00
Peter Papp
be2690fd1c Merge remote-tracking branch 'origin/master'
# Conflicts:
#	.php-cs-fixer.cache
2021-07-23 13:28:50 +02:00
Peter Papp
eaec744356 Disable account registering from disabled email provider 2021-07-23 13:28:40 +02:00
Peter Papp
8951ebc69f php cs fixer tweak 2021-07-23 10:50:29 +02:00
MakingCG
c38ecb412b Fix backend code styling 2021-07-22 15:39:39 +00:00
Peter Papp
d190eeb46d Merge remote-tracking branch 'origin/master' 2021-07-22 17:39:12 +02:00
Peter Papp
03fc533848 php unit fixes 2021-07-22 17:39:01 +02:00
MakingCG
7cb485fb43 Fix backend code styling 2021-07-22 15:28:36 +00:00
Peter Papp
fffede1c10 fixes 2021-07-22 17:26:22 +02:00
Peter Papp
093c9451ec Refactoring 2021-07-22 14:24:07 +02:00
Peter Papp
69eb8dacce share delete fix 2021-07-22 12:39:32 +02:00
Peter Papp
b0e8bfa3ce Setup Wizard middleware implemented 2021-07-22 12:27:36 +02:00
Peter Papp
5167f082f7 controller refactoring part 25 2021-07-22 07:49:25 +02:00
Peter Papp
6d8a7a429c controller refactoring part 24 2021-07-21 18:46:55 +02:00
Peter Papp
54f1f4c9a8 controller refactoring part 24 2021-07-21 18:14:23 +02:00
Peter Papp
91cb795054 controller refactoring part 23 2021-07-21 18:00:45 +02:00
Peter Papp
9fb9b8a1b0 controller refactoring part 22 2021-07-21 17:21:19 +02:00
Peter Papp
d55f5c3b41 controller refactoring part 21 2021-07-21 17:20:19 +02:00
Peter Papp
91fc7f2d9d controller refactoring part 20 2021-07-21 12:22:26 +02:00
Peter Papp
3860faf851 controller refactoring part 19 2021-07-21 12:01:44 +02:00
Peter Papp
76e1cd1113 controller refactoring part 18 2021-07-21 11:41:50 +02:00
Peter Papp
dccf98602d controller refactoring part 17 2021-07-21 11:20:41 +02:00
Peter Papp
e0eaf5cede controller refactoring part 16 2021-07-21 10:00:41 +02:00
Peter Papp
58d8724cea controller refactoring part 15 2021-07-21 09:42:39 +02:00
Peter Papp
1534696e0d controller refactoring part 14 2021-07-21 09:01:51 +02:00
Peter Papp
b659f2ad8d controller refactoring part 13 2021-07-20 17:46:38 +02:00
Peter Papp
2333b52d68 controller refactoring part 12 2021-07-20 17:27:18 +02:00
Peter Papp
b0859f71cd controller refactoring part 11 2021-07-20 17:17:18 +02:00
Peter Papp
2d814f3839 controller refactoring part 10 2021-07-20 16:45:17 +02:00
Peter Papp
8b250e94cb controller refactoring part 9 2021-07-20 13:13:33 +02:00
Peter Papp
0633131a73 controller refactoring part 8 2021-07-20 12:54:54 +02:00
Peter Papp
dc98c839a2 controller refactoring part 7 2021-07-20 12:22:48 +02:00
Peter Papp
0232a7abeb controller refactoring part 6 2021-07-20 11:50:03 +02:00
Peter Papp
cde8b6aae3 controller refactoring part 5 2021-07-20 11:23:45 +02:00
Peter Papp
8c493395c4 controller refactoring part 4 2021-07-20 10:27:00 +02:00
Peter Papp
2e52af5275 controller refactoring part 3 2021-07-20 10:17:40 +02:00
Peter Papp
20a6404d8d controller refactoring part 2 2021-07-20 09:50:23 +02:00
Peter Papp
d6db2f3a7c controller refactoring part 1 2021-07-20 08:58:20 +02:00
Peter Papp
29d1b68dd5 namespaces refactoring part 3 2021-07-19 13:40:26 +02:00
Peter Papp
54dc57fcbf namespaces refactoring part 2 2021-07-18 18:05:33 +02:00
Peter Papp
8f77a497b5 namespaces refactoring 2021-07-18 17:21:37 +02:00
Peter Papp
a1778eab52 test groups refactoring 2021-07-18 16:53:12 +02:00
Peter Papp
18150cd920 test folder refactoring 2021-07-18 14:53:00 +02:00
Peter Papp
5046071f3a src folder refactoring 2021-07-18 14:43:50 +02:00
MakingCG
fc952d089b Fix backend code styling 2021-07-18 11:47:18 +00:00
Peter Papp
79e2dfc502 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	public/mix-manifest.json
2021-07-18 13:46:42 +02:00
Peter Papp
c14aefd5ea added translations for Personal Access Token UI 2021-07-18 13:46:31 +02:00
Peter Papp
a9a572c434 Personal Access Token page implementation 2021-07-18 13:32:08 +02:00
Peter Papp
ddf88304ff CreatePersonaTokenPopup implementation 2021-07-18 11:38:44 +02:00
Peter Papp
aeb5c8419a PersonalAccessTokenTest refactoring 2021-07-18 10:20:47 +02:00
MakingCG
49d8b5abd9 Application Build 2021-07-17 18:46:26 +00:00
Peter Papp
4384e50f34 Merge remote-tracking branch 'origin/master' 2021-07-17 20:44:25 +02:00
Peter Papp
90efc51359 it_get_user_data fix 2021-07-17 20:44:18 +02:00
MakingCG
ec6d11b7ae Fix backend code styling 2021-07-17 18:38:41 +00:00
Peter Papp
9ba3d9a6ba - PhpCsFixer rules 3.0 upgrade 2021-07-17 20:38:11 +02:00
Peter Papp
66cca02b36 Merge remote-tracking branch 'origin/master' 2021-07-17 20:36:26 +02:00
Peter Papp
c1d9622879 - removed token profile page
- PhpCsFixer fix
2021-07-17 20:36:11 +02:00
MakingCG
840bdc3878 Application Build 2021-07-17 18:27:49 +00:00
Peter Papp
460b95e6de Merge remote-tracking branch 'origin/2fa'
# Conflicts:
#	.php-cs-fixer.cache
#	config/language-translations.php
#	public/mix-manifest.json
#	resources/js/views/Auth/SignIn.vue
#	webpack.mix.js
2021-07-17 20:25:30 +02:00
Peter Papp
a438f8fb99 added "I have already 2FA app" into recovery 2fa page 2021-07-16 18:16:11 +02:00
Peter Papp
097a930245 Two Factor Recovery Codes functionality 2021-07-16 17:38:01 +02:00
Peter Papp
40866405fc twoFactorChallenge() refactoring 2021-07-16 11:26:27 +02:00
Peter Papp
d90af84311 2fa polishing 2021-07-16 11:00:46 +02:00
Peter Papp
cdd99f66b7 Merge remote-tracking branch 'origin/master' 2021-07-16 09:26:15 +02:00
Peter Papp
36cea4853f it_use_user_token_in_public_api_request test 2021-07-16 09:26:07 +02:00
MakingCG
d05e9bf43e Application Build 2021-07-15 12:03:29 +00:00
Peter Papp
8ac41837b2 Merge remote-tracking branch 'origin/email-verification'
# Conflicts:
#	composer.lock
#	public/mix-manifest.json
#	tests/TestCase.php
2021-07-15 14:00:43 +02:00
Peter Papp
157427c750 email verification review 2021-07-15 13:55:49 +02:00
MakingCG
e7cfa07392 Fix backend code styling 2021-07-09 10:05:40 +00:00
Milos Holba
838a412823 repeat login after fail of the 2fa code / recovery_code 2021-07-05 10:38:50 +02:00
Milos Holba
16eb105f03 Create TwoFactorAuthentication Popup 2021-06-30 13:37:44 +02:00
Milos Holba
14eaf6da4e 2fa page translation 2021-06-29 19:07:35 +02:00
Milos Holba
7d28e09042 add 2fa, make 2fa login page 2021-06-29 18:41:23 +02:00
Milos Holba
edfcf8e1bd changes in email verify function 2021-06-14 17:02:19 +02:00
Milos Holba
2bba4f961a added Successfully verify email send route(Vue) 2021-05-31 18:19:42 +02:00
Milos Holba
359ae80e22 add user_verification option to settings for Setup Dev/Prod Enviroment 2021-05-29 12:55:04 +02:00
dependabot[bot]
dd489d48ba Bump dns-packet from 1.3.1 to 1.3.4
Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 1.3.1 to 1.3.4.
- [Release notes](https://github.com/mafintosh/dns-packet/releases)
- [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mafintosh/dns-packet/compare/v1.3.1...v1.3.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-29 06:01:28 +00:00
Milos Holba
9189d73df9 create AccessToken route(Vue) 2021-05-28 16:47:14 +02:00
Milos Holba
6456950081 Merge remote-tracking branch 'origin/master' into email-verification 2021-05-26 13:17:39 +02:00
Milos Holba
0df72b1803 change text in the successfully verified page 2021-05-26 13:08:31 +02:00
Milos Holba
904e2d705f change in backend-code-style-fix after rename the file 2021-05-22 19:41:09 +02:00
Milos Holba
4d078dc24a create new register route(Laravel) , create new email successfully verified route(Vue) 2021-05-22 19:36:02 +02:00
Milos Holba
a7e26cb61f update tests for the user email verification 2021-05-22 16:01:25 +02:00
Milos Holba
fd7a23225c added schedule for delete users older as 30 days 2021-05-22 13:12:03 +02:00
Milos Holba
0139cc92bf added user verification option in admin settings 2021-05-20 21:18:28 +02:00
Milos Holba
32bc3bacc0 add user email verification 2021-05-14 11:41:48 +02:00
Milos Holba
1ba685c484 make personal token for the users 2021-05-07 16:22:31 +02:00
Milos Holba
23c0e8b0f7 create CheckBox component 2021-04-27 18:46:31 +02:00
1479 changed files with 85871 additions and 78535 deletions

View File

@@ -1,6 +1,6 @@
APP_NAME=VueFileManager
APP_ENV=production
APP_KEY=base64:sB1YuKsbWv7MdWugb9ZsYBqv2QZJ+QOuHZHEddOsUuo=
APP_ENV=local
APP_KEY=base64:sC1YuKsbWv7MdWugb9ZsYBqv2QZJ+QOuHZHEddOsAao=
APP_DEBUG=true
APP_URL=http://localhost
APP_DEMO=false
@@ -10,8 +10,7 @@ LOG_CHANNEL=daily
SCOUT_DRIVER=tntsearch
SCOUT_QUEUE=true
FILESYSTEM_DRIVER=
CHUNK_SIZE=128
FILESYSTEM_DISK=local
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
@@ -20,9 +19,9 @@ DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
DB_MYSQLDUMP_PATH=
DB_MYSQLDUMP_PATH=/usr/bin
BROADCAST_DRIVER=log
BROADCAST_DRIVER=null
CACHE_DRIVER=file
QUEUE_CONNECTION=database
SESSION_DRIVER=file
@@ -32,52 +31,76 @@ REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=
MAIL_DRIVER=log
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=
MAIL_USERNAME=example@domain.com
MAIL_PASSWORD=
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=
POSTMARK_TOKEN=
MAILGUN_DOMAIN=
MAILGUN_SECRET=
MAILGUN_ENDPOINT=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=
AWS_SESSION_TOKEN=
DO_SPACES_KEY=
DO_SPACES_SECRET=
DO_SPACES_ENDPOINT=
DO_SPACES_REGION=
DO_SPACES_BUCKET=
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_DEFAULT_REGION=
S3_BUCKET=
S3_URL=
WASABI_KEY=
WASABI_SECRET=
WASABI_ENDPOINT=
WASABI_REGION=
WASABI_BUCKET=
BACKBLAZE_KEY=
BACKBLAZE_SECRET=
BACKBLAZE_ENDPOINT=
BACKBLAZE_REGION=
BACKBLAZE_BUCKET=
APP_DEPLOY_SECRET=
CASHIER_LOGGER=stack
CASHIER_CURRENCY=
STRIPE_KEY=
STRIPE_SECRET=
STRIPE_SECRET_KEY=
STRIPE_PUBLIC_KEY=
STRIPE_WEBHOOK_SECRET=
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment
SANCTUM_STATEFUL_DOMAINS=localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1
PAYSTACK_SECRET=
PAYSTACK_PUBLIC_KEY=
PAYPAL_CLIENT_ID=
PAYPAL_CLIENT_SECRET=
PAYPAL_WEBHOOK_ID=
PAYPAL_IS_LIVE=false
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
RECAPTCHA_CLIENT_ID=
RECAPTCHA_CLIENT_SECRET=
SANCTUM_STATEFUL_DOMAINS=localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1
PUSHER_APP_ID=local
PUSHER_APP_KEY=local
PUSHER_APP_SECRET=local
PUSHER_APP_CLUSTER=mt1
PUSHER_APP_HOST=
PUSHER_APP_PORT=
PUSHER_APP_TLS=true
PUSHER_APP_ALLOWED_ORIGIN=
IS_ADMIN_VUEFILEMANAGER_BAR=true
IS_SETUP_WIZARD_DEMO=false
IS_SETUP_WIZARD_DEBUG=false
FTP_HOST=
FTP_USERNAME=
FTP_PASSWORD=
AZURE_STORAGE_NAME=
AZURE_STORAGE_KEY=
AZURE_STORAGE_CONTAINER=
AZURE_STORAGE_URL=

View File

@@ -1,6 +1,6 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:47yorkyoH3qCrKKO4eG6LpZUogoTC51qey5vYq/O3AM=
APP_KEY=base64:loZzMlfoaLRn2ASLI94No42c7aUvmhXkoU/I2ljmxQI=
APP_DEBUG=true
APP_URL=http://localhost
APP_DEMO=false
@@ -14,11 +14,11 @@ DB_DATABASE=database/test.sqlite
DB_USERNAME=null
DB_PASSWORD=null
FILESYSTEM_DRIVER=local
BROADCAST_DRIVER=log
FILESYSTEM_DISK=local
BROADCAST_DRIVER=null
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_LIFETIME="15120"
SCOUT_DRIVER=tntsearch
REDIS_HOST=127.0.0.1
@@ -34,25 +34,12 @@ 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=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
CASHIER_LOGGER=stack
CASHIER_CURRENCY=EUR
STRIPE_KEY=pk_test_51GsACaCBETHMUxzVsYkeApHtqb85paMuye7G77PDDQ28kXqDJ5HTmqLi13aM6xee81OQK1fhkTZ7vmDiWLStU9160061Yb2MtL
STRIPE_SECRET=sk_test_51GsACaCBETHMUxzVviYCrv0CeZMyWAOfBPe4uH5rkKJcJxrXhIciWQTr7UB1sgw9geoJMkNDVSWBQW36tuAsVznd00zhNHXhok
STRIPE_WEBHOOK_SECRET=whsec_eKrDhqtpbMUXOKqrUHf78SrZxHHYOdrf
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment
CASHIER_MODEL=App\Models\User
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_DEFAULT_REGION=us-east-1
S3_BUCKET=
SANCTUM_STATEFUL_DOMAINS=localhost,127.0.0.1,127.0.0.1:8000,::1
DB_MYSQLDUMP_PATH="/usr/bin"

2
.gitignore vendored
View File

@@ -10,6 +10,7 @@
.env
.env.backup
.env.testing
.php-cs-fixer.cache
.phpunit.result.cache
.phpstorm.meta.php
.vscode/
@@ -19,3 +20,4 @@ Homestead.yaml
npm-debug.log
yarn-error.log
prettier.json
/public/temp

File diff suppressed because one or more lines are too long

View File

@@ -2,9 +2,10 @@
$finder = PhpCsFixer\Finder::create()
->in([
__DIR__ . '/app',
__DIR__ . '/src',
__DIR__ . '/routes',
__DIR__ . '/config',
__DIR__ . '/tests',
])
->name('*.php')
->notName('*.blade.php')
@@ -12,62 +13,68 @@ $finder = PhpCsFixer\Finder::create()
->ignoreVCS(true);
$config = new PhpCsFixer\Config();
return $config->setRules([
'@PSR2' => true,
'array_syntax' => [
'@PSR2' => true,
'nullable_type_declaration_for_default_null_value' => [
'use_nullable_type_declaration' => true
],
'array_syntax' => [
'syntax' => 'short'
],
'ordered_imports' => [
'ordered_imports' => [
'sort_algorithm' => 'length'
],
'blank_line_before_statement' => [
'blank_line_before_statement' => [
'statements' => ['break', 'case', 'continue', 'declare', 'default', 'do', 'exit', 'for', 'foreach', 'goto', 'if', 'include', 'include_once', 'require', 'require_once', 'return', 'switch', 'throw', 'try', 'while', 'yield', 'yield_from'],
],
'method_argument_space' => [
'method_argument_space' => [
'on_multiline' => 'ensure_fully_multiline',
'keep_multiple_spaces_after_comma' => true,
],
'no_extra_blank_lines' => [
'no_extra_blank_lines' => [
'tokens' => ['break', 'case', 'continue', 'curly_brace_block', 'default', 'extra', 'parenthesis_brace_block', 'return', 'square_brace_block', 'switch', 'throw', 'use', 'use_trait'],
],
'cast_spaces' => [
'cast_spaces' => [
'space' => 'single'
],
'phpdoc_single_line_var_spacing' => true,
'phpdoc_var_without_name' => true,
'single_space_after_construct' => true,
'single_line_after_imports' => true,
'no_unused_imports' => true,
'not_operator_with_successor_space' => true,
'trailing_comma_in_multiline' => ['elements' => ['arrays']],
'phpdoc_scalar' => true,
'unary_operator_spaces' => true,
'binary_operator_spaces' => true,
'single_trait_insert_per_statement' => false,
'method_chaining_indentation' => true,
'array_indentation' => true,
'single_quote' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_empty_statement' => true,
'standardize_increment' => true,
'object_operator_without_whitespace' => true,
'ternary_operator_spaces' => true,
'no_leading_namespace_whitespace' => true,
'no_blank_lines_before_namespace' => true,
'blank_line_after_namespace' => true,
'fully_qualified_strict_types' => true,
'single_line_throw' => true,
'function_typehint_space' => true,
'simplified_if_return' => true,
'no_useless_else' => true,
'no_unneeded_curly_braces' => true,
'no_empty_comment' => true,
'no_blank_lines_after_class_opening' => true,
'whitespace_after_comma_in_array' => true,
'trim_array_spaces' => true,
'no_whitespace_before_comma_in_array' => true,
'constant_case' => true,
'lowercase_keywords' => true,
'lowercase_static_reference' => true,
'use_arrow_functions' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_var_without_name' => true,
'single_space_after_construct' => true,
'single_line_after_imports' => true,
'no_unused_imports' => true,
'not_operator_with_successor_space' => true,
'trailing_comma_in_multiline' => ['elements' => ['arrays']],
'phpdoc_scalar' => true,
'unary_operator_spaces' => true,
'binary_operator_spaces' => ['operators' => ['=>' => 'align']],
'single_trait_insert_per_statement' => false,
'method_chaining_indentation' => true,
'array_indentation' => true,
'single_quote' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_empty_statement' => true,
'standardize_increment' => true,
'object_operator_without_whitespace' => true,
'ternary_operator_spaces' => true,
'no_leading_namespace_whitespace' => true,
'no_blank_lines_before_namespace' => true,
'blank_line_after_namespace' => true,
'fully_qualified_strict_types' => true,
'single_line_throw' => true,
'function_typehint_space' => true,
'simplified_if_return' => true,
'no_useless_else' => true,
'no_unneeded_curly_braces' => true,
'no_empty_comment' => true,
'no_blank_lines_after_class_opening' => true,
'whitespace_after_comma_in_array' => true,
'trim_array_spaces' => true,
'no_whitespace_before_comma_in_array' => true,
'constant_case' => true,
'lowercase_keywords' => true,
'lowercase_static_reference' => true,
'lambda_not_used_import' => true,
])
->setFinder($finder);

View File

@@ -51,23 +51,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -93,6 +94,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -140,6 +142,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -250,23 +253,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -292,6 +296,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -339,6 +344,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -449,23 +455,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -491,6 +498,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -538,6 +546,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -648,23 +657,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -690,6 +700,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -737,6 +748,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -847,23 +859,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -889,6 +902,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -936,6 +950,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -1046,23 +1061,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -1088,6 +1104,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -1135,6 +1152,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -1245,23 +1263,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -1287,6 +1306,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -1334,6 +1354,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -1444,23 +1465,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -1486,6 +1508,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -1533,6 +1556,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -1643,23 +1667,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -1685,6 +1710,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -1732,6 +1758,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -1842,23 +1869,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -1884,6 +1912,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -1931,6 +1960,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,
@@ -2041,23 +2071,24 @@ namespace PHPSTORM_META {
'Illuminate\Session\Middleware\StartSession' => \Illuminate\Session\Middleware\StartSession::class,
'Illuminate\Testing\ParallelTesting' => \Illuminate\Testing\ParallelTesting::class,
'LaravelCrawlerDetect' => \Jaybizzle\CrawlerDetect\CrawlerDetect::class,
'Laravel\Fortify\Contracts\CreatesNewUsers' => \App\Actions\Fortify\CreateNewUser::class,
'Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse' => \Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse::class,
'Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\LockoutResponse' => \Laravel\Fortify\Http\Responses\LockoutResponse::class,
'Laravel\Fortify\Contracts\LoginResponse' => \Laravel\Fortify\Http\Responses\LoginResponse::class,
'Laravel\Fortify\Contracts\LogoutResponse' => \Laravel\Fortify\Http\Responses\LogoutResponse::class,
'Laravel\Fortify\Contracts\PasswordConfirmedResponse' => \Laravel\Fortify\Http\Responses\PasswordConfirmedResponse::class,
'Laravel\Fortify\Contracts\PasswordUpdateResponse' => \Laravel\Fortify\Http\Responses\PasswordUpdateResponse::class,
'Laravel\Fortify\Contracts\RegisterResponse' => \Laravel\Fortify\Http\Responses\RegisterResponse::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Actions\Fortify\ResetUserPassword::class,
'Laravel\Fortify\Contracts\ResetsUserPasswords' => \App\Users\Actions\ResetUserPassword::class,
'Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider' => \Laravel\Fortify\TwoFactorAuthenticationProvider::class,
'Laravel\Fortify\Contracts\TwoFactorLoginResponse' => \Laravel\Fortify\Http\Responses\TwoFactorLoginResponse::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Actions\Fortify\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Actions\Fortify\UpdateUserProfileInformation::class,
'Laravel\Fortify\Contracts\UpdatesUserPasswords' => \App\Users\Actions\UpdateUserPassword::class,
'Laravel\Fortify\Contracts\UpdatesUserProfileInformation' => \App\Users\Actions\UpdateUserProfileInformation::class,
'Laravel\Scout\EngineManager' => \Laravel\Scout\EngineManager::class,
'NunoMaduro\Collision\Contracts\Provider' => \NunoMaduro\Collision\Provider::class,
'Spatie\Backup\Helpers\ConsoleOutput' => \Spatie\Backup\Helpers\ConsoleOutput::class,
'Spatie\Backup\Tasks\Cleanup\CleanupStrategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,
'Spatie\QueryBuilder\QueryBuilderRequest' => \Spatie\QueryBuilder\QueryBuilderRequest::class,
'Stripe\Util\LoggerInterface' => \Laravel\Cashier\Logger::class,
'Whoops\Handler\HandlerInterface' => \Facade\Ignition\ErrorPage\IgnitionWhoopsHandler::class,
'auth' => \Illuminate\Auth\AuthManager::class,
@@ -2083,6 +2114,7 @@ namespace PHPSTORM_META {
'command.config.clear' => \Illuminate\Foundation\Console\ConfigClearCommand::class,
'command.console.make' => \Illuminate\Foundation\Console\ConsoleMakeCommand::class,
'command.controller.make' => \Illuminate\Routing\Console\ControllerMakeCommand::class,
'command.db.prune' => \Illuminate\Database\Console\PruneCommand::class,
'command.db.wipe' => \Illuminate\Database\Console\WipeCommand::class,
'command.down' => \Illuminate\Foundation\Console\DownCommand::class,
'command.environment' => \Illuminate\Foundation\Console\EnvironmentCommand::class,
@@ -2130,6 +2162,7 @@ namespace PHPSTORM_META {
'command.queue.forget' => \Illuminate\Queue\Console\ForgetFailedCommand::class,
'command.queue.listen' => \Illuminate\Queue\Console\ListenCommand::class,
'command.queue.prune-batches' => \Illuminate\Queue\Console\PruneBatchesCommand::class,
'command.queue.prune-failed-jobs' => \Illuminate\Queue\Console\PruneFailedJobsCommand::class,
'command.queue.restart' => \Illuminate\Queue\Console\RestartCommand::class,
'command.queue.retry' => \Illuminate\Queue\Console\RetryCommand::class,
'command.queue.retry-batch' => \Illuminate\Queue\Console\RetryBatchCommand::class,

5
.prettierrc.yaml Normal file
View File

@@ -0,0 +1,5 @@
trailingComma: "es5"
tabWidth: 4
semi: false
singleQuote: true
printWidth: 120

364
README.md
View File

@@ -1,48 +1,53 @@
[![Frontend Build](https://github.com/MakingCG/vuefilemanager/actions/workflows/build.yml/badge.svg)](https://github.com/MakingCG/vuefilemanager/actions/workflows/build.yml)
[![Unit Testing](https://github.com/MakingCG/vuefilemanager/actions/workflows/unit-testing.yml/badge.svg)](https://github.com/MakingCG/vuefilemanager/actions/workflows/unit-testing.yml)
![logo](https://vuefilemanager.com/assets/images/vuefilemanager-horizontal-logo.svg)
# Private Cloud Storage Build on Laravel & Vue.js
# Private Cloud Storage Build by Laravel & Vue.js
## Contents
- [Installation](#installation)
- [Server Requirements](#server-requirements)
- [Installation](#installation)
- [PHP Configuration](#php-configuration)
- [Chunk Upload](#chunk-upload)
- [Nginx Configuration](#nginx-configuration)
- [Apache Configuration](#apache-configuration)
- [Upgrade Guide](#upgrade-guide)
- [Payments](#payments)
- [Get your active plans](#get-your-active-plans)
- [Manage Failed Payments](#manage-failed-payments)
- [Tax Rates](#tax-rates)
- [Server Requirements](#server-requirements)
- [Installation](#installation)
- [Updating Application](#updating-application)
- [Nginx Configuration](#nginx-configuration)
- [Apache Configuration](#apache-configuration)
- [Migrating to Another Domain](#migrating-to-another-domain)
- [Social Authentication](#social-authentication)
- [Subscription Configuration](#subscription-configuration)
- [Configuring Production/Testing Environment](#configuring-productiontesting-environment)
- [Upgrading From Testing Environment to the Production Mode](#upgrading-from-testing-environment-to-the-production-mode)
- [Broadcasting](#broadcasting)
- [About Broadcasting](#about-broadcasting)
- [Install VueFileManager Broadcast Server](#install-vuefilemanager-broadcast-server)
- [Developers](#developers)
- [Running development environment on your localhost](#running-development-environment-on-your-localhost)
- [Supported Storages](#supported-storages)
- [Running Environment On Your Localhost](#running-environment-on-your-localhost)
- [Express Installation](#express-installation)
- [Express Installation with Demo Data](#express-installation-with-demo-data)
- [Generate Demo Data for Metered Subscription](#generate-demo-data-for-metered-subscription)
- [Generate Demo Data for Fixed Subscription](#generate-demo-data-for-fixed-subscription)
- [Sanctum Stateful Domains](#sanctum-stateful-domains)
- [Running your Local Server](#running-your-local-server)
- [Building Your App for Production](#building-your-app-for-production)
- [Others](#others)
- [Changelog](#changelog)
- [Support](#support)
- [Security Vulnerabilities](#security-vulnerabilities)
- [Support](#support)
- [Security Vulnerabilities](#security-vulnerabilities)
# Installation
## Server Requirements
**For running app make sure you have:**
**For running app make sure you have installed:**
- PHP >= 7.3 version
- PHP >= 8.1
- MySQL 5.6+
- Nginx or Apache
- Nginx or Apache (Nginx recommended)
**These PHP Extensions are require:**
- finfo
- Intl
- GD
- BCMath
- PDO
- SQLite
- SQLite3
- Ctype
- Fileinfo
- JSON
@@ -54,60 +59,57 @@
## Installation
#### 1. Upload files on your server
Upload project files to web root folder of your domain. It's mostly located in `html`, `www` or `public_html` folder name.
- [How to install VPS with Debian 10](https://medium.com/vuefilemanager/how-to-set-up-vuefilemanager-laravel-application-on-vps-with-debian-10-64676a3ff4d7)
- [How to Set Up AWS S3](https://medium.com/vuefilemanager/how-to-set-up-vuefilemanager-with-aws-s3-as-an-external-storage-a2c525aec698)
- [How to Set Up Digital Ocean Spaces](https://medium.com/vuefilemanager/how-to-set-up-vuefilemanager-with-digital-ocean-spaces-as-a-external-storage-6cccf590c23d)
#### 2. Configure your web root folder
Configure your web server's document root to point to the public directory of the files you previously uploaded. For example, if you've uploaded the files in `html` folder, your domain root directory should be changed to `html/project_files/public` folder or anything else where domain root is in project `/public` directory.
### 1. Upload files on your server
Upload project files to the web root folder of your domain. It's mostly located in `html`, `www` or `public_html` folder name.
Please don't try go to `yourdomain.com/public` URL address, you will have issue to verify your purchase code, this is not correct domain root setup, you must do this in your webhosting settings panel.
### 2. Configure your Document Root
Configure your domain document root to the point of the files you previously uploaded directly into `/public` folder. So, if you uploaded files into `/public_html` folder, your document root must be set as `/public_html/public`. It should [look like this](https://i.ibb.co/SfLdmCQ/Screenshot-2022-04-06-at-08-53-29.png)
![Domain Root](https://vuefilemanager.com/assets/images/domain-root.jpg)
Don't forget to enable Force HTTPS Redirect.
#### 3. Check your .env file
Make sure `.env` file was uploaded. This type of file can be hidden in default.
### 3. Set write permissions
Set `755` permission (CHMOD) to these files and folders directory within all children subdirectories:
#### 4. Set write permissions
Set `755` permission (CHMOD) to these file and folders directory within all children subdirectories:
- /bootstrap/cache
- /bootstrap
- /storage
- /.env
#### 5. Open your application in your web browser
Then open your application in web browser. If everything works fine, you will be redirect to setup wizard installation process.
### 4. Open your application in your web browser
Then open your application in web browser. If everything works fine, you will be redirected to the setup wizard installation process.
At first step you have to verify your purchase code. **Subscription service with stripe payments is available only for Extended License.** If you can't verify your purchase code, check, if you did previously steps correctly.
### 5. Server Check
On the first page you will see server check. Make sure all items are green. If not, then correct your server setup by recommended values and refresh your setup wizard page.
#### 6. Follow setup wizard steps
### 6. Follow setup wizard steps
That was the hardest part of installation proces. Please follow instructions in every step of Setup Wizard to successfully install VueFileManager.
That was the hardest part of installation process. Please follow instructions in every step of Setup Wizard to successfully install VueFileManager.
#### 7. Set up Cron
### 7. Set up Cron
Add the following Cron entry to your server. Just update your php path (if it's different) and project path:
```
* * * * * /usr/local/bin/php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
```
#### If you are running VueFileManager on shared web hosting (CPanel, Plesk etc.)
1. Create new cron job
2. Set execution cycle for every minute
3. Login to the VueFileManager as admin and go to the admin dashboard, you will see command which you have to copy and paste into the command input.
## PHP Configuration
There are several PHP settings good to know to setup before you try upload any file. Please set these values in your php.ini, we provide minimal setup for you. When you set `-1` then you set infinity limits.
#### If you are running VueFileManager on linux server
1. Go to the terminal and run command `crontab -e`
2. Login to the VueFileManager as admin and go to the admin dashboard, you will see command which you have to copy and paste into the end of file.
3. Leave crontab and save the file.
```
memory_limit = 512M
upload_max_filesize = 128M
post_max_size = 128M
max_file_uploads = 50
max_execution_time = 3600
```
### 8. CORS Configuration (When you Set External S3 Storage)
In your s3 bucket settings you should have option to set up your CORS (Cross-Origin Resource Sharing). It's basically adding your app url to the list of allowed CORS. This step is required for reading pdf documents from s3 in your VueFileManager app without loading issues.
## Chunk & Multipart Upload
VueFileManager in default supporting chunk upload. Default chunk upload size is `128MB`. If you wish change this default value, go to your `.env` and change `CHUNK_SIZE` attribute.
When you use external storage, and upload large files, to prevent failing upload process make sure you have enough space in your application space and set higher `max_execution_time` in your php.ini to move your files to external storage.
# Updating Application
1. Replace all files where the app is located except `/storage` folder and `.env` file.
2. Clear the application cache (Admin / Settings / Application).
3. In 5 minutes the app update stuff automatically on the background if needed.
## Nginx Configuration
If you running VueFileManager undex Nginx, don't forget set this value in your `nginx.conf` file:
If you running VueFileManager under Nginx, don't forget set this value in your `nginx.conf` file:
```
http {
client_max_body_size 1024M;
@@ -167,57 +169,208 @@ Make sure you have enabled mod_rewrite. There is an example config for running V
</VirtualHost>
```
## Upgrade Guide
### Common Instructions
`Don't forget create backup of your database before make any changes in your production application. If you serve your files in local storage driver pay attention and don't delete your /storage folder!`
## Migrating to Another Domain
If you move your VueFileManager application into another domain or subdomain, you have to manually change values in your `.env` file.
1. Open your `/.env` file.
2. Find `APP_URL` variable and write your new domain location. Don't forget start with defining `https://` protocol.
3. Find `SANCTUM_STATEFUL_DOMAINS` variable and write your new domain location without http protocol.
4. Remove your cached config file which is located `/bootstrap/cache/config.php`.
These instructions is applicable for all updates. Please follow this step:
## Social Authentication
If you'd like to allow your users to authenticate via their social accounts, the setup is pretty convenient. Just don't forget to set up redirect url and required permissions.
- Just rewrite all project files with new excluded `/.env` file and `/storage` folder. These items must be preserved!
#### Required permissions:
- Name and profile picture
- Email
# Subscription Configuration
# Payments
VueFileManager is packed with **Stripe** payment options. To configure Stripe, you will be asked in Setup Wizard to set up. Or, if you skip this installation process, you will find stripe set up in you admin `Dashboard / Settings / Payments`.
## Configuring Production/Testing Environment
To set up your subscription, please follow these steps below.
1. If you didn't set up your subscription type in Setup Wizard, go to the `Admin / Settings / Application` and find subscription widget. Next set value as `Fixed`.
2. Go to the `Admin / Billings` and fill the inputs with your billing information.
3. Go to the `Admin / Payments` and turn on the switch `Allow Subscription Payments`.
4. Set up credentials for all payment gateway you want. If you set production mode, make sure you fill your credentials with production keys, and vice versa. If needed, don't forget to turn on `live mode` for PayPal.
5. Set up your webhooks, you can find your webhook url in payment gateway widget.
6. Go to the `Admin / Plans` and create your first plan. Make sure all payment gateways support the currency you want, especially for Paystack, it supports only `GHS, NGN, USD and ZAR`.
## Manage Failed Payments
VueFileManager manage failed payments with additional email notification. But, there is more you can do for better User Experience. There is some additionals option in Stripe, look on [prevent failed payments](https://dashboard.stripe.com/settings/billing/automatic).
## Upgrading From Testing Environment to the Production Mode
1. Go to the `Admin / Payments` and set up credentials for all payment gateway you want with production keys type. Don't forget to turn on `live mode` for PayPal.
2. Go to the `Admin / Plans` and delete all your previously created plans. They will be archived.
3. Create new production plans you want offer.
## Tax Rates
You are able to manage tax rates. When adding a new tax rate, if no Region is specified, the tax rate will apply to everyone. Add a [ISO 3166-1 alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) to the Region field if you wish to apply taxes per country.
# Broadcasting
### About Broadcasting
Broadcasting is responsible for real time app experience. If broadcasting is set, you will be able to get just in time updates in your app.
Just log in to your stripe dashboard, and you will find taxes under `Dashboard / Products / Tax Rates`.
For example, remote upload works on the background, while the files are downloading and showing in your view immediately after they are ready without refreshing the app. Or, you will get immediately notifications about new events like team invitations, file requests and many more.
More real time features will be implemented in incoming updates.
VueFileManager support 2 types of connections:
1. [Pusher](https://pusher.com/) - Suitable for all users and all hosting platforms
2. VueFileManager Broadcast Server - Free of charge, suitable for experienced users, limited for VPS servers
## Install VueFileManager Broadcast Server
We strongly recommend only for experienced users to set up and running VueFileManager broadcast server. For others, we recommend to use Pusher service to easy set up and host broadcasting service.
### Server Requirements
**For running app make sure you have:**
- VPS server with SSH access
- PHP >= 8.0.2 version (8.1+ recommended)
- Nginx
- Supervisor
- Certbot
### Installation
We assume you have installed and running properly your VPS server.
### Websocket Server Set Up
Upload VueFileManager into your server, for example path directory `/var/www/sockets` would be great. Next connect to your server with ssh and change your terminal directory into VueFileManager:
```
cd /var/www/sockets
```
Run installation command for websocket server. You will be prompted to type host of which you want to allow incoming requests.
```
php artisan websockets:install
```
### Domain & Nginx Set Up
Create subdomain for your socket host, for example `socket.vuefilemanager.com` and direct this subdomain to your vps where socket server will be running.
Then, create nginx config for your subdomain:
```
nano /etc/nginx/sites-available/socket.conf
```
And paste the template below, just replace subdomain with yours:
```
server {
listen 80;
server_name socket.vuefilemanager.com;
location / {
proxy_pass http://127.0.0.1:6001;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_redirect off;
# Allow the use of websockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
```
Enable your created config by this command:
```
ln -s /etc/nginx/sites-available/socket.conf /etc/nginx/sites-enabled/
```
Restart your nginx:
```
systemctl restart nginx
```
In the last step, install ssl certificate for your previously created subdomain with certbot:
```
certbot --nginx
```
### Supervisor Configuration
We need supervisor to manage running your websocket server on the background.
In `/etc/supervisor/conf.d` (Debian/Ubuntu) or `/etc/supervisord.d/` (Red Hat/CentOS) create a file `websockets.conf`.
Just edit php path, project path and user when they are different for your vps:
```
[program:websockets]
command=/usr/bin/php /var/www/socket/artisan websockets:serve
numprocs=1
autostart=true
autorestart=true
user=www-data
```
Run command below to start your websocket server:
```
supervisorctl start websockets
```
Run command below to stop your websocket server:
```
supervisorctl stop websockets
```
When you update code or server for some reason, you must also update running supervisor:
```
supervisorctl reload
```
### VueFileManager Set Up
Log in to your VueFileManager admin account and go to `Admin / Settings / Environment`.
Find Broadcasting form and select `VueFileManager` as broadcasting driver. Set your hostname and save the form.
That's all, you are running your own Broadcast server.
# Developers
## Running development environment on your localhost
## Running Environment On Your Localhost
When you download repository from GitHub, you have to rename your `.env.example` file to `.env`. Then run command below in your terminal to install vendors. Composer is required.
**For running development environment make sure you have:**
- Node >= 14
- NPM >= 6
### Express Installation
If you would like to have express installation without Setup Wizard process, please update your database credentials in .env file
```
composer install
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
```
Next, run this command below. Admin account will be created with credentials `howdy@hi5ve.digital` and password `vuefilemanager`.
```
php artisan setup:prod
```
Set your `APP_ENV` to local mode, in default, it's in production mode.
### Express Installation with Demo Data
If you would like to generate demo content, run this command below. Admin account will be created with credentials `howdy@hi5ve.digital` and password `vuefilemanager`.
```
APP_ENV=local
php artisan setup:dev
```
Also, to debug application, set `APP_DEBUG` on true:
### Generate Demo Data for Metered Subscription
If you would like to generate demo content for the subscription with the metered billing, run this command below.
```
APP_DEBUG=true
php artisan subscription:demo metered
```
To start server on your localhost, run command below. Then go to your generated localhost URL by terminal, and follow Setup Wizard steps to configure VueFileManager.
### Generate Demo Data for Fixed Subscription
If you would like to generate demo content for the subscription with the fixed billing, please fill the credentials in your `.env` file for the payment systems you'd like to use:
```
STRIPE_SECRET_KEY=
STRIPE_PUBLIC_KEY=
STRIPE_WEBHOOK_SECRET=
PAYSTACK_SECRET=
PAYSTACK_PUBLIC_KEY=
PAYPAL_CLIENT_ID=
PAYPAL_CLIENT_SECRET=
PAYPAL_WEBHOOK_ID=
PAYPAL_IS_LIVE=false
```
and then run this command to generate demo content for fixed subscription:
```
php artisan subscription:demo fixed
```
### Sanctum Stateful Domains
After installation, please make sure your current host/domain where you are running app is included in your `.env` file in `SANCTUM_STATEFUL_DOMAINS` variable.
### Running your Local Server
To start server on your localhost, run command below.
```
php artisan serve
```
After successfully installation via Setup Wizard, stop your artisan server, clear config cache and run your artisan server again:
```
php artisan config:clear
php artisan serve
```
*After any change in your .env you have to restart your artisan server to reload your config cache.*
To develop your Vue front-end, you have to install npm modules by this command:
For developing Vue front-end, you have to install npm modules by this command:
```
npm install
```
@@ -227,36 +380,12 @@ To compiles and hot-reloads for front-end development. Then run this command:
npm run hot
```
### Building Your App for Production
To compiles for production build, run this command
```
npm run prod
```
## Supported Storages
VueFileManager support these storages for your files:
- [Amazon Web Services S3](https://aws.amazon.com/s3/)
- [Digital Ocean Spaces](https://www.digitalocean.com/products/spaces/)
- [Object Cloud Storage by Wasabi](https://wasabi.com/)
- [Backblaze B2 Cloud Storage](https://www.backblaze.com/b2/cloud-storage.html)
- Your local disk
In case of installation process, you will be able to set storage driver and credentials. After this, you can change your credentials later in `/.env` file.
To set or change your storage driver, you have to edit `FILESYSTEM_DRIVER` in your `/.env` file. Supported drivers are `s3`, `spaces`, `wasabi`,`backblaze` or `local`:
```
FILESYSTEM_DRIVER=local
```
Then you can find corresponding credentials options for your storage driver like key, secret, region in `/.env` file.
# Others
## Changelog
Refer to the [Changelog](https://vuefilemanager.com/changelog) for a full history of the project.
## GitHub Repository
[Join our GitHub repository](https://vuefilemanager.com/github-access) to submit your issues or suggestions, track VueFileManager progress and get new updates as fast as possible.
## Support
The following support channels are available at your fingertips:
@@ -264,11 +393,10 @@ The following support channels are available at your fingertips:
- [CodeCanyon support message](https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986/support)
## Supporting VueFileManager
Hi, we are trying make the best experience with VueFileManager. There is a lot things to do, and a lot of features we can make.
We are trying to make the best for VueFileManager. There are a lot of things to do, and a lot of features we can make.
But, it can't be done without you, development is more and more complicated and we have to hire new colleagues to help us. There is couple way you can support us, and then, we support you with all great new features we can make. Thank you for participating on this awesome application!
But, it can't be done without you, development is more and more complicated and we have to hire new colleagues to help with it. There is couple way you can support us, and then, we support you with all great new features which can be. Thanks you for participating on this awesome software!
- [Buy me a Coffe](https://www.buymeacoffee.com/pepe)
- [Buy me a Coffee](https://www.buymeacoffee.com/pepe)
- [Become a Patreon](https://www.patreon.com/vuefilemanager)
- [One-time donation via PayPal](https://www.paypal.me/peterpapp)

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +0,0 @@
<?php
namespace App\Actions\Fortify;
use App\Models\User;
use App\Models\Setting;
use App\Models\UserSettings;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\CreatesNewUsers;
class CreateNewUser implements CreatesNewUsers
{
use PasswordValidationRules;
/**
* Validate and create a newly registered user.
*
* @param array $input
* @return \App\Models\User
*/
public function create(array $input)
{
$settings = Setting::whereIn('name', ['storage_default', 'registration'])
->pluck('value', 'name');
// Check if account registration is enabled
if (! intval($settings['registration'])) {
abort(401);
}
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique(User::class),
],
'password' => $this->passwordRules(),
])->validate();
$user = User::create([
'email' => $input['email'],
'password' => bcrypt($input['password']),
]);
UserSettings::unguard();
$user
->settings()
->create([
'name' => $input['name'],
'storage_capacity' => $settings['storage_default'],
]);
UserSettings::reguard();
return $user;
}
}

View File

@@ -1,889 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\File;
use App\Models\User;
use App\Models\Share;
use App\Models\Folder;
use App\Models\Setting;
use Illuminate\Support\Str;
use App\Services\SetupService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\WithFaker;
class SetupDevEnvironment extends Command
{
use WithFaker;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'setup:dev';
protected $license = 'Extended';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Set up development environment with demo data';
private $setup;
public function __construct()
{
parent::__construct();
$this->setUpFaker();
$this->setup = resolve(SetupService::class);
}
/**
* Execute the console command.
* return @void
*/
public function handle(): void
{
$this->info('Setting up development environment');
$this->info('Creating system directories...');
$this->setup->create_directories();
$this->info('Migrating Databases...');
$this->migrate_and_generate();
$this->info('Storing default settings and content...');
$this->store_default_settings();
$this->setup->seed_default_pages();
$this->setup->seed_default_settings($this->license);
$this->setup->seed_default_language();
$this->info('Creating default admin...');
$this->create_admin();
$this->info('Creating demo users...');
$this->create_demo_users();
$this->info('Creating default admin content...');
$this->create_admin_default_content();
$this->create_share_records();
$this->info('Clearing application cache...');
$this->clear_cache();
$this->info('Dispatching jobs...');
$this->call('queue:work', [
'--stop-when-empty' => true,
]);
$this->info('Everything is done, congratulations! 🥳🥳🥳');
}
/**
* Create default admin account
*/
private function create_admin(): void
{
$user = User::forceCreate([
'role' => 'admin',
'email' => 'howdy@hi5ve.digital',
'password' => bcrypt('vuefilemanager'),
]);
$user
->settings()
->create([
'avatar' => 'avatars/avatar-01.png',
'storage_capacity' => 5,
'name' => 'Jane Doe',
'address' => $this->faker->address,
'state' => $this->faker->state,
'city' => $this->faker->city,
'postal_code' => $this->faker->postcode,
'country' => $this->faker->randomElement(['SK', 'CZ', 'DE', 'FR']),
'phone_number' => $this->faker->phoneNumber,
'timezone' => $this->faker->randomElement(['+1.0', '+2.0', '+3.0']),
]);
Storage::putFileAs('avatars', storage_path('demo/avatars/avatar-01.png'), 'avatar-01.png', 'private');
// Show user credentials
$this->info('Default admin account created. Email: howdy@hi5ve.digital and Password: vuefilemanager');
}
/**
* Create default admin account
*/
private function create_demo_users(): void
{
collect([
[
'avatar' => 'avatar-02.png',
],
[
'avatar' => 'avatar-03.png',
],
])->each(function ($user) {
$newbie = User::forceCreate([
'role' => 'user',
'email' => $this->faker->email,
'password' => bcrypt('vuefilemanager'),
]);
$newbie
->settings()
->create([
'avatar' => "avatars/{$user['avatar']}",
'storage_capacity' => 5,
'name' => $this->faker->name,
'address' => $this->faker->address,
'state' => $this->faker->state,
'city' => $this->faker->city,
'postal_code' => $this->faker->postcode,
'country' => $this->faker->randomElement(['SK', 'CZ', 'DE', 'FR']),
'phone_number' => $this->faker->phoneNumber,
'timezone' => $this->faker->randomElement(['+1.0', '+2.0', '+3.0']),
]);
Storage::putFileAs('avatars', storage_path("demo/avatars/{$user['avatar']}"), $user['avatar'], 'private');
$this->info("Generated user with email: $newbie->email and Password: vuefilemanager");
});
}
/**
* Create default admin content
*/
private function create_admin_default_content(): void
{
$user = User::whereEmail('howdy@hi5ve.digital')
->first();
// 1.
$shared_folder = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'author' => 'user',
'name' => 'Shared Folder',
'emoji' => [
'codes' => '1F680',
'char' => '🚀',
'name' => 'rocket',
'category' => 'Travel & Places (transport-air)',
'group' => 'Travel & Places',
'subgroup' => 'transport-air',
],
'created_at' => now(),
]);
Share::factory(Share::class)
->create([
'type' => 'folder',
'item_id' => $shared_folder->id,
'user_id' => $user->id,
'permission' => 'editor',
'is_protected' => false,
'password' => null,
'expire_in' => null,
]);
$peters_files = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $shared_folder->id,
'author' => 'visitor',
'name' => "Peter's Files",
]);
// 2.
$random_pics = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'author' => 'user',
'name' => 'Random Pics',
'emoji' => [
'codes' => '1F4F7',
'char' => '📷',
'name' => 'camera',
'category' => 'Objects (light & video)',
'group' => 'Objects',
'subgroup' => 'light & video',
],
'created_at' => now()->subMinutes(1),
]);
$nature = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $random_pics->id,
'author' => 'user',
'name' => 'Nature',
'emoji' => [
'codes' => '26F0',
'char' => '⛰',
'name' => 'mountain',
'category' => 'Travel & Places (place-geographic)',
'group' => 'Travel & Places',
'subgroup' => 'place-geographic',
],
]);
$apartments = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $random_pics->id,
'author' => 'user',
'name' => 'Apartments',
'emoji' => [
'codes' => '1F3E0',
'char' => '🏠',
'name' => 'house',
'category' => 'Travel & Places (place-building)',
'group' => 'Travel & Places',
'subgroup' => 'place-building',
],
]);
// 3.
$playable_media = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'author' => 'user',
'name' => 'Playable Media',
'created_at' => now()->subMinutes(2),
]);
$video = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $playable_media->id,
'author' => 'user',
'name' => 'Video',
]);
$audio = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $playable_media->id,
'author' => 'user',
'name' => 'Audio',
]);
// 4.
$multi_level = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'author' => 'user',
'name' => 'Multi Level Folder',
'created_at' => now()->subMinutes(3),
]);
$first_level = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $multi_level->id,
'author' => 'user',
'name' => 'First Level',
]);
$second_level = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $first_level->id,
'author' => 'user',
'name' => 'Second Level',
]);
$third_level = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'parent_id' => $second_level->id,
'author' => 'user',
'name' => 'Third Level',
]);
// 5.
$documents = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'author' => 'user',
'name' => 'Documents',
'created_at' => now()->subMinutes(4),
]);
Share::factory(Share::class)
->create([
'type' => 'folder',
'item_id' => $documents->id,
'user_id' => $user->id,
'permission' => 'editor',
'is_protected' => false,
'password' => null,
'expire_in' => null,
]);
// 6.
$videohive = Folder::factory(Folder::class)
->create([
'user_id' => $user->id,
'author' => 'user',
'name' => 'Videohive by MakingCG',
'created_at' => now()->subMinutes(5),
]);
$user
->favouriteFolders()
->sync([
$shared_folder->id,
$random_pics->id,
$documents->id,
$peters_files->id,
]);
// Get documents to root directory
collect([
[
'name' => 'Random Document',
'basename' => 'Licence.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'School Report',
'basename' => 'Project Notes.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'Personal Savings',
'basename' => 'School Report.pages',
'mimetype' => 'pages',
],
[
'name' => 'Top Secret Files',
'basename' => 'Stories of the Night Skies.pages',
'mimetype' => 'pages',
],
])
->each(function ($file) use ($user) {
$basename = Str::random(12) . '-' . $file['basename'];
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/documents/{$file['basename']}"), $basename, 'private');
// Create file record
File::create([
'folder_id' => null,
'user_id' => $user->id,
'name' => $file['name'],
'basename' => $basename,
'type' => 'file',
'author' => 'user',
'mimetype' => $file['mimetype'],
'filesize' => rand(1000000, 4000000),
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get documents to documents folder
collect([
[
'name' => 'Home Improvement',
'basename' => 'Licence.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'Project Notes',
'basename' => 'Project Notes.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'Personal Savings',
'basename' => 'School Report.pages',
'mimetype' => 'pages',
],
[
'name' => 'License',
'basename' => 'Stories of the Night Skies.pages',
'mimetype' => 'pages',
],
])
->each(function ($file) use ($user, $documents) {
$basename = Str::random(12) . '-' . $file['basename'];
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/documents/{$file['basename']}"), $basename, 'private');
// Create file record
File::create([
'folder_id' => $documents->id,
'user_id' => $user->id,
'name' => $file['name'],
'basename' => $basename,
'type' => 'file',
'author' => 'user',
'mimetype' => $file['mimetype'],
'filesize' => rand(1000000, 4000000),
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get documents to shared folder
collect([
[
'name' => 'Home plan',
'basename' => 'Licence.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'Software Licence',
'basename' => 'Project Notes.pdf',
'mimetype' => 'pdf',
],
])
->each(function ($file) use ($user, $shared_folder) {
$basename = Str::random(12) . '-' . $file['basename'];
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/documents/{$file['basename']}"), $basename, 'private');
// Create file record
File::create([
'folder_id' => $shared_folder->id,
'user_id' => $user->id,
'name' => $file['name'],
'basename' => $basename,
'type' => 'file',
'author' => 'user',
'mimetype' => $file['mimetype'],
'filesize' => rand(1000000, 4000000),
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get documents to peter's files folder
collect([
[
'name' => 'Project Backup',
'basename' => 'Licence.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'Yearly report',
'basename' => 'Project Notes.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'Work Update',
'basename' => 'School Report.pages',
'mimetype' => 'pages',
],
[
'name' => 'Person Writing on Notebook',
'basename' => 'Stories of the Night Skies.pages',
'mimetype' => 'pages',
],
[
'name' => 'Blank Business Composition Computer',
'basename' => 'Licence.pdf',
'mimetype' => 'pdf',
],
[
'name' => '2020 April - Export',
'basename' => 'Project Notes.pdf',
'mimetype' => 'pdf',
],
[
'name' => 'Ballpen Blur Close Up Computer',
'basename' => 'School Report.pages',
'mimetype' => 'pages',
],
])
->each(function ($file) use ($user, $peters_files) {
$basename = Str::random(12) . '-' . $file['basename'];
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/documents/{$file['basename']}"), $basename, 'private');
// Create file record
File::create([
'folder_id' => $peters_files->id,
'user_id' => $user->id,
'name' => $file['name'],
'basename' => $basename,
'type' => 'file',
'author' => 'visitor',
'mimetype' => $file['mimetype'],
'filesize' => rand(1000000, 4000000),
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get videos
collect([
'Apple Watch App Video Promotion.mp4',
'Professional 3D Device Pack for Element 3D.mp4',
'Smart Watch 3D Device Pack for Element 3D.mp4',
'Sphere Bound 3D Titles.mp4',
])
->each(function ($file) use ($user, $videohive) {
$basename = Str::random(12) . '-' . $file;
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/video/$file"), $basename, 'private');
// Create file record
File::create([
'folder_id' => $videohive->id,
'user_id' => $user->id,
'name' => $file,
'basename' => $basename,
'type' => 'video',
'author' => 'user',
'mimetype' => 'mp4',
'filesize' => rand(1000000, 4000000),
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get video into video folder
collect([
'Apple Watch App Video Promotion.mp4',
])
->each(function ($file) use ($user, $video) {
$basename = Str::random(12) . '-' . $file;
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/video/$file"), $basename, 'private');
// Create file record
File::create([
'folder_id' => $video->id,
'user_id' => $user->id,
'name' => $file,
'basename' => $basename,
'type' => 'video',
'author' => 'user',
'mimetype' => 'mp4',
'filesize' => rand(1000000, 4000000),
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get audios
collect([
'D-Block & S-te-Fan - Bla Bla.mp3',
])
->each(function ($file) use ($user, $audio) {
$basename = Str::random(12) . '-' . $file;
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/audio/$file"), $basename, 'private');
// Create file record
File::create([
'folder_id' => $audio->id,
'user_id' => $user->id,
'name' => $file,
'basename' => $basename,
'type' => 'audio',
'author' => 'user',
'mimetype' => 'mp3',
'filesize' => rand(1000000, 4000000),
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get meme gallery
collect([
'Eggcited bro.jpg',
'Get a Rest.jpg',
'Get Your Shit Together.jpg',
'Happiness is when you are right beside me.jpg',
'Have a Nice Day.jpg',
'It Works On My Machine.jpg',
'I am Just Trying to shine.jpg',
'It Works On My Machine.jpg',
'Missing you It is Pig Time.jpg',
'Sofishticated.jpg',
'whaaaaat.jpg',
'You Are My Sunshine.jpg',
])
->each(function ($file) use ($user) {
$basename = Str::random(12) . '-' . $file;
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/images/memes/$file"), $basename, 'private');
Storage::putFileAs("files/$user->id", storage_path("demo/images/memes/thumbnail-$file"), "thumbnail-$basename", 'private');
// Create file record
File::create([
'folder_id' => null,
'user_id' => $user->id,
'name' => $file,
'basename' => $basename,
'type' => 'image',
'author' => 'user',
'mimetype' => 'jpg',
'filesize' => rand(1000000, 4000000),
'thumbnail' => "thumbnail-$basename",
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get apartments gallery
collect([
'Apartment Architecture Ceiling Chairs.jpg',
'Apartment Chair.jpg',
'Apartment Contemporary Couch Curtains.jpg',
'Brown Wooden Center Table.jpg',
'Home.jpg',
'Kitchen Appliances.jpg',
'Kitchen Island.jpg',
])
->each(function ($file) use ($user, $apartments) {
$basename = Str::random(12) . '-' . $file;
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/images/apartments/$file"), $basename, 'private');
Storage::putFileAs("files/$user->id", storage_path("demo/images/apartments/thumbnail-$file"), "thumbnail-$basename", 'private');
// Create file record
File::create([
'folder_id' => $apartments->id,
'user_id' => $user->id,
'name' => $file,
'basename' => $basename,
'type' => 'image',
'author' => 'user',
'mimetype' => 'jpg',
'filesize' => rand(1000000, 4000000),
'thumbnail' => "thumbnail-$basename",
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
// Get nature gallery
collect([
'Bird Patterncolorful Green.jpg',
'Close Up Of Peacock.jpg',
'Close Up Photography Of Tiger.jpg',
'Cold Nature Cute Ice.jpg',
'Landscape Photo of Forest.jpg',
'Photo of Hawksbill Sea Turtle.jpg',
'Photo Of Reindeer in The Snow.jpg',
'View Of Elephant in Water.jpg',
'Waterfall Between Trees.jpg',
'Wildlife Photography of Elephant During Golden Hour.jpg',
'Yellow Animal Eyes Fur.jpg',
])
->each(function ($file) use ($user, $nature) {
$basename = Str::random(12) . '-' . $file;
// Copy file into app storage
Storage::putFileAs("files/$user->id", storage_path("demo/images/nature/$file"), $basename, 'private');
Storage::putFileAs("files/$user->id", storage_path("demo/images/nature/thumbnail-$file"), "thumbnail-$basename", 'private');
// Create file record
File::create([
'folder_id' => $nature->id,
'user_id' => $user->id,
'name' => $file,
'basename' => $basename,
'type' => 'image',
'author' => 'user',
'mimetype' => 'jpg',
'filesize' => rand(1000000, 4000000),
'thumbnail' => "thumbnail-$basename",
'created_at' => now()->subMinutes(rand(1, 5)),
]);
});
}
private function create_share_records(): void
{
$user = User::whereEmail('howdy@hi5ve.digital')
->first();
$images = File::whereType('image')
->whereFolderId(null)
->take(3)
->pluck('id');
$images->each(function ($id) use ($user) {
Share::create([
'user_id' => $user->id,
'item_id' => $id,
'type' => 'file',
'is_protected' => false,
'permission' => 'editor',
'password' => null,
'expire_in' => null,
]);
});
$files = File::whereType('file')
->whereFolderId(null)
->take(2)
->pluck('id');
$files->each(function ($id) use ($user) {
Share::create([
'user_id' => $user->id,
'item_id' => $id,
'type' => 'file',
'is_protected' => false,
'permission' => 'editor',
'password' => null,
'expire_in' => null,
]);
});
}
/**
* Store main app settings into database
*/
private function store_default_settings(): void
{
// Get options
collect([
[
'name' => 'setup_wizard_database',
'value' => 1,
],
[
'name' => 'app_title',
'value' => 'VueFileManager',
],
[
'name' => 'app_description',
'value' => 'Your self-hosted storage cloud software powered by Laravel and Vue',
],
[
'name' => 'app_logo',
'value' => 'system/logo.svg',
],
[
'name' => 'app_logo_horizontal',
'value' => 'system/logo-horizontal.svg',
],
[
'name' => 'app_favicon',
'value' => 'system/favicon.png',
],
[
'name' => 'app_og_image',
'value' => 'system/og-image.jpg',
],
[
'name' => 'app_touch_icon',
'value' => 'system/touch-icon.png',
],
[
'name' => 'google_analytics',
'value' => '',
],
[
'name' => 'contact_email',
'value' => '',
],
[
'name' => 'registration',
'value' => 1,
],
[
'name' => 'payments_active',
'value' => 1,
],
[
'name' => 'storage_limitation',
'value' => 1,
],
[
'name' => 'storage_default',
'value' => 5,
],
[
'name' => 'setup_wizard_success',
'value' => 1,
],
[
'name' => 'license',
'value' => $this->license,
],
[
'name' => 'purchase_code',
'value' => '26b889eb-3602-4bf2-beb3-3sc378fcf484',
],
[
'name' => 'billing_address',
'value' => 'Palo Alto 20',
],
[
'name' => 'billing_city',
'value' => 'Palo Alto',
],
[
'name' => 'billing_country',
'value' => 'US',
],
[
'name' => 'billing_name',
'value' => 'VueFileManager Inc.',
],
[
'name' => 'billing_phone_number',
'value' => '312343141243214',
],
[
'name' => 'billing_postal_code',
'value' => '43213',
],
[
'name' => 'billing_state',
'value' => 'California',
],
[
'name' => 'billing_vat_number',
'value' => '41241241234',
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
// Get system images
collect(['logo.svg', 'logo-horizontal.svg', 'favicon.png', 'og-image.jpg', 'touch-icon.png'])
->each(function ($file) {
Storage::putFileAs('system', storage_path("demo/app/$file"), $file, 'private');
});
}
/**
* Migrate database and generate application keys
*/
private function migrate_and_generate(): void
{
// Migrate database
$this->call('migrate:fresh', [
'--force' => true,
]);
// Generate app key
$this->call('key:generate', [
'--force' => true,
]);
}
/**
* Clear app cache
*/
private function clear_cache(): void
{
$this->call('cache:clear');
$this->call('config:clear');
$this->call('view:clear');
}
}

View File

@@ -1,222 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Models\Setting;
use App\Services\SetupService;
use Illuminate\Console\Command;
class SetupProdEnvironment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'setup:prod';
protected $license = 'Extended';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Set up production environment';
private $setup;
public function __construct()
{
parent::__construct();
$this->setup = resolve(SetupService::class);
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$this->info('Setting up production environment');
$this->info('Creating system directories...');
$this->setup->create_directories();
$this->info('Migrating Databases...');
$this->migrate_and_generate();
$this->info('Storing default settings and content...');
$this->store_default_settings();
$this->setup->seed_default_pages();
$this->setup->seed_default_settings($this->license);
$this->setup->seed_default_language();
$this->info('Creating default admin...');
$this->create_admin();
$this->info('Clearing application cache...');
$this->clear_cache();
$this->info('Everything is done, congratulations! 🥳🥳🥳');
}
/**
* Store main app settings into database
*/
private function store_default_settings(): void
{
// Get options
collect([
[
'name' => 'setup_wizard_database',
'value' => 1,
],
[
'name' => 'app_title',
'value' => 'VueFileManager',
],
[
'name' => 'app_description',
'value' => 'Your self-hosted storage cloud software powered by Laravel and Vue',
],
[
'name' => 'app_logo',
'value' => null,
],
[
'name' => 'app_logo_horizontal',
'value' => null,
],
[
'name' => 'app_favicon',
'value' => null,
],
[
'name' => 'app_og_image',
'value' => null,
],
[
'name' => 'app_touch_icon',
'value' => null,
],
[
'name' => 'google_analytics',
'value' => null,
],
[
'name' => 'contact_email',
'value' => null,
],
[
'name' => 'registration',
'value' => 0,
],
[
'name' => 'storage_limitation',
'value' => 1,
],
[
'name' => 'storage_default',
'value' => 5,
],
[
'name' => 'setup_wizard_success',
'value' => 1,
],
[
'name' => 'license',
'value' => $this->license,
],
[
'name' => 'purchase_code',
'value' => '26b889eb-3602-4bf2-beb3-3sc378fcf484',
],
[
'name' => 'billing_address',
'value' => null,
],
[
'name' => 'billing_city',
'value' => null,
],
[
'name' => 'billing_country',
'value' => null,
],
[
'name' => 'billing_name',
'value' => null,
],
[
'name' => 'billing_phone_number',
'value' => null,
],
[
'name' => 'billing_postal_code',
'value' => null,
],
[
'name' => 'billing_state',
'value' => null,
],
[
'name' => 'billing_vat_number',
'value' => null,
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
}
/**
* Create default admin account
*/
private function create_admin(): void
{
$user = User::forceCreate([
'role' => 'admin',
'email' => 'howdy@hi5ve.digital',
'password' => bcrypt('vuefilemanager'),
]);
$user
->settings()
->create([
'storage_capacity' => 5,
'name' => 'Admin',
]);
// Show user credentials
$this->info('Default admin account created. Email: howdy@hi5ve.digital and Password: vuefilemanager');
}
/**
* Migrate database and generate application keys
*/
private function migrate_and_generate(): void
{
// Migrate database
$this->call('migrate:fresh', [
'--force' => true,
]);
// Generate app key
$this->call('key:generate', [
'--force' => true,
]);
}
/**
* Clear app cache
*/
private function clear_cache(): void
{
$this->call('cache:clear');
$this->call('config:clear');
$this->call('view:clear');
}
}

View File

@@ -1,69 +0,0 @@
<?php
namespace App\Console;
use App\Services\SchedulerService;
use Illuminate\Console\Scheduling\Schedule;
use App\Console\Commands\SetupDevEnvironment;
use App\Console\Commands\SetupProdEnvironment;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
SetupDevEnvironment::class,
SetupProdEnvironment::class,
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$scheduler = resolve(SchedulerService::class);
$schedule->call(function () use ($scheduler) {
$scheduler->delete_expired_shared_links();
})->everyTenMinutes();
$schedule->call(function () use ($scheduler) {
$scheduler->delete_old_zips();
if (! is_storage_driver(['local'])) {
$scheduler->delete_failed_files();
}
})->everySixHours();
// Run queue jobs every minute
$schedule->command('queue:work --stop-when-empty')
->everyMinute()
->withoutOverlapping();
// Backup app database daily
$schedule->command('backup:clean')
->daily()
->at('01:00');
$schedule->command('backup:run --only-db')
->daily()
->at('01:30');
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
}

View File

@@ -1,57 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Models\User;
use ByteUnits\Metric;
use App\Services\StripeService;
use Laravel\Cashier\Subscription;
use App\Http\Controllers\Controller;
use App\Http\Resources\UsersCollection;
class DashboardController extends Controller
{
private StripeService $stripe;
public function __construct(StripeService $stripe)
{
$this->stripe = $stripe;
}
/**
* Get data for dashboard
*
* @return array
*/
public function index()
{
// Get total premium users
$premium_users = Subscription::whereStripeStatus('active')
->count();
// Get total storage usage
$storage_usage = Metric::bytes(
\DB::table('files')->sum('filesize')
)->format();
return [
'license' => get_setting('license'),
'app_version' => config('vuefilemanager.version'),
'total_users' => User::count(),
'total_used_space' => $storage_usage,
'total_premium_users' => $premium_users,
];
}
/**
* Get the newest users
*
* @return UsersCollection
*/
public function newbies()
{
return new UsersCollection(
User::sortable(['created_at' => 'desc'])
->paginate(10)
);
}
}

View File

@@ -1,44 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Invoice;
use App\Services\StripeService;
use App\Http\Controllers\Controller;
use App\Http\Resources\InvoiceResource;
use App\Http\Resources\InvoiceAdminCollection;
class InvoiceController extends Controller
{
private StripeService $stripe;
public function __construct(StripeService $stripe)
{
$this->stripe = $stripe;
}
/**
* Get all invoices
*
* @return InvoiceAdminCollection
*/
public function index()
{
return new InvoiceAdminCollection(
$this->stripe->getInvoices()['data']
);
}
/**
* Get single invoice by invoice $token
*
* @param $customer
* @param $token
* @return InvoiceResource|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*/
public function show($customer, $token)
{
return view('vuefilemanager.invoice')
->with('settings', get_settings_in_json())
->with('invoice', $this->stripe->getUserInvoice($customer, $token));
}
}

View File

@@ -1,138 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Setting;
use App\Models\Language;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use App\Http\Resources\LanguageResource;
use App\Http\Resources\LanguageCollection;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Requests\Languages\UpdateStringRequest;
use App\Http\Requests\Languages\CreateLanguageRequest;
use App\Http\Requests\Languages\UpdateLanguageRequest;
class LanguageController extends Controller
{
/**
* Get all languages for admin translate
*
* @return array|Application|ResponseFactory|Response
*/
public function get_languages()
{
return response(
new LanguageCollection(Language::sortable(['created_at', 'DESC'])->get()),
200
);
}
/**
* Get all language strings for admin translate
*
* @param Language $language
*/
public function get_language(Language $language)
{
return response(
new LanguageResource($language),
200
);
}
/**
* Create new language
*
* @param CreateLanguageRequest $request
* @return string
*/
public function create_language(CreateLanguageRequest $request)
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
$language = Language::create([
'name' => $request->input('name'),
'locale' => $request->input('locale'),
]);
return response(
new LanguageResource($language),
201
);
}
/**
* Update language
*
* @param UpdateLanguageRequest $request
* @param Language $language
*/
public function update_language(UpdateLanguageRequest $request, Language $language)
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
$language->update(make_single_input($request));
return response(
new LanguageResource($language),
201
);
}
/**
* Update string for language
*
* @param UpdateStringRequest $request
* @param Language $language
* @return Application|ResponseFactory|Response
*/
public function update_string(UpdateStringRequest $request, Language $language)
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
$language
->languageTranslations()
->where('key', $request->name)
->update([
'value' => $request->value,
]);
cache()->forget("language-translations-{$language->locale}");
return response(
'Done',
204
);
}
/**
* Delete the language with all children strings
* @param Language $language
* @return Response
*/
public function delete_language(Language $language): Response
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
abort_if($language->locale === 'en', 401, "Sorry, you can't delete default language.");
// If user try to delete language used as default,
// then set en language as default
if ($language->locale === get_setting('language')) {
Setting::whereName('language')->first()
->update(['value' => 'en']);
}
$language->delete();
return response(
'Done',
204
);
}
}

View File

@@ -1,64 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Page;
use Illuminate\Http\Request;
use App\Services\DemoService;
use Illuminate\Http\Response;
use App\Http\Controllers\Controller;
use App\Http\Resources\PageResource;
use App\Http\Resources\PageCollection;
use Illuminate\Contracts\Routing\ResponseFactory;
class PagesController extends Controller
{
private $demo;
public function __construct()
{
$this->demo = resolve(DemoService::class);
}
/**
* Get all pages
*
* @return PageCollection
*/
public function index()
{
return new PageCollection(
Page::sortable()
->paginate(10)
);
}
/**
* Get single page resource
*
* @param $page
* @return PageResource
*/
public function show(Page $page)
{
return new PageResource($page);
}
/**
* Update page content
*
* @param Request $request
* @param Page $page
* @return ResponseFactory|Response
*/
public function update(Request $request, Page $page)
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
$page->update(
make_single_input($request)
);
return response(new PageResource($page), 204);
}
}

View File

@@ -1,158 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Plan;
use App\Models\User;
use Illuminate\Http\Request;
use App\Services\DemoService;
use Illuminate\Http\Response;
use App\Services\StripeService;
use Laravel\Cashier\Subscription;
use App\Http\Controllers\Controller;
use App\Http\Resources\PlanResource;
use Illuminate\Support\Facades\Cache;
use App\Http\Resources\PlanCollection;
use App\Http\Resources\UsersCollection;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
class PlanController extends Controller
{
private StripeService $stripe;
private DemoService $demo;
public function __construct()
{
$this->stripe = resolve(StripeService::class);
$this->demo = resolve(DemoService::class);
}
/**
* Get all plans
*
* @return PlanCollection|Application|ResponseFactory|Response
*/
public function index()
{
// Store or Get plans to cache
if (Cache::has('plans')) {
$plans = Cache::get('plans');
} else {
$plans = Cache::rememberForever('plans', function () {
return $this->stripe->getPlans();
});
}
return response(new PlanCollection($plans), 200);
}
/**
* Get plan record
*
* @param $id
* @return PlanResource|Application|ResponseFactory|Response
*/
public function show($id)
{
// Store or Get plan to cache
if (Cache::has('plan-' . $id)) {
$plan = Cache::get('plan-' . $id);
} else {
$plan = Cache::rememberForever('plan-' . $id, function () use ($id) {
return $this->stripe->getPlan($id);
});
}
return response(new PlanResource($plan), 200);
}
/**
* Create new plan
*
* @param Request $request
* @return PlanResource|Application|ResponseFactory|Response
*/
public function store(Request $request)
{
// TODO: inline request
if (is_demo()) {
if (Cache::has('plan-starter-pack')) {
$plan = Cache::get('plan-starter-pack');
} else {
$plan = Cache::rememberForever('plan-starter-pack', function () {
return $this->stripe->getPlan('starter-pack');
});
}
return new PlanResource($plan);
}
$plan = new PlanResource(
$this->stripe->createPlan($request)
);
// Clear cached plans
cache_forget_many(['plans', 'pricing']);
return response($plan, 201);
}
/**
* Update plan attribute
*
* @param Request $request
* @param $id
* @return ResponseFactory|Response
*/
public function update(Request $request, $id)
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
// Update plan
$this->stripe->updatePlan($request, $id);
// Clear cached plans
cache_forget_many(['plans', 'pricing', 'plan-' . $id]);
return response('Saved!', 201);
}
/**
* Delete plan
*
* @param $id
* @return ResponseFactory|Response
*/
public function delete($id)
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
// Delete plan
$this->stripe->deletePlan($id);
// Clear cached plans
cache_forget_many(['plans', 'pricing']);
return response('Done!', 204);
}
/**
* Get subscriptions
*
* @param $id
* @return mixed
*/
public function subscribers($id)
{
$subscribers = Subscription::whereStripePlan($id)
->pluck('user_id');
return new UsersCollection(
User::sortable()
->findMany($subscribers)
);
}
}

View File

@@ -1,182 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use Stripe;
use Artisan;
use App\Models\Setting;
use Illuminate\Http\Request;
use App\Services\DemoService;
use App\Http\Controllers\Controller;
use Cartalyst\Stripe\Exception\UnauthorizedException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class SettingController extends Controller
{
private $demo;
public function __construct()
{
$this->demo = resolve(DemoService::class);
}
/**
* Get table content
*
* @param Request $request
* @return mixed
*/
public function show(Request $request)
{
if (strpos($request->column, '|') !== false) {
$columns = explode('|', $request->column);
return Setting::whereIn('name', $columns)
->pluck('value', 'name');
}
return Setting::where('name', $request->column)
->pluck('value', 'name');
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function update(Request $request)
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
// Store image if exist
if ($request->hasFile($request->name)) {
// Find and update image path
Setting::updateOrCreate([
'name' => $request->name,
], [
'value' => store_system_image($request, $request->name),
]);
return response('Done', 204);
}
// Find and update variable
Setting::updateOrCreate(
['name' => $request->name],
['value' => $request->value]
);
return response('Done', 204);
}
/**
* Set new email credentials to .env file
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function set_email(Request $request)
{
// TODO: pridat validator do requestu
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
if (! app()->runningUnitTests()) {
setEnvironmentValue([
'MAIL_DRIVER' => $request->driver,
'MAIL_HOST' => $request->host,
'MAIL_PORT' => $request->port,
'MAIL_USERNAME' => $request->username,
'MAIL_PASSWORD' => $request->password,
'MAIL_ENCRYPTION' => $request->encryption,
]);
// Clear config cache
Artisan::call('config:clear');
Artisan::call('config:cache');
}
return response('Done', 204);
}
/**
* Configure stripe additionally
*
* @param Request $request
*/
public function set_stripe(Request $request)
{
// TODO: pridat validator do requestu
// Check payment setup status
if (get_setting('payments_configured')) {
abort(401, 'Gone');
}
// Try to get stripe account details
try {
if (! app()->runningUnitTests()) {
Stripe::make($request->secret, '2020-03-02')
->account()
->details();
}
} catch (UnauthorizedException $e) {
throw new HttpException(401, $e->getMessage());
}
// Get options
collect([
[
'name' => 'stripe_currency',
'value' => $request->currency,
],
[
'name' => 'payments_configured',
'value' => 1,
],
[
'name' => 'payments_active',
'value' => 1,
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
if (! app()->runningUnitTests()) {
// Set stripe credentials to .env
setEnvironmentValue([
'CASHIER_CURRENCY' => $request->currency,
'STRIPE_KEY' => $request->key,
'STRIPE_SECRET' => $request->secret,
'STRIPE_WEBHOOK_SECRET' => $request->webhookSecret,
]);
// Clear cache
Artisan::call('cache:clear');
Artisan::call('config:clear');
Artisan::call('config:cache');
}
return response('Done', 204);
}
/**
* Clear application cache
*/
public function flush_cache()
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
if (! app()->runningUnitTests()) {
Artisan::call('cache:clear');
Artisan::call('config:clear');
Artisan::call('config:cache');
}
return response('Done', 204);
}
}

View File

@@ -1,230 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use Storage;
use App\Models\User;
use App\Models\UserSettings;
use Illuminate\Http\Response;
use App\Services\StripeService;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserResource;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\UsersCollection;
use App\Http\Resources\UserSubscription;
use Illuminate\Support\Facades\Password;
use App\Http\Resources\InvoiceCollection;
use App\Http\Resources\UserStorageResource;
use App\Http\Requests\Admin\ChangeRoleRequest;
use App\Http\Requests\Admin\CreateUserByAdmin;
use App\Http\Requests\Admin\DeleteUserRequest;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Requests\Admin\ChangeStorageCapacityRequest;
class UserController extends Controller
{
private StripeService $stripe;
public function __construct(StripeService $stripe)
{
$this->stripe = $stripe;
}
/**
* Get user details
*
* @param User $user
* @return UserResource
*/
public function details(User $user)
{
return new UserResource(
$user
);
}
/**
* Get user storage details
*
* @param User $user
* @return UserStorageResource
*/
public function storage(User $user)
{
return new UserStorageResource(
$user
);
}
/**
* Get user storage details
*
* @param User $user
* @return InvoiceCollection
*/
public function invoices(User $user)
{
return new InvoiceCollection(
$this
->stripe
->getUserInvoices($user)
);
}
/**
* Get user subscription details
*
* @param User $user
* @return UserSubscription|Application|ResponseFactory|Response
*/
public function subscription(User $user)
{
if (! $user->stripeId() || ! $user->subscription('main')) {
return response("User doesn't have any subscription.", 404);
}
return new UserSubscription(
$user
);
}
/**
* Get all users
*
* @return UsersCollection
*/
public function users()
{
return new UsersCollection(
User::sortable(['created_at', 'DESC'])
->paginate(20)
);
}
/**
* Change user role
*
* @param ChangeRoleRequest $request
* @param User $user
* @return UserResource
*/
public function change_role(ChangeRoleRequest $request, User $user)
{
// Demo preview
if (is_demo_account('howdy@hi5ve.digial')) {
return new UserResource($user);
}
// Update user role
$user->role = $request->input('attributes.role');
$user->save();
return new UserResource(
$user
);
}
/**
* Change user storage capacity
*
* @param ChangeStorageCapacityRequest $request
* @param User $user
* @return UserStorageResource
*/
public function change_storage_capacity(ChangeStorageCapacityRequest $request, User $user)
{
$user
->settings()
->update(
$request->input('attributes')
);
return new UserStorageResource(
$user
);
}
/**
* Send user password reset link
*
* @param User $user
* @return ResponseFactory|Response
*/
public function reset_password(User $user)
{
// Demo preview
if (is_demo()) {
return response('Done!', 204);
}
// Get password token
$token = Password::getRepository()
->create($user);
// Send user email
$user->sendPasswordResetNotification($token);
return response('Done!', 204);
}
/**
* Create new user by admin
*
* @param CreateUserByAdmin $request
* @return UserResource|Application|ResponseFactory|Response
*/
public function create_user(CreateUserByAdmin $request)
{
// Create user
$user = User::forceCreate([
'role' => $request->role,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
UserSettings::unguard();
$user
->settings()
->create([
'name' => $request->name,
'avatar' => store_avatar($request, 'avatar'),
'storage_capacity' => $request->storage_capacity,
]);
UserSettings::reguard();
return response(new UserResource($user), 201);
}
/**
* Delete user with all user data
*
* @param DeleteUserRequest $request
* @param User $user
* @return ResponseFactory|Response
* @throws \Exception
*/
public function delete_user(DeleteUserRequest $request, User $user)
{
if (is_demo()) {
return response('Done!', 204);
}
if ($user->subscribed('main')) {
abort(202, "You can\'t delete this account while user have active subscription.");
}
if ($user->id === Auth::id()) {
abort(406, "You can\'t delete your account");
}
if ($user->settings->name !== $request->name) {
abort(403, 'The name you typed is wrong!');
}
$user->delete();
return response('Done!', 204);
}
}

View File

@@ -1,202 +0,0 @@
<?php
namespace App\Http\Controllers\App;
use App\Models\Page;
use App\Models\Share;
use App\Models\Setting;
use App\Models\Language;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Services\StripeService;
use App\Http\Controllers\Controller;
use App\Http\Resources\PageResource;
use Illuminate\Support\Facades\Mail;
use App\Http\Mail\SendContactMessage;
use Illuminate\Support\Facades\Cache;
use Doctrine\DBAL\Driver\PDOException;
use Illuminate\Database\QueryException;
use App\Http\Resources\PricingCollection;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use App\Http\Requests\PublicPages\SendContactMessageRequest;
class AppFunctionsController extends Controller
{
/**
* List of allowed settings to get from public request
*
* @var array
*/
private array $blacklist = [
'purchase_code',
'license',
];
private StripeService $stripe;
public function __construct(StripeService $stripe)
{
$this->stripe = $stripe;
}
/**
* Show index page
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
try {
// Try to connect to database
\DB::getPdo();
// Get setup status
$setup_status = get_setup_status();
// Get app pages
$pages = Page::all();
// Get all settings
$settings = get_settings_in_json();
} catch (PDOException $e) {
$setup_status = 'setup-database';
}
return view('index')
->with('settings', $settings ?? null)
->with('legal', $pages ?? null)
->with('installation', $setup_status);
}
/**
* Get og site for web crawlers
*
* @param Share $shared
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
*/
public function og_site(Share $shared)
{
// Get file/folder record
$item = ('App\\Models\\' . ucfirst($shared->type))
::where('user_id', $shared->user->id)
->where('id', $shared->item_id)
->first();
if ($item->thumbnail) {
$item->setPublicUrl($shared->token);
}
return view('vuefilemanager.crawler.og-view')
->with('settings', get_settings_in_json())
->with('metadata', [
'url' => url('/share', ['token' => $shared->token]),
'is_protected' => $shared->is_protected,
'user' => $shared->user->settings->name,
'name' => $item->name,
'size' => $shared->type === 'folder'
? $item->items
: $item->filesize,
'thumbnail' => $item->thumbnail ?? null,
]);
}
/**
* Send contact message from pages
*
* @param SendContactMessageRequest $request
* @return ResponseFactory|Response
*/
public function contact_form(SendContactMessageRequest $request)
{
Mail::to(
get_setting('contact_email')
)->send(
new SendContactMessage($request->all())
);
return response('Done', 201);
}
/**
* Get single page content
*
* @param Page $page
* @return PageResource
*/
public function get_page(Page $page)
{
return new PageResource($page);
}
/**
* Get selected settings from public route
*
* @param Request $request
* @return mixed
*/
public function get_setting_columns(Request $request)
{
if (strpos($request->column, '|') !== false) {
$columns = collect(explode('|', $request->column))
->each(function ($column) {
if (in_array($column, $this->blacklist)) {
abort(401);
}
});
return Setting::whereIn('name', $columns)
->pluck('value', 'name');
}
if (in_array($request->column, $this->blacklist)) {
abort(401);
}
return Setting::where('name', $request->column)
->pluck('value', 'name');
}
/**
* Get all active storage plans
*
* @return PricingCollection
*/
public function get_storage_plans()
{
// Get pricing from cache
$pricing = Cache::rememberForever('pricing', function () {
return $this->stripe->getActivePlans();
});
// Format pricing to collection
$collection = new PricingCollection($pricing);
// Sort and return pricing
return $collection
->sortBy('product.metadata.capacity')
->values()
->all();
}
/**
* Get language translations for frontend app
*/
public function get_translations($lang)
{
$translations = cache()
->rememberForever("language-translations-$lang", function () use ($lang) {
try {
return Language::whereLocale($lang)
->firstOrFail()
->languageTranslations;
} catch (QueryException | ModelNotFoundException $e) {
return null;
}
});
return $translations
? map_language_translations($translations)
: get_default_language_translations();
}
}

View File

@@ -1,84 +0,0 @@
<?php
namespace App\Http\Controllers\App;
use Gate;
use Artisan;
use App\Models\Language;
use Illuminate\Http\Response;
use App\Services\LanguageService;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
class Maintenance extends Controller
{
/**
* Start maintenance mode
*/
public function up()
{
// Check admin permission
Gate::authorize('maintenance');
$command = Artisan::call('up');
if ($command === 0) {
echo 'System is in production mode';
}
}
/**
* End maintenance mode
*/
public function down()
{
// Check admin permission
Gate::authorize('maintenance');
$command = Artisan::call('down');
if ($command === 0) {
echo 'System is in maintenance mode';
}
}
/**
* Get new language translations from default translations
* and insert it into database
*
* @return Application|ResponseFactory|Response
*/
public function upgrade_translations()
{
// Check admin permission
Gate::authorize('maintenance');
resolve(LanguageService::class)
->upgrade_language_translations();
return response('Done.', 201);
}
/**
* @return int|mixed
*/
public function upgrade_database()
{
// Check admin permission
Gate::authorize('maintenance');
$command = Artisan::call('migrate', [
'--force' => true,
]);
if ($command === 0) {
echo 'Operation was successful.';
}
if ($command === 1) {
echo 'Operation failed.';
}
return $command;
}
}

View File

@@ -1,479 +0,0 @@
<?php
namespace App\Http\Controllers\App;
use Schema;
use Stripe;
use Artisan;
use App\Models\User;
use App\Models\Setting;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Services\SetupService;
use App\Services\StripeService;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
use Doctrine\DBAL\Driver\PDOException;
use Illuminate\Contracts\Routing\ResponseFactory;
use Cartalyst\Stripe\Exception\UnauthorizedException;
use App\Http\Requests\SetupWizard\StoreAppSetupRequest;
use Symfony\Component\HttpKernel\Exception\HttpException;
use App\Http\Requests\SetupWizard\StoreStripePlansRequest;
use App\Http\Requests\SetupWizard\StoreStripeBillingRequest;
use App\Http\Requests\SetupWizard\StoreEnvironmentSetupRequest;
use App\Http\Requests\SetupWizard\StoreStripeCredentialsRequest;
use App\Http\Requests\SetupWizard\StoreDatabaseCredentialsRequest;
class SetupWizardController extends Controller
{
/**
* Inject Stripe Service
*/
public function __construct()
{
$this->stripe = resolve(StripeService::class);
$this->setup = resolve(SetupService::class);
$this->check_setup_status();
}
/**
* Verify Envato purchase code
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response|mixed
*/
public function verify_purchase_code(Request $request)
{
// Verify purchase code
$response = Http::get('https://verify.vuefilemanager.com/api/verify-code/' . $request->purchaseCode);
if ($response->successful()) {
return response($response, 204);
}
return response('Purchase code is invalid.', 400);
}
/**
* Set up database credentials
*
* @param StoreDatabaseCredentialsRequest $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function setup_database(StoreDatabaseCredentialsRequest $request)
{
if (! app()->runningUnitTests()) {
try {
// Set temporary database connection
config(['database.connections.test.driver' => $request->connection]);
config(['database.connections.test.host' => $request->host]);
config(['database.connections.test.port' => $request->port]);
config(['database.connections.test.database' => $request->name]);
config(['database.connections.test.username' => $request->username]);
config(['database.connections.test.password' => $request->password]);
// Test connection
\DB::connection('test')->getPdo();
} catch (PDOException $e) {
throw new HttpException(500, $e->getMessage());
}
// TODO: add SANCTUM_STATEFUL_DOMAINS parameter
setEnvironmentValue([
'DB_CONNECTION' => $request->connection,
'DB_HOST' => $request->host,
'DB_PORT' => $request->port,
'DB_DATABASE' => $request->name,
'DB_USERNAME' => $request->username,
'DB_PASSWORD' => $request->password,
]);
Artisan::call('config:cache');
Artisan::call('key:generate', [
'--force' => true,
]);
Artisan::call('migrate:fresh', [
'--force' => true,
]);
}
// Store setup wizard progress
Setting::forceCreate([
'name' => 'setup_wizard_database',
'value' => 1,
]);
return response('Done', 204);
}
/**
* Store and test stripe credentials
*
* @param StoreStripeCredentialsRequest $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function store_stripe_credentials(StoreStripeCredentialsRequest $request)
{
if (! app()->runningUnitTests()) {
// Create stripe instance
$stripe = Stripe::make($request->secret, '2020-03-02');
try {
// Try to get stripe account details
$stripe->account()->details();
} catch (UnauthorizedException $e) {
throw new HttpException(401, $e->getMessage());
}
}
// Set settings
collect([
[
'name' => 'stripe_currency',
'value' => $request->currency,
],
[
'name' => 'payments_configured',
'value' => 1,
],
[
'name' => 'payments_active',
'value' => 1,
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
if (! app()->runningUnitTests()) {
// Set stripe credentials to .env
setEnvironmentValue([
'CASHIER_CURRENCY' => $request->currency,
'STRIPE_KEY' => $request->key,
'STRIPE_SECRET' => $request->secret,
'STRIPE_WEBHOOK_SECRET' => $request->webhookSecret,
]);
// Clear cache
Artisan::call('config:cache');
}
return response('Done', 204);
}
/**
* Store Stripe billings
*
* @param StoreStripeBillingRequest $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function store_stripe_billings(StoreStripeBillingRequest $request)
{
// Get options
collect([
[
'name' => 'billing_phone_number',
'value' => $request->billing_phone_number,
],
[
'name' => 'billing_postal_code',
'value' => $request->billing_postal_code,
],
[
'name' => 'billing_vat_number',
'value' => $request->billing_vat_number,
],
[
'name' => 'billing_address',
'value' => $request->billing_address,
],
[
'name' => 'billing_country',
'value' => $request->billing_country,
],
[
'name' => 'billing_state',
'value' => $request->billing_state,
],
[
'name' => 'billing_city',
'value' => $request->billing_city,
],
[
'name' => 'billing_name',
'value' => $request->billing_name,
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
if (! app()->runningUnitTests()) {
Artisan::call('config:cache');
}
return response('Done', 204);
}
/**
* Create Stripe subscription plan
*
* @param StoreStripePlansRequest $request
* @return \Illuminate\Contracts\Foundation\Application|ResponseFactory|\Illuminate\Http\Response
*/
public function store_stripe_plans(StoreStripePlansRequest $request)
{
foreach ($request->plans as $plan) {
$this->stripe->createPlan($plan);
}
return response('Done', 204);
}
/**
* Store environment setup
*
* @param StoreEnvironmentSetupRequest $request
* @return string
*/
public function store_environment_setup(StoreEnvironmentSetupRequest $request)
{
if (! app()->runningUnitTests()) {
$drivers = [
'local' => [
'FILESYSTEM_DRIVER' => 'local',
],
's3' => [
'FILESYSTEM_DRIVER' => $request->storage['driver'] ?? null,
'AWS_ACCESS_KEY_ID' => $request->storage['key'] ?? null,
'AWS_SECRET_ACCESS_KEY' => $request->storage['secret'] ?? null,
'AWS_DEFAULT_REGION' => $request->storage['region'] ?? null,
'AWS_BUCKET' => $request->storage['bucket'] ?? null,
],
'spaces' => [
'FILESYSTEM_DRIVER' => $request->storage['driver'] ?? null,
'DO_SPACES_KEY' => $request->storage['key'] ?? null,
'DO_SPACES_SECRET' => $request->storage['secret'] ?? null,
'DO_SPACES_ENDPOINT' => $request->storage['endpoint'] ?? null,
'DO_SPACES_REGION' => $request->storage['region'] ?? null,
'DO_SPACES_BUCKET' => $request->storage['bucket'] ?? null,
],
'wasabi' => [
'FILESYSTEM_DRIVER' => $request->storage['driver'] ?? null,
'WASABI_KEY' => $request->storage['key'] ?? null,
'WASABI_SECRET' => $request->storage['secret'] ?? null,
'WASABI_ENDPOINT' => $request->storage['endpoint'] ?? null,
'WASABI_REGION' => $request->storage['region'] ?? null,
'WASABI_BUCKET' => $request->storage['bucket'] ?? null,
],
'backblaze' => [
'FILESYSTEM_DRIVER' => $request->storage['driver'] ?? null,
'BACKBLAZE_KEY' => $request->storage['key'] ?? null,
'BACKBLAZE_SECRET' => $request->storage['secret'] ?? null,
'BACKBLAZE_ENDPOINT' => $request->storage['endpoint'] ?? null,
'BACKBLAZE_REGION' => $request->storage['region'] ?? null,
'BACKBLAZE_BUCKET' => $request->storage['bucket'] ?? null,
],
'oss' => [
'FILESYSTEM_DRIVER' => $request->storage['driver'] ?? null,
'OSS_ACCESS_KEY_ID' => $request->storage['key'] ?? null,
'OSS_SECRET_ACCESS_KEY' => $request->storage['secret'] ?? null,
'OSS_ENDPOINT' => $request->storage['endpoint'] ?? null,
'OSS_REGION' => $request->storage['region'] ?? null,
'OSS_BUCKET' => $request->storage['bucket'] ?? null,
],
];
// Storage credentials for storage
setEnvironmentValue(
$drivers[$request->storage['driver']]
);
// Store credentials for mail
// TODO: add options for mailgun
setEnvironmentValue([
'MAIL_DRIVER' => $request->mail['driver'],
'MAIL_HOST' => $request->mail['host'],
'MAIL_PORT' => $request->mail['port'],
'MAIL_USERNAME' => $request->mail['username'],
'MAIL_PASSWORD' => $request->mail['password'],
'MAIL_ENCRYPTION' => $request->mail['encryption'],
]);
Artisan::call('config:cache');
}
return response('Done', 204);
}
/**
* Store app settings
* @param StoreAppSetupRequest $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function store_app_settings(StoreAppSetupRequest $request)
{
// Get options
collect([
[
'name' => 'app_title',
'value' => $request->title,
],
[
'name' => 'app_description',
'value' => $request->description,
],
[
'name' => 'app_logo',
'value' => store_system_image($request, 'logo'),
],
[
'name' => 'app_logo_horizontal',
'value' => store_system_image($request, 'logo_horizontal'),
],
[
'name' => 'app_favicon',
'value' => store_system_image($request, 'favicon'),
],
[
'name' => 'app_og_image',
'value' => store_system_image($request, 'og_image'),
],
[
'name' => 'app_touch_icon',
'value' => store_system_image($request, 'touch_icon'),
],
[
'name' => 'google_analytics',
'value' => $request->googleAnalytics,
],
[
'name' => 'contact_email',
'value' => $request->contactMail,
],
[
'name' => 'registration',
'value' => $request->userRegistration,
],
[
'name' => 'storage_limitation',
'value' => $request->storageLimitation,
],
[
'name' => 'storage_default',
'value' => $request->defaultStorage ?? 5,
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
if (! app()->runningUnitTests()) {
setEnvironmentValue([
'APP_NAME' => Str::camel($request->title),
]);
}
return response('Done', 204);
}
/**
* Create and login admin account
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
*/
public function create_admin_account(Request $request)
{
// Validate request
// TODO: validator do requestu
$request->validate([
'email' => 'required|string|email|unique:users',
'password' => 'required|string|min:6|confirmed',
'name' => 'required|string',
'purchase_code' => 'required|string',
'license' => 'required|string',
'avatar' => 'sometimes|file',
]);
// Create user
$user = User::forceCreate([
'role' => 'admin',
'email' => $request->email,
'password' => bcrypt($request->password),
]);
$user
->settings()
->create([
'storage_capacity' => get_setting('storage_default') ?? 5,
'avatar' => store_avatar($request, 'avatar'),
'name' => $request->name,
]);
collect([
[
'name' => 'setup_wizard_success',
'value' => 1,
],
[
'name' => 'license',
'value' => $request->license,
],
[
'name' => 'purchase_code',
'value' => $request->purchase_code,
],
])->each(function ($col) {
Setting::forceCreate([
'name' => $col['name'],
'value' => $col['value'],
]);
});
// Set up application
$this->setup->seed_default_pages();
$this->setup->seed_default_settings($request->license);
$this->setup->seed_default_language();
// Login account
if (Auth::attempt($request->only(['email', 'password']))) {
$request->session()->regenerate();
return response('Registration was successful', 204);
}
return response('Something went wrong', 500);
}
/**
* Get setup wizard status
*
* @return false | null
*/
private function check_setup_status()
{
try {
// Check database connections
DB::getPdo();
// Get setup_wizard status
if (Schema::hasTable('settings') && get_setting('setup_wizard_success')) {
abort(410, 'Gone');
}
} catch (PDOException $e) {
return false;
}
}
}

View File

@@ -1,31 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Models\User;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\CheckAccountRequest;
class AuthController extends Controller
{
/**
* Check if user account exist
*
* @param CheckAccountRequest $request
* @return mixed
*/
public function check_account(CheckAccountRequest $request)
{
// Get User
$user = User::whereEmail($request->email)
->first();
if (! $user) {
return response(__t('user_not_fount'), 404);
}
return [
'name' => $user->settings->name,
'avatar' => $user->settings->avatar,
];
}
}

View File

@@ -1,215 +0,0 @@
<?php
namespace App\Http\Controllers\FileManager;
use App\Models\File;
use App\Models\User;
use App\Models\Share;
use App\Models\Folder;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests\FileBrowser\SearchRequest;
class BrowseController extends Controller
{
/**
* Get directory with files
*
* @param Request $request
* @param $id
* @return Collection
*/
public function folder(Request $request, $id)
{
$root_id = $id === 'undefined' ? null : $id;
// Get folder trash items
if ($request->query('trash')) {
// Get folders and files
$folders = Folder::onlyTrashed()
->with('parent')
->where('parent_id', $root_id)
->sortable()
->get();
$files = File::onlyTrashed()
->with('parent')
->where('folder_id', $root_id)
->sortable()
->get();
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
// Get folders and files
$folders = Folder::with(['parent:id,name', 'shared:token,id,item_id,permission,is_protected,expire_in'])
->where('parent_id', $root_id)
->where('user_id', Auth::id())
->sortable()
->get();
$files = File::with(['parent:id,name', 'shared:token,id,item_id,permission,is_protected,expire_in'])
->where('folder_id', $root_id)
->where('user_id', Auth::id())
->sortable()
->get();
// Collect folders and files to single array
return collect([$folders, $files])
->collapse();
}
/**
* Get latest user uploads
*
* @return mixed
*/
public function latest()
{
$user = User::with(['latest_uploads' => function ($query) {
$query->sortable(['created_at' => 'desc']);
}])
->where('id', Auth::id())
->first();
return $user->latest_uploads;
}
/**
* Get trashed files
*
* @return Collection
*/
public function trash()
{
$user_id = Auth::id();
// Get folders and files
$folders_trashed = Folder::onlyTrashed()
->with(['trashed_folders', 'parent'])
->where('user_id', $user_id)
->get(['parent_id', 'id', 'name']);
$folders = Folder::onlyTrashed()
->with(['parent'])
->where('user_id', $user_id)
->whereIn('id', filter_folders_ids($folders_trashed))
->sortable()
->get();
// Get files trashed
$files_trashed = File::onlyTrashed()
->with(['parent'])
->where('user_id', $user_id)
->where(function ($query) use ($folders_trashed) {
$query->whereNull('folder_id');
$query->orWhereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'id'))));
})
->sortable()
->get();
// Collect folders and files to single array
return collect([$folders, $files_trashed])
->collapse();
}
/**
* Get user shared items
*
* @return Collection
*/
public function shared()
{
$user_id = Auth::id();
// Get shared folders and files
$folder_ids = Share::where('user_id', $user_id)
->where('type', 'folder')
->pluck('item_id');
$file_ids = Share::where('user_id', $user_id)
->where('type', '!=', 'folder')
->pluck('item_id');
// Get folders and files
$folders = Folder::with(['parent', 'shared:token,id,item_id,permission,is_protected,expire_in'])
->where('user_id', $user_id)
->whereIn('id', $folder_ids)
->sortable()
->get();
$files = File::with(['parent', 'shared:token,id,item_id,permission,is_protected,expire_in'])
->where('user_id', $user_id)
->whereIn('id', $file_ids)
->sortable()
->get();
// Collect folders and files to single array
return collect([$folders, $files])
->collapse();
}
/**
* Get participant uploads
*
* @return mixed
*/
public function participant_uploads()
{
return File::with(['parent'])
->where('user_id', Auth::id())
->whereAuthor('visitor')
->sortable()
->get();
}
/**
* Get user folder tree
*
* @return array
*/
public function navigation_tree()
{
$folders = Folder::with('folders:id,parent_id,id,name')
->where('parent_id', null)
->where('user_id', Auth::id())
->sortable()
->get(['id', 'parent_id', 'id', 'name']);
return [
[
'name' => __t('home'),
'location' => 'base',
'folders' => $folders,
],
];
}
/**
* Search files
*
* @param SearchRequest $request
* @return Collection
*/
public function search(SearchRequest $request)
{
$user_id = Auth::id();
$query = remove_accents($request->input('query'));
// Search files id db
$searched_files = File::search($query)
->where('user_id', $user_id)
->get();
$searched_folders = Folder::search($query)
->where('user_id', $user_id)
->get();
// Collect folders and files to single array
return collect([$searched_folders, $searched_files])
->collapse();
}
}

View File

@@ -1,167 +0,0 @@
<?php
namespace App\Http\Controllers\FileManager;
use Exception;
use App\Models\File;
use App\Models\Folder;
use Illuminate\Http\Request;
use App\Services\DemoService;
use App\Services\HelperService;
use App\Http\Controllers\Controller;
use App\Services\FileManagerService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Requests\FileFunctions\UploadRequest;
use App\Http\Requests\FileFunctions\MoveItemRequest;
use App\Http\Requests\FileFunctions\DeleteItemRequest;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\Http\Requests\FileFunctions\CreateFolderRequest;
class EditItemsController extends Controller
{
private $filemanager;
private $helper;
private $demo;
public function __construct()
{
$this->filemanager = resolve(FileManagerService::class);
$this->helper = resolve(HelperService::class);
$this->demo = resolve(DemoService::class);
}
/**
* Create new folder for authenticated master|editor user
*
* @param CreateFolderRequest $request
* @return Folder|array|Model
* @throws Exception
*/
public function create_folder(CreateFolderRequest $request)
{
if (is_demo_account('howdy@hi5ve.digital')) {
return $this->demo->create_folder($request);
}
// Create new folder
return $this->filemanager->create_folder($request);
}
/**
* Rename item for authenticated master|editor user
*
* @param RenameItemRequest $request
* @param $id
* @return mixed
* @throws Exception
*/
public function rename_item(RenameItemRequest $request, $id)
{
if (is_demo_account('howdy@hi5ve.digital')) {
return $this->demo->rename_item($request, $id);
}
// If request contain icon or color, then change it
if ($request->filled('emoji') || $request->filled('color')) {
$this->filemanager->edit_folder_properties($request, $id);
}
// Rename Item
return $this->filemanager->rename_item($request, $id);
}
/**
* Delete item for authenticated master|editor user
*
* @param DeleteItemRequest $request
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function delete_item(DeleteItemRequest $request)
{
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
foreach ($request->input('items') as $item) {
$this->filemanager->delete_item($item, $item['id']);
}
return response('Done', 204);
}
/**
* Upload file for authenticated master|editor user
*
* @param UploadRequest $request
* @return array|Model|\Illuminate\Support\Facades\File
* @throws Exception
*/
public function upload(UploadRequest $request)
{
if (is_demo_account('howdy@hi5ve.digital')) {
return $this->demo->upload($request);
}
return $this->filemanager->upload($request);
}
/**
* Move item for authenticated master|editor user
*
* @param MoveItemRequest $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function move(MoveItemRequest $request)
{
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
$this->filemanager->move($request, $request->to_id);
return response('Done!', 204);
}
/**
* User download folder via zip
*
* @param $id
* @return string
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function zip_folder($id)
{
$folder = Folder::whereUserId(Auth::id())
->where('id', $id);
if (! $folder->exists()) {
abort(404, "Requested folder doesn't exists.");
}
$zip = $this->filemanager->zip_folder($id);
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 201);
}
/**
* User download multiple files via zip
*
* @param Request $request
* @return string
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function zip_multiple_files(Request $request)
{
$files = File::whereUserId(Auth::id())
->whereIn('id', $request->input('items'))
->get();
$zip = $this->filemanager->zip_files($files);
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 201);
}
}

View File

@@ -1,70 +0,0 @@
<?php
namespace App\Http\Controllers\FileManager;
use App\Models\Folder;
use Illuminate\Http\Request;
use App\Services\DemoService;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class FavouriteController extends Controller
{
/**
* FavouriteController constructor.
*/
public function __construct()
{
$this->demo = resolve(DemoService::class);
}
/**
* Add folder to user favourites
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function store(Request $request)
{
// todo: pridat validator ako AddToFavouritesRequest
foreach ($request->folders as $id) {
// Get user & folder
$user = Auth::user();
if (is_demo($user->id)) {
return $this->demo->favourites($user);
}
// Add folder to user favourites
$user
->favouriteFolders()
->syncWithoutDetaching($id);
}
// Return updated favourites
return response($user->favouriteFolders, 204);
}
/**
* Remove folder from user favourites
*
* @param $id
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function destroy($id)
{
// Get user
$user = Auth::user();
if (is_demo($user->id)) {
return $this->demo->favourites($user);
}
// Remove folder from user favourites
$user->favouriteFolders()->detach($id);
// Return updated favourites
return response($user->favouriteFolders, 204);
}
}

View File

@@ -1,143 +0,0 @@
<?php
namespace App\Http\Controllers\FileManager;
use App\Models\Zip;
use Illuminate\Http\Request;
use App\Services\HelperService;
use App\Models\File as UserFile;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class FileAccessController extends Controller
{
private $helper;
public function __construct()
{
$this->helper = resolve(HelperService::class);
}
/**
* Get avatar
*
* @param $basename
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_avatar($basename)
{
// Check if file exist
if (! Storage::exists("/avatars/$basename")) {
abort(404);
}
// Return avatar
return Storage::download("/avatars/$basename", $basename);
}
/**
* Get system image
*
* @param $basename
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_system_image($basename)
{
// Check if file exist
if (! Storage::exists("/system/$basename")) {
abort(404);
}
// Return avatar
return Storage::download("/system/$basename", $basename);
}
/**
* Get file
*
* @param Request $request
* @param $filename
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_file(Request $request, $filename)
{
// Get file record
$file = UserFile::withTrashed()
->where('user_id', Auth::id())
->where('basename', $filename)
->firstOrFail();
// Check user permission
/*if (!$request->user()->tokenCan('master')) {
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to file
$this->check_file_access($shared, $file);
}*/
// Store user download size
$request->user()->record_download(
(int) $file->getRawOriginal('filesize')
);
return $this->helper->download_file($file, Auth::id());
}
/**
* Get generated zip for user
*
* @param $id
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function get_zip($id)
{
$disk = Storage::disk('local');
$zip = Zip::whereId($id)
->where('user_id', Auth::id())
->firstOrFail();
$zip
->user
->record_download(
$disk->size("zip/$zip->basename")
);
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",
]);
}
/**
* Get image thumbnail
*
* @param Request $request
* @param $filename
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_thumbnail(Request $request, $filename)
{
// Get file record
$file = UserFile::withTrashed()
->whereUserId(Auth::id())
->whereThumbnail($filename)
->firstOrFail();
// Check user permission
/*if (!$request->user()->tokenCan('master')) {
$this->check_file_access($request, $file);
}*/
return $this->helper->download_thumbnail_file($file, Auth::id());
}
}

View File

@@ -1,148 +0,0 @@
<?php
namespace App\Http\Controllers\FileManager;
use Validator;
use App\Models\Zip;
use App\Models\Share;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\ShareResource;
use App\Notifications\SharedSendViaEmail;
use Illuminate\Support\Facades\Notification;
use App\Http\Requests\Share\CreateShareRequest;
use App\Http\Requests\Share\UpdateShareRequest;
use Illuminate\Contracts\Routing\ResponseFactory;
class ShareController extends Controller
{
/**
* Get shared record
*
* @param Share $shared
* @return ShareResource
*/
public function show(Share $shared)
{
return new ShareResource(
$shared
);
}
/**
* Generate file share link
*
* @param CreateShareRequest $request
* @param $id
* @return ShareResource
*/
public function store(CreateShareRequest $request, $id)
{
// Create shared options
$shared = Share::create([
'password' => $request->has('password') ? bcrypt($request->password) : null,
'type' => $request->type === 'folder' ? 'folder' : 'file',
'is_protected' => $request->isPassword,
'permission' => $request->permission ?? null,
'item_id' => $id,
'expire_in' => $request->expiration ?? null,
'user_id' => Auth::id(),
]);
// Send shared link via email
if ($request->has('emails')) {
foreach ($request->emails as $email) {
Notification::route('mail', $email)->notify(
new SharedSendViaEmail($shared->token)
);
}
}
// Return created shared record
return new ShareResource($shared);
}
/**
* Update sharing
*
* @param UpdateShareRequest $request
* @param $token
* @return ShareResource
*/
public function update(UpdateShareRequest $request, $token)
{
// Get sharing record
$shared = Share::where('token', $token)
->where('user_id', Auth::id())
->firstOrFail();
// Update sharing record
$shared->update([
'permission' => $request->permission,
'is_protected' => $request->protected,
'expire_in' => $request->expiration,
'password' => $request->password ? bcrypt($request->password) : $shared->password,
]);
// Return shared record
return new ShareResource($shared);
}
/**
* Delete sharing item
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function destroy(Request $request)
{
foreach ($request->tokens as $token) {
// Get sharing record
Share::where('token', $token)
->where('user_id', Auth::id())
->firstOrFail()
->delete();
// Get zip record
$zip = Zip::where('shared_token', $token)
->where('user_id', Auth::id())
->first();
if ($zip) {
$zip->delete();
}
}
return response('Done!', 204);
}
/**
* Send shared link via email to recipients
*
* @param $token
* @param $request
*/
public function send_to_emails_recipients(Request $request, $token)
{
// TODO: pridat validation request
// Make validation of array of emails
$validator = Validator::make($request->all(), [
'emails.*' => 'required|email',
]);
// Return error
if ($validator->fails()) {
abort(400, 'Bad email input');
}
// Send shared link via email
if ($request->has('emails')) {
foreach ($request->emails as $email) {
Notification::route('mail', $email)
->notify(new SharedSendViaEmail($token));
}
}
return response('Done!', 204);
}
}

View File

@@ -1,121 +0,0 @@
<?php
namespace App\Http\Controllers\FileManager;
use App\Models\File;
use App\Models\Folder;
use Illuminate\Http\Request;
use App\Services\DemoService;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Contracts\Routing\ResponseFactory;
class TrashController extends Controller
{
/**
* TrashController constructor.
*/
public function __construct()
{
$this->demo = resolve(DemoService::class);
}
/**
* Restore item from trash
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function restore(Request $request)
{
// Validate request
// TODO: zrefaktorovat validator do requestu
$validator = Validator::make($request->input('items'), [
'*.type' => 'required|string',
'*.id' => 'string',
]);
// Return error
if ($validator->fails()) {
abort(400, 'Bad input');
}
// Get user id
$user_id = Auth::id();
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
foreach ($request->input('items') as $restore) {
// Get folder
if ($restore['type'] === 'folder') {
// Get folder
$item = Folder::onlyTrashed()
->where('user_id', $user_id)
->where('id', $restore['id'])
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->parent_id = null;
$item->save();
}
} else {
// Get item
$item = File::onlyTrashed()
->where('user_id', $user_id)
->where('id', $restore['id'])
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->folder_id = null;
$item->save();
}
}
// Restore Item
$item->restore();
}
// Return response
return response('Done!', 204);
}
/**
* Empty user trash
*
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function dump()
{
// Get user id
$user_id = Auth::id();
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
// Get files and folders
$folders = Folder::onlyTrashed()->where('user_id', $user_id)->get();
$files = File::onlyTrashed()->where('user_id', $user_id)->get();
// Force delete folder
$folders->each->forceDelete();
// Force delete files
foreach ($files as $file) {
// Delete file
Storage::delete("/files/$user_id/{$file->basename}");
// Delete thumbnail if exist
if ($file->thumbnail) {
Storage::delete("/files/$user_id/{$file->getRawOriginal('thumbnail')}");
}
// Delete file permanently
$file->forceDelete();
}
// Return response
return response('Done!', 204);
}
}

View File

@@ -1,248 +0,0 @@
<?php
namespace App\Http\Controllers\Sharing;
use App\Models\File;
use App\Models\Share;
use App\Models\Folder;
use Illuminate\Support\Arr;
use Illuminate\Http\Request;
use App\Services\HelperService;
use Illuminate\Support\Collection;
use App\Http\Controllers\Controller;
use App\Http\Resources\FileResource;
use Illuminate\Support\Facades\Hash;
use App\Http\Resources\ShareResource;
use Illuminate\Support\Facades\Storage;
use App\Http\Requests\Share\AuthenticateShareRequest;
class BrowseShareController extends Controller
{
private $helper;
public function __construct()
{
$this->helper = resolve(HelperService::class);
}
/**
* Show page index and delete access_token & shared_token cookie
* @param Share $shared
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Symfony\Component\HttpFoundation\StreamedResponse
*/
public function index(Share $shared)
{
// Delete share_session if exist
if ($shared->is_protected) {
cookie()->queue('share_session', '', -1);
}
// Check if shared is image file and then show it
if ($shared->type === 'file' && ! $shared->is_protected) {
$image = File::whereUserId($shared->user_id)
->whereType('image')
->whereId($shared->item_id)
->first();
if ($image) {
// Store user download size
$shared
->user
->record_download(
(int) $image->getRawOriginal('filesize')
);
return $this->get_single_image($image, $shared->user_id);
}
}
return view('index')
->with('installation', 'setup-done')
->with('settings', get_settings_in_json() ?? null);
}
/**
* Check Password for protected item
*
* @param AuthenticateShareRequest $request
* @param Share $shared
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function authenticate(AuthenticateShareRequest $request, Share $shared)
{
// Check password
if (Hash::check($request->password, $shared->password)) {
$cookie = json_encode([
'token' => $shared->token,
'authenticated' => true,
]);
// Return authorize token with shared options
return response(new ShareResource($shared), 200)
->cookie('share_session', $cookie, 43200);
}
abort(401, __t('incorrect_password'));
}
/**
* Browse shared folder
*
* @param $id
* @param Share $shared
* @return Collection
*/
public function browse_folder($id, Share $shared)
{
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check if user can get directory
$this->helper->check_item_access($id, $shared);
// Get files and folders
list($folders, $files) = $this->helper->get_items_under_shared_by_folder_id($id, $shared);
// Set thumbnail links for public files
$files->map(function ($file) use ($shared) {
$file->setPublicUrl($shared->token);
});
// Collect folders and files to single array
return collect([$folders, $files])
->collapse();
}
/**
* Search shared files
*
* @param Request $request
* @param Share $shared
* @return Collection
*/
public function search(Request $request, Share $shared)
{
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
$query = remove_accents(
$request->input('query')
);
// Search files id db
$searched_files = File::search($query)
->where('user_id', $shared->user_id)
->get();
$searched_folders = Folder::search($query)
->where('user_id', $shared->user_id)
->get();
// Get all children content
$foldersIds = Folder::with('folders:id,parent_id,id,name')
->where('user_id', $shared->user_id)
->where('parent_id', $shared->item_id)
->get();
// Get accessible folders
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Filter files
$files = $searched_files->filter(function ($file) use ($accessible_folder_ids, $shared) {
// Set public urls
$file->setPublicUrl($shared->token);
// check if item is in accessible folders
return in_array($file->folder_id, $accessible_folder_ids);
});
// Filter folders
$folders = $searched_folders->filter(function ($folder) use ($accessible_folder_ids) {
// check if item is in accessible folders
return in_array($folder->id, $accessible_folder_ids);
});
// Collect folders and files to single array
return collect([$folders, $files])
->collapse();
}
/**
* Get navigation tree of shared folder
*
* @param Share $shared
* @return array
*/
public function navigation_tree(Share $shared)
{
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check if user can get directory
$this->helper->check_item_access($shared->item_id, $shared);
// Get folders
$folders = Folder::with('folders:id,parent_id,name')
->whereParentId($shared->item_id)
->whereUserId($shared->user_id)
->sortable()
->get(['id', 'parent_id', 'id', 'name']);
return [
[
'id' => $shared->item_id,
'name' => __t('home'),
'location' => 'public',
'folders' => $folders,
],
];
}
/**
* Get shared file record
*
* @param Share $shared
* @return mixed
*/
public function get_single_file(Share $shared)
{
// Check ability to access protected share files
$this->helper->check_protected_share_record($shared);
// Get file
$file = File::whereUserId($shared->user_id)
->whereId($shared->item_id)
->firstOrFail();
// Set access urls
$file->setPublicUrl($shared->token);
return response(new FileResource($file), 200);
}
/**
* Get image from storage and show it
*
* @param $file
* @param $user_id
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
private function get_single_image($file, $user_id)
{
// Format pretty filename
$file_pretty_name = $file->name . '.' . $file->mimetype;
// Get file path
$path = "/files/$user_id/$file->basename";
// Check if file exist
if (! Storage::exists($path)) {
abort(404);
}
return Storage::response($path, $file_pretty_name, [
'Content-Type' => Storage::mimeType($path),
'Content-Length' => Storage::size($path),
'Accept-Ranges' => 'bytes',
'Content-Range' => 'bytes 0-600/' . Storage::size($path),
]);
}
}

View File

@@ -1,110 +0,0 @@
<?php
namespace App\Http\Controllers\Sharing;
use App\Models\Zip;
use App\Models\Share;
use App\Services\HelperService;
use App\Models\File as UserFile;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
class FileSharedAccessController extends Controller
{
private $helper;
public function __construct()
{
$this->helper = resolve(HelperService::class);
}
/**
* Get generated zip for guest
*
* @param $id
* @param $token
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function get_zip_public($id, $token)
{
$disk = Storage::disk('local');
$zip = Zip::where('id', $id)
->where('shared_token', $token)
->first();
$zip
->user
->record_download(
$disk->size("zip/$zip->basename")
);
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,
]);
}
/**
* Get file public
*
* @param $filename
* @param Share $shared
* @return mixed
*/
public function get_file_public($filename, Share $shared)
{
// Check ability to access protected share files
$this->helper->check_protected_share_record($shared);
// Get file record
$file = UserFile::where('user_id', $shared->user_id)
->where('basename', $filename)
->firstOrFail();
// Check file access
$this->helper->check_guest_access_to_shared_items($shared, $file);
// Store user download size
$shared
->user
->record_download(
(int) $file->getRawOriginal('filesize')
);
return $this->helper->download_file($file, $shared->user_id);
}
/**
* Get public image thumbnail
*
* @param $filename
* @param Share $shared
* @return mixed
*/
public function get_thumbnail_public($filename, Share $shared)
{
// Check ability to access protected share files
$this->helper->check_protected_share_record($shared);
// Get file record
$file = UserFile::where('user_id', $shared->user_id)
->where('thumbnail', $filename)
->firstOrFail();
// Check file access
$this->helper->check_guest_access_to_shared_items($shared, $file);
// Store user download size
$shared
->user
->record_download(
(int) $file->getRawOriginal('filesize')
);
return $this->helper->download_thumbnail_file($file, $shared->user_id);
}
}

View File

@@ -1,300 +0,0 @@
<?php
namespace App\Http\Controllers\Sharing;
use App\Models\File;
use App\Models\Share;
use App\Models\Folder;
use Illuminate\Http\Request;
use App\Services\DemoService;
use App\Services\HelperService;
use App\Http\Controllers\Controller;
use App\Services\FileManagerService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Requests\FileFunctions\UploadRequest;
use App\Http\Requests\FileFunctions\MoveItemRequest;
use App\Http\Requests\FileFunctions\DeleteItemRequest;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\Http\Requests\FileFunctions\CreateFolderRequest;
class ManipulateShareItemsController extends Controller
{
private $filemanager;
private $helper;
public function __construct()
{
$this->filemanager = resolve(FileManagerService::class);
$this->helper = resolve(HelperService::class);
$this->demo = resolve(DemoService::class);
}
/**
* Create new folder for guest user with edit permission
*
* @param CreateFolderRequest $request
* @param Share $shared
* @return array|\Illuminate\Contracts\Foundation\Application|ResponseFactory|\Illuminate\Http\Response
* @throws \Exception
*/
public function create_folder(CreateFolderRequest $request, Share $shared)
{
if (is_demo_account($shared->user->email)) {
return $this->demo->create_folder($request);
}
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check shared permission
if (is_visitor($shared)) {
abort(403);
}
// Check access to requested directory
$this->helper->check_item_access($request->parent_id, $shared);
// Create folder
$folder = $this->filemanager->create_folder($request, $shared);
return response($folder, 201);
}
/**
* Rename item for guest user with edit permission
*
* @param RenameItemRequest $request
* @param $id
* @param Share $shared
* @return mixed
* @throws \Exception
*/
public function rename_item(RenameItemRequest $request, $id, Share $shared)
{
if (is_demo_account($shared->user->email)) {
return $this->demo->rename_item($request, $id);
}
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check shared permission
if (is_visitor($shared)) {
abort(403);
}
// Get file|folder item
$item = get_item($request->type, $id);
// Check access to requested item
if ($request->type === 'folder') {
$this->helper->check_item_access($item->id, $shared);
} else {
$this->helper->check_item_access($item->folder_id, $shared);
}
// If request have a change folder icon values set the folder icon
if ($request->type === 'folder' && $request->filled('icon')) {
$this->filemanager->edit_folder_properties($request, $id);
}
// Rename item
$item = $this->filemanager->rename_item($request, $id, $shared);
// Set public url
if ($item->type !== 'folder') {
$item->setPublicUrl($shared->token);
}
return response($item, 201);
}
/**
* Delete item for guest user with edit permission
*
* @param DeleteItemRequest $request
* @param Share $shared
* @return ResponseFactory|\Illuminate\Http\Response
* @throws \Exception
*/
public function delete_item(DeleteItemRequest $request, Share $shared)
{
abort_if(is_demo_account($shared->user->email), 204, 'Done.');
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check shared permission
if (is_visitor($shared)) {
abort(403);
}
foreach ($request->items as $file) {
// Get file|folder item
$item = get_item($file['type'], $file['id']);
// Check access to requested item
if ($file['type'] === 'folder') {
$this->helper->check_item_access($item->id, $shared);
} else {
$this->helper->check_item_access($item->folder_id, $shared);
}
// Delete item
$this->filemanager->delete_item($file, $file['id'], $shared);
}
return response('Done', 204);
}
/**
* Delete file for guest user with edit permission
*
* @param UploadRequest $request
* @param Share $shared
* @return File|\Illuminate\Contracts\Foundation\Application|ResponseFactory|Model|\Illuminate\Http\Response
* @throws \Exception
*/
public function upload(UploadRequest $request, Share $shared)
{
if (is_demo_account($shared->user->email)) {
return $this->demo->upload($request);
}
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check shared permission
if (is_visitor($shared)) {
abort(403);
}
// Check access to requested directory
$this->helper->check_item_access($request->folder_id, $shared);
// Return new uploaded file
$new_file = $this->filemanager->upload($request, $shared);
// Set public access url
$new_file->setPublicUrl($shared->token);
return response($new_file, 201);
}
/**
* Move item for guest user with edit permission
*
* @param MoveItemRequest $request
* @param Share $shared
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function move(MoveItemRequest $request, Share $shared)
{
abort_if(is_demo_account($shared->user->email), 204, 'Done.');
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check shared permission
if (is_visitor($shared)) {
abort(403);
}
foreach ($request->items as $item) {
if ($item['type'] === 'folder') {
$this->helper->check_item_access([
$request->to_id, $item['id'],
], $shared);
}
if ($item['type'] !== 'folder') {
$file = File::where('id', $item['id'])
->where('user_id', $shared->user_id)
->firstOrFail();
$this->helper->check_item_access([
$request->to_id, $file->folder_id,
], $shared);
}
}
$this->filemanager->move($request, $request->to_id);
return response('Done!', 204);
}
/**
* Guest download folder via zip
*
* @param $id
* @param Share $shared
* @return string
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function zip_folder($id, Share $shared)
{
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
// Check access to requested folder
$this->helper->check_item_access($id, $shared);
// Get folder
$folder = Folder::whereUserId($shared->user_id)
->where('id', $id);
if (! $folder->exists()) {
abort(404, 'Requested folder doesn\'t exists.');
}
$zip = $this->filemanager->zip_folder($id, $shared);
// Get file
return response([
'url' => route('zip_public', [
'id' => $zip->id,
'token' => $shared->token,
]),
'name' => $zip->basename,
], 201);
}
/**
* Guest download multiple files via zip
*
* @param Request $request
* @param Share $shared
* @return string
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function zip_multiple_files(Request $request, Share $shared)
{
// Check ability to access protected share record
$this->helper->check_protected_share_record($shared);
$file_parent_folders = File::whereUserId($shared->user_id)
->whereIn('id', $request->items)
->get()
->pluck('folder_id')
->toArray();
// Check access to requested directory
$this->helper->check_item_access($file_parent_folders, $shared);
// Get requested files
$files = File::whereUserId($shared->user_id)
->whereIn('id', $request->items)
->get();
$zip = $this->filemanager->zip_files($files, $shared);
// Get file
return response([
'url' => route('zip_public', [
'id' => $zip->id,
'token' => $shared->token,
]),
'name' => $zip->basename,
], 201);
}
}

View File

@@ -1,69 +0,0 @@
<?php
namespace App\Http\Controllers\Subscription;
use App\Models\User;
use App\Services\StripeService;
use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;
class StripeWebhookController extends CashierController
{
public function __construct()
{
$this->stripe = resolve(StripeService::class);
}
/**
* Handle a cancelled customer from a Stripe subscription.
*
* @param array $payload
* @return \Symfony\Component\HttpFoundation\Response
*/
public function handleCustomerSubscriptionDeleted($payload)
{
if ($user = $this->getUserByStripeId($payload['data']['object']['customer'])) {
$user->subscriptions->filter(function ($subscription) use ($payload) {
return $subscription->stripe_id === $payload['data']['object']['id'];
})->each(function ($subscription) {
$subscription->markAsCancelled();
});
}
// Get user
$user = User::whereStripeId($payload['data']['object']['customer'])
->firstOrFail();
// Update storage capacity
$user
->settings()
->update([
'storage_capacity' => get_setting('storage_default'),
]);
return $this->successMethod();
}
/**
* Handle Invoice Payment Succeeded
*
* @param $payload
* @return \Symfony\Component\HttpFoundation\Response
*/
public function handleInvoicePaymentSucceeded($payload)
{
// Get user
$user = User::whereStripeId($payload['data']['object']['customer'])
->firstOrFail();
// Get requested plan
$plan = $this->stripe->getPlan($user->subscription('main')->stripe_plan);
// Update user storage limit
$user
->settings()
->update([
'storage_capacity' => $plan['product']['metadata']['capacity'],
]);
return $this->successMethod();
}
}

View File

@@ -1,128 +0,0 @@
<?php
namespace App\Http\Controllers\User;
use Illuminate\Http\Request;
use App\Services\DemoService;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserResource;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\InvoiceCollection;
use Illuminate\Support\Facades\Validator;
use App\Http\Resources\UserStorageResource;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Requests\User\UpdateUserPasswordRequest;
class AccountController extends Controller
{
/**
* AccountController constructor.
*/
public function __construct()
{
$this->demo = resolve(DemoService::class);
}
/**
* Get all user data to frontend
*
* @return UserResource
*/
public function user()
{
return new UserResource(
Auth::user()
);
}
/**
* Get storage details
*
* @return UserStorageResource
*/
public function storage()
{
return new UserStorageResource(
Auth::user()
);
}
/**
* Get user invoices
*
* @return InvoiceCollection
*/
public function invoices()
{
return new InvoiceCollection(
Auth::user()->invoices()
);
}
/**
* Update user settings relationship
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function update_user_settings(Request $request)
{
// Validate request
// TODO: pridat validator do requestu
$validator = Validator::make($request->all(), [
'avatar' => 'sometimes|file',
'name' => 'string',
'value' => 'string',
]);
// Return error
if ($validator->fails()) {
abort(400, 'Bad input');
}
// Get user
$user = Auth::user();
// Check if is demo
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
// Update avatar
if ($request->hasFile('avatar')) {
$user
->settings()
->update([
'avatar' => store_avatar($request, 'avatar'),
]);
return response('Saved!', 204);
}
$user
->settings()
->update(
make_single_input($request)
);
return response('Saved!', 204);
}
/**
* Change user password
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function change_password(UpdateUserPasswordRequest $request)
{
// Get user
$user = Auth::user();
// Check if is demo
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
// Change and store new password
$user->password = bcrypt($request->input('password'));
$user->save();
return response('Changed!', 204);
}
}

View File

@@ -1,164 +0,0 @@
<?php
namespace App\Http\Controllers\User;
use Auth;
use Illuminate\Http\Request;
use App\Services\DemoService;
use App\Services\StripeService;
use Laravel\Cashier\PaymentMethod;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;
use App\Http\Resources\PaymentCardResource;
use App\Http\Resources\PaymentCardCollection;
use App\Http\Resources\PaymentDefaultCardResource;
use App\Http\Requests\Payments\RegisterNewPaymentMethodRequest;
class PaymentMethodsController extends Controller
{
private StripeService $stripe;
private DemoService $demo;
public function __construct(StripeService $stripe)
{
$this->stripe = $stripe;
$this->demo = resolve(DemoService::class);
}
/**
* Get user payment methods grouped by default and others
*
* @return array
*/
public function index()
{
$user = Auth::user();
if (! $user->hasPaymentMethod()) {
return abort(204, 'User don\'t have any payment methods');
}
$slug_payment_methods = 'payment-methods-user-' . $user->id;
$slug_default_payment_method = 'default-payment-methods-user-' . $user->id;
if (Cache::has($slug_payment_methods) && Cache::has($slug_default_payment_method)) {
$defaultPaymentMethod = Cache::get($slug_default_payment_method);
$paymentMethodsMapped = Cache::get($slug_payment_methods);
} else {
// Get default payment method
$defaultPaymentMethod = Cache::rememberForever($slug_default_payment_method, function () use ($user) {
$defaultPaymentMethodObject = $user->defaultPaymentMethod();
return $defaultPaymentMethodObject instanceof PaymentMethod
? $defaultPaymentMethodObject->asStripePaymentMethod()
: $defaultPaymentMethodObject;
});
// filter payment methods without default payment
$paymentMethodsMapped = Cache::rememberForever($slug_payment_methods, function () use ($defaultPaymentMethod, $user) {
$paymentMethods = $user->paymentMethods()->filter(function ($paymentMethod) use ($defaultPaymentMethod) {
return $paymentMethod->id !== $defaultPaymentMethod->id;
});
// Get payment methods
return $paymentMethods->map(function ($paymentMethod) {
return $paymentMethod->asStripePaymentMethod();
})->values()->all();
});
}
if (! $user->card_brand || ! $user->stripe_id || is_null($paymentMethodsMapped) && is_null($paymentMethodsMapped)) {
return [
'default' => null,
'others' => [],
];
}
return [
'default' => $defaultPaymentMethod instanceof PaymentMethod
? new PaymentCardResource($defaultPaymentMethod)
: new PaymentDefaultCardResource($defaultPaymentMethod),
'others' => new PaymentCardCollection($paymentMethodsMapped),
];
}
/**
* Update default payment method
*
* @param Request $request
* @param $id
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function update($id)
{
$user = Auth::user();
// Check if is demo
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
// Update DefaultPayment Method
$user->updateDefaultPaymentMethod($id);
// Sync default payment method
$user->updateDefaultPaymentMethodFromStripe();
// Clear cached payment methods
cache_forget_many([
'payment-methods-user-' . $user->id,
'default-payment-methods-user-' . $user->id,
]);
return response('Done', 204);
}
/**
* Register new payment method for user
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function store(RegisterNewPaymentMethodRequest $request)
{
// Get user
$user = Auth::user();
// Check if is demo
if (is_demo($user->id)) {
return response('Done', 201);
}
// Register new payment method
$this->stripe->registerNewPaymentMethod($request, $user);
return response('Done', 201);
}
/**
* Delete user payment method
*
*/
public function delete($id)
{
$user = Auth::user();
// Check if is demo
abort_if(is_demo_account('howdy@hi5ve.digital'), 204, 'Done.');
// Get payment method
$paymentMethod = $user->findPaymentMethod($id);
// Delete payment method
$paymentMethod->delete();
// Sync default payment method
$user->updateDefaultPaymentMethodFromStripe();
// Clear cached payment methods
cache_forget_many([
'payment-methods-user-' . $user->id,
'default-payment-methods-user-' . $user->id,
]);
return response('Done!', 204);
}
}

View File

@@ -1,151 +0,0 @@
<?php
namespace App\Http\Controllers\User;
use Auth;
use App\Models\User;
use Stripe\SetupIntent;
use App\Services\DemoService;
use Illuminate\Http\Response;
use App\Services\StripeService;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;
use App\Http\Resources\UserSubscription;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Requests\Subscription\StoreUpgradeAccountRequest;
class SubscriptionController extends Controller
{
private $stripe;
private $demo;
public function __construct()
{
$this->stripe = resolve(StripeService::class);
$this->demo = DemoService::class;
}
/**
* Generate setup intent
*
* @return Application|ResponseFactory|Response|SetupIntent
*/
public function setup_intent()
{
return response(
$this->stripe->getSetupIntent(Auth::user()),
201
);
}
/**
* Get user subscription detail
*
* @return void
*/
public function show()
{
$user = User::find(Auth::id());
if (! $user->subscription('main')) {
return abort(204, 'User don\'t have any subscription');
}
$slug = 'subscription-user-' . $user->id;
if (Cache::has($slug)) {
return Cache::get($slug);
}
return Cache::rememberForever($slug, function () use ($user) {
return new UserSubscription(
$user
);
});
}
/**
* Upgrade account to subscription
*
* @param StoreUpgradeAccountRequest $request
* @return ResponseFactory|Response
*/
public function upgrade(StoreUpgradeAccountRequest $request)
{
// Get user
$user = Auth::user();
// Check if is demo
if (is_demo($user->id)) {
return $this->demo->response_204();
}
// Forget user subscription
Cache::forget('subscription-user-' . $user->id);
// Get requested plan
$plan = $this->stripe->getPlan($request->input('plan.data.id'));
// Set user billing
$user->setBilling($request->input('billing'));
// Update stripe customer billing info
$this->stripe->updateCustomerDetails($user);
// Make subscription
$this->stripe->createOrReplaceSubscription($request, $user);
// Update user storage limit
$user->settings()->update([
'storage_capacity' => $plan['product']['metadata']['capacity'],
]);
return response('Done!', 204);
}
/**
* Cancel Subscription
*
* @return ResponseFactory|Response
*/
public function cancel()
{
$user = User::find(Auth::id());
// Check if is demo
if (is_demo($user->id)) {
return $this->demo->response_204();
}
// Cancel subscription
$user->subscription('main')->cancel();
// Forget user subscription
Cache::forget('subscription-user-' . $user->id);
return response('Done!', 204);
}
/**
* Resume Subscription
*
* @return ResponseFactory|Response
*/
public function resume()
{
$user = User::find(Auth::id());
// Check if is demo
if (is_demo($user->id)) {
return $this->demo->response_204();
}
// Resume subscription
$user->subscription('main')->resume();
// Forget user subscription
Cache::forget('subscription-user-' . $user->id);
return response('Done!', 204);
}
}

View File

@@ -1,68 +0,0 @@
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
EnsureFrontendRequestsAreStateful::class,
//'throttle:api',
//\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array|string
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

View File

@@ -1,67 +0,0 @@
<?php
namespace App\Http\Notifications;
use Laravel\Cashier\Payment;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class ConfirmPayment extends Notification implements ShouldQueue
{
use Queueable;
/**
* The PaymentIntent identifier.
*
* @var string
*/
public $paymentId;
/**
* The payment amount.
*
* @var string
*/
public $amount;
/**
* Create a new payment confirmation notification.
*
* @param \Laravel\Cashier\Payment $payment
* @return void
*/
public function __construct(Payment $payment)
{
$this->paymentId = $payment->id;
$this->amount = $payment->amount();
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$url = route('cashier.payment', ['id' => $this->paymentId]);
return (new MailMessage)
->subject(__('cashier.confirm_payment'))
->greeting(__('cashier.confirm_amount', ['amount' => $this->amount]))
->line(__('cashier.confirm_description'))
->action(__('cashier.confirm_button'), $url);
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace App\Http\Requests\SetupWizard;
use Illuminate\Foundation\Http\FormRequest;
class StoreAppSetupRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|string',
'description' => 'required|string',
'logo' => 'sometimes|file',
'logo_horizontal' => 'sometimes|file',
'favicon' => 'sometimes|file',
'contactMail' => 'required|email',
'googleAnalytics' => 'sometimes|string',
'defaultStorage' => 'sometimes|digits_between:1,9',
'userRegistration' => 'required|boolean',
'storageLimitation' => 'required|boolean',
];
}
}

View File

@@ -1,42 +0,0 @@
<?php
namespace App\Http\Requests\SetupWizard;
use Illuminate\Foundation\Http\FormRequest;
class StoreEnvironmentSetupRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'storage' => 'required|array',
'storage.driver' => 'required|string',
'storage.key' => 'sometimes|nullable|string',
'storage.secret' => 'sometimes|nullable|string',
'storage.endpoint' => 'sometimes|nullable|string',
'storage.region' => 'sometimes|nullable|string',
'storage.bucket' => 'sometimes|nullable|string',
'mail' => 'required|array',
'mail.driver' => 'required|string',
'mail.host' => 'required|string',
'mail.port' => 'required|string',
'mail.username' => 'required|string',
'mail.password' => 'required|string',
'mail.encryption' => 'required|string',
];
}
}

View File

@@ -1,36 +0,0 @@
<?php
namespace App\Http\Requests\SetupWizard;
use Illuminate\Foundation\Http\FormRequest;
class StoreStripeBillingRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'billing_phone_number' => 'sometimes|nullable|string',
'billing_postal_code' => 'required|string',
'billing_vat_number' => 'required|string',
'billing_address' => 'required|string',
'billing_country' => 'required|string',
'billing_state' => 'required|string',
'billing_city' => 'required|string',
'billing_name' => 'required|string',
];
}
}

View File

@@ -1,32 +0,0 @@
<?php
namespace App\Http\Requests\SetupWizard;
use Illuminate\Foundation\Http\FormRequest;
class StoreStripeCredentialsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'currency' => 'required|string',
'webhookSecret' => 'required|string',
'secret' => 'required|string',
'key' => 'required|string',
];
}
}

View File

@@ -1,34 +0,0 @@
<?php
namespace App\Http\Requests\SetupWizard;
use Illuminate\Foundation\Http\FormRequest;
class StoreStripePlansRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'plans' => 'required|array',
'plans.*.type' => 'required|string',
'plans.*.attributes.name' => 'required|string',
'plans.*.attributes.price' => 'required|string',
'plans.*.attributes.description' => 'sometimes|nullable|string',
'plans.*.attributes.capacity' => 'required|digits_between:1,9',
];
}
}

View File

@@ -1,55 +0,0 @@
<?php
namespace App\Http\Requests\Subscription;
use Illuminate\Foundation\Http\FormRequest;
class StoreUpgradeAccountRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
// Billings
'billing' => 'required|array',
'billing.billing_address' => 'required|string',
'billing.billing_city' => 'required|string',
'billing.billing_country' => 'required|string',
'billing.billing_name' => 'required|string',
'billing.billing_phone_number' => 'required|string',
'billing.billing_postal_code' => 'required|string',
'billing.billing_state' => 'required|string',
// Payment
'payment' => 'required|array',
'payment.type' => 'required|string',
'payment.meta' => 'required|sometimes|array',
'payment.meta.pm' => 'required|sometimes|string',
// Plan
'plan.data' => 'required|array',
'plan.data.attributes' => 'required|array',
'plan.data.attributes.capacity' => 'required|digits_between:1,9',
'plan.data.attributes.capacity_formatted' => 'required|string',
'plan.data.attributes.currency' => 'required|string',
'plan.data.attributes.description' => 'sometimes|string|nullable',
'plan.data.attributes.name' => 'required|string',
'plan.data.attributes.price' => 'required|string',
'plan.data.id' => 'required|string',
'plan.data.type' => 'required|string',
];
}
}

View File

@@ -1,34 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class FileResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'id' => $this->id,
'type' => 'file',
'attributes' => [
'name' => $this->name,
'basename' => $this->basename,
'mimetype' => $this->mimetype,
'filesize' => $this->filesize,
'type' => $this->type,
'file_url' => $this->file_url,
'thumbnail' => $this->thumbnail,
'created_at' => $this->created_at,
'updated_at' => $this->created_at,
],
],
];
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class InvoiceAdminCollection extends ResourceCollection
{
public $collects = InvoiceAdminResource::class;
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
];
}
}

View File

@@ -1,65 +0,0 @@
<?php
namespace App\Http\Resources;
use App\Models\User;
use Laravel\Cashier\Cashier;
use Illuminate\Http\Resources\Json\JsonResource;
class InvoiceAdminResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$user = User::where('stripe_id', $this['customer'])
->first();
return [
'data' => [
'id' => $this['id'],
'type' => 'invoices',
'attributes' => [
'customer' => $this['customer'],
'total' => Cashier::formatAmount($this['total']),
'currency' => $this['currency'],
'created_at_formatted' => format_date($this['created']),
'created_at' => $this['created'],
'order' => $this['number'],
'user_id' => $user->id ?? null,
'client' => [
'billing_address' => $this['customer_address'],
'billing_name' => $this['customer_name'],
'billing_phone_number' => $this['customer_phone'],
],
'bag' => [
'amount' => $this['lines']['data'][0]['amount'],
'currency' => $this['lines']['data'][0]['currency'],
'type' => $this['lines']['data'][0]['type'],
'description' => $this['lines']['data'][0]['description'],
],
'seller' => null,
],
$this->mergeWhen($user, function () use ($user) {
return [
'relationships' => [
'user' => [
'data' => [
'id' => $user->id,
'type' => 'user',
'attributes' => [
'name' => $user->settings->name,
'avatar' => $user->settings->avatar,
],
],
],
],
];
}),
],
];
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class InvoiceCollection extends ResourceCollection
{
public $collects = InvoiceResource::class;
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
];
}
}

View File

@@ -1,96 +0,0 @@
<?php
namespace App\Http\Resources;
use App\Models\User;
use Illuminate\Http\Resources\Json\JsonResource;
class InvoiceResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$user = User::whereStripeId($this->customer)
->first();
return [
'data' => [
'id' => $this->id,
'type' => 'invoices',
'attributes' => [
'customer' => $this->customer,
'total' => $this->total(),
'currency' => $this->currency,
'created_at_formatted' => format_date($this->date(), '%d. %B. %Y'),
'created_at' => $this->created,
'order' => $this->number,
'user_id' => $user->id ?? null,
'client' => [
'billing_address' => $this->customer_address,
'billing_name' => $this->customer_name,
'billing_phone_number' => $this->customer_phone,
],
'seller' => null,
'invoice_items' => $this->get_invoice_items(),
'invoice_subscriptions' => $this->get_invoice_subscriptions(),
],
$this->mergeWhen($user, [
'relationships' => [
'user' => [
'data' => [
'id' => $user->id,
'type' => 'user',
'attributes' => [
'name' => $user->settings->name,
'avatar' => $user->settings->avatar,
],
],
],
],
]),
],
];
}
/**
* @return array
*/
private function get_invoice_subscriptions(): array
{
$array = [];
foreach ($this->subscriptions() as $item) {
array_push($array, [
'amount' => $item->total(),
'description' => $item->description,
'currency' => $item->currency,
'type' => $item->type,
]);
}
return $array;
}
/**
* @return array
*/
private function get_invoice_items(): array
{
$array = [];
foreach ($this->invoiceItems() as $item) {
array_push($array, [
'amount' => $item->total(),
'description' => $item->description,
'currency' => $item->currency,
'type' => $item->type,
]);
}
return $array;
}
}

View File

@@ -1,34 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class PaymentCardResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'id' => (string) $this['id'],
'type' => 'payment_method',
'attributes' => [
'provider' => 'stripe',
'card_id' => $this['id'],
'brand' => strtolower($this['card']['brand']),
'last4' => $this['card']['last4'],
'exp_month' => $this['card']['exp_month'],
'exp_year' => $this['card']['exp_year'],
'created_at' => format_date($this['created_at'], '%d. %B. %Y'),
'status' => 'active',
'default' => 0,
],
],
];
}
}

View File

@@ -1,34 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class PaymentDefaultCardResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'id' => (string) $this['id'],
'type' => 'payment_method',
'attributes' => [
'provider' => 'stripe',
'card_id' => $this['id'],
'brand' => isset($this['brand']) ? strtolower($this['brand']) : strtolower($this['card']['brand']),
'last4' => isset($this['last4']) ? $this['last4'] : $this['card']['last4'],
'exp_month' => isset($this['exp_month']) ? $this['exp_month'] : $this['card']['exp_month'],
'exp_year' => isset($this['exp_year']) ? $this['exp_year'] : $this['card']['exp_year'],
'created_at' => format_date($this['created_at'], '%d. %B. %Y'),
'status' => 'active',
'default' => 0,
],
],
];
}
}

View File

@@ -1,40 +0,0 @@
<?php
namespace App\Http\Resources;
use Laravel\Cashier\Cashier;
use Laravel\Cashier\Subscription;
use Illuminate\Http\Resources\Json\JsonResource;
class PlanResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
// Get subscribers
$subscriber_count = Subscription::where('stripe_plan', $this['plan']['id'])->where('stripe_status', 'active')->get();
return [
'data' => [
'id' => $this['plan']['id'],
'type' => 'plans',
'attributes' => [
'subscribers' => $subscriber_count->count(),
'status' => $this['plan']['active'] ? 1 : 0,
'name' => $this['product']['name'],
'description' => $this['product']['description'],
'price' => $this['plan']['amount'],
'price_formatted' => Cashier::formatAmount($this['plan']['amount']),
'capacity_formatted' => format_gigabytes($this['product']['metadata']['capacity']),
'capacity' => (int) $this['product']['metadata']['capacity'],
'created_at_formatted' => format_date($this['plan']['created']),
'created_at' => $this['plan']['created'],
],
],
];
}
}

View File

@@ -1,22 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class PricingCollection extends ResourceCollection
{
public $collects = PricingResource::class;
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
];
}
}

View File

@@ -1,34 +0,0 @@
<?php
namespace App\Http\Resources;
use Laravel\Cashier\Cashier;
use App\Services\StripeService;
use Illuminate\Http\Resources\Json\JsonResource;
class PricingResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'id' => $this['plan']['id'],
'type' => 'plans',
'attributes' => [
'name' => $this['product']['name'],
'description' => $this['product']['description'],
'price' => Cashier::formatAmount($this['plan']['amount']),
'capacity_formatted' => format_gigabytes($this['product']['metadata']['capacity']),
'capacity' => (int) $this['product']['metadata']['capacity'],
'currency' => config('cashier.currency'),
'tax_rates' => resolve(StripeService::class)->get_tax_rates($this['plan']['amount']),
],
],
];
}
}

View File

@@ -1,34 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ShareResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'id' => (string) $this->id,
'type' => 'shares',
'attributes' => [
'permission' => $this->permission,
'is_protected' => $this->is_protected,
'item_id' => $this->item_id,
'expire_in' => (int) $this->expire_in,
'token' => $this->token,
'link' => $this->link,
'type' => $this->type,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
],
],
];
}
}

View File

@@ -1,65 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
// TODO: zrefaktorovat
return [
'data' => [
'id' => $this->id,
'type' => 'user',
'attributes' => [
'storage_capacity' => $this->settings->storage_capacity,
'subscription' => $this->subscribed('main'),
'incomplete_payment' => $this->hasIncompletePayment('main') ? route('cashier.payment', $this->subscription('main')->latestPayment()->id) : null,
'stripe_customer' => is_null($this->stripe_id) ? false : true,
'email' => is_demo() ? obfuscate_email($this->email) : $this->email,
'role' => $this->role,
'folders' => $this->folder_tree,
'storage' => $this->storage,
'created_at_formatted' => format_date($this->created_at, '%d. %B. %Y'),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
],
'relationships' => [
'settings' => [
'data' => [
'id' => $this->id,
'type' => 'settings',
'attributes' => [
'avatar' => $this->settings->avatar,
'name' => $this->settings->name,
'address' => $this->settings->address,
'state' => $this->settings->state,
'city' => $this->settings->city,
'postal_code' => $this->settings->postal_code,
'country' => $this->settings->country,
'phone_number' => $this->settings->phone_number,
'timezone' => $this->settings->timezone,
],
],
],
'favourites' => [
'data' => [
'id' => $this->id,
'type' => 'favourite_folders',
'attributes' => [
'folders' => $this->favouriteFolders->makeHidden(['pivot']),
],
],
],
],
],
];
}
}

View File

@@ -1,88 +0,0 @@
<?php
namespace App\Http\Resources;
use App\Models\File;
use ByteUnits\Metric;
use Illuminate\Http\Resources\Json\JsonResource;
class UserStorageResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$document_mimetypes = [
'pdf', 'numbers', 'xlsx', 'xls', 'txt', 'md', 'rtf', 'pptx', 'ppt', 'odt', 'ods', 'odp', 'epub', 'docx', 'doc', 'csv', 'pages',
];
// Get all images
$images = File::where('user_id', $this->id)
->where('type', 'image')->get()->map(function ($item) {
return (int) $item->getRawOriginal('filesize');
})->sum();
// Get all audios
$audios = File::where('user_id', $this->id)
->where('type', 'audio')->get()->map(function ($item) {
return (int) $item->getRawOriginal('filesize');
})->sum();
// Get all videos
$videos = File::where('user_id', $this->id)
->where('type', 'video')->get()->map(function ($item) {
return (int) $item->getRawOriginal('filesize');
})->sum();
// Get all documents
$documents = File::where('user_id', $this->id)
->whereIn('mimetype', $document_mimetypes)->get()->map(function ($item) {
return (int) $item->getRawOriginal('filesize');
})->sum();
// Get all other files
$others = File::where('user_id', $this->id)
->whereNotIn('mimetype', $document_mimetypes)
->whereNotIn('type', ['audio', 'video', 'image'])
->get()->map(function ($item) {
return (int) $item->getRawOriginal('filesize');
})->sum();
return [
'data' => [
'id' => (string) $this->id,
'type' => 'storage',
'attributes' => [
'used' => Metric::bytes($this->used_capacity)->format(),
'capacity' => format_gigabytes($this->settings->storage_capacity),
'percentage' => (float) get_storage_fill_percentage($this->used_capacity, $this->settings->storage_capacity),
],
'meta' => [
'images' => [
'used' => Metric::bytes($images)->format(),
'percentage' => (float) get_storage_fill_percentage($images, $this->settings->storage_capacity),
],
'audios' => [
'used' => Metric::bytes($audios)->format(),
'percentage' => (float) get_storage_fill_percentage($audios, $this->settings->storage_capacity),
],
'videos' => [
'used' => Metric::bytes($videos)->format(),
'percentage' => (float) get_storage_fill_percentage($videos, $this->settings->storage_capacity),
],
'documents' => [
'used' => Metric::bytes($documents)->format(),
'percentage' => (float) get_storage_fill_percentage($documents, $this->settings->storage_capacity),
],
'others' => [
'used' => Metric::bytes($others)->format(),
'percentage' => (float) get_storage_fill_percentage($others, $this->settings->storage_capacity),
],
],
],
];
}
}

View File

@@ -1,42 +0,0 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserSubscription extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$active_subscription = $this->subscription('main')
->asStripeSubscription();
// TODO: vybrat z cache
$subscription = resolve('App\Services\StripeService')
->getPlan($this->subscription('main')->stripe_plan);
return [
'data' => [
'id' => $subscription['plan']['id'],
'type' => 'subscription',
'attributes' => [
'incomplete' => $this->subscription('main')->incomplete(),
'active' => $this->subscription('main')->active(),
'canceled' => $this->subscription('main')->cancelled(),
'name' => $subscription['product']['name'],
'capacity' => (int) $subscription['product']['metadata']['capacity'],
'capacity_formatted' => format_gigabytes($subscription['product']['metadata']['capacity']),
'slug' => $subscription['plan']['id'],
'canceled_at' => format_date($active_subscription['canceled_at'], '%d. %B. %Y'),
'created_at' => format_date($active_subscription['current_period_start'], '%d. %B. %Y'),
'ends_at' => format_date($active_subscription['current_period_end'], '%d. %B. %Y'),
],
],
];
}
}

View File

@@ -1,211 +0,0 @@
<?php
namespace App\Models;
use ByteUnits\Metric;
use Illuminate\Support\Str;
use Laravel\Scout\Searchable;
use Kyslik\ColumnSortable\Sortable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
use \Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @method static whereUserId($user_id)
* @method static whereId($id)
*/
class File extends Model
{
use Searchable, SoftDeletes, Sortable, HasFactory;
public $public_access = null;
protected $guarded = [
'id',
];
protected $appends = [
'file_url',
];
protected $casts = [
'metadata' => 'array',
];
protected $hidden = [
'author_id',
];
/**
* Sortable columns
*
* @var string[]
*/
public $sortable = [
'name',
'created_at',
];
public $incrementing = false;
protected $keyType = 'string';
/**
* Set routes with public access
*
* @param $token
*/
public function setPublicUrl($token)
{
$this->public_access = $token;
}
/**
* Format created at date
*
* @return string
*/
public function getCreatedAtAttribute()
{
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __t('time'));
}
/**
* Form\a\t created at date reformat
*
* @return string|null
*/
public function getDeletedAtAttribute()
{
if (! $this->attributes['deleted_at']) {
return null;
}
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __t('time'));
}
/**
* Format fileSize
*
* @return string
*/
public function getFilesizeAttribute()
{
return Metric::bytes($this->attributes['filesize'])->format();
}
/**
* Format thumbnail url
*
* @return string|null
*/
public function getThumbnailAttribute()
{
// Get thumbnail from external storage
if ($this->attributes['thumbnail'] && ! is_storage_driver(['local'])) {
return Storage::temporaryUrl("files/$this->user_id/{$this->attributes['thumbnail']}", now()->addHour());
}
// Get thumbnail from local storage
if ($this->attributes['thumbnail']) {
// Thumbnail route
$route = route('thumbnail', ['name' => $this->attributes['thumbnail']]);
if ($this->public_access) {
return "$route/$this->public_access";
}
return $route;
}
return null;
}
/**
* Format file url
*
* @return string
*/
public function getFileUrlAttribute()
{
// Get file from external storage
if (! is_storage_driver(['local'])) {
$file_pretty_name = is_storage_driver('backblaze')
? Str::snake(mb_strtolower($this->attributes['name']))
: get_pretty_name($this->attributes['basename'], $this->attributes['name'], $this->attributes['mimetype']);
$header = [
'ResponseAcceptRanges' => 'bytes',
'ResponseContentType' => $this->attributes['mimetype'],
'ResponseContentLength' => $this->attributes['filesize'],
'ResponseContentRange' => 'bytes 0-600/' . $this->attributes['filesize'],
'ResponseContentDisposition' => 'attachment; filename=' . $file_pretty_name,
];
return Storage::temporaryUrl("files/$this->user_id/{$this->attributes['basename']}", now()->addDay(), $header);
}
// Get thumbnail from local storage
$route = route('file', ['name' => $this->attributes['basename']]);
if ($this->public_access) {
return "$route/$this->public_access";
}
return $route;
}
/**
* Index file
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
$name = Str::slug($array['name'], ' ');
return [
'id' => $this->id,
'name' => $name,
'nameNgrams' => utf8_encode((new TNTIndexer)->buildTrigrams(implode(', ', [$name]))),
];
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function parent()
{
return $this->belongsTo(Folder::class, 'folder_id', 'id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function folder()
{
return $this->hasOne(Folder::class, 'id', 'folder_id');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function shared()
{
return $this->hasOne(Share::class, 'item_id', 'id');
}
/**
* Model events
*/
protected static function boot()
{
parent::boot();
static::creating(function ($file) {
$file->id = (string) Str::uuid();
});
}
}

View File

@@ -1,245 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Support\Str;
use Laravel\Scout\Searchable;
use Kyslik\ColumnSortable\Sortable;
use Illuminate\Database\Eloquent\Model;
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
use \Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @method static whereUserId(int|string|null $id)
*/
class Folder extends Model
{
use Searchable, SoftDeletes, Sortable, HasFactory;
protected $guarded = [
'id',
];
protected $appends = [
'items',
'trashed_items',
'type',
];
protected $casts = [
'emoji' => 'array',
];
protected $hidden = [
'author_id',
];
/**
* Sortable columns
*
* @var string[]
*/
public $sortable = [
'name',
'created_at',
];
public $incrementing = false;
protected $keyType = 'string';
public function getTypeAttribute()
{
return 'folder';
}
/**
* Index folder
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
$name = Str::slug($array['name'], ' ');
return [
'id' => $this->id,
'name' => $name,
'nameNgrams' => utf8_encode((new TNTIndexer)->buildTrigrams(implode(', ', [$name]))),
];
}
/**
* Counts how many folder have items
*
* @return int
*/
public function getItemsAttribute()
{
$folders = $this->folders()->count();
$files = $this->files()->count();
return $folders + $files;
}
/**
* Counts how many folder have items
*
* @return int
*/
public function getTrashedItemsAttribute()
{
$folders = $this->trashed_folders()->count();
$files = $this->trashed_files()->count();
return $folders + $files;
}
/**
* Format created at date reformat
*
* @return string
*/
public function getCreatedAtAttribute()
{
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __t('time'));
}
/**
* Format created at date reformat
*
* @return string|null
*/
public function getDeletedAtAttribute()
{
if (! $this->attributes['deleted_at']) {
return null;
}
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __t('time'));
}
/**
* Get parent
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function parent()
{
return $this->belongsTo(Folder::class, 'parent_id', 'id');
}
public function folderIds()
{
return $this->children()->with('folderIds')->select(['id', 'parent_id']);
}
/**
* Get all files
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function files()
{
return $this->hasMany(File::class, 'folder_id', 'id');
}
/**
* Get all trashed files
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function trashed_files()
{
return $this->hasMany(File::class, 'folder_id', 'id')->withTrashed();
}
/**
* Get all folders
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function folders()
{
return $this->children()->with('folders');
}
/**
* Get all trashed folders
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function trashed_folders()
{
return $this->children()->with('trashed_folders')->withTrashed()->select(['parent_id', 'id', 'name']);
}
/**
* Get childrens
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function children()
{
return $this->hasMany(Folder::class, 'parent_id', 'id');
}
/**
* Get trashed childrens
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function trashed_children()
{
return $this->hasMany(Folder::class, 'parent_id', 'id')->withTrashed();
}
/**
* Get sharing attributes
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function shared()
{
return $this->hasOne(Share::class, 'item_id', 'id');
}
// Delete all folder children
public static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->id = (string) Str::uuid();
});
static::deleting(function ($item) {
if ($item->isForceDeleting()) {
$item->trashed_children()->each(function ($folder) {
$folder->forceDelete();
});
} else {
$item->children()->each(function ($folder) {
$folder->delete();
});
$item->files()->each(function ($file) {
$file->delete();
});
}
});
static::restoring(function ($item) {
// Restore children folders
$item->trashed_children()->each(function ($folder) {
$folder->restore();
});
// Restore children files
$item->trashed_files()->each(function ($files) {
$files->restore();
});
});
}
}

View File

@@ -1,25 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
protected $guarded = [
'id',
];
protected $casts = [
'seller' => 'array',
'client' => 'array',
'bag' => 'array',
];
/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function user()
{
return $this->hasOne(User::class, 'id', 'user_id');
}
}

View File

@@ -1,23 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
/**
* @method static whereName(string $string)
*/
class Setting extends Model
{
use HasFactory;
protected $fillable = [
'value', 'name',
];
public $timestamps = false;
protected $primaryKey = 'name';
protected $keyType = 'string';
}

View File

@@ -1,33 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Traffic extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'upload',
'download',
];
public $incrementing = false;
protected $keyType = 'string';
/**
* Model events
*/
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->id = (string) Str::uuid();
});
}
}

View File

@@ -1,271 +0,0 @@
<?php
namespace App\Models;
use ByteUnits\Metric;
use Illuminate\Support\Str;
use Laravel\Cashier\Billable;
use App\Services\HelperService;
use App\Services\StripeService;
use Laravel\Sanctum\HasApiTokens;
use Kyslik\ColumnSortable\Sortable;
use App\Notifications\ResetPassword;
use Illuminate\Support\Facades\Storage;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable, Billable, Sortable, HasFactory, HasApiTokens;
protected $guarded = [
'id',
'role',
];
protected $fillable = [
'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'id' => 'string',
'email_verified_at' => 'datetime',
];
protected $appends = [
'used_capacity',
'storage',
];
public $sortable = [
'id',
'name',
'role',
'created_at',
'storage_capacity',
];
public $incrementing = false;
protected $keyType = 'string';
/**
* Get tax rate id for user
*
* @return array
*/
public function taxRates()
{
// Get tax rates
$rates = collect(resolve(StripeService::class)->getTaxRates());
// Find tax rate
$user_tax_rate = $rates->first(function ($item) {
return $item['country'] === $this->settings->country && $item['active'];
});
return $user_tax_rate ? [$user_tax_rate['id']] : [];
}
/**
* Get user used storage details
*
* @return mixed
*/
public function getStorageAttribute()
{
// Get storage limitation setup
$storage_limitation = get_setting('storage_limitation');
$is_storage_limit = $storage_limitation ? $storage_limitation : 1;
// Get user storage usage
if (! $is_storage_limit) {
return [
'used' => $this->used_capacity,
'used_formatted' => Metric::bytes($this->used_capacity)->format(),
];
}
return [
'used' => (float) get_storage_fill_percentage($this->used_capacity, $this->settings->storage_capacity),
'used_formatted' => get_storage_fill_percentage($this->used_capacity, $this->settings->storage_capacity) . '%',
'capacity' => $this->settings->storage_capacity,
'capacity_formatted' => format_gigabytes($this->settings->storage_capacity),
];
}
/**
* Get user used storage capacity in bytes
*
* @return mixed
*/
public function getUsedCapacityAttribute()
{
$user_capacity = $this->files_with_trashed->map(function ($item) {
return $item->getRawOriginal();
})->sum('filesize');
return $user_capacity;
}
/**
* Get user full folder tree
*
* @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
*/
public function getFolderTreeAttribute()
{
return Folder::with(['folders.shared', 'shared:token,id,item_id,permission,is_protected,expire_in'])
->where('parent_id', null)
->where('user_id', $this->id)
->sortable()
->get();
}
/**
* Set user billing info
*
* @param $billing
* @return UserSettings
*/
public function setBilling($billing)
{
$this->settings()->update([
'address' => $billing['billing_address'],
'city' => $billing['billing_city'],
'country' => $billing['billing_country'],
'name' => $billing['billing_name'],
'phone_number' => $billing['billing_phone_number'],
'postal_code' => $billing['billing_postal_code'],
'state' => $billing['billing_state'],
]);
return $this->settings;
}
/**
* Send the password reset notification.
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPassword($token));
}
/**
* Record user upload filesize
*
* @param $file_size
*/
public function record_upload($file_size)
{
$now = now();
$record = Traffic::whereYear('created_at', '=', $now->year)
->whereMonth('created_at', '=', $now->month)
->firstOrCreate([
'user_id' => $this->id,
]);
$record->update([
'upload' => $record->upload + $file_size,
]);
}
/**
* Record user download filesize
*
* @param $file_size
*/
public function record_download($file_size)
{
$now = now();
$record = Traffic::whereYear('created_at', '=', $now->year)
->whereMonth('created_at', '=', $now->month)
->firstOrCreate([
'user_id' => $this->id,
]);
$record->update([
'download' => $record->download + $file_size,
]);
}
/**
* Get user favourites folder
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function favouriteFolders()
{
return $this->belongsToMany(Folder::class, 'favourite_folder', 'user_id', 'folder_id', 'id', 'id')
->with('shared:token,id,item_id,permission,is_protected,expire_in');
}
/**
* Get 5 latest uploads
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Query\Builder
*/
public function latest_uploads()
{
return $this->hasMany(File::class)->with(['parent:id,name'])->take(40);
}
/**
* Get all user files
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function files()
{
return $this->hasMany(File::class);
}
/**
* Get all user files
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function files_with_trashed()
{
return $this->hasMany(File::class)->withTrashed();
}
/**
* Get user attributes
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function settings()
{
return $this->hasOne(UserSettings::class);
}
/**
* Model Events
*/
protected static function boot()
{
parent::boot();
static::creating(function ($user) {
$user->id = Str::uuid();
// Create user directory for his files
Storage::makeDirectory("files/$user->id");
});
static::deleted(function ($user) {
resolve(HelperService::class)
->erase_user_data($user);
});
}
}

View File

@@ -1,35 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
class UserSettings extends Model
{
public $timestamps = false;
protected $guarded = [
'id',
'storage_capacity',
];
/**
* Format avatar to full url
*
* @return \Illuminate\Contracts\Routing\UrlGenerator|string
*/
public function getAvatarAttribute()
{
// Get avatar from external storage
if ($this->attributes['avatar'] && ! is_storage_driver('local')) {
return Storage::temporaryUrl($this->attributes['avatar'], now()->addDay());
}
// Get avatar from local storage
if ($this->attributes['avatar']) {
return url('/' . $this->attributes['avatar']);
}
return url('/assets/images/default-avatar.png');
}
}

View File

@@ -1,66 +0,0 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class ResetPassword extends Notification
{
use Queueable;
private $token;
/**
* Create a new notification instance.
*
* @param $token
*/
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$reset_url = url('/create-new-password?token=' . $this->token);
$app_name = get_setting('app_title') ?? 'VueFileManager';
return (new MailMessage)
->subject(__t('reset_password_subject') . $app_name)
->greeting(__t('reset_password_greeting'))
->line(__t('reset_password_line_1'))
->action(__t('reset_password_action'), $reset_url)
->line(__t('reset_password_line_2'))
->salutation(__t('salutation') . ', ' . $app_name);
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
];
}
}

View File

@@ -1,53 +0,0 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
try {
$app_locale = get_setting('language') ?? 'en';
} catch (\PDOException $exception) {
$app_locale = 'en';
}
// Set locale for application
app()->setLocale($app_locale);
// Set locale for carbon dates
setlocale(LC_TIME, $app_locale . '_' . mb_strtoupper($app_locale));
// Get all migrations with all directories
$this->loadMigrationsFrom(
$this->get_migration_paths()
);
}
/**
* @return array
*/
private function get_migration_paths(): array
{
$mainPath = database_path('migrations');
$directories = glob($mainPath . '/*', GLOB_ONLYDIR);
return array_merge([$mainPath], $directories);
}
}

View File

@@ -1,34 +0,0 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
//use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
// Define admin maintenance gate
Gate::define('maintenance', function ($user) {
return $user->role === 'admin';
});
}
}

View File

@@ -1,133 +0,0 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* The path to the "home" route for your application.
*
* @var string
*/
public const HOME = '/home';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapShareRoutes();
$this->mapAdminApiRoutes();
$this->mapSetupWizardApiRoutes();
$this->mapUserApiRoutes();
$this->mapMaintenanceRoutes();
$this->mapFileRoutes();
$this->mapWebRoutes();
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
protected function mapMaintenanceRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/maintenance.php'));
}
protected function mapFileRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/file.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
protected function mapShareRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/share.php'));
}
protected function mapAdminApiRoutes()
{
Route::prefix('api/admin')
->middleware(['api', 'auth:sanctum'])
->namespace($this->namespace)
->group(base_path('routes/admin.php'));
}
protected function mapUserApiRoutes()
{
Route::prefix('api/user')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/user.php'));
}
protected function mapSetupWizardApiRoutes()
{
Route::prefix('api/setup')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/setup.php'));
}
}

View File

@@ -1,114 +0,0 @@
<?php
namespace App\Services;
use App\Models\File;
use ByteUnits\Metric;
use App\Models\Folder;
use Illuminate\Support\Str;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Requests\FileFunctions\RenameItemRequest;
class DemoService
{
/**
* Create new directory
*
* @param $request
* @return array
* @throws \Exception
*/
public function create_folder($request)
{
return [
'user_id' => 1,
'id' => Str::uuid(),
'parent_id' => random_int(1000, 9999),
'name' => $request->name,
'type' => 'folder',
'author' => $request->user() ? 'user' : 'visitor',
'items' => '0',
'color' => isset($request->icon['color']) ? $request->icon['color'] : null,
'emoji' => isset($request->icon['emoji']) ? $request->icon['emoji'] : null,
'updated_at' => now()->format('j M Y \a\t H:i'),
'created_at' => now()->format('j M Y \a\t H:i'),
];
}
/**
* Rename item name
*
* @param RenameItemRequest $request
* @param $id
* @return mixed
*/
public function rename_item($request, $id)
{
// Get item
if ($request->type === 'folder') {
$item = Folder::where('id', $id)
->where('user_id', 1)
->first();
} else {
$item = File::where('id', $id)
->where('user_id', 1)
->first();
}
if ($item) {
$item->name = $request->name;
$item->emoji = $request->icon['emoji'] ?? null;
$item->color = $request->icon['color'] ?? null;
return $item;
}
return [
'id' => $request->id,
'name' => $request->name,
'type' => $request->type,
];
}
/**
* Upload file
*
* @param $request
* @return array
* @throws \Exception
*/
public function upload($request)
{
// File
$file = $request->file('file');
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$thumbnail = null;
$filesize = $file->getSize();
$filetype = get_file_type($file->getMimeType());
return [
'id' => Str::uuid(),
'folder_id' => $request->parent_id,
'thumbnail' => 'data:' . $request->file('file')->getMimeType() . ';base64, ' . base64_encode(file_get_contents($request->file('file'))),
'name' => $file->getClientOriginalName(),
'basename' => $filename,
'mimetype' => $file->getClientOriginalExtension(),
'filesize' => Metric::bytes($filesize)->format(),
'type' => $filetype,
'file_url' => 'https://vuefilemanager.hi5ve.digital/assets/vue-file-manager-preview.jpg',
'author' => $request->user() ? 'user' : 'visitor',
'created_at' => now()->format('j M Y \a\t H:i'),
'updated_at' => now()->format('j M Y \a\t H:i'),
];
}
/**
* Return 204 status
*
* @param $user
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function favourites($user)
{
return $user->favouriteFolders->makeHidden(['pivot']);
}
}

View File

@@ -1,450 +0,0 @@
<?php
namespace App\Services;
use DB;
use App\Models\Zip;
use App\Models\User;
use App\Models\Share;
use App\Models\Folder;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use App\Models\File as UserFile;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FileNotFoundException;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use Symfony\Component\HttpKernel\Exception\HttpException;
class FileManagerService
{
private $helper;
public function __construct()
{
$this->helper = resolve(HelperService::class);
}
/**
* Zip requested folder
*
* @param $id
* @param $shared
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function zip_folder($id, $shared = null)
{
// 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,
]);
}
/**
* Zip selected files, store it in /zip folder and retrieve zip record
*
* @param $files
* @param null $shared
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function zip_files($files, $shared = null)
{
// 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(16) . '.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,
]);
}
/**
* Create new directory
*
* @param $request
* @param null $shared
* @return Folder|\Illuminate\Database\Eloquent\Model
*/
public function create_folder($request, $shared = null)
{
return Folder::create([
'parent_id' => $request->parent_id,
'author' => $shared ? 'visitor' : 'user',
'user_id' => $shared ? $shared->user_id : Auth::id(),
'name' => $request->name,
'color' => $request->color ?? null,
'emoji' => $request->emoji ?? null,
]);
}
/**
* Rename item name
*
* @param RenameItemRequest $request
* @param $id
* @param null $shared
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
* @throws \Exception
*/
public function rename_item($request, $id, $shared = null)
{
// Get user id
$user_id = $shared ? $shared->user_id : Auth::id();
// Get item
$item = get_item($request->type, $id, $user_id);
// Rename item
$item->update([
'name' => $request->name,
]);
// Return updated item
return $item;
}
/**
* Delete file or folder
*
* @param $item
* @param $id
* @param null $shared
* @throws \Exception
*/
public function delete_item($item, $id, $shared = null)
{
// Delete folder
if ($item['type'] === 'folder') {
// Get folder
$folder = Folder::withTrashed()
->with('folders')
->find($id);
// Get folder shared record
$shared = Share::where('type', 'folder')
->where('item_id', $id)
->first();
// Delete folder shared record
if ($shared) {
$shared->delete();
}
// Remove folder from user favourites
DB::table('favourite_folder')
->where('folder_id', $folder->id)
->delete();
// Soft delete items
if (! $item['force_delete']) {
// Soft delete folder record
$folder->delete();
}
// Force delete children files
if ($item['force_delete']) {
// Get children folder ids
$child_folders = filter_folders_ids($folder->trashed_folders, 'id');
// Get children files
$files = UserFile::onlyTrashed()
->whereIn('folder_id', Arr::flatten([$id, $child_folders]))
->get();
// Remove all children files
foreach ($files as $file) {
// Delete file
Storage::delete("/files/$file->user_id/$file->basename");
// Delete thumbnail if exist
if ($file->thumbnail) {
Storage::delete(
"/files/$file->user_id/{$file->getRawOriginal('thumbnail')}"
);
}
// Delete file permanently
$file->forceDelete();
}
// Delete folder record
$folder->forceDelete();
}
}
// Delete item
if ($item['type'] !== 'folder') {
// Get file
$file = UserFile::withTrashed()
->find($id);
// Get folder shared record
$shared = Share::where('type', 'file')
->where('item_id', $id)
->first();
// Delete file shared record
if ($shared) {
$shared->delete();
}
// Force delete file
if ($item['force_delete']) {
// Delete file
Storage::delete("/files/$file->user_id/$file->basename");
// Delete thumbnail if exist
if ($file->thumbnail) {
Storage::delete(
"/files/$file->user_id/{$file->getRawOriginal('thumbnail')}"
);
}
// Delete file permanently
$file->forceDelete();
}
// Soft delete file
if (! $item['force_delete']) {
// Soft delete file
$file->delete();
}
}
}
/**
* Move folder or file to new location
*
* @param $request
* @param $to_id
*/
public function move($request, $to_id)
{
foreach ($request->items as $item) {
// Move folder
if ($item['type'] === 'folder') {
Folder::find($item['id'])
->update(['parent_id' => $to_id]);
}
// Move file
if ($item['type'] !== 'folder') {
UserFile::find($item['id'])
->update(['folder_id' => $to_id]);
}
}
}
/**
* Upload file
*
* @param $request
* @param null $shared
* @return File|\Illuminate\Database\Eloquent\Model
* @throws \Exception
*/
public function upload($request, $shared = null)
{
// Get parent_id from request
$file = $request->file('file');
// File name
$user_file_name = basename('chunks/' . substr($file->getClientOriginalName(), 17), '.part');
$disk_file_name = basename('chunks/' . $file->getClientOriginalName(), '.part');
$temp_filename = $file->getClientOriginalName();
// File Path
$file_path = Storage::disk('local')->path('chunks/' . $temp_filename);
// Generate file
File::append($file_path, $file->get());
// Size of file
$file_size = File::size($file_path);
// Size of limit
$limit = get_setting('upload_limit');
// File size handling
if ($limit && $file_size > format_bytes($limit)) {
abort(413);
}
// If last then process file
if ($request->boolean('is_last')) {
$metadata = get_image_meta_data($file);
$disk_local = Storage::disk('local');
// Get user data
$user_id = $shared->user_id ?? Auth::id();
// File Info
$file_size = $disk_local->size("chunks/$temp_filename");
$file_mimetype = $disk_local->mimeType("chunks/$temp_filename");
// Check if user has enough space to upload file
$this->helper->check_user_storage_capacity($user_id, $file_size, $temp_filename);
// Create thumbnail
$thumbnail = $this->helper->create_image_thumbnail("chunks/$temp_filename", $disk_file_name, $user_id);
// Move finished file from chunk to file-manager directory
$disk_local->move("chunks/$temp_filename", "files/$user_id/$disk_file_name");
// Move files to external storage
if (! is_storage_driver(['local'])) {
$this->helper->move_file_to_external_storage($disk_file_name, $user_id);
}
// Store user upload size
User::find($user_id)
->record_upload($file_size);
// Return new file
return UserFile::create([
'mimetype' => get_file_type_from_mimetype($file_mimetype),
'type' => get_file_type($file_mimetype),
'folder_id' => $request->folder_id,
'metadata' => $metadata,
'name' => $request->filename,
'basename' => $disk_file_name,
'author' => $shared ? 'visitor' : 'user',
'thumbnail' => $thumbnail,
'filesize' => $file_size,
'user_id' => $user_id,
]);
}
}
/**
* Store folder icon
*
* @param $request
* @param $id
*/
public function edit_folder_properties($request, $id)
{
// Get folder
$folder = Folder::find($id);
// Set default folder icon
if ($request->emoji === 'default') {
$folder->update([
'emoji' => null,
'color' => null,
]);
}
// Set emoji
if ($request->filled('emoji')) {
$folder->update([
'emoji' => $request->emoji,
'color' => null,
]);
}
// Set color
if ($request->filled('color')) {
$folder->update([
'emoji' => null,
'color' => $request->color,
]);
}
}
}

View File

@@ -1,310 +0,0 @@
<?php
namespace App\Services;
use DB;
use App\Models\File;
use App\Models\Share;
use App\Models\Folder;
use Illuminate\Support\Arr;
use Aws\S3\MultipartUploader;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Aws\Exception\MultipartUploadException;
use Intervention\Image\ImageManagerStatic as Image;
use Symfony\Component\HttpKernel\Exception\HttpException;
class HelperService
{
/**
* Delete all user data including files, folders, avatar etc.
*
* @param $user
*/
public function erase_user_data($user)
{
// Delete user avatar if exists
if ($user->settings->getRawOriginal('avatar')) {
Storage::delete($user->settings->getRawOriginal('avatar'));
}
// Delete all user files
Storage::deleteDirectory("files/$user->id");
// Delete all user records in database
collect(['folders', 'files', 'user_settings', 'shares', 'favourite_folder', 'zips'])
->each(function ($table) use ($user) {
DB::table($table)
->whereUserId($user->id)
->delete();
});
}
/**
* Check access to requested directory
*
* @param int|array $requested_id
* @param string $shared Shared record detail
*/
public function check_item_access($requested_id, $shared)
{
// Get all children folders
$foldersIds = Folder::with('folders:id,parent_id,id,name')
->where('user_id', $shared->user_id)
->where('parent_id', $shared->item_id)
->get();
// Get all authorized parent folders by shared folder as root of tree
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Check user access
if (is_array($requested_id)) {
foreach ($requested_id as $id) {
if (! in_array($id, $accessible_folder_ids)) {
abort(403);
}
}
}
if (! is_array($requested_id)) {
if (! in_array($requested_id, $accessible_folder_ids)) {
abort(403);
}
}
}
/**
* Check user file access
*
* @param $shared
* @param $file
*/
public function check_guest_access_to_shared_items($shared, $file): void
{
// Check by parent folder permission
if ($shared->type === 'folder') {
$this->check_item_access($file->folder_id, $shared);
}
// Check by single file permission
if ($shared->type === 'file') {
if ($shared->item_id !== $file->id) {
abort(403);
}
}
}
/**
* Check if user has enough space to upload file
*
* @param $user_id
* @param int $file_size
* @param $temp_filename
*/
public function check_user_storage_capacity($user_id, int $file_size, $temp_filename): void
{
// Get user storage percentage and get storage_limitation setting
$user_storage_used = user_storage_percentage($user_id, $file_size);
// Check if user can upload
if (get_setting('storage_limitation') && $user_storage_used >= 100) {
// Delete file
Storage::disk('local')
->delete("chunks/$temp_filename");
// Abort uploading
// TODO: test pre exceed storage limit
abort(423, 'You exceed your storage limit!');
}
}
/**
* Move file to external storage if is set
*
* @param string $file
* @param string $user_id
*/
public function move_file_to_external_storage($file, $user_id): void
{
$disk_local = \Storage::disk('local');
// Get file size
$filesize = $disk_local->size("files/$user_id/$file");
// If file is bigger than 5.2MB then run multipart upload
if ($filesize > 5242880) {
// Get driver
$driver = \Storage::getDriver();
// Get adapter
$adapter = $driver->getAdapter();
// Get client
$client = $adapter->getClient();
// Prepare the upload parameters.
// TODO: replace local files with temp folder
$uploader = new MultipartUploader($client, config('filesystems.disks.local.root') . "/files/$user_id/$file", [
'bucket' => $adapter->getBucket(),
'key' => "files/$user_id/$file",
]);
try {
// Upload content
$uploader->upload();
} catch (MultipartUploadException $e) {
// Write error log
Log::error($e->getMessage());
// Delete file after error
$disk_local->delete("files/$user_id/$file");
throw new HttpException(409, $e->getMessage());
}
} else {
// Stream file object to s3
// TODO: replace local files with temp folder
Storage::putFileAs("files/$user_id", config('filesystems.disks.local.root') . "/files/$user_id/$file", $file, 'private');
}
// Delete file after upload
$disk_local->delete("files/$user_id/$file");
}
/**
* Create image thumbnail from gif, jpeg, jpg, png, webp or svg
*
* @param string $file_path
* @param string $filename
* @param string $user_id
* @return string|null
*/
public function create_image_thumbnail($file_path, $filename, $user_id)
{
// Create thumbnail from image
if (in_array(Storage::disk('local')->mimeType($file_path), ['image/gif', 'image/jpeg', 'image/jpg', 'image/png', 'image/webp'])) {
// Get thumbnail name
$thumbnail = "thumbnail-$filename";
// Create intervention image
$image = Image::make(Storage::disk('local')->path($file_path))
->orientate();
// Resize image
$image->resize(512, null, function ($constraint) {
$constraint->aspectRatio();
})->stream();
// Store thumbnail to disk
Storage::put("files/$user_id/$thumbnail", $image);
}
// Return thumbnail as svg file
if (Storage::disk('local')->mimeType($file_path) === 'image/svg+xml') {
$thumbnail = $filename;
}
return $thumbnail ?? null;
}
/**
* Call and download file
*
* @param $file
* @param $user_id
* @return mixed
*/
public function download_file($file, $user_id)
{
// Get file path
$path = "files/$user_id/$file->basename";
// Check if file exist
if (! Storage::exists($path)) {
abort(404);
}
// Get pretty name
$pretty_name = get_pretty_name($file->basename, $file->name, $file->mimetype);
return response()
->download(Storage::path($path), $pretty_name, [
'Accept-Ranges' => 'bytes',
'Content-Type' => Storage::mimeType($path),
'Content-Length' => Storage::size($path),
'Content-Range' => 'bytes 0-600/' . Storage::size($path),
'Content-Disposition' => "attachment; filename=$pretty_name",
]);
}
/**
* Get image thumbnail for browser
*
* @param $file
* @param $user_id
* @return mixed
*/
public function download_thumbnail_file($file, $user_id)
{
// Get file path
$path = "/files/$user_id/{$file->getRawOriginal('thumbnail')}";
// Check if file exist
if (! Storage::exists($path)) {
abort(404);
}
// Return image thumbnail
return Storage::download($path, $file->getRawOriginal('thumbnail'));
}
/**
* Get all folders and files under the share record
*
* @param $id
* @param $shared
* @return array
*/
public function get_items_under_shared_by_folder_id($id, $shared): array
{
$folders = Folder::where('user_id', $shared->user_id)
->where('parent_id', $id)
->sortable()
->get();
$files = File::where('user_id', $shared->user_id)
->where('folder_id', $id)
->sortable()
->get();
return [$folders, $files];
}
/**
* @param Share $shared
*/
public function check_protected_share_record(Share $shared): void
{
if ($shared->is_protected) {
$abort_message = "Sorry, you don't have permission";
if (! request()->hasCookie('share_session')) {
abort(403, $abort_message);
}
// Get shared session
$share_session = json_decode(
request()->cookie('share_session')
);
// Check if is requested same share record
if ($share_session->token !== $shared->token) {
abort(403, $abort_message);
}
// Check if share record was authenticated previously via ShareController@authenticate
if (! $share_session->authenticated) {
abort(403, $abort_message);
}
}
}
}

View File

@@ -1,100 +0,0 @@
<?php
namespace App\Services;
use DB;
use App\Models\Language;
use App\Models\LanguageTranslation;
class LanguageService
{
/**
* @param $license
* @param $locale
*/
public function create_default_language_translations($license, $locale)
{
$translations = [
'extended' => collect([
config('language-translations.extended'),
config('language-translations.regular'),
config('custom-language-translations'),
])->collapse(),
'regular' => collect([
config('language-translations.regular'),
config('custom-language-translations'),
])->collapse(),
];
$translations = $translations[strtolower($license)]
->map(function ($value, $key) use ($locale) {
return [
'lang' => $locale,
'value' => $value,
'key' => $key,
];
})->toArray();
$chunks = array_chunk($translations, 100);
foreach ($chunks as $chunk) {
DB::table('language_translations')
->insert($chunk);
}
}
/**
* Find newly added translations in default language
* translations file and insert it into database
*/
public function upgrade_language_translations()
{
// Get all app locales
$locales = Language::all()
->pluck('locale');
// Get default translations
$translations = LanguageTranslation::whereLang('en')
->get();
$default_translations = [
'extended' => collect([
config('language-translations.extended'),
config('language-translations.regular'),
config('custom-language-translations'),
])->collapse(),
'regular' => collect([
config('language-translations.regular'),
config('custom-language-translations'),
])->collapse(),
];
$license = strtolower(get_setting('license'));
// Find new translations in default translations
$newbies = $default_translations[$license]
->diffKeys(map_language_translations($translations));
// Store new translations for every language
$locales->each(function ($locale) use ($newbies) {
$translations = $newbies
->map(function ($value, $key) use ($locale) {
return [
'lang' => $locale,
'value' => $value,
'key' => $key,
];
})->toArray();
$chunks = array_chunk($translations, 100);
foreach ($chunks as $chunk) {
// Store translations into database
DB::table('language_translations')
->insert($chunk);
}
// Flush cache
cache()->forget("language-translations-$locale");
});
}
}

View File

@@ -1,77 +0,0 @@
<?php
namespace App\Services;
use Carbon\Carbon;
use App\Models\Zip;
use App\Models\Share;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
class SchedulerService
{
/**
* Delete old zips
*/
public function delete_old_zips(): 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();
});
}
/**
* Get and delete expired shared links
*/
public function delete_expired_shared_links(): void
{
Share::whereNotNull('expire_in')
->get()
->each(function ($share) {
// Get dates
$created_at = Carbon::parse($share->created_at);
// If time was over, then delete share record
if ($created_at->diffInHours(now()) >= $share->expire_in) {
$share->delete();
}
});
}
/**
* Get and delete failed files older than 24 hours
*/
public function delete_failed_files(): void
{
$local_disk = Storage::disk('local');
// Get all files from storage
$files = collect([
//$local_disk->allFiles('files'),
$local_disk->allFiles('chunks'),
])->collapse();
$files->each(function ($file) use ($local_disk) {
// Get the file's last modification time.
$last_modified = $local_disk
->lastModified($file);
// Get diffInHours
$diff = Carbon::parse($last_modified)
->diffInHours(now());
// Delete if file is in local storage more than 24 hours
if ($diff >= 24) {
Log::info("Failed file or chunk $file deleted.");
// Delete file from local storage
$local_disk->delete($file);
}
});
}
}

View File

@@ -1,68 +0,0 @@
<?php
namespace App\Services;
use App\Models\Page;
use App\Models\Setting;
use App\Models\Language;
use Illuminate\Support\Facades\Storage;
class SetupService
{
/**
* Create default folders which application to process files.
*/
public function create_directories()
{
collect(['avatars', 'chunks', 'system', 'files', 'temp', 'zip'])
->each(function ($directory) {
// Create directory for local driver
Storage::disk('local')
->makeDirectory($directory);
// Create directory for external driver
Storage::makeDirectory($directory);
});
}
/**
* Store default pages content like Terms of Service, Privacy Policy and Cookie Policy into database
*/
public function seed_default_pages()
{
collect(config('content.pages'))
->each(function ($page) {
Page::updateOrCreate($page);
});
}
/**
* Store default VueFileManager settings into database
*
* @param $license
*/
public function seed_default_settings($license)
{
collect(config('content.content.' . strtolower($license)))
->each(function ($content) {
Setting::forceCreate($content);
});
}
/**
* Store default VueFileManager settings into database
*
* @param $license
*/
public function seed_default_language()
{
Language::create([
'name' => 'English',
'locale' => 'en',
]);
Setting::create([
'name' => 'language',
'value' => 'en',
]);
}
}

View File

@@ -1,411 +0,0 @@
<?php
namespace App\Services;
use Stripe;
use App\Models\User;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Laravel\Cashier\Cashier;
use Illuminate\Support\Facades\Cache;
use Laravel\Cashier\Exceptions\IncompletePayment;
use Laravel\Cashier\Exceptions\PaymentActionRequired;
use Symfony\Component\HttpKernel\Exception\HttpException;
class StripeService
{
private \Cartalyst\Stripe\Stripe $stripe;
/**
* Stripe Service constructor.
*/
public function __construct()
{
$this->stripe = Stripe::make(config('cashier.secret'), '2020-03-02');
}
/**
* Get setup intent
*
* @param $user
* @return mixed
*/
public function getSetupIntent($user)
{
// Create stripe customer if not exist
$user->createOrGetStripeCustomer();
// Return setup intent
return $user->createSetupIntent();
}
/**
* Get tax rate ids
* @return array
*/
public function getTaxRates()
{
return $this->stripe
->taxRates()
->all()['data'];
}
/**
* Get plan tax rates
*
* @param $amount
* @return array
*/
public function get_tax_rates($amount): array
{
$rates_public = [];
foreach ($this->getTaxRates() as $rate) {
// Continue when is not active
if (! $rate['active']) {
continue;
}
// Calculate tax
$tax = $amount * ($rate['percentage'] / 100);
array_push($rates_public, [
'id' => $rate['id'],
'active' => $rate['active'],
'country' => $rate['country'],
'percentage' => $rate['percentage'],
'plan_price_formatted' => Cashier::formatAmount(round($amount + $tax)),
]);
}
return $rates_public;
}
/**
* Get default payment option or set new default payment
*
* @param $request
* @param $user
* @return mixed
*/
public function getOrSetDefaultPaymentMethod($request, $user)
{
// Check payment method
if (! $request->has('payment.meta.pm') && $user->hasDefaultPaymentMethod()) {
// Get default payment
return $user->defaultPaymentMethod()->paymentMethod;
}
// Clear cached payment methods
cache_forget_many([
'payment-methods-user-' . $user->id,
'default-payment-methods-user-' . $user->id,
]);
if ($request->has('payment.meta.pm') && $user->hasDefaultPaymentMethod()) {
// Set new payment
return $user->addPaymentMethod($request->input('payment.meta.pm'))->paymentMethod;
} elseif ($request->has('payment.meta.pm') && ! $user->hasDefaultPaymentMethod()) {
// Set new payment
return $user->updateDefaultPaymentMethod($request->input('payment.meta.pm'))->paymentMethod;
}
throw new HttpException(400, 'Something went wrong.');
}
/**
* Register new payment method
*
* @param $request
* @param $user
*/
public function registerNewPaymentMethod($request, $user): void
{
// Clear cached payment methods
cache_forget_many([
'payment-methods-user-' . $user->id,
'default-payment-methods-user-' . $user->id,
]);
// Set new payment method
$user->addPaymentMethod($request->token)->paymentMethod;
// Set new default payment
if ($request->default) {
$user->updateDefaultPaymentMethod($request->token)->paymentMethod;
}
}
/**
* Create new subscription or replace by new subscription
*
* @param $request
* @param $user
*/
public function createOrReplaceSubscription($request, $user): void
{
try {
// Get payment method
$paymentMethod = $this->getOrSetDefaultPaymentMethod($request, $user);
// Check if user have subscription
if ($user->subscribed('main')) {
// Change subscription plan
$user->subscription('main')->skipTrial()->swap($request->input('plan.data.id'));
} else {
// Create subscription
$user->newSubscription('main', $request->input('plan.data.id'))->create($paymentMethod);
}
} catch (IncompletePayment $exception) {
if ($exception instanceof PaymentActionRequired) {
$cashier_route = route('cashier.payment', [$exception->payment->id, 'redirect' => url('/settings/subscription')]);
throw new HttpException(402, $cashier_route);
}
throw new HttpException(400, $exception->getMessage());
}
}
/**
* Update customer details
*
* @param $user
*/
public function updateCustomerDetails($user)
{
$user->updateStripeCustomer([
'name' => $user->settings->name,
'phone' => $user->settings->phone_number,
'address' => [
'line1' => $user->settings->address,
'city' => $user->settings->city,
'country' => $user->settings->country,
'postal_code' => $user->settings->postal_code,
'state' => $user->settings->state,
],
'preferred_locales' => [
$user->settings->country, 'en',
],
]);
}
/**
* Get all plans
*
* @return mixed
*/
public function getPlans()
{
// Get stripe plans
$stripe_plans = $this->stripe->plans()->all([
'limit' => 100,
]);
// Plans container
$plans = [];
foreach ($stripe_plans['data'] as $plan) {
// Get stripe product
$product = $this->stripe->products()->find($plan['product']);
// Push data to $plan container
if ($product['active'] && isset($product['metadata']['capacity'])) {
array_push($plans, [
'plan' => $plan,
'product' => $product,
]);
}
}
return $plans;
}
/**
* Get all active plans
*
* @return mixed
*/
public function getActivePlans()
{
// Get stripe plans
$stripe_plans = $this->stripe->plans()->all([
'limit' => 100,
]);
// Plans container
$plans = [];
foreach ($stripe_plans['data'] as $plan) {
if ($plan['active']) {
// Get stripe product
$product = $this->stripe->products()->find($plan['product']);
// Push data to $plan container
if ($product['active'] && isset($product['metadata']['capacity'])) {
array_push($plans, [
'plan' => $plan,
'product' => $product,
]);
}
}
}
return $plans;
}
/**
* Get plan details
*
* @param $id
* @return mixed
*/
public function getPlan($id)
{
if (Cache::has("plan-$id")) {
return Cache::get("plan-$id");
}
return Cache::rememberForever("plan-$id", function () use ($id) {
$plan = $this->stripe->plans()->find($id);
$product = $this->stripe->products()->find($plan['product']);
return [
'plan' => $plan,
'product' => $product,
];
});
}
/**
* Create plan
*
* @param $data
* @return mixed
*/
public function createPlan($data)
{
if ($data instanceof Request) {
$plan = [
'name' => $data->input('attributes.name'),
'description' => $data->input('attributes.description'),
'price' => $data->input('attributes.price'),
'capacity' => $data->input('attributes.capacity'),
];
} else {
$plan = [
'name' => $data['attributes']['name'],
'description' => $data['attributes']['description'],
'price' => $data['attributes']['price'],
'capacity' => $data['attributes']['capacity'],
];
}
$product = $this->stripe->products()->create([
'name' => $plan['name'],
'description' => $plan['description'],
'metadata' => [
'capacity' => $plan['capacity'],
],
]);
$plan = $this->stripe->plans()->create([
'id' => Str::slug($plan['name']),
'amount' => $plan['price'],
'currency' => config('cashier.currency'),
'interval' => 'month',
'product' => $product['id'],
]);
return compact('plan', 'product');
}
/**
* Update plan
*
* @param $request
* @param $id
*/
public function updatePlan($request, $id)
{
$plan_colls = ['is_active', 'price'];
$product_colls = ['name', 'description', 'capacity'];
$plan = $this->stripe->plans()->find($id);
// Update product
if (in_array($request->name, $product_colls)) {
if ($request->name === 'capacity') {
$this->stripe->products()->update($plan['product'], ['metadata' => ['capacity' => $request->value]]);
}
if ($request->name === 'name') {
$this->stripe->products()->update($plan['product'], ['name' => $request->value]);
}
if ($request->name === 'description') {
$this->stripe->products()->update($plan['product'], ['description' => $request->value]);
}
}
// Update plan
if (in_array($request->name, $plan_colls)) {
if ($request->name === 'is_active') {
$this->stripe->plans()->update($id, ['active' => $request->value]);
}
}
}
/**
* Delete plan
*
* @param $slug
*/
public function deletePlan($slug)
{
$this
->stripe
->plans()
->delete($slug);
}
/**
* Get all user invoices
*
* @param $user
* @return mixed
*/
public function getUserInvoices($user)
{
return $user
->invoices();
}
/**
* Get user invoice by id
*
* @param $customer
* @param $id
* @return \Laravel\Cashier\Invoice|null
*/
public function getUserInvoice($customer, $id)
{
return User::whereStripeId($customer)
->firstOrFail()
->findInvoice($id);
}
/**
* Get all invoices
*
* @return mixed
*/
public function getInvoices()
{
return $this
->stripe
->invoices()
->all([
'limit' => 20,
]);
}
}

873
changelog.md Normal file
View File

@@ -0,0 +1,873 @@
## Version 2.2.2
#### Release date: 16. July 2022
- Fixed issue when email wasn't sent in active app language
- Fixed issue with subscription module loading
## Version 2.2.1
#### Release date: 1. July 2022
### New Usage Restriction Rules for User Accounts for Metered Billing
- Allow limiting max usage before users will be forced to increase balance in first month of account existence
- Force users to increase balance when usage is bigger than their current balance
#### Release date: 29. Jun 2022
- Fixed reCaptcha for the contact form
## Version 2.2.0.13
#### Release date: 29. Jun 2022
- Extended login time up to 3 months
- Fixed deleted at language string in grid view browsed in trash section
- ## Version 2.2.0.12
#### Release date: 28. Jun 2022
- Fixed paystack transaction issue
## Version 2.2.0.11
#### Release date: 27. Jun 2022
- Added hint to set cron command in dashboard panel when cron is not set correctly
## Version 2.2.0.10
#### Release date: 27. Jun 2022
- Fixed issue with downloading certain file types when you are using Backblaze storage driver
- Fixed issue when Google Analytics doesn't record visitors
## Version 2.2.0.9
#### Release date: 23. Jun 2022
- Added spinner when pdf is loading
- Set sandbox/live mode in PayPal key configuration setup form
- Fixed issue when after deleting user, the related subscription wasn't deleted
- Fixed issue when you perform composer update with private repository
- Fixed issue where change in sorting option will duplicate the content in file view
- Fixed issue where Dragged & Dropped folder from desktop didn't start uploading
- Fixed issue when you upload empty .txt file, it stops the upload process
## Version 2.2.0.8
#### Release date: 15. Jun 2022
- Fixed issue when you tried switch to another language, the language stay same
## Version 2.2.0.7
#### Release date: 13. Jun 2022
- Solved issue when you click on the PayPal logo it makes the new copy of the payment buttons
## Version 2.2.0.6
#### Release date: 13. Jun 2022
- Solved issue when user wasn't redirected into stripe checkout
## Version 2.2.0.5
#### Release date: 12. Jun 2022
- Solved issue with showing trash content (Affected since 2.2.0)
## Version 2.2
#### Release date: 18. May 2022
### Fixes
- Solved issue with database backup notifications
- Solved issue where after team member was invited into team folder, email with urging the recipient to create new account was sent
- You are now allowed to set price for metered billing in 3 decimal places
- Solved UI issue with empty notification popup
- Plans in fixed subscription are now automatically sorted from lower to higher price
- When new user was created via admin, the verification email was send
- Item name in list view type is now extended on the full page width
### New Features
- API version 1 released
- Paginated records loading with infinity scroller
- If you send file request for native user via email option, the push notification will be sent to the user
- Ability to test your websocket (Broadcasting) connection via Admin / Server / Broadcasting tab
## Version 2.1.3
#### Release date: 10. May 2022
- Ability to manually synchronize plans in fixed subscription type
- Improved sanitization for .env values to prevent crash your app
- Improved reCaptcha validation errors
- Fixed issue when upload doesn't start after you drag the file into empty view
- Fixed issue when homepage flash to sign in screen after the homepage was disabled in admin panel
- Fixed trash navigator issue
- Fixed issue when you create plan with 0 team members amount
## Version 2.1.2
#### Release date: 8. May 2022
- Fixed issue with chunk uploads (Critical issue affected since 2.1.1)
- Fixed issue with creating plan with unlimited team members
## Version 2.1.1
#### Release date: 29. April 2022
- Fixed issue with reading image upload
## Version 2.1.0
#### Release date: 25. April 2022
- New remote upload function
- Broadcast server implementation, for more info check [Broadcasting Guide](https://gist.github.com/MakingCG/a702a112be63bc6f0032dd55522327cf#broadcasting)
## Version 2.0.19
#### Release date: 21. April 2022
- Fixed issue with Backblaze credentials set up
- The switch button in archived plans is now hidden
- updated readme.md
- Fixed upload progressbar in mobile version
- Added Viet Nam language into the language editor
## Version 2.0.18
#### Release date: 19. April 2022
- Fixed issue with Google login button
- Fixed issue with PayPal subscription
## Version 2.0.17
#### Release date: 12. April 2022
- Added option to use FTP as VueFileManager file storage server
## Version 2.0.16
#### Release date: 8. April 2022
- Test mailgun, ses and postmark connection before storing your credentials into the app
- UI enhancements & fixes
## Version 2.0.15
#### Release date: 6. April 2022
- Wasabi region list updated
- The delay after first upload in file request when the interface wasn't showing was removed
- If adsense banner location isn't filled, the ads space won't be showed
- Fixed issue when in grid view you tried to move image into another folder
- Fixed issue when you can't move or delete items via mobile multiselect function
- You can now open searched file from spotlight in FilePreview mode to access file settings and functions
## Version 2.0.14
#### Release date: 5. April 2022
- Added option to set default max team members for new user registrations
- Added new app settings shortcuts findable by spotlight - Application, Login & Registration, Appearance, Adsense, Homepage, Environment, Server
- Now in 2fa set up challenge user is required to confirm his app setup with code
## Version 2.0.13
#### Release date: 4. April 2022
- Auto plan synchronization improvements.
- Fixed issue with thumbnails in grid preview type
- PayPal sandbox option was added into PayPal credentials setup
- Fixed issue in mobile spotlight where you trying open searched image
## Version 2.0.12
#### Release date: 2. April 2022
- Added status column to the fixed plan table
- Ability to delete fixed plan if there isn't any subscribed user
- Improved error handling in subscription module
## Version 2.0.11
#### Release date: 1. April 2022
- Improved email setup in administration settings and setup wizard
- Ability to set custom s3 compatible service in administration settings and setup wizard
- Test s3 connection before set up in administration settings and setup wizard
- Test smtp connection before set up in administration settings and setup wizard
## Version 2.0.0 - 2.0.10
#### Release date: 31. March 2022
- You can now generate link for direct download via context menu in copy link input
- You can now upgrade from regular to extended license version via admin panel
- Fixed issue with .dwg file icon
- You can now set uploading chunk file size directly in your admin
- Team Folders and Shared With Me root folder has now disabled delete/move function
- When you invite someone to your team folder, all his usage (storage, bandwidth) will be on behalf of you, not the member
- Fixed issue when you are moving folders between your Team Folders and Private files and vice versa
- Fixed issue when downloading bandwidth doesn't write to the user total bandwidth stats
- Fixed issue with language strings which indicate limited/unlimited team members in fixed plans
- Fixed issue when you are trying delete user registered with only the first name
- Fixed issue with Adsense where banners wasn't placed correctly by their described location
## Version 2.0.0
#### Release date: 21. March 2022
**User Interface**
- Fullscreen mode can be set by double arrow icon on top of navigation sidebar in file page or by action in spotlight
- In mobile version you can now by opening image or document move seamlessly to another by swipe gesture
- Emoji picker was redesigned and now offer better experience to pick your favourite emoji for your folder icon
- Actions like create folder, upload files and any others was moved and grouped by 'Frequently used' and 'Others' category under single button
- User profile, Dashboard and other admin pages was redesigned
- Mac users can now switch between native emojis and twemojis
- New button to switch between dark/light mode was added under the main navigation in desktop
- Now when you undo in your browser, it goes back to the previous folder
**Spotlight**
- Search through your files and folders
- Can be used as quick navigation through your folders or app pages
- Ability to search actions like toggle emojis, toggle dark/light mode, creating file request, new user and many more
- Search your users by activating user filter with keyboard shortcut (u+space)
- Ability to call spotlight with cmd/ctrl + k from any location in app like admin or user profile
- Ability from any location in the app to show document, image or video in file preview component
- Ability to use keyboard shortcuts to navigate in spotlight like arrow up/down, enter
**Collaboration**
- New Team Folders and Shared with Me categories
- Ability to create new team folder and invite users by email invitation, or if user is app user, then push notification will be sent as well.
- Ability to convert existing folder into Team Folder and invite members into it.
- Ability to dissolve your team folder. All members permissions will be revoked and your folder will be moved into My Files category.
- Ability to leave folder if you are member of someone team folder
- Received invitation can be accepted or declined
- User avatar indicate in file icon who is the owner of the file
- New team heads icon in desktop and mobile toolbar to indicate team members in the team folder
**Metered Billing**
- New metered billing where user can be charged by what he uses.
- Bandwidth, storage, flat fee and members are optional features which can be charged, not required
- Native balance system from which user is charger at the end of current billing period
- User can fund his balance by PayPal and Paystack single payment option
- If Stripe payment method is allowed, user can register his credit card and all future payments for billing period will be automatically charged. If there is any credit in balance and is sufficient, then this amount will be preferred instead of credit card charging
- User has ability to add/delete his payment methods (only Stripe)
- Admin has ability to increase user balance with certain amount
- Ability to set registration bonus for every new user registration
- User can set billing alert with certain amount. When this amount will be reached, the notification will be sent.
- New Usage Estimates widget in user profile which provide price estimates for current billing period
- New transactions widget in user profile with usage history
**Fixed Billing**
- Plans with yearly billing period is now supported
- New subscription widget with subscription details in user profile
- New Payment Method widget to manage user credit cards (available only for Stripe)
- New popup component to subscribe or upgrade account plan
**Notification Center**
- Ability to see notifications by Unread and Read category
- Interactive notifications to seamlessly perform actions from it if needed
- If broadcasting is set, notifications will be received just in time and showed in bottom right corner of the app
- Ability to clear all notifications by button
**Zip**
- New on the fly zipping system zips files without additional storage usage
- User can now select any files with any folders and zip them together
**Sharing**
- Redesigned sharing popup component for better user experience
- Shared video file (.mp4) has now ability to play video in shared page
- Ability to get share link via QR code
- Ability to generate embeddable code with shared item (beta)
- App logo was added into single file share pages
**File Request**
- User can generate file request by opening context menu over single folder or call file request from spotlight
- Ability to set custom folder name if file request will be filled
- Ability to leave a message for guest
- Ability to send file request by email for certain email recipient
- Full-fledged reach UI for guests to upload and manage their files directly in file request
- Push notification about filled file request will be received for user
**Folder Upload**
- Now user can upload their folders. The same folder structure will be recreated in the app
**User Settings**
- New appearance option was added where user can set his theme mode by dark, light or based by system option
- New default emoji option was added where Apple user can switch between native emojis or twemoji
- 2fa setup challenge option was added. User can store and generate backup keys.
- New Personal Access Token section was added where user can generate access token for API requests.
- New 'Current Password' input was added into change password functionality
- New widget to track the latest upload and download was added into the Storage tab
- Storage usage widget was redesigned
- New Billing tab with all subscription related items was added
**Login & Registration**
- Email confirmation for new account registrations can be required
- Integrated database with more than 550 disposable temporary email services to automatically deny new account registrations
- Users can now set up 2 factor verification with their favourite authenticator app
- reCaptcha was added to provide security for your registration and contact form
- Social authentication was implemented with Facebook, Google and GitHub drivers.
**Adsense**
- Adsense will be integrated into VueFileManager
- The ads are showing in 3 locations - File Viewport, Download Page and Homepage
**Setup Wizard**
- Server check before you running installation, it will show you if you had set up your server correctly
- Dark mode support
- Now you don't need to set up your subscription system in setup wizard
**Broadcasting**
- Pusher implementation for live communication
- Native websocket server as replacement for Pusher (more details soon)
- Live notification
**System**
- Database backups on daily basis
- After you upload image, additionals thumbnails will be generated to provide you faster browsign experience through your image gallery
**Admin & Settings**
**Dashboard**
- New widget to track the latest upload and download was added
- New widget with the latest transactions was added into extended license version
- New earnings widget was added
- New alerts will tell you if you are missing plan or you don't have running cron correctly
**Settings / Server**
- Ability to see if cron job is running correctly
- Ability to download your server log from admin panel
- Ability to see latest 5 database backups
- Ability to check if writable permission for exact folders are set correctly
- Ability to check if you have correctly set php version and php.ini variables
- Ability to see if you have installed all required php extensions
**Settings / Environment**
- Ability to set Broadcasting from admin settings
- Ability to set Storage Driver from admin settings
- Ability to set Mail Driver from admin settings
**Settings / Appearance**
- Ability to change entire VueFileManager color scheme
- Ability to set dark mode logo for main and horizontal logo
- Ability to set your own OG Image
- Ability to set your own Touch Image
**Settings / Login & Registration**
- New option where you can require email verification was added
- New widgets to set up Facebook, Google and GitHub social authentication
**Settings / Application**
- New options to set up reCaptcha
**Settings / Adsense**
- Ability to manage Google Adsense
**Dev**
- PHP 8 support
- New DDD design for the backend
- Shipped with the latest version of Laravel 9.x
- Passport was replaced by Sanctum
- New artisan command that expressly installs the entire application
- New artisan command that expressly installs the entire application with the demo data
- ~80% Of the frontend code was migrated into Tailwind v3. We will continue to reach 100% tailwind friendly
## Version 1.8.3.13
#### Release date: 9. December 2021
- Fixed issue when visitor can't download files from shared folder with 'Can only view and download' privilege
- Fixed issue with sending contact form
## Version 1.8.3.11-12
#### Release date: 7. July 2021
- Fixed issue when you tried load folders/files with special characters name
## Version 1.8.3.10
#### Release date: 29. June 2021
- Security patch (Critical severity)
## Version 1.8.3.9
#### Release date: 18. June 2021
**Fixes:**
- Fixed issue when in some cases your server can suffer with increasing RAM usage
- Fixed translation issue in some user mobile pages
- Mobile navigation fix with hidden back button
- Fixed issue where in some case special characters was excerpted from uploaded filename
## Version 1.8.3.8
#### Release date: 15. June 2021
- Alibaba Cloud OSS support
## Version 1.8.3.7
#### Release date: 9. June 2021
- App name fix in email templates
## Version 1.8.3.6
#### Release date: 7. June 2021
- Translation improvements on backend
## Version 1.8.3.5
#### Release date: 24. May 2021
- Translation improvements on backend
## Version 1.8.3.4
#### Release date: 15. May 2021
- Upload progressbar fix
## Version 1.8.3.3
#### Release date: 10. May 2021
- Security update (upgrade required)
## Version 1.8.3.2
#### Release date: 17. April 2021
**Fixes:**
- Fixed multi select on desktop browser
## Version 1.8.3.1
#### Release date: 18. April 2021
**Fixes:**
- Fixed previewing files in mobile devices
## Version 1.8.3
#### Release date: 17. April 2021
**Features:**
- Ability to create new language
- Ability to set default language for aplication
- Ability to show pdf files in VueFileManager
## Version 1.8.2.3
#### Release date: 21. March 2021
**Fixes:**
- Fixed not found page
- Fixed admin menu in regular license
## Version 1.8.2.2
#### Release date: 12. March 2021
**Fixes:**
- Fixed file preview in single shared file wasn't showing correctly
## Version 1.8.2.1
#### Release date: 25. February 2021
**Fixes:**
- Fixed jumping upload progressbar
## Version 1.8.2
#### Release date: 20. February 2021
**Folders:**
- Ability to change folder icon as Emoji
- Ability to change folder icon color from 22 colors set
**Fixes:**
- Added zip folder into mobile folder menu
- Removed Autofocus in mobile creating folder
## Version 1.8.1
#### Release date: 7. February 2021
**Functions:**
- Ability to zip and download folder with content within
- Ability to send shared folder/file to multiple email recipients
- Ability to send share link in existing shared items
- Every user has ability to change his timezone in profile settings
**UI & UX:**
- After click on logout if your request is long, you will see processing window
- Move/Share/Delete icons is unactive when you don't have selected file in desktop version
- Move/Share/Delete icons is hidden in touchable devices
- Delete item in contextmenu is now highlighted as red
- Hidden scroller in navigation panel on windows
- Delete icon for clear text field in rename popup
- After opening video, it's start playing automatically
- Autofocus and selecting folder name after creating it in desktop version
**Fixes:**
- Max Upload frontend validation fix
- In latest uploads files are sorted alwas from newest
- Download icon in image/video preview on mobile device and shared folder with read/download privilegies
**Regular License:**
- Included landing page
- Included Privacy Policy, Terms of Condition and Cookies policy pages
- Included contact form page
## Version 1.8
#### Release date: 21. December 2020
**User Interface:**
- Added navigator to shared page with folders when you have multiple folders within for better user experience
- New popup to rename your item in desktop & mobile version
- Trash moved to Home page under 'Recent Uploads' navigation item
- Ability to collapse navigator or favourites widget in File page
- Ability to remove uploaded logo and get back to text logo
- Ability to cancel uploading via x button
- Prevent browser 'Go Back' when you undesirably trying to go to previous page after sign in to your account
**Sorting**
- New sorting menu in desktop version buttons panel with multiple actions
- New view button with sorting options in mobile version
- Ability to sort files & folders in date or alphabetical order
**Bulk Operations**
- Select multiple items in desktop version by holding shift key or ctrl/cmd key for increase or decrease selection
- New multi select mode in mobile version activated by clicking on 'Select' button below search bar
- Ability to select all or deselect all items in mobile version of multi select
- Select multiple items and delete them by delete/backspace key
- Select multiple items and move them by drag&drop to another folder in view or move them via move option
- Ability to move multiple item by dragging them to folder in navigator panel
- Ability to set multiple favourite folders by dragging them to favourites group in sidebar panel
- Ability to cancel multiple shareing items in 'My Sharing Items' sections via context menu action
- New compact UI component for indicate dragging action
- Ability to download multiple files from selection as zip
- New scrollbar for the Windows users
**Bug Fixes:**
- Title name of favourite folder overflowed sidebar when you have long title
- Share button in image preview appear when you are in shared public folder
- Fixed search indexer overload in high traffic demands scenario
- Folder tree in navigator now has correct ordering with folder list in file view
## Version 1.7.12
#### Release date: 16. November 2020
- Limit maximum upload size on single file
## Version 1.7.11
#### Release date: 24. October 2020
- Reading exif data and showing them in file info panel
- Ability to ban mimetypes. You can find blacklist setup in Settings / Application
- Lazy loading for images. If you have hundreds of images in your folder, you will have experience with seamlessly loading.
- Fixed bug with context menu overflow in shared page
- Fixed button overflow on small mobile screens in popups.
## Version 1.7.10
#### Release date: 31. August 2020
- Ability to see file in full preview (images, videos[mp4, web, ogv], audios)
## Version 1.7.9
#### Release date: 26. August 2020
- Ability to set expiration for shared link
- If user is logged in, after visit SignIn page will be redirected to files page
## Version 1.7.8
#### Release date: 25. August 2020
- Ability to read file metadata in shared link for instant messengers
## Version 1.7.7
#### Release date: 24. August 2020
- Backend pagination for native data
- Added clear cache button to app settings
- Removed deprecated commands
- Code splitting support for Vue router
- Added region list to setup wizard
- added htaccess to redirect domain root to /public folder
- Fixed issue with non VueFileManager created Stripe plans
- Fixed email setup in app settings
- Additional text logo fix in Sign pages
## Version 1.7.6
#### Release date: 19. August 2020
- Folder delete fix
## Version 1.7.5
#### Release date: 10. August 2020
- Bug fixes and UX enhancement
## Version 1.7.4
#### Release date: 5. August 2020
- Bug fixes and UX enhancement
## Version 1.7.3
#### Release date: 30. July 2020
- Chunk Upload
- Multipart upload support on external storages (Ability to upload bigger files)
- Progressbar now show upload in %
## Version 1.7.2
#### Release date: 22. July 2020
- Readme update
- Improvement on Setup Wizard
## Version 1.7.1
#### Release date: 21. July 2020
- Fixed register button in Regular license
## Version 1.7
#### Release date: 20. July 2020
**Software as a Service**
- Ability to create monthly subscription plans with storage space
- Ability to charge customers for storage space with Stripe payment service
- List all of your customer invoices
- Included Legal pages (Terms of Service, Privacy Policy, Cookie Policy)
- Included Cookie disclaimer in SaaS version
- Landing page for present your service solution
**Settings - Application**
- Storage limitation option
- Default storage space for new accounts option
- Allow user registration option
- Set your contact email for message form in landing page
- Set your google analytics code to track visitors
**Settings - Appearance**
- App title option
- App description option
- Change your logo and favicon option
**Settings - Billing**
- Set your company name and VAT number options in SaaS version
- Set your billing country adress. options in SaaS version
**Settings - Payments**
- Allow subscription payments option
- Get your stripe webhook link option
**Settings - Homepage**
- Ability to change content, show/hide sections for Landing page presentation
**Settings - Email**
- Ability to set your email credentials from admin panel
**Admin - Users**
- Subscription plan details
- List of all user invoices
**Dashboard**
- Showed widget with your total users
- Showed widget with total space usage
- Showed widget with total premium users
- Showed widget with latest registrations
- Showed latest VueFileManager version
- Showed license type (Extend/Regular)
**User**
- Added billing information to profile settings in Saas Version
- Added subscription plan page to get information about current subscription. Ability to cancel or renew subscription
- Added payment card page with ability to list all registered card, add new credit card, remove card or set selected card as default payment.
- Added invoices page where are listed all invoices
- Added invoice page detail with ability to print invoice with
**VueFileManager design**
- Circle notice icon in avatar in case of incomplete payment or required action to upgrade storage capacity
**Setup Wizard**
- The UI for Install and configure your VueFIlemanager
- Purchase code verification
- Database credentials setup
- Ability to setup Stripe for Extended License (Set Credentials, set billing informations and create subscription plans)
- Storage Setup
- Email credentials setup
- General settings setup
- Admin setup
**Storage**
- Added support for Object Cloud Storage by Wasabi
- Added support for Backblaze B2 Cloud Storage
Fixes
- Fixed issue when you move parent directory to its children directory, then your folder disappear.
- Fixed issue which appear on specifical hosting configuration when you cant load shared folder content.
**Others**
- Improved form design
- Profile settings get sidebar panel navigation
- Improved design for important notices
- Updated i18n language files
- Added agreement in registration page for SaaS version
- Upgraded laravel framework from 6 to 7 version
**Upgrading**
- All upgrading backend operations is running on background after putting new source code to app directory (Don't forget create backup of your database and storage before make any changes in your production application)
- UI page for additional options when its neccesarily
- Upgrading To 1.7 From 1.6.x or newest
## Version 1.6.4
#### Release date: 9. June 2020
- Fileview xscroller fix
## Version 1.6.3
#### Release date: 5. June 2020
- Fixed svg upload
- Fixed scrolling in main file view
## Version 1.6.2
#### Release date: 31. May 2020
- Fixed popups on mobile version
## Version 1.6.1
#### Release date: 31. May 2020
- Fixed npm building crash on web server
## Version 1.6
#### Release date: 28. May 2020
**User Management**
- List of all registered users
- Ability to create new user
- Change user role (Admin or User)
- Change user storage capacity in GBs
- User storage capacity usage preview
- Send email to user for password reset
- Ability to delete user with all user data and stored files
Others
- Redesigned User profile settings
- Small bug fixes
- New artisan command for upgrade app (for more info check upgrade guide)
- Upgrading To 1.6 From 1.4.2 or newest
## Version 1.5.2
#### Release date: 22. May 2020
- Empty page fix
- Log out in mobile fix
- Dark mode fixes
- Password reset bug fixes
## Version 1.5
#### Release date: 19. May 2020
**UI & UX**
- New navigation menu with Home, Shared, Trash, Settings locations in desktop
- New dynamic sidebar with folder tree navigation, file categories and tools
- Folder tree navigator in main file page
- Added Participant uploads category to shared page
- Added recent uploads category to file page
- New settings page with separated Profile, Password and Storage
- Updated colors for dark mode
- Improvement desgin across all components
- Added (X) close button to all popups
- Added editing icons (move, share) to main bar
- More transparent context menus with action groups
Mobile
- New main navigation menu
- Added item thumbnails to mobile contextmenu
Others
- Public shared image now open in an original image page
- New page with storage usage details
## Version 1.4.2
#### Release date: 6. May 2020
**External Storage Services**
- Amazon Web Services S3 support
- Digital Ocean Spaces support
- Updated documentation
- New blog with some handy tips and news about VueFileManager
## Version 1.4.1
#### Release date: 4. May 2020
**Translations**
- Added Chinese (Simplified) language (thanks haimang to contribute)
Bugs
- Go to profile in mobile version
- Internal front-end bug
Error logs
- Added when passport client isnt set up correctly
- Added when database connection isnt available
**Others**
- Updated terminal info when you are running php artisan setup:prod
- Updated documentation with more describing installation process
## Version 1.4
#### Release date: 1. May 2020
**Sharing**
- Share your folders and files
- Added sidebar group with shared items
- Added UI icons to item preview to look which item is shared and which item was uploaded by participant
**Folders**
- User can share folder content
- User can protect folder content by password
- User can set permission to interact with shared folder - only view and download or view, download, upload, rename, delete and move items
**Files**
- User can share single file
- User can protect single file by password
**Others**
- Small UI improvements
- Bug fixes
- Upgrading to 1.4 from 1.3.x
## Version 1.3.1
#### Release date: 8. April 2020
- Bug fixes
- Upgrading to 1.3.1 from 1.2
## Version 1.3
#### Release date: 3. April 2020
- i18n localization support
- Added SK, EN language files
- Video/Audio preview in file preview panel (Thanks to Joshua Fouyon to participating on this feature)
- Drop uploading (You can now drag files from desktop and drop it to VueFileManager)
- Fixed bug when rename item in safari browser
- Fixed bug when you drag folder from trash to favourites in sidebar panel
- small functions and design improvements
- Upgrading to 1.3 from 1.2
## Version 1.2
#### Release date: 29. March 2020
- Move your items by folder tree
- Fixed bug with image rotation on iOS Device
- Improved animations
- Small design changes
- iOS web app capable support
## Version 1.1.1
#### Release date: 17. March 2020
- Bug fixes
## Version 1.1
#### Release date: 15. March 2020
**User Authentication**
- Login to user account
- Register new user account
- Reset user password
**Functionality**
- Added locations to menu
- Added trash for deleted folders & files
- Restore files or folders from trash
- Empty trash function
- Favourites folders
- List of 5 latest uploads
- Profile settings page
- Storage info and upload limits
**Design**
- Night Mode
- Navigation sidebar
- Quick action buttons in mobile version
- Improved mobile UX
- Other small design improvements
**Settings**
- Enable/Disable user account registration
- Set storage limitation
- Set storage capacity for all users
## Version 1
#### Release date: 25. February 2020
- Official release

313
codecanyon.html Normal file
View File

@@ -0,0 +1,313 @@
<h3>VueFileManager Mobile Browser Screenshots</h3>
<img src="https://i.ibb.co/g3r3H49/mobile-files.jpg" alt="Files">
<img src="https://i.ibb.co/4Mb7dCN/mobile-teams.jpg" alt="Teams">
<img src="https://i.ibb.co/MCB5wjY/mobile-file-popups.jpg" alt="Popups">
<img src="https://i.ibb.co/NCQ5RKL/mobile-user-profile.jpg" alt="User Profile">
<img src="https://i.ibb.co/8PSJt51/mobile-administration-panel.jpg" alt="App Settings">
<img src="https://i.ibb.co/d5kY6cs/mobile-spotlight.jpg" alt="Spotlight">
<h3>Core Functionalities</h3>
<h5><strong>Meticulously Designed User Interface & User Experience</strong></h5>
<p>
In last 2 years of VueFileManager evolution with help of our users, we spend a lot of time designing gorgeous
looking user interface and seamless user experience with our file management frontend. We advocate simplicity and
usability.
</p>
<h5><strong>Responsive</strong></h5>
<p>
Meticulously optimized mobile version of VueFileManager, we just love how nice and easy are all components working.
Mobile responsive version should be nice and usable as his bigger desktop brother.
</p>
<h5><strong>Metered Billing System - SaaS (Extended License Required)</strong></h5>
<p>
Metered billing works like Pay as You Go. You can charge your users by their usage, how many Gigabytes of data
they have stored, how many Gigabytes of data they transfer or just you can set up your fixed flat fee.
</p>
<h5><strong>Offline Payments - SaaS (Extended License Required)</strong></h5>
<p>
With a metered billing system, users don't need to own and have registered credit cards. VueFileManager has its own
credit system where users can increase deposit with a single-payment charge. This charge can be processed By PayPal,
Stripe or Paystack provided payment methods - for example Apple Pay, Google Pay, Bank Account, USSD, Mobile Money,
EFT, QR Code, PayPal credit and many more.
</p>
<p>
Also, you as an admin can give a bonus in a certain value for every new registration, or send an existing bonus for
a user in a certain value. Users with a metered billing system can set their Billing alert with a certain value. All
metered subscriptions are settled every 30 days.
</p>
<p>With Stripe enabled, users can register their credit to charge any payments automatically.</p>
<h5><strong>Fixed Billing System - SaaS (Extended License Required)</strong></h5>
<p>
With fixed billing you can set your billing plans in monthly or yearly periods. You can set a limit for max storage
disk size or max number of team members.
</p>
<h5><strong>No-SaaS in Default</strong></h5>
<p>
If you dont want to run your business with a storage cloud but just using VueFileManager as your own file storage
client, you can use the app without all billing functions as well. See our basic demo without subscription module.
</p>
<h5><strong>Upload Files</strong></h5>
<p>
With VueFileManager you can upload files up to tens of gigabytes, dont worry that your big files won't be uploaded.
We support chunk upload and multipart uploads for your s3 storage service. All work seamlessly.
</p>
<h5><strong>Folder Upload</strong></h5>
<p>
For VueFileManager it isn't any problem to upload a folder with your files. The same folder structure will be
recreated in the app.
</p>
<h5><strong>Sharing Files</strong></h5>
<p>
With our reach sharing functionalities, you can easily just click on your file or folder, and generate a shared link
for everyone. Also you can protect your shared files with your password. 
</p>
<p>
Use expiration functionality to automatically expire links, share links directly via email or generate QR code and
share it with guys on your left.
</p>
<h5><strong>Shared Pages</strong></h5>
<p>
If you share any folder with files within, the user has the same user experience as a logged user. He can create
folders, name it, upload files or move them into other folders directly in your shared folder.
</p>
<p>
Videos have their own dedicated shared page with your app logo and ability to play video directly in this page with
the download button above, try it, its magic!
</p>
<h5><strong>File Request</strong></h5>
<p>
Do you need a lot of files? Just generate a file request, and send your link for this person. The person can use it
to upload files directly into your folder or into your home section for files. The user whos uploading files has
the same user experience as the internal account.
</p>
<h5><strong>Teams</strong></h5>
<p>
Invite your colleagues or family into your team folders, set their permissions and collaborate together seamlessly.
</p>
<h5><strong>Spotlight</strong></h5>
<p>
With the spotlight, you can search for your users, files, folders, navigate throughout the app, toggle dark mode,
toggle emojis and many more from any location in the app. Its like magic. Good suit for super users.
</p>
<h5><strong>Notification Center</strong></h5>
<p>
All important events that occur in your account will be recorded in your notifications center. For example, a new
team invite, file request was filled, bonus received, billing alert was reached and many more.
</p>
<h5><strong>External Storage Services</strong></h5>
<p>
You can use it as main storage for all your files external storage service. We support all S3 compatible services
like Amazon Web Services S3, Spaces from Digital Ocean, Backblaze, Wasabi, Alibaba Cloud OSS, Storj and many more.
</p>
<h5><strong>Decentralized Storage Service</strong></h5>
<p>
With Storj DCS (Decentralized Cloud Storage) files arent stored in centralized data centers — instead, they're
encrypted, split into pieces, and distributed on a global cloud network.
</p>
<h5><strong>Full-Fledged API</strong></h5>
<p>
You can integrate VueFileManager into your app seamlessly. Users can generate authentication tokens in their profile
settings. Documentation for API coming soon.
</p>
<h5><strong>2-Factor Verification</strong></h5>
<p>
Another layer of security to make sure your files are secured. Users can set up 2 factor verification with their
favourite authenticator app.
</p>
<h5><strong>Social Logins</strong></h5>
<p>
Log into your app with your social account. Currently we support Facebook, Github and Google providers. More is
coming soon.
</p>
<h5><strong>Customizable Folder Icons</strong></h5>
<p>
Set your favourite emoji to your folder as an icon and make VueFileManager more personal for you! If you are an
apple user, you can switch between Apple emojis and Tweemojis from twitter.
</p>
<h5><strong>Admin Panel</strong></h5>
<p>
As admin, you have full control over the entire app, you can create or delete users, manage their storage size, disable registration, require email verification, set upload limits and many more.
</p>
<h5><strong>Dark Mode</strong></h5>
<p>
We support dark mode natively. Users can set dark mode via application, or let Dark/Light mode handle with preferred
OS settings.
</p>
<h5><strong>Language Editor</strong></h5>
<p>
With our language editor you can translate applications into your home language. Its at your hand in the admin
panel.
</p>
<h5><strong>Auto Database Backup</strong></h5>
<p>
VueFileManager will take care of your daily database backups. When an unexpected event occurs, your database backup
will be ready for you.
</p>
<h5><strong>reCaptcha</strong></h5>
<p>
reCaptcha will provide security for registration and contact form from internet bots and prevent spammers from
abusing your application.
</p>
<h5><strong>Blacklist with more than 550+ Temporary Email Services</strong></h5>
<p>
We integrated a database with more than 550 disposable temporary email services to deny new account registrations
with abusive behavior.
</p>
<h5><strong>AdSense</strong></h5>
<p>
Monetize your file cloud with Google Adsense service. We natively implement 3 ad slots into the VueFileManager
frontend.
</p>
<h5><strong>Server Status</strong></h5>
<p>
You can check the admin panel server status. You can download your server logs for support communication, check your
latest database backups, check if your cron is running smoothly or if you have correctly set up your PHP with all
required php extensions.
</p>
<h5><strong>Easy Installation with Setup Wizard</strong></h5>
<p>
Setup Wizard is a convenient way to set up and configure your VueFileManager app in a few steps. Before you run your
installation, Setup Wizard will check all your server components and let you know, when you are missing something.
</p>
<h5><strong>Drag & Drop</strong></h5>
<p>You can drag your files or folder to another folder seamlessly</p>
<h5><strong>Source Code</strong></h5>
<p>
All source files of VueFileManager are included in download. You can easily inspect code and build your own
functionality.
</p>
<h3>Technologies</h3>
<ul>
<li>Laravel 9.x</li>
<li>Vue 2.6.x</li>
<li>Tailwind 3</li>
</ul>
<h3>Server Requirements</h3>
<ul>
<li>PHP >= 8.0.2 version (8.1+ recommended)</li>
<li>MySQL 5.6+</li>
<li>Nginx or Apache</li>
</ul>
<h3>Useful Links</h3>
<p>
<a href="https://gist.github.com/MakingCG/a702a112be63bc6f0032dd55522327cf">
<strong>Installation Guide</strong>
</a>
</p>
<p>
<a href="https://gist.github.com/MakingCG/9c07f8af392081ae5d5290d920a79b5d">
<strong>Changelog</strong>
</a>
</p>
<h3>Tips</h3>
<p>
<a
href="https://medium.com/vuefilemanager/how-to-set-up-vuefilemanager-laravel-application-on-vps-with-debian-10-64676a3ff4d7"
>
<strong>How to install VueFileManager on VPS with Debian 10</strong>
</a>
</p>
<p>
<a
href="https://medium.com/vuefilemanager/how-to-set-up-vuefilemanager-with-aws-s3-as-an-external-storage-a2c525aec698"
>
<strong>How to Set Up AWS S3</strong>
</a>
</p>
<p>
<a
href="https://medium.com/vuefilemanager/how-to-set-up-vuefilemanager-with-digital-ocean-spaces-as-a-external-storage-6cccf590c23d"
>
<strong>How to Set Up Digital Ocean Spaces</strong>
</a>
</p>
<h3>Demos</h3>
<h5>
<strong>
<a href="https://demo-metered.vuefilemanager.com/sign-in"> Metered Billing </a>
</strong>
</h5>
<p>
Browse demo with the Pay as You Go model. You can try credit system, fund your account balance and see how usage
estimates works. Some functions for default howdy account are restricted. Feel free to create your own account with
1 GB upload limit.
</p>
<h5>
<strong>
<a href="https://demo-fixed.vuefilemanager.com/sign-in"> Fixed Billing </a>
</strong>
</h5>
<p>
Browse demo with the Fixed model. You can try subscribe to any billing plan available in the app. Some functions for
default howdy account are restricted. Feel free to create your own account with 1 GB upload limit.
</p>
<h5>
<strong>
<a href="https://demo-regular.vuefilemanager.com/sign-in"> Regular without Subscription Module </a>
</strong>
</h5>
<p>
Browse demo without the subscription system. This demo with suit for regular license. Some functions for default
howdy account are restricted. Feel free to create your own account with 1 GB upload limit.
</p>
<h3>Frequently asked</h3>
<h5><strong>Is there any future plan for the mobile app?</strong></h5>
<p>
Yes, partially, but it depends on how VueFileManager sales will perform. We have to earn some money for mobile
development. If it goes well, then we can start work on mobile development. So please buy some more licenses to
support further development. Thank you, you are the best!
</p>
<h5><strong>Do you have any future plans to integrate FTP upload?</strong></h5>
<p>We dont have any plan to support FTP uploading, its out of scope.</p>
<p>
When you upload file via app, the app must process the file, create database record, attach it to the owner of the
file, move file to storage directory where are stored other user files and any other related functions must run,
this cant be done when user upload file via ftp. This will need to build another software for the server part, but
this does not pay off in terms of development costs and benefits for our focused users.
</p>
<p>
But, you can upload files without trouble in any size via VueFileManager, we support chunk upload in browser and
multipart upload for your s3 storage disk to manage big files. With this you are able to upload files in the tens of
gigabytes.
</p>

View File

@@ -8,42 +8,59 @@
],
"license": "MIT",
"require": {
"php": "^8.0",
"php": "^8.0.2",
"ext-json": "*",
"brianium/paratest": "^6.2",
"cartalyst/stripe-laravel": "^13.1",
"doctrine/dbal": "^2.12.1",
"fideloper/proxy": "^4.4.1",
"fruitcake/laravel-cors": "^2.0.3",
"ext-pdo": "*",
"beyondcode/laravel-websockets": "^1.13",
"brianium/paratest": "^6.4.1",
"cocur/slugify": "^4.1",
"doctrine/dbal": "^2.13.7",
"fruitcake/laravel-cors": "^2.0.5",
"gabrielelana/byte-units": "^0.5.0",
"guzzlehttp/guzzle": "^7.2.0",
"intervention/image": "^2.5.1",
"guzzlehttp/guzzle": "^7.4.1",
"intervention/image": "^2.7.1",
"jaybizzle/laravel-crawler-detect": "^1.2",
"kyslik/column-sortable": "^6.4",
"laravel/cashier": "^12.9.1",
"laravel/fortify": "^1.7.7",
"laravel/framework": "^8.30.1",
"laravel/sanctum": "^2.9",
"laravel/tinker": "^2.6.1",
"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.15",
"spatie/laravel-tail": "^4.3",
"teamtnt/laravel-scout-tntsearch-driver": "^11.1.0",
"vimeo/psalm": "^4.7"
"kyslik/column-sortable": "^6.4.1",
"laravel/fortify": "^1.12.0",
"laravel/framework": "^9.2",
"laravel/sanctum": "^2.14.2",
"laravel/socialite": "^5.5.1",
"laravel/tinker": "^2.7",
"laravel/ui": "^3.4.2",
"league/flysystem-aws-s3-v3": "^3.0.9",
"league/flysystem-ftp": "^3.0",
"makingcg/saas-billing": "^1.0",
"matthewbdaly/laravel-azure-storage": "^2.0",
"pusher/pusher-php-server": "^7.0",
"spatie/data-transfer-object": "^3.7.3",
"spatie/laravel-backup": "^8.0.8",
"spatie/laravel-query-builder": "^5.0.0",
"spatie/laravel-queueable-action": "^2.13.1",
"spatie/laravel-tail": "^4.4.0",
"stechstudio/laravel-zipstream": "^4.5",
"symfony/http-client": "^6.0",
"symfony/mailgun-mailer": "^6.0",
"symfony/postmark-mailer": "^6.0",
"teamtnt/laravel-scout-tntsearch-driver": "^11.6",
"vimeo/psalm": "^4.19.0"
},
"require-dev": {
"ext-json": "*",
"friendsofphp/php-cs-fixer": "^3.0",
"barryvdh/laravel-ide-helper": "^2.9",
"facade/ignition": "^2.5.14",
"fakerphp/faker": "^1.14.1",
"mockery/mockery": "^1.4.3",
"nunomaduro/collision": "^5.3.0",
"phpunit/phpunit": "^9.5.2"
"barryvdh/laravel-ide-helper": "^2.12.1",
"friendsofphp/php-cs-fixer": "^3.5.0",
"spatie/laravel-ignition": "^1.0",
"nunomaduro/larastan": "^0.7.15",
"nunomaduro/collision": "^6.1",
"phpunit/phpunit": "^9.5.16",
"mockery/mockery": "^1.5.0",
"fakerphp/faker": "^1.19.0",
"ext-json": "*"
},
"repositories":[
{
"type": "github",
"url": "https://github.com/makingcg/saas-billing.git"
}
],
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
@@ -56,7 +73,9 @@
},
"autoload": {
"psr-4": {
"App\\": "app/",
"App\\" : "src/App/",
"Domain\\" : "src/Domain/",
"Support\\" : "src/Support/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
@@ -65,7 +84,8 @@
"database/factories"
],
"files": [
"app/Http/helpers.php"
"src/Support/errors.php",
"src/Support/helpers.php"
]
},
"autoload-dev": {
@@ -86,7 +106,6 @@
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
],
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes",
"psalm": "vendor/bin/psalm"
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes"
}
}

9003
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -161,8 +161,8 @@ return [
Illuminate\View\ViewServiceProvider::class,
TeamTNT\Scout\TNTSearchScoutServiceProvider::class,
Laravel\Socialite\SocialiteServiceProvider::class,
Intervention\Image\ImageServiceProvider::class,
Madnest\Madzipper\MadzipperServiceProvider::class,
App\Providers\FortifyServiceProvider::class,
/*
@@ -174,7 +174,7 @@ return [
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
@@ -191,74 +191,64 @@ return [
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'App' => Illuminate\Support\Facades\App::class,
'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Image' => Intervention\Image\Facades\Image::class,
'Stripe' => Cartalyst\Stripe\Laravel\Facades\Stripe::class,
'Crawler' => Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect::class,
//'Madzipper' => Madnest\Madzipper\Madzipper::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Image' => Intervention\Image\Facades\Image::class,
'Stripe' => Cartalyst\Stripe\Laravel\Facades\Stripe::class,
'Crawler' => Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect::class,
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
],
'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',
],
],

View File

@@ -13,7 +13,7 @@ return [
*/
'defaults' => [
'guard' => 'web',
'guard' => 'web',
'passwords' => 'users',
],
@@ -36,14 +36,14 @@ return [
'guards' => [
'web' => [
'driver' => 'session',
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'driver' => 'token',
'provider' => 'users',
'hash' => false,
'hash' => false,
],
],
@@ -67,7 +67,7 @@ return [
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
'model' => App\Users\Models\User::class,
],
// 'users' => [
@@ -94,8 +94,8 @@ return [
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],

View File

@@ -111,7 +111,7 @@ return [
* The disk names on which the backups will be stored.
*/
'disks' => [
env('FILESYSTEM_DRIVER', 'local'),
env('FILESYSTEM_DISK', 'local'),
],
],
@@ -145,12 +145,12 @@ return [
*/
'notifications' => [
'notifications' => [
\Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\BackupHasFailedNotification::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFoundNotification::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\CleanupHasFailedNotification::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\BackupWasSuccessfulNotification::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\HealthyBackupWasFoundNotification::class => ['mail'],
\Spatie\Backup\Notifications\Notifications\CleanupWasSuccessfulNotification::class => ['mail'],
],
/*
@@ -159,26 +159,13 @@ return [
*/
'notifiable' => \Spatie\Backup\Notifications\Notifiable::class,
/*'mail' => [
'to' => 'your@example.com',
'mail' => [
'to' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
],*/
'slack' => [
'webhook_url' => '',
/*
* If this is set to null the default channel of the webhook will be used.
*/
'channel' => null,
'username' => null,
'icon' => null,
],
],
@@ -189,10 +176,12 @@ return [
*/
'monitor_backups' => [
[
'name' => env('APP_NAME', 'laravel-backup'),
'disks' => ['local'],
'name' => env('APP_NAME', 'vuefilemanager-backup'),
'disks' => [
env('FILESYSTEM_DISK', 'local'),
],
'health_checks' => [
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1,
\Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000,
],
],

View File

@@ -29,18 +29,21 @@ return [
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
'host' => env('PUSHER_APP_HOST'),
'port' => env('PUSHER_APP_PORT'),
'scheme' => env('PUSHER_APP_TLS', true) ? 'https' : 'http',
],
],
'redis' => [
'driver' => 'redis',
'driver' => 'redis',
'connection' => 'default',
],

View File

@@ -40,20 +40,20 @@ return [
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'driver' => 'database',
'table' => 'cache',
'connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
@@ -62,24 +62,24 @@ return [
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'driver' => 'redis',
'connection' => 'cache',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'driver' => 'dynamodb',
'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'),
],
],

View File

@@ -1,127 +0,0 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Stripe Keys
|--------------------------------------------------------------------------
|
| The Stripe publishable key and secret key give you access to Stripe's
| API. The "publishable" key is typically used when interacting with
| Stripe.js while the "secret" key accesses private API endpoints.
|
*/
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
/*
|--------------------------------------------------------------------------
| Cashier Path
|--------------------------------------------------------------------------
|
| This is the base URI path where Cashier's views, such as the payment
| verification screen, will be available from. You're free to tweak
| this path according to your preferences and application design.
|
*/
'path' => env('CASHIER_PATH', 'stripe'),
/*
|--------------------------------------------------------------------------
| Stripe Webhooks
|--------------------------------------------------------------------------
|
| Your Stripe webhook secret is used to prevent unauthorized requests to
| your Stripe webhook handling controllers. The tolerance setting will
| check the drift between the current time and the signed request's.
|
*/
'webhook' => [
'secret' => env('STRIPE_WEBHOOK_SECRET'),
'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300),
],
/*
|--------------------------------------------------------------------------
| Cashier Model
|--------------------------------------------------------------------------
|
| This is the model in your application that implements the Billable trait
| provided by Cashier. It will serve as the primary model you use while
| interacting with Cashier related methods, subscriptions, and so on.
|
*/
'model' => env('CASHIER_MODEL', App\Models\User::class),
/*
|--------------------------------------------------------------------------
| Currency
|--------------------------------------------------------------------------
|
| This is the default currency that will be used when generating charges
| from your application. Of course, you are welcome to use any of the
| various world currencies that are currently supported via Stripe.
|
*/
'currency' => env('CASHIER_CURRENCY', 'usd'),
/*
|--------------------------------------------------------------------------
| Currency Locale
|--------------------------------------------------------------------------
|
| This is the default locale in which your money values are formatted in
| for display. To utilize other locales besides the default en locale
| verify you have the "intl" PHP extension installed on the system.
|
*/
'currency_locale' => env('CASHIER_CURRENCY_LOCALE', 'en'),
/*
|--------------------------------------------------------------------------
| Payment Confirmation Notification
|--------------------------------------------------------------------------
|
| If this setting is enabled, Cashier will automatically notify customers
| whose payments require additional verification. You should listen to
| Stripe's webhooks in order for this feature to function correctly.
|
*/
'payment_notification' => env('CASHIER_PAYMENT_NOTIFICATION'),
/*
|--------------------------------------------------------------------------
| Invoice Paper Size
|--------------------------------------------------------------------------
|
| This option is the default paper size for all invoices generated using
| Cashier. You are free to customize this settings based on the usual
| paper size used by the customers using your Laravel applications.
|
| Supported sizes: 'letter', 'legal', 'A4'
|
*/
'paper' => env('CASHIER_PAPER', 'letter'),
/*
|--------------------------------------------------------------------------
| Stripe Logger
|--------------------------------------------------------------------------
|
| This setting defines which logging channel will be used by the Stripe
| library to write log messages. You are free to specify any of your
| logging channels listed inside the "logging" configuration file.
|
*/
'logger' => env('CASHIER_LOGGER'),
];

View File

@@ -4,179 +4,127 @@ return [
'pages' => [
[
'visibility' => 1,
'title' => 'Terms of Service',
'slug' => 'terms-of-service',
'content' => 'Laoreet cum hendrerit iaculis arcu phasellus congue et elementum, pharetra risus imperdiet aptent posuere rutrum parturient blandit, dapibus tellus ridiculus potenti aliquam sociis turpis. Nullam commodo eget laoreet risus cursus vel placerat, in dapibus sociis gravida faucibus sodales, fringilla potenti elit semper iaculis ullamcorper. Dignissim vulputate pretium montes pellentesque mollis, consectetur adipiscing curabitur semper sem rhoncus, litora viverra curae proin.',
'title' => 'Terms of Service',
'slug' => 'terms-of-service',
'content' => 'Laoreet cum hendrerit iaculis arcu phasellus congue et elementum, pharetra risus imperdiet aptent posuere rutrum parturient blandit, dapibus tellus ridiculus potenti aliquam sociis turpis. Nullam commodo eget laoreet risus cursus vel placerat, in dapibus sociis gravida faucibus sodales, fringilla potenti elit semper iaculis ullamcorper. Dignissim vulputate pretium montes pellentesque mollis, consectetur adipiscing curabitur semper sem rhoncus, litora viverra curae proin.',
],
[
'visibility' => 1,
'title' => 'Privacy Policy',
'slug' => 'privacy-policy',
'content' => 'Sit orci justo augue maecenas laoreet consectetur natoque magnis in viverra sagittis, himenaeos urna facilisis mus proin primis diam accumsan tristique inceptos. Primis quisque posuere sit praesent lobortis feugiat semper convallis facilisis, vivamus gravida ligula nostra curae eu donec duis parturient senectus, arcu dolor viverra penatibus natoque cum nisi commodo. Litora sociis mauris justo nullam suspendisse mattis maecenas nascetur congue phasellus cras ultricies posuere donec, dapibus egestas diam lacus ornare montes senectus tincidunt eu taciti sed consequat.',
'title' => 'Privacy Policy',
'slug' => 'privacy-policy',
'content' => 'Sit orci justo augue maecenas laoreet consectetur natoque magnis in viverra sagittis, himenaeos urna facilisis mus proin primis diam accumsan tristique inceptos. Primis quisque posuere sit praesent lobortis feugiat semper convallis facilisis, vivamus gravida ligula nostra curae eu donec duis parturient senectus, arcu dolor viverra penatibus natoque cum nisi commodo. Litora sociis mauris justo nullam suspendisse mattis maecenas nascetur congue phasellus cras ultricies posuere donec, dapibus egestas diam lacus ornare montes senectus tincidunt eu taciti sed consequat.',
],
[
'visibility' => 1,
'title' => 'Cookie Policy',
'slug' => 'cookie-policy',
'content' => 'Metus penatibus ligula dolor natoque non habitasse laoreet facilisis, libero vivamus eget semper vulputate interdum integer, phasellus lorem enim blandit consectetur nullam sollicitudin. Hendrerit interdum luctus ut in molestie himenaeos eros cum laoreet parturient est, eu lectus hac et netus viverra dictumst congue elit sem senectus litora, fames scelerisque adipiscing inceptos fringilla montes sociosqu suscipit auctor potenti. Elementum lacus vulputate viverra ac morbi ligula ipsum facilisi, sit eu imperdiet lacinia congue dis vitae.',
'title' => 'Cookie Policy',
'slug' => 'cookie-policy',
'content' => 'Metus penatibus ligula dolor natoque non habitasse laoreet facilisis, libero vivamus eget semper vulputate interdum integer, phasellus lorem enim blandit consectetur nullam sollicitudin. Hendrerit interdum luctus ut in molestie himenaeos eros cum laoreet parturient est, eu lectus hac et netus viverra dictumst congue elit sem senectus litora, fames scelerisque adipiscing inceptos fringilla montes sociosqu suscipit auctor potenti. Elementum lacus vulputate viverra ac morbi ligula ipsum facilisi, sit eu imperdiet lacinia congue dis vitae.',
],
],
'content' => [
'regular' => [
[
'name' => 'section_features',
'value' => 1,
],
[
'name' => 'section_feature_boxes',
'value' => 1,
],
[
'name' => 'section_get_started',
'value' => 1,
],
[
'name' => 'header_title',
'value' => 'Simple <span class="text-theme">&</span> Powerful Personal Cloud Storage',
],
[
'name' => 'header_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'features_title',
'value' => 'The Fastest Growing <span class="text-theme">File Manager</span> on the CodeCanyon Market',
],
[
'name' => 'features_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'feature_title_1',
'value' => 'Truly Freedom',
],
[
'name' => 'feature_description_1',
'value' => 'You have full control over VueFileManager, no third authorities will control your service or usage, only you.',
],
[
'name' => 'feature_title_2',
'value' => 'The Sky is the Limit',
],
[
'name' => 'feature_description_2',
'value' => 'VueFileManager is cloud storage software. You have to install and running application on your own server hosting.',
],
[
'name' => 'feature_title_3',
'value' => 'No Monthly Fees',
],
[
'name' => 'feature_description_3',
'value' => 'When you running VueFileManager on your own server hosting, anybody can\'t control your content or resell your user data. Your data is safe.',
],
[
'name' => 'get_started_title',
'value' => 'Ready to Get <span class="text-theme">Started</span><br> With Us?',
],
[
'name' => 'get_started_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2021 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
],
[
'name' => 'allow_homepage',
'value' => 1,
],
[
'name' => 'app_color',
'value' => '#00BC7E',
],
[
'name' => 'section_features',
'value' => 1,
],
'extended' => [
[
'name' => 'section_features',
'value' => 1,
],
[
'name' => 'section_feature_boxes',
'value' => 1,
],
[
'name' => 'section_pricing_content',
'value' => 1,
],
[
'name' => 'section_get_started',
'value' => 1,
],
[
'name' => 'header_title',
'value' => 'Simple <span class="text-theme">&</span> Powerful Personal Cloud Storage',
],
[
'name' => 'header_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'features_title',
'value' => 'The Fastest Growing <span class="text-theme">File Manager</span> on the CodeCanyon Market',
],
[
'name' => 'features_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'feature_title_1',
'value' => 'Truly Freedom',
],
[
'name' => 'feature_description_1',
'value' => 'You have full control over VueFileManager, no third authorities will control your service or usage, only you.',
],
[
'name' => 'feature_title_2',
'value' => 'The Sky is the Limit',
],
[
'name' => 'feature_description_2',
'value' => 'VueFileManager is cloud storage software. You have to install and running application on your own server hosting.',
],
[
'name' => 'feature_title_3',
'value' => 'No Monthly Fees',
],
[
'name' => 'feature_description_3',
'value' => 'When you running VueFileManager on your own server hosting, anybody can\'t control your content or resell your user data. Your data is safe.',
],
[
'name' => 'pricing_title',
'value' => 'Pick the <span class="text-theme">Best Plan</span> For Your Needs',
],
[
'name' => 'pricing_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'get_started_title',
'value' => 'Ready to Get <span class="text-theme">Started</span><br> With Us?',
],
[
'name' => 'get_started_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2021 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank" class="text-theme">Hi5Ve.Digital</a>',
],
[
'name' => 'app_color',
'value' => '#00BC7E',
],
[
'name' => 'section_feature_boxes',
'value' => 1,
],
[
'name' => 'section_pricing_content',
'value' => 1,
],
[
'name' => 'section_get_started',
'value' => 1,
],
[
'name' => 'header_title',
'value' => 'Simple <span class="text-theme">&</span> Powerful Personal Cloud Storage',
],
[
'name' => 'header_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'features_title',
'value' => 'The Fastest Growing <span class="text-theme">File Manager</span> on the CodeCanyon Market',
],
[
'name' => 'features_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'feature_title_1',
'value' => 'Truly Freedom',
],
[
'name' => 'feature_description_1',
'value' => 'You have full control over VueFileManager, no third authorities will control your service or usage, only you.',
],
[
'name' => 'feature_title_2',
'value' => 'The Sky is the Limit',
],
[
'name' => 'feature_description_2',
'value' => 'VueFileManager is cloud storage software. You have to install and running application on your own server hosting.',
],
[
'name' => 'feature_title_3',
'value' => 'No Monthly Fees',
],
[
'name' => 'feature_description_3',
'value' => 'When you running VueFileManager on your own server hosting, anybody can\'t control your content or resell your user data. Your data is safe.',
],
[
'name' => 'pricing_title',
'value' => 'Pick the <span class="text-theme">Best Plan</span> For Your Needs',
],
[
'name' => 'pricing_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'get_started_title',
'value' => 'Ready to Get <span class="text-theme">Started</span><br> With Us?',
],
[
'name' => 'get_started_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2022 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank" class="text-theme">Hi5Ve.Digital</a>',
],
[
'name' => 'allowed_adsense',
'value' => 0,
],
[
'name' => 'allowed_recaptcha',
'value' => 0,
],
[
'name' => 'paypal_payment_description',
'value' => 'Available PayPal Credit, Debit or Credit Card.',
],
[
'name' => 'paystack_payment_description',
'value' => 'Available Bank Account, USSD, Mobile Money, Apple Pay.',
],
[
'name' => 'stripe_payment_description',
'value' => 'Available credit card or Apple Pay.',
],
[
'name' => 'allowed_registration_bonus',
'value' => 0,
],
[
'name' => 'registration_bonus_amount',
'value' => 0,
],
],
];

View File

@@ -34,29 +34,29 @@ return [
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
'dump' => [
@@ -67,30 +67,30 @@ return [
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
@@ -124,22 +124,22 @@ return [
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', '6379'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],

View File

@@ -0,0 +1,557 @@
<?php
// List based on michenriksen/disposable-email-provider-domains
// https://gist.github.com/michenriksen/8710649
return [
'0815.ru',
'0wnd.net',
'0wnd.org',
'10minutemail.co.za',
'10minutemail.com',
'123-m.com',
'1fsdfdsfsdf.tk',
'1pad.de',
'20minutemail.com',
'21cn.com',
'2fdgdfgdfgdf.tk',
'2prong.com',
'30minutemail.com',
'33mail.com',
'3trtretgfrfe.tk',
'4gfdsgfdgfd.tk',
'4warding.com',
'5ghgfhfghfgh.tk',
'6hjgjhgkilkj.tk',
'6paq.com',
'7tags.com',
'9ox.net',
'a-bc.net',
'agedmail.com',
'ama-trade.de',
'amilegit.com',
'amiri.net',
'amiriindustries.com',
'anonmails.de',
'anonymbox.com',
'antichef.com',
'antichef.net',
'antireg.ru',
'antispam.de',
'antispammail.de',
'armyspy.com',
'artman-conception.com',
'azmeil.tk',
'baxomale.ht.cx',
'beefmilk.com',
'bigstring.com',
'binkmail.com',
'bio-muesli.net',
'bobmail.info',
'bodhi.lawlita.com',
'bofthew.com',
'bootybay.de',
'boun.cr',
'bouncr.com',
'breakthru.com',
'brefmail.com',
'bsnow.net',
'bspamfree.org',
'bugmenot.com',
'bund.us',
'burstmail.info',
'buymoreplays.com',
'byom.de',
'c2.hu',
'card.zp.ua',
'casualdx.com',
'cek.pm',
'centermail.com',
'centermail.net',
'chammy.info',
'childsavetrust.org',
'chogmail.com',
'choicemail1.com',
'clixser.com',
'cmail.net',
'cmail.org',
'coldemail.info',
'cool.fr.nf',
'courriel.fr.nf',
'courrieltemporaire.com',
'crapmail.org',
'cust.in',
'cuvox.de',
'd3p.dk',
'dacoolest.com',
'dandikmail.com',
'dayrep.com',
'dcemail.com',
'deadaddress.com',
'deadspam.com',
'delikkt.de',
'despam.it',
'despammed.com',
'devnullmail.com',
'dfgh.net',
'digitalsanctuary.com',
'dingbone.com',
'disposableaddress.com',
'disposableemailaddresses.com',
'disposableinbox.com',
'dispose.it',
'dispostable.com',
'dodgeit.com',
'dodgit.com',
'donemail.ru',
'dontreg.com',
'dontsendmespam.de',
'drdrb.net',
'dump-email.info',
'dumpandjunk.com',
'dumpyemail.com',
'e-mail.com',
'e-mail.org',
'e4ward.com',
'easytrashmail.com',
'einmalmail.de',
'einrot.com',
'eintagsmail.de',
'emailgo.de',
'emailias.com',
'emaillime.com',
'emailsensei.com',
'emailtemporanea.com',
'emailtemporanea.net',
'emailtemporar.ro',
'emailtemporario.com.br',
'emailthe.net',
'emailtmp.com',
'emailwarden.com',
'emailx.at.hm',
'emailxfer.com',
'emeil.in',
'emeil.ir',
'emz.net',
'ero-tube.org',
'evopo.com',
'explodemail.com',
'express.net.ua',
'eyepaste.com',
'fakeinbox.com',
'fakeinformation.com',
'fansworldwide.de',
'fantasymail.de',
'fightallspam.com',
'filzmail.com',
'fivemail.de',
'fleckens.hu',
'frapmail.com',
'friendlymail.co.uk',
'fuckingduh.com',
'fudgerub.com',
'fyii.de',
'garliclife.com',
'gehensiemirnichtaufdensack.de',
'get2mail.fr',
'getairmail.com',
'getmails.eu',
'getonemail.com',
'giantmail.de',
'girlsundertheinfluence.com',
'gishpuppy.com',
'gmial.com',
'goemailgo.com',
'gotmail.net',
'gotmail.org',
'gotti.otherinbox.com',
'great-host.in',
'greensloth.com',
'grr.la',
'gsrv.co.uk',
'guerillamail.biz',
'guerillamail.com',
'guerrillamail.biz',
'guerrillamail.com',
'guerrillamail.de',
'guerrillamail.info',
'guerrillamail.net',
'guerrillamail.org',
'guerrillamailblock.com',
'gustr.com',
'harakirimail.com',
'hat-geld.de',
'hatespam.org',
'herp.in',
'hidemail.de',
'hidzz.com',
'hmamail.com',
'hopemail.biz',
'ieh-mail.de',
'ikbenspamvrij.nl',
'imails.info',
'inbax.tk',
'inbox.si',
'inboxalias.com',
'inboxclean.com',
'inboxclean.org',
'infocom.zp.ua',
'instant-mail.de',
'ip6.li',
'irish2me.com',
'iwi.net',
'jetable.com',
'jetable.fr.nf',
'jetable.net',
'jetable.org',
'jnxjn.com',
'jourrapide.com',
'jsrsolutions.com',
'kasmail.com',
'kaspop.com',
'killmail.com',
'killmail.net',
'klassmaster.com',
'klzlk.com',
'koszmail.pl',
'kurzepost.de',
'lawlita.com',
'letthemeatspam.com',
'lhsdv.com',
'lifebyfood.com',
'link2mail.net',
'litedrop.com',
'lol.ovpn.to',
'lolfreak.net',
'lookugly.com',
'lortemail.dk',
'lr78.com',
'lroid.com',
'lukop.dk',
'm21.cc',
'mail-filter.com',
'mail-temporaire.fr',
'mail.by',
'mail.mezimages.net',
'mail.zp.ua',
'mail1a.de',
'mail21.cc',
'mail2rss.org',
'mail333.com',
'mailbidon.com',
'mailbiz.biz',
'mailblocks.com',
'mailbucket.org',
'mailcat.biz',
'mailcatch.com',
'mailde.de',
'mailde.info',
'maildrop.cc',
'maileimer.de',
'mailexpire.com',
'mailfa.tk',
'mailforspam.com',
'mailfreeonline.com',
'mailguard.me',
'mailin8r.com',
'mailinater.com',
'mailinator.com',
'mailinator.net',
'mailinator.org',
'mailinator2.com',
'mailincubator.com',
'mailismagic.com',
'mailme.lv',
'mailme24.com',
'mailmetrash.com',
'mailmoat.com',
'mailms.com',
'mailnesia.com',
'mailnull.com',
'mailorg.org',
'mailpick.biz',
'mailrock.biz',
'mailscrap.com',
'mailshell.com',
'mailsiphon.com',
'mailtemp.info',
'mailtome.de',
'mailtothis.com',
'mailtrash.net',
'mailtv.net',
'mailtv.tv',
'mailzilla.com',
'makemetheking.com',
'manybrain.com',
'mbx.cc',
'mega.zik.dj',
'meinspamschutz.de',
'meltmail.com',
'messagebeamer.de',
'mezimages.net',
'ministry-of-silly-walks.de',
'mintemail.com',
'misterpinball.de',
'moncourrier.fr.nf',
'monemail.fr.nf',
'monmail.fr.nf',
'monumentmail.com',
'mt2009.com',
'mt2014.com',
'mycard.net.ua',
'mycleaninbox.net',
'mymail-in.net',
'mypacks.net',
'mypartyclip.de',
'myphantomemail.com',
'mysamp.de',
'mytempemail.com',
'mytempmail.com',
'mytrashmail.com',
'nabuma.com',
'neomailbox.com',
'nepwk.com',
'nervmich.net',
'nervtmich.net',
'netmails.com',
'netmails.net',
'neverbox.com',
'nice-4u.com',
'nincsmail.hu',
'nnh.com',
'no-spam.ws',
'noblepioneer.com',
'nomail.pw',
'nomail.xl.cx',
'nomail2me.com',
'nomorespamemails.com',
'nospam.ze.tc',
'nospam4.us',
'nospamfor.us',
'nospammail.net',
'notmailinator.com',
'nowhere.org',
'nowmymail.com',
'nurfuerspam.de',
'nus.edu.sg',
'objectmail.com',
'obobbo.com',
'odnorazovoe.ru',
'oneoffemail.com',
'onewaymail.com',
'onlatedotcom.info',
'online.ms',
'opayq.com',
'ordinaryamerican.net',
'otherinbox.com',
'ovpn.to',
'owlpic.com',
'pancakemail.com',
'pcusers.otherinbox.com',
'pjjkp.com',
'plexolan.de',
'poczta.onet.pl',
'politikerclub.de',
'poofy.org',
'pookmail.com',
'privacy.net',
'privatdemail.net',
'proxymail.eu',
'prtnx.com',
'putthisinyourspamdatabase.com',
'putthisinyourspamdatabase.com',
'qq.com',
'quickinbox.com',
'rcpt.at',
'reallymymail.com',
'realtyalerts.ca',
'recode.me',
'recursor.net',
'reliable-mail.com',
'rhyta.com',
'rmqkr.net',
'royal.net',
'rtrtr.com',
's0ny.net',
'safe-mail.net',
'safersignup.de',
'safetymail.info',
'safetypost.de',
'saynotospams.com',
'schafmail.de',
'schrott-email.de',
'secretemail.de',
'secure-mail.biz',
'senseless-entertainment.com',
'services391.com',
'sharklasers.com',
'shieldemail.com',
'shiftmail.com',
'shitmail.me',
'shitware.nl',
'shmeriously.com',
'shortmail.net',
'sibmail.com',
'sinnlos-mail.de',
'slapsfromlastnight.com',
'slaskpost.se',
'smashmail.de',
'smellfear.com',
'snakemail.com',
'sneakemail.com',
'sneakmail.de',
'snkmail.com',
'sofimail.com',
'solvemail.info',
'sogetthis.com',
'soodonims.com',
'spam4.me',
'spamail.de',
'spamarrest.com',
'spambob.net',
'spambog.ru',
'spambox.us',
'spamcannon.com',
'spamcannon.net',
'spamcon.org',
'spamcorptastic.com',
'spamcowboy.com',
'spamcowboy.net',
'spamcowboy.org',
'spamday.com',
'spamex.com',
'spamfree.eu',
'spamfree24.com',
'spamfree24.de',
'spamfree24.org',
'spamgoes.in',
'spamgourmet.com',
'spamgourmet.net',
'spamgourmet.org',
'spamherelots.com',
'spamherelots.com',
'spamhereplease.com',
'spamhereplease.com',
'spamhole.com',
'spamify.com',
'spaml.de',
'spammotel.com',
'spamobox.com',
'spamslicer.com',
'spamspot.com',
'spamthis.co.uk',
'spamtroll.net',
'speed.1s.fr',
'spoofmail.de',
'stuffmail.de',
'super-auswahl.de',
'supergreatmail.com',
'supermailer.jp',
'superrito.com',
'superstachel.de',
'suremail.info',
'talkinator.com',
'teewars.org',
'teleworm.com',
'teleworm.us',
'temp-mail.org',
'temp-mail.ru',
'tempe-mail.com',
'tempemail.co.za',
'tempemail.com',
'tempemail.net',
'tempemail.net',
'tempinbox.co.uk',
'tempinbox.com',
'tempmail.eu',
'tempmaildemo.com',
'tempmailer.com',
'tempmailer.de',
'tempomail.fr',
'temporaryemail.net',
'temporaryforwarding.com',
'temporaryinbox.com',
'temporarymailaddress.com',
'tempthe.net',
'thankyou2010.com',
'thc.st',
'thelimestones.com',
'thisisnotmyrealemail.com',
'thismail.net',
'throwawayemailaddress.com',
'tilien.com',
'tittbit.in',
'tizi.com',
'tmailinator.com',
'toomail.biz',
'topranklist.de',
'tradermail.info',
'trash-mail.at',
'trash-mail.com',
'trash-mail.de',
'trash2009.com',
'trashdevil.com',
'trashemail.de',
'trashmail.at',
'trashmail.com',
'trashmail.de',
'trashmail.me',
'trashmail.net',
'trashmail.org',
'trashymail.com',
'trialmail.de',
'trillianpro.com',
'twinmail.de',
'tyldd.com',
'uggsrock.com',
'umail.net',
'uroid.com',
'us.af',
'venompen.com',
'veryrealemail.com',
'viditag.com',
'viralplays.com',
'vpn.st',
'vsimcard.com',
'vubby.com',
'wasteland.rfc822.org',
'webemail.me',
'weg-werf-email.de',
'wegwerf-emails.de',
'wegwerfadresse.de',
'wegwerfemail.com',
'wegwerfemail.de',
'wegwerfmail.de',
'wegwerfmail.info',
'wegwerfmail.net',
'wegwerfmail.org',
'wh4f.org',
'whyspam.me',
'willhackforfood.biz',
'willselfdestruct.com',
'winemaven.info',
'wronghead.com',
'www.e4ward.com',
'www.mailinator.com',
'wwwnew.eu',
'x.ip6.li',
'xagloo.com',
'xemaps.com',
'xents.com',
'xmaily.com',
'xoxy.net',
'yep.it',
'yogamaven.com',
'yopmail.com',
'yopmail.fr',
'yopmail.net',
'yourdomain.com',
'yuurok.com',
'z1p.biz',
'za.com',
'zehnminuten.de',
'zehnminutenmail.de',
'zippymail.info',
'zoemail.net',
'zomg.info',
];

View File

@@ -12,20 +12,7 @@ return [
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
'default' => env('FILESYSTEM_DISK', 'local'),
/*
|--------------------------------------------------------------------------
@@ -43,60 +30,37 @@ return [
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'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'),
'driver' => 's3',
'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'),
'visibility' => 'private',
],
'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'),
'ftp' => [
'driver' => 'ftp',
'host' => env('FTP_HOST'),
'username' => env('FTP_USERNAME'),
'password' => env('FTP_PASSWORD'),
],
'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'),
'azure' => [
'driver' => 'azure',
'name' => env('AZURE_STORAGE_NAME'),
'key' => env('AZURE_STORAGE_KEY'),
'container' => env('AZURE_STORAGE_CONTAINER'),
'url' => env('AZURE_STORAGE_URL'),
'prefix' => null,
'connection_string' => env('AZURE_STORAGE_CONNECTION_STRING'), // optional, will override default endpoint builder
],
],
];

View File

@@ -102,7 +102,7 @@ return [
*/
'limiters' => [
'login' => 'login',
'login' => 'login',
'two-factor' => 'two-factor',
],
@@ -131,13 +131,9 @@ return [
*/
'features' => [
Features::registration(),
//Features::resetPasswords(),
// Features::emailVerification(),
Features::updateProfileInformation(),
//Features::updatePasswords(),
/*Features::twoFactorAuthentication([
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
]),*/
]),
],
];

View File

@@ -43,8 +43,8 @@ return [
*/
'argon' => [
'memory' => 1024,
'memory' => 1024,
'threads' => 2,
'time' => 2,
'time' => 2,
],
];

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,6 @@
return [
'enable' => env('LARAVEL_QUERY_MONITOR', true),
'host' => env('LARAVEL_QUERY_MONITOR_HOST', '0.0.0.0'),
'port' => env('LARAVEL_QUERY_MONITOR_PORT', 8081),
'host' => env('LARAVEL_QUERY_MONITOR_HOST', '0.0.0.0'),
'port' => env('LARAVEL_QUERY_MONITOR_PORT', 8081),
];

View File

@@ -35,36 +35,36 @@ return [
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
'emoji' => ':boom:',
'level' => 'critical',
],
'papertrail' => [
'driver' => 'monolog',
'level' => 'debug',
'handler' => SyslogUdpHandler::class,
'driver' => 'monolog',
'level' => 'debug',
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
@@ -72,26 +72,26 @@ return [
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
'level' => 'debug',
],
'null' => [
'driver' => 'monolog',
'driver' => 'monolog',
'handler' => NullHandler::class,
],

View File

@@ -56,7 +56,7 @@ return [
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*

View File

@@ -33,35 +33,35 @@ return [
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
'block_for' => 0,
],
'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'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('S3_DEFAULT_REGION', 'us-east-1'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
'block_for' => null,
],
],
@@ -77,8 +77,8 @@ return [
*/
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
'table' => 'failed_jobs',
],
];

45
config/sanctum.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1,127.0.0.1:8000,::1')),
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. If this value is null, personal access tokens do
| not expire. This won't tweak the lifetime of first-party sessions.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'verify_csrf_token' => Support\Middleware\VerifyCsrfToken::class,
'encrypt_cookies' => Support\Middleware\EncryptCookies::class,
],
];

Some files were not shown because too many files have changed in this diff Show More