Compare commits

...

314 Commits

Author SHA1 Message Date
Peter Papp
28b39a79e6 - frontend build 2021-02-20 16:30:12 +01:00
Peter Papp
2dbd9dd62d Merge remote-tracking branch 'origin/version-v1.8.1'
# Conflicts:
#	resources/js/components/FilesView/FileItemGrid.vue
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/Others/ThumbnailItem.vue
2021-02-20 15:30:44 +01:00
Peter Papp
9dbce7a73a - autofocus disabled on mobile devices
- tabwrapper icon fix
2021-02-20 14:48:59 +01:00
Peter Papp
8ac5c8fd38 - css refactoring to grid for emoji picker
- frontend build
2021-02-20 12:07:55 +01:00
Milos Holba
2a105877f3 add Zip & Download folder to mobile menu, fix thumbnailItem for images without thumbnail, change color of file icon in mobile menu dark mode 2021-02-16 00:07:05 +01:00
Milos Holba
28efba5773 fix open Processing popup for download files 2021-02-15 12:37:06 +01:00
Milos Holba
60f02622da add default class for Folder in FolderIcon 2021-02-15 12:32:46 +01:00
Milos Holba
7eee7deba5 fix create folder on mobile 2021-02-15 10:00:39 +01:00
Peter Papp
ba0b2bd3b9 apple emojis 2021-02-13 12:05:47 +01:00
Peter Papp
86090b5870 folder color picker 2021-02-13 10:30:54 +01:00
Peter Papp
39681bc48a emoji ios styling for list 2021-02-13 09:29:49 +01:00
Milos Holba
96e1bdd99f make folder icon component 2021-02-12 20:43:33 +01:00
Milos Holba
eebeee6948 scss changes in SetFolderIcon, add translation to sk/cn 2021-02-11 20:14:27 +01:00
Milos Holba
7be02edead change base_path to public_path in get_emojis_list function 2021-02-11 16:44:16 +01:00
Milos Holba
d65c27091c change functionality of Emojis List to async load from backend 2021-02-10 19:45:59 +01:00
Milos Holba
6c3630085e test for iOS emojis 2021-02-09 20:42:48 +01:00
Milos Holba
f6dbb5e71e expansion functionality for the reset button in selected emoji input for possibility to set default icon 2021-02-09 19:20:21 +01:00
Peter Papp
a80e4364ae - allow share files to email for demo 2021-02-07 18:20:29 +01:00
Peter Papp
bfb3888555 Merge remote-tracking branch 'origin/version-v1.8.1'
# Conflicts:
#	config/vuefilemanager.php
#	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-others.js
#	public/chunks/app-payments.js
#	public/chunks/app-settings.js
#	public/chunks/app-setup.js
#	public/chunks/billings-detail.js
#	public/chunks/contact-us.js
#	public/chunks/dashboard.js
#	public/chunks/database.js
#	public/chunks/environment-setup.js
#	public/chunks/files.js
#	public/chunks/files~chunks/shared-files~chunks/shared-page.js
#	public/chunks/installation-disclaimer.js
#	public/chunks/invoices.js
#	public/chunks/landing-page.js
#	public/chunks/pages.js
#	public/chunks/plan-create.js
#	public/chunks/plan-delete.js
#	public/chunks/plan-settings.js
#	public/chunks/plan-subscribers.js
#	public/chunks/plan.js
#	public/chunks/plans.js
#	public/chunks/profile.js
#	public/chunks/purchase-code.js
#	public/chunks/settings-create-payment-methods.js
#	public/chunks/settings-invoices.js
#	public/chunks/settings-payment-methods.js
#	public/chunks/settings-storage.js
#	public/chunks/settings-subscription.js
#	public/chunks/settings.js
#	public/chunks/shared-files.js
#	public/chunks/shared-page.js
#	public/chunks/sign-up.js
#	public/chunks/stripe-credentials.js
#	public/chunks/subscription-plans.js
#	public/chunks/subscription-service.js
#	public/chunks/upgrade-billing.js
#	public/chunks/upgrade.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/chunks/user-subscription.js
#	public/chunks/user.js
#	public/chunks/users.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/views/FilePages/Files.vue
2021-02-07 18:05:56 +01:00
Peter Papp
5e408267ee - frontend build 2021-02-07 18:03:40 +01:00
Peter Papp
a4725df5f7 - added createFolder to SharedPage.vue
- queueable email
- frontend build
2021-02-07 17:28:00 +01:00
Peter Papp
dee562c56e - frontend build 2021-02-07 16:40:44 +01:00
Peter Papp
e1016502a1 Merge remote-tracking branch 'origin/version-v1.8.1' into version-v1.8.1
# Conflicts:
#	app/Http/Controllers/FileFunctions/ShareController.php
#	public/mix-manifest.json
2021-02-07 16:36:49 +01:00
Peter Papp
541924448b - Toggle for enable/disable landing page
- New app screenshots for landing page
- frontend build
- some ui fixes
2021-02-07 16:35:48 +01:00
Milos Holba
18b97866f2 MultiEmailInput first email dont need to be separated by comma or space, RenameItem comment ActionButton for more options 2021-02-07 13:26:42 +01:00
Milos Holba
6f2278b908 fix function shared_send_via_email in ShareController 2021-02-07 12:29:08 +01:00
Peter Papp
bdd8d63162 - Toggle for enable/disable landing page
- New app screenshots for laanding page
- frontend build
2021-02-07 12:18:56 +01:00
Peter Papp
8ca7881c5e frontend build 2021-02-07 11:21:51 +01:00
Peter Papp
8d04a94dbc - on-demand notification
- error message on failed after shared link was created
- Shared link email text edit
2021-02-07 11:19:21 +01:00
Milos Holba
44158c74e3 merge remote with local 2021-02-06 16:29:55 +01:00
Milos Holba
847bcec22f add emojis groups navigation, add X icon to select input for reset emoji 2021-02-06 16:12:21 +01:00
Peter Papp
e984ae6beb TabWrapper background change 2021-02-06 16:02:22 +01:00
Peter Papp
e2a52d27f5 Logging out progressbar 2021-02-06 14:18:53 +01:00
Peter Papp
9c92cffde3 Zip and Download title change 2021-02-06 13:57:34 +01:00
Peter Papp
ce20452f38 TabWrapper color change 2021-02-06 13:53:43 +01:00
Peter Papp
6c888c6bd3 Merge remote-tracking branch 'origin/version-v1.8.1' into version-v1.8.1
# Conflicts:
#	public/mix-manifest.json
2021-02-06 13:48:34 +01:00
Peter Papp
2b2d9a0764 - fixed more actions in public shared folder
- 'There is nothing' title changed in new folder
- Play video after click on full preview
- Expanded close cookie disclaimer area
- Show fileinfopanel as default
- Hidden file icons in DesktopToolbar.vue on ipad landscape
- Changed background color in context menu dark mode mobile
2021-02-06 13:48:22 +01:00
Milos Holba
ed2d008f4b stop uploading after failed uploadLimit validation on frontend 2021-02-06 11:15:09 +01:00
Milos Holba
9972f471c4 add Emoji component 2021-02-06 10:37:36 +01:00
Milos Holba
03ef16d90d make component for emojis 2021-02-05 18:13:22 +01:00
Milos Holba
4158d4f31e fix click to rename item in FileItemList/Grid 2021-02-02 18:26:01 +01:00
Milos Holba
e65acd8a4f make new emoji module in vuex, add funcionality for grouping emojis 2021-02-02 16:10:16 +01:00
Milos Holba
ba5e05f77a add tweomji transfer for single emojis 2021-02-01 19:43:30 +01:00
Peter Papp
82cf82e4b5 dashboard widget background changed 2021-02-01 17:02:47 +01:00
Peter Papp
f5e19e47f7 version changing 2021-02-01 16:56:45 +01:00
Peter Papp
43b1aa7f89 frontend build 2021-02-01 16:54:36 +01:00
Peter Papp
0e1ebdd809 Removed confirm dialog when user go back after login in 2021-02-01 16:51:44 +01:00
Peter Papp
6e3adcd459 Fixed streaming video/mp3 on safari browsers with using local disk 2021-02-01 16:37:40 +01:00
Milos Holba
9c147165e1 add to FileItemList/Grid function to unfocuse new foler name input, ThumbnaillItem folderIconHandle revision 2021-01-31 14:39:44 +01:00
Peter Papp
689b064756 - reset emails input after close popup 2021-01-30 15:31:48 +01:00
Peter Papp
6b32ae9795 - Box message fix part 2 2021-01-30 15:08:57 +01:00
Peter Papp
267556b39d - Prevent submit shared form
- Send shared link from FileInfoPanel.vue
2021-01-30 14:01:36 +01:00
Peter Papp
eb2e39cd32 Prevent submit shared form 2021-01-30 13:33:33 +01:00
Peter Papp
58ae75ecc9 MultiEmailInput 2021-01-30 11:52:38 +01:00
Peter Papp
a5dd0e0d30 Tab component reedit 2021-01-30 10:12:33 +01:00
Peter Papp
cec2450940 CopyInput.vue restyling 2021-01-30 09:31:25 +01:00
Milos Holba
fdd8f16384 solved error for get exif data 2021-01-28 11:21:23 +01:00
Milos Holba
2112fe879b add twemoji 2021-01-26 23:17:09 +01:00
Milos Holba
078d920c19 change icon for share , change color in text of Infobox 2021-01-21 20:49:32 +01:00
Milos Holba
98d1926ab3 add send shared link via email in edit sharing option 2021-01-20 18:54:12 +01:00
Milos Holba
2263cc9511 Make table wrapper and table options components 2021-01-19 18:47:53 +01:00
Milos Holba
9a736a2615 Create folder in contextMenu fix empty ul 2021-01-18 20:17:10 +01:00
Milos Holba
4b1e5fcb46 Create Folder - ContextMenu,add X icon for rename popup input, Dekstoptolbar icons,Recent uploads sorting,Windows scroller in nav sidebar,Change color of Delere in context menu 2021-01-18 20:00:26 +01:00
Peter Papp
a0c39bd955 - upgrade service to 1.8.1 from 1.8
- Landing page for Regular Licenses
- Legal pages for Regular Licenses
2021-01-17 16:21:49 +01:00
Peter Papp
973b301a46 Merge remote-tracking branch 'origin/version-v1.8.1' into version-v1.8.1 2021-01-17 13:30:27 +01:00
Peter Papp
e0f192777f - zip folder fix for sisters directories 2021-01-17 13:30:18 +01:00
Milos Holba
ce1bad57cd add change folder icon to rename item popup 2021-01-17 10:24:13 +01:00
Milos Holba
77b126b85a sned shared link via email add validation 2021-01-12 19:13:52 +01:00
Peter Papp
3adf57a6b1 front-end build 2021-01-12 18:34:55 +01:00
Milos Holba
cc72e4e3a2 fixes for mobiles/tablets FileFullPreview,FileInfoPanel after click to non media item,scroll for iPad, ThumbnailItem for media without thumbnail 2021-01-12 17:14:17 +01:00
Milos Holba
3285af3603 add to create share link a send share vie email option 2021-01-11 21:11:09 +01:00
Milos Holba
04990fcf7b add for backend send shared link via email 2021-01-06 17:33:15 +01:00
Milos Holba
ba28ac6184 Change timezone input to select in Settings.vue 2021-01-05 11:40:05 +01:00
Milos Holba
a100671cc0 timezone change int do decimal fix set_time_by_user_timezone function 2021-01-04 12:09:23 +01:00
Milos Holba
ded02fc15b user timezone v1 , add autofocus for CreateFolder,RenameItem popup 2021-01-03 18:00:28 +01:00
Milos Holba
64fd6a2265 first commit Multi restore in trash, focus on the new folder name 2020-12-29 11:39:37 +01:00
Peter Papp
c2a5d4bc74 - removed unwanted file 2020-12-23 18:00:02 +01:00
Peter Papp
fed95cbd64 - updated readme 2020-12-22 10:27:15 +01:00
Peter Papp
e60bbb369a - upgrade controller to v1.8 2020-12-21 20:50:56 +01:00
Peter Papp
7379d17a40 - zip file name fix 2020-12-21 19:00:54 +01:00
Peter Papp
26e0535407 - frontend build 2020-12-21 18:22:22 +01:00
Peter Papp
0f8a89bbad Merge remote-tracking branch 'origin/master'
# Conflicts:
#	public/chunks/app-others.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/FilesView/FilePreview.vue
#	resources/js/helpers.js
#	resources/js/store/modules/fileFunctions.js
2020-12-21 18:20:10 +01:00
Peter Papp
2f89f6303a Merge branch 'upload-limit'
# Conflicts:
#	app/Http/Helpers/helpers.php
#	config/vuefilemanager.php
#	public/chunks/app-others.js
#	public/chunks/files~chunks/shared-files~chunks/shared-page~chunks/trash.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/FilesView/FilePreview.vue
#	resources/js/helpers.js
#	resources/js/store/modules/fileFunctions.js
2020-12-21 18:19:37 +01:00
Peter Papp
4b3ca7e34b Merge remote-tracking branch 'origin/bulk-operations'
# Conflicts:
#	app/Http/Helpers/helpers.php
#	public/chunks/app-others.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/FilesView/FilePreview.vue
#	resources/js/helpers.js
#	resources/js/store/modules/fileFunctions.js
2020-12-21 17:17:10 +01:00
Peter Papp
2c0cf43802 - frontend build
- merge upload limit
2020-12-21 17:15:12 +01:00
Peter Papp
d255b01c70 Merge branch 'upload-limit' into bulk-operations
# Conflicts:
#	app/Http/Helpers/helpers.php
#	config/vuefilemanager.php
#	public/chunks/app-others.js
#	public/chunks/files~chunks/shared-files~chunks/shared-page~chunks/trash.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/FilesView/FilePreview.vue
#	resources/js/helpers.js
#	resources/js/store/modules/fileFunctions.js
2020-12-21 17:14:21 +01:00
Peter Papp
6a9edc49c0 Merge remote-tracking branch 'origin/bulk-operations'
# Conflicts:
#	app/Http/Helpers/helpers.php
#	config/vuefilemanager.php
#	public/chunks/app-others.js
#	public/chunks/files~chunks/shared-files~chunks/shared-page~chunks/trash.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/FilesView/FilePreview.vue
#	resources/js/helpers.js
#	resources/js/store/modules/fileFunctions.js
2020-12-21 17:02:49 +01:00
Peter Papp
96faf2de0e - frontend build
- MobileActionButton enhancement
2020-12-21 17:00:41 +01:00
Peter Papp
5a2e6a5e53 - frontend build 2020-12-21 11:46:11 +01:00
Milos Holba
c509eeceb1 merge local with remote changes (Peter) 2020-12-21 11:31:50 +01:00
Milos Holba
299292a817 add actionButtons for mobile multiSelecting, refactoring sortingAndPreview icon 2020-12-21 11:23:18 +01:00
Peter Papp
b11bd0e521 - checkbox restyle in light mode 2020-12-21 11:05:12 +01:00
Peter Papp
8fb859b441 - checkbox restyle in dark mode 2020-12-21 10:57:07 +01:00
Peter Papp
28a5f58b80 - MobileAction buttons animation
- build
2020-12-21 10:47:06 +01:00
Peter Papp
7da4d1f64b - .multiselect-actions as position:fixed
- zipping popup when generate zip for multiple files download
2020-12-21 09:56:03 +01:00
Peter Papp
07086c7550 - turnOff delete in MobileActions.vue 2020-12-20 22:02:08 +01:00
Peter Papp
5246c47c86 - MobileActions.vue refactoring
- added select all / deselect all buttons to mobile multi select mode
2020-12-20 21:57:24 +01:00
Peter Papp
2975d1555d - frontend build 2020-12-20 19:22:35 +01:00
Milos Holba
bd946be0b0 merge local with remote 2020-12-20 16:53:32 +01:00
Milos Holba
e6ff90f6fc solved issues: FullFilePreview menu , MultiSelected move action ; refactoring contextMenu 2020-12-20 16:41:30 +01:00
Peter Papp
08dc813af9 - fixes 2020-12-19 17:04:52 +01:00
Peter Papp
9098634b99 - upload bar x margin fix 2020-12-19 16:31:14 +01:00
Milos Holba
00213824f1 brench merge 2020-12-19 15:18:58 +01:00
Milos Holba
65624326c7 solved issuis from Bulk Review v3,v4 2020-12-19 15:12:56 +01:00
Peter Papp
e92d9344b9 - App popup for creating folder in mobile version
- bug fixes
2020-12-19 13:47:14 +01:00
Peter Papp
55cf58fffd - local zip file 2020-12-19 11:50:48 +01:00
Peter Papp
a3c43af7ba - local zip file 2020-12-19 11:49:00 +01:00
Peter Papp
a10d394abb - download multiple files in public folder
- frontend build
2020-12-19 11:34:32 +01:00
Milos Holba
b16f22b0eb refactoring sorting and preview component 2020-12-17 12:25:08 +01:00
Milos Holba
5bc66d51be add close sortingAndPreview after click anywhere in application 2020-12-16 12:21:55 +01:00
Peter Papp
7b27fa70d8 - download multiple files in private folder
- sorting context menu changes
- download icon active only if files was selected
2020-12-15 18:05:08 +01:00
Peter Papp
372b3aa407 - frontend build 2020-12-14 18:53:06 +01:00
Peter Papp
bda293bc53 Merge remote-tracking branch 'origin/bulk-operations' into bulk-operations
# Conflicts:
#	public/mix-manifest.json
#	resources/js/components/FilesView/ContextMenu.vue
2020-12-13 17:52:24 +01:00
Peter Papp
11873d06ff - zip implementation for users 2020-12-13 17:49:44 +01:00
Milos Holba
89ea50b893 solved issues bulk review part.1 2020-12-13 16:33:28 +01:00
Peter Papp
874b4bb768 - multiple download test 2020-12-12 17:44:24 +01:00
Peter Papp
1e49f52abe - timeout changed in ContextMenu.vue 2020-12-12 10:44:13 +01:00
Peter Papp
94088e76ec - timeout changed in ContextMenu.vue 2020-12-12 10:38:25 +01:00
Peter Papp
c7abcce729 - code review
- frontend build
2020-12-12 10:31:22 +01:00
Milos Holba
e9d2f4bacc delete sorting icon 2020-12-11 18:26:57 +01:00
Milos Holba
7e7965f98e merge with sorting 2020-12-11 18:25:04 +01:00
Milos Holba
d823ae687b refactor getDataByLocation helper, fix moveItem popup from File info panel 2020-12-11 18:18:09 +01:00
Milos Holba
21a36c0965 add translation for preview and sorting, add sorting for moveItem tree and remove for favourites tree 2020-12-10 18:38:48 +01:00
Milos Holba
c3d162b991 add preview&Sorting menu for mobile version, refacoring sorting URI 2020-12-09 18:24:05 +01:00
Milos Holba
7e325c5101 add sorting for every getData and navigator, Favourites need to be fixed 2020-12-08 19:14:53 +01:00
Milos Holba
59ff07fb01 remove clear fileInfoDetail after load data , add clear fileInfoDetail after open another folder 2020-12-07 19:08:45 +01:00
Milos Holba
2ba92ed3b6 add aplhabet icon 2020-12-07 19:00:50 +01:00
Milos Holba
418c072414 optimalize UI for preview and sorting options 2020-12-07 18:57:40 +01:00
Milos Holba
397fe6b7e4 fixed record_upload for guest ,add clear fileInfoDetail after data change 2020-12-07 16:03:48 +01:00
Milos Holba
97d500028a grid and list view working 2020-12-07 14:23:29 +01:00
Milos Holba
527dfeef9f merge with bulk-operations 2020-12-07 11:32:43 +01:00
Milos Holba
1b3baab691 set timeout between multi download cycles 2020-12-05 18:17:45 +01:00
Milos Holba
5d512f7806 available create folder and upload files at multi selecting 2020-12-05 17:46:22 +01:00
Milos Holba
0da525f692 add the command key for selecting to FileItemGrid 2020-12-05 17:38:08 +01:00
Milos Holba
d076817c9e Merge branch 'bulk-operations' into sorting 2020-12-05 17:25:38 +01:00
Peter Papp
d2af7c1f5e version changed 2020-12-05 17:17:11 +01:00
Peter Papp
ef002f9186 frontend build 2020-12-05 17:15:27 +01:00
Peter Papp
f1006355c4 changed default sorting in navigation tree for move popup action 2020-12-05 17:09:44 +01:00
Milos Holba
ec6087a03c sorting first commit 2020-12-05 17:08:57 +01:00
Peter Papp
2e465f4d03 'Cancel Sharing' edit in language files 2020-12-05 16:56:17 +01:00
Peter Papp
08bf6654fc - Folder tree in navigator now has correct ordering with folder list in file view
- added translation to alert popup
- SCOUT_QUEUE default to true
2020-12-05 11:18:37 +01:00
Peter Papp
77e29852a5 SQLite indexer overload fix
- added jobs migration
- added queue:work to scheduler
- new setup in env.example
- frontend build
2020-12-05 10:22:50 +01:00
Milos Holba
6bc84d4b25 bulk-operations v0.3 fixed DragUI subtitle for single item , add handle for move item to the same parent 2020-12-04 15:47:32 +01:00
Milos Holba
d31e2ab98b bulk-operations v0.3 add multi shared cancel to contextMenu 2020-12-04 13:34:00 +01:00
Milos Holba
ee14c34671 bulk-operations fix desktopToolbar delete 2020-12-04 11:26:15 +01:00
Milos Holba
a8b290692e bulk-operations merge 2020-12-04 11:15:10 +01:00
Milos Holba
441f911560 bulk-operations v0.3 issues solved 2020-12-04 10:56:27 +01:00
Peter Papp
10090b474a - navigator in shared folder page fix
- fixed trash in MobileNavigation.vue
- MobileMultiSelectMenu.vue refactor
- frontend build
2020-12-03 20:19:21 +01:00
Milos Holba
aff2594ef2 bulk-operations fix drop of dragged item 2020-12-02 19:56:54 +01:00
Milos Holba
66aad7c488 merge 2020-12-02 17:09:35 +01:00
Milos Holba
896be9c9c9 bulk-operations change MultiSelect component 2020-12-02 17:06:35 +01:00
Peter Papp
8d1821e05d changed version 2020-12-01 17:55:20 +01:00
Peter Papp
b7014552d2 frontend build 2020-12-01 17:53:25 +01:00
Milos Holba
8561556f5c bulk-operations fixed moveItem popup Three, fixed multiSelect with Shift from bottom to top 2020-11-30 18:49:54 +01:00
Milos Holba
58f7479380 bulk-operations v0.1 add opcaity for draged items 2020-11-29 17:50:59 +01:00
Peter Papp
7b70c81d4d binding key delete 2020-11-29 09:55:58 +01:00
Peter Papp
1981f39f9e traffic fix
drag preview styling
2020-11-29 09:39:26 +01:00
Milos Holba
e86ea3e5c4 bulk-operations v0.1 disable rename if are multiple items selected , add Drag & Drop UI Ghost for share 2020-11-28 18:06:42 +01:00
Milos Holba
8e01b837a2 bulk-operations v0.1 add the Drag & Drop UI Ghost , styled scrollbar 2020-11-28 15:56:12 +01:00
Peter Papp
f33fe84350 traffic id fix 2020-11-28 14:46:59 +01:00
Milos Holba
dbbad817c7 bulk-operations multiSelect items UI v0.1 2020-11-26 12:28:59 +01:00
Milos Holba
0eb0939598 bulk-operations multiSelect items UI v0.1 2020-11-26 12:26:30 +01:00
Peter Papp
65f7855703 I killed that ghost beach! 2020-11-25 20:40:18 +01:00
Peter Papp
45d482d347 Merge remote-tracking branch 'origin/monitor' into bulk-operations
# Conflicts:
#	public/mix-manifest.json
2020-11-24 15:58:43 +01:00
Milos Holba
1654dc8678 bulk-operations draged item multiSelect UI 2020-11-24 11:19:40 +01:00
Peter Papp
cb417ea76d added basic traffic meter for upload/download 2020-11-23 18:29:23 +01:00
Milos Holba
17df4aea35 bulk-operations add the command key for selecting the items 2020-11-22 19:09:10 +01:00
Milos Holba
714429d8f4 bulk-operations merge with the improvements branch 2020-11-22 16:39:58 +01:00
Milos Holba
0df03f1d32 bulk-operations make new MobileMultiSelectMenu component, add multi dwonload 2020-11-22 16:21:51 +01:00
Peter Papp
fefc10afb8 Prevent browser 'Go Back' when you undesirably trying to go to previous page after sign in to your account 2020-11-22 10:30:06 +01:00
Peter Papp
1658627069 updated language files 2020-11-22 09:44:50 +01:00
Peter Papp
16ab540298 Ability to cancel uploading progress via x button 2020-11-22 09:42:44 +01:00
Peter Papp
4e5afa4747 Ability to remove uploaded logo and get back to text logo 2020-11-22 08:56:53 +01:00
Peter Papp
d76ff07bf4 Ability to collapse navigator or favourites widget in File page 2020-11-21 19:56:51 +01:00
Peter Papp
b38333bb64 Trash moved to file page 2020-11-21 18:02:46 +01:00
Peter Papp
f863537190 Integrated rename popup 2020-11-21 17:14:56 +01:00
Peter Papp
a72a672aaf Added navigator to shared page with folders when you have multiple folders within for better user experience
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
2020-11-21 10:33:27 +01:00
Milos Holba
a3dd817e7a bulk-operations v0.1 adding Drag & Drop for moving items to navigations folders, add folders to favourites 2020-11-20 17:54:39 +01:00
Milos Holba
9d9e07d0fa bulk-operations v0.1 mobileSeleting finished, change FileFullPreview code 2020-11-16 17:57:43 +01:00
Peter Papp
30783d0e5d frontend build 2020-11-16 17:19:59 +01:00
Peter Papp
3a296f0f9c Merge remote-tracking branch 'origin/upload-limit' into upload-limit 2020-11-16 17:17:46 +01:00
Peter Papp
c0d5a771a5 upload-limit branch review 2020-11-16 17:16:38 +01:00
Milos Holba
8fc7272e38 upload-limit v0.3 solved the multiple DB querys,uploadLimit in config 2020-11-16 17:16:38 +01:00
Milos Holba
8b8dc34ba6 upload-limit v0.2 solved uploadLimitFormate issues , add helper for format_megabytes 2020-11-16 17:16:38 +01:00
Milos Holba
966145d384 upload-limit v0.2 2020-11-16 17:16:38 +01:00
Milos Holba
2b4060cb7b upload-limit v0.1 2020-11-16 17:16:38 +01:00
Peter Papp
9455a361dc upload-limit branch review 2020-11-16 17:15:10 +01:00
Milos Holba
26132e23a3 bulk-operations v0.1 ContextMenu Add selecting for mobile version 2020-11-15 20:24:12 +01:00
Milos Holba
5acaadeaae bulk-version v0.1 contextMenu Mobile version selecting 2020-11-15 19:59:12 +01:00
Milos Holba
324f4b1ffa bulk-operations v0.1 setup bulk delete,move items and FileInfoPanel 2020-11-13 19:10:36 +01:00
Milos Holba
0c02952f7a bulk-operations v0.1 add selecting to FileItem List and Grid 2020-11-13 19:05:47 +01:00
Milos Holba
f76a4b37e4 bulk-operations v0.1 2020-11-13 19:03:13 +01:00
Milos Holba
f33f93006e bulk-operations v0.1 user_move, guest_move BE 2020-11-13 19:02:27 +01:00
Milos Holba
382756a6f0 rebase 2020-11-13 19:02:08 +01:00
Milos Holba
559bee6ca2 bulk-operations v0.1 setup bulk delete,move items and FileInfoPanel 2020-11-13 17:56:45 +01:00
Milos Holba
190fc651ae upload-limit v0.3 solved the multiple DB querys,uploadLimit in config 2020-11-12 17:46:23 +01:00
Peter Papp
1c62da4e7c fixed plan description validation in payment request 2020-11-12 17:16:37 +01:00
Milos Holba
8a9d2d7f9a bulk-operations add select for FileItemgrid 2020-11-12 17:12:09 +01:00
Peter Papp
ae3be12934 fixed plan description validation in payment request 2020-11-12 09:46:38 +01:00
Milos Holba
4683e0d084 bulk-operations select items v0.1 2020-11-11 18:03:46 +01:00
Milos Holba
c55d3f5350 upload-limit v0.2 solved uploadLimitFormate issues , add helper for format_megabytes 2020-11-07 15:19:03 +01:00
Milos Holba
7273d60154 upload-limit v0.2 2020-11-06 12:19:31 +01:00
Milos Holba
587daa5ffe upload-limit v0.1 2020-11-04 12:48:15 +01:00
Milos Holba
064e635d35 bulk-operations v0.1 user_move, guest_move BE 2020-11-03 15:36:08 +01:00
Milos Holba
06db522545 bulk-operations v0.1 user_delete,guest_delete BE 2020-11-01 19:52:33 +01:00
Peter Papp
e5335c2472 Merge remote-tracking branch 'origin/exifBlacklist' into exifBlacklist
# Conflicts:
#	public/mix-manifest.json
#	resources/js/helpers.js
#	resources/js/i18n/lang/cn.json
#	resources/js/i18n/lang/en.json
#	resources/js/i18n/lang/sk.json
#	resources/js/store/modules/fileFunctions.js
#	resources/js/views/Admin/AppSettings/AppSettingsTabs/Others.vue
2020-10-24 10:40:59 +02:00
Peter Papp
a2ec066c6d added metadata to UpgradeAppController.php
updated readme with upgrading step to 1.7.11
Frontend build
2020-10-24 10:39:39 +02:00
Miloš Holba
15d4ffc349 Add to metadata Longitude and Latitude 2020-10-24 09:44:23 +02:00
Peter Papp
9af9e45b8a night mode for ImageMetaData.vue 2020-10-24 09:44:23 +02:00
Peter Papp
f30dd38b96 migration column in file_manager_files renamed from meta_data to metadata
context menu feractoring
Editor.php typo changes
FileInfoPanel.vue small changes when to show metadata info
Added new exif information and reordering existing in ImageMetaData.vue
Added new translation strings to i18n files
2020-10-24 09:44:23 +02:00
Miloš Holba
d5f3599b9e v0.1 Add enable empty input in uploadText method 2020-10-24 09:44:23 +02:00
Miloš Holba
de62ab535c v0.1 Fix exif data function just for jpeg and Fix config in index.blade for mimetype_blacklist 2020-10-24 09:44:18 +02:00
Miloš Holba
8b8562916b v0.1 exifBlacklist 2020-10-24 09:44:05 +02:00
Miloš Holba
0d7b920cbe v0.1 add check mimetype if mimetype of file is undefined 2020-10-24 09:44:04 +02:00
Miloš Holba
f3254a380f v0.1 exif Blacklist add frontend validation 2020-10-24 09:44:02 +02:00
Miloš Holba
0e12029efc v0.1 Blacklist and Exif data 2020-10-24 09:43:58 +02:00
Miloš Holba
fd6aa5c6b2 Lazy loading (#41)
* lazy-loading and solved bugs

* lazy-loading for pull request on master

* Update vuefilemanager.php

Co-authored-by: Peter Papp <peterpapp@makingcg.com>
2020-10-24 09:40:05 +02:00
Miloš Holba
5be9db83f7 version change to v1.7.11 2020-10-23 16:14:34 +02:00
Peter Papp
12d6b0bf57 scheduler changed from hourly to every minute 2020-10-13 17:09:05 +02:00
nourisk
961462fe54 Update package.json (#32)
The "vue" and "vue-template[..]" versions not being the same, this has the effect of breaking the "npm run prod" command with error "version missmatch".
For people who have already installed it, just change the version then "npm install" and that should solve the problem.
2020-10-07 08:19:39 +02:00
nourisk
f0e0103d81 Update router.js (#31)
Capital i missing
2020-10-06 17:03:26 +02:00
Miloš Holba
755523e07b Add to metadata Longitude and Latitude 2020-09-25 09:31:31 +02:00
Peter Papp
c4ace0697b version change to v1.7.10.3 2020-09-20 12:09:07 +02:00
Peter Papp
69489c4ee2 - fixed simultaneously action with show and download file on doubleclick
- Changed download name for Backblaze
- Price plan can be defined in 12 digit number
2020-09-20 12:08:29 +02:00
Peter Papp
e05d7468b5 night mode for ImageMetaData.vue 2020-09-20 11:23:50 +02:00
Peter Papp
1a6a91335e migration column in file_manager_files renamed from meta_data to metadata
context menu feractoring
Editor.php typo changes
FileInfoPanel.vue small changes when to show metadata info
Added new exif information and reordering existing in ImageMetaData.vue
Added new translation strings to i18n files
2020-09-20 11:17:34 +02:00
Miloš Holba
80de069c7b v0.1 Add enable empty input in uploadText method 2020-09-15 13:20:39 +02:00
Miloš Holba
2de8bbe548 v0.1 Fix exif data function just for jpeg and Fix config in index.blade for mimetype_blacklist 2020-09-15 10:33:39 +02:00
Peter Papp
7ba2a3bec1 fixed backblaze broken download link when filename contain space (Content Disposition header wasn't read properly with space) 2020-09-14 09:53:38 +02:00
Miloš Holba
89fa2fce23 v0.1 exifBlacklist 2020-09-12 11:15:32 +02:00
Miloš Holba
84b47416d6 v0.1 add check mimetype if mimetype of file is undefined 2020-09-06 20:29:16 +02:00
Miloš Holba
55c72cddba v0.1 exif Blacklist add frontend validation 2020-09-05 18:35:27 +02:00
Miloš Holba
6effd4a7d9 v0.1 Blacklist and Exif data 2020-09-05 14:35:51 +02:00
Peter Papp
95f6695d00 Fixed when default value incorrectly showing in switches in app settings 2020-09-01 07:41:05 +02:00
Peter Papp
fde7f0f73b Fixed when default value incorrectly showing in switches in app settings 2020-09-01 07:10:56 +02:00
Peter Papp
dd1bffec09 typo error 2020-08-31 08:38:40 +02:00
Peter Papp
83a951b3af cache bursting support in webpack.mix.js 2020-08-31 08:22:51 +02:00
Peter Papp
6762ed25dc frontend build 2020-08-30 15:33:52 +02:00
Peter Papp
6ba869234e FileFullPreview functionality in file grid view 2020-08-30 15:33:20 +02:00
Peter Papp
2c04376a61 v1.7.10 2020-08-30 11:18:28 +02:00
Peter Papp
f180f1fff8 expand tap area for FilePreviewActions.vue arrows 2020-08-30 11:15:51 +02:00
Peter Papp
ab65ca7a13 hide subscription, payment cards and invoices in profile menu when is 'Allow subscription payment' option disabled
frontend build
2020-08-30 11:05:08 +02:00
Peter Papp
8895b5062a small design improves 2020-08-30 09:01:00 +02:00
Peter Papp
2f4aafb1b3 frontend build 2020-08-28 16:17:53 +02:00
Peter Papp
be08c8487a Merge remote-tracking branch 'origin/master' into filepreview
# Conflicts:
#	.env.example
#	package-lock.json
#	package.json
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/App.vue
#	resources/js/helpers.js
#	resources/js/i18n/lang/en.json
#	resources/js/i18n/lang/sk.json
#	resources/js/store/modules/fileFunctions.js
#	resources/js/views/Shared/SharedPage.vue
2020-08-28 16:14:28 +02:00
Peter Papp
0d5df91d2d frontend build 2020-08-27 14:48:48 +02:00
Peter Papp
72e4067beb logo fix in shared page
Renamed option title in share popup
2020-08-27 14:46:07 +02:00
Peter Papp
ba4f888826 Updated README.md and dark mode logo in Dashboard.vue page 2020-08-27 08:25:08 +02:00
Miloš Holba
82b43eb996 FilePreview solved v0.3 issues 2020-08-26 22:37:33 +02:00
Peter Papp
777132ec40 dark mode expiration buttons fix 2020-08-26 18:30:10 +02:00
Peter Papp
7f6f60227a Ability to set expiration for shared link
If user is logged in, after visit SignIn page will be redirected to files page
2020-08-26 08:17:49 +02:00
Peter Papp
ab6ff5dbfd force migration
added maintenance mode
2020-08-26 07:51:16 +02:00
Peter Papp
0d272bc9b7 version change 2020-08-26 07:30:48 +02:00
Peter Papp
2b08d7801b Shared link expiration backend
Redirect from sign in page when user is logged
Updated README.md
2020-08-26 07:29:28 +02:00
Peter Papp
cec4ff6cda shared link title fix 2020-08-25 15:33:16 +02:00
Peter Papp
6f300ba1d5 Link expiration frontend 2020-08-25 15:25:18 +02:00
Peter Papp
86813629ed updated readme 2020-08-25 12:53:46 +02:00
Peter Papp
73a728e606 change vuefilemanager version 2020-08-25 12:37:09 +02:00
Peter Papp
af1228e363 reading metadata in shared link RC 2020-08-25 12:36:21 +02:00
Peter Papp
f3a2758bcc reading metadata in shared link v0.1 2020-08-25 12:04:13 +02:00
Peter Papp
6f9f2f2d34 reading metadata in shared link 2020-08-25 11:03:53 +02:00
Peter Papp
9f4c21a1b1 UserSubscription page fix
PaymentMethods page fix
2020-08-24 09:30:38 +02:00
Peter Papp
88315e4a91 fixed paginated button 2020-08-24 07:20:45 +02:00
Peter Papp
25bb186c89 updated readme 2020-08-24 07:17:11 +02:00
Peter Papp
cca832a1c1 backend pagination and sorting from laravel database release 2020-08-24 06:35:42 +02:00
Miloš Holba
aac0aa755f fix arrow function when is just one file in MediaPreview 2020-08-22 17:55:03 +02:00
Miloš Holba
4be77c07ac remove addEventListener change the video sizing wrapper 2020-08-22 14:18:57 +02:00
Miloš Holba
9372906a3e open to click at audio for mobile 2020-08-22 12:19:23 +02:00
Miloš Holba
e12e521622 add audio mimetypes : mp4, flac 2020-08-21 17:32:36 +02:00
Peter Papp
6dd0b4f026 backend pagination and sorting from laravel database 2020-08-21 16:04:21 +02:00
Miloš Holba
0082c3a6a8 change arrows position 2020-08-20 20:31:47 +02:00
Miloš Holba
f79973e922 Fix issues from FilePreview v0.2 2020-08-20 18:50:07 +02:00
Peter Papp
3e6e046dfc folder delete fix 2020-08-19 06:10:07 +02:00
Miloš Holba
59ca45e9b1 update filePreview ContextMenu 2020-08-18 19:22:54 +02:00
Peter Papp
5f5caae9e7 updated language files, cache clear button loading 2020-08-18 15:12:34 +02:00
Peter Papp
93a7542502 - Moved chunk size option to .env
- Added ability into App Settings to flush application cache
- Renew password page logo fix
- removed put|patch|delete methods from axios and replaced by faking these methods to support incompatible shared hostings where you can't install php extension to support these methods.
- Getting unique_ids fix
2020-08-18 10:21:24 +02:00
Miloš Holba
bb22ec1e88 key binds fix 2020-08-17 20:10:30 +02:00
Peter Papp
5c2326e492 fixed non-vuefilemanager stripe plans loading 2020-08-17 10:04:47 +02:00
Peter Papp
47faadef51 strip non-asci characters from filename 2020-08-17 08:42:22 +02:00
Peter Papp
aa26501100 - added support for custom local storage path 2020-08-17 07:38:58 +02:00
Peter Papp
d333d53e9c - added eu-central to setup wizard for backblaze regions 2020-08-17 05:55:50 +02:00
Miloš Holba
ba315014fa split code to components, add arrow functions 2020-08-15 17:41:46 +02:00
Peter Papp
4a9f040c32 - added chunks 2020-08-14 10:22:41 +02:00
Peter Papp
13de58fdbd - relative chunks path 2020-08-14 10:21:57 +02:00
Peter Papp
40111b95c1 - frontend build with included chunks 2020-08-14 10:13:57 +02:00
Peter Papp
f03c6edec1 - code splitting with vue router 2020-08-14 10:02:24 +02:00
Peter Papp
840898ec9a - added region list to setup wizard
- dark mode disabled input fix
- fixed deprecated scopes
- updated screenshots for SaaS version
2020-08-14 08:39:11 +02:00
Peter Papp
a906a98cce frontend build 2020-08-13 10:58:43 +02:00
Peter Papp
962b76dd8b fix email setup 2020-08-13 10:57:29 +02:00
Peter Papp
23bbae8a74 meta description fix 2020-08-11 08:46:03 +02:00
Miloš Holba
8387f56048 Move item from gallery fix 2020-08-10 10:30:54 +02:00
Miloš Holba
68acf5f986 Add Gallery 2020-08-08 21:53:43 +02:00
Miloš Holba
785dade6b2 Add Gallery 2020-08-08 21:46:56 +02:00
carodej
8e93a92fcc updated readme 2020-08-07 16:33:30 +02:00
carodej
4393fc6f12 clear kernel 2020-08-07 10:57:04 +02:00
carodej
cba38b58c3 removed deprecated commands 2020-08-07 10:55:32 +02:00
carodej
1ff43b3557 added htaccess to redirect domain root to /public folder 2020-08-07 09:38:22 +02:00
carodej
bfc2253f4d set version 2020-08-05 16:54:26 +02:00
carodej
fb790200d4 bug fixes 2020-08-05 16:51:44 +02:00
carodej
fc2c4de50f additional text logo fix 2020-07-31 08:37:21 +02:00
carodej
a947882449 Merge branch 'master' of github.com:MakingCG/vue-filemanager-laravel
* 'master' of github.com:MakingCG/vue-filemanager-laravel:
  Update README.md
2020-07-30 09:01:34 +02:00
carodej
192b843a85 Merge branch 'dev'
* dev:
  v1.7.3 rc.1
  chunk upload and multipart upload beta.2
  chunk upload and multipart upload beta.1
  multipart upload build
  multipart upload
  chunk upload
  chunk upload
2020-07-30 08:58:19 +02:00
carodej
cd0627e8b8 v1.7.3 rc.1 2020-07-30 08:47:05 +02:00
carodej
46256f6332 chunk upload and multipart upload beta.2 2020-07-29 16:33:42 +02:00
Peter Papp
9935db4bb1 Update README.md 2020-07-29 16:33:05 +02:00
carodej
18761eb5b3 chunk upload and multipart upload beta.1 2020-07-29 12:29:30 +02:00
carodej
bf8db1be52 multipart upload build 2020-07-28 17:01:14 +02:00
carodej
9fea65bd52 multipart upload 2020-07-28 16:57:54 +02:00
carodej
fe8e329fea chunk upload 2020-07-27 17:40:16 +02:00
carodej
6ac543128e chunk upload 2020-07-27 17:28:55 +02:00
carodej
3a643da14e Updated readme 2020-07-24 09:07:41 +02:00
carodej
8cbc0d65dc download butten centered 2020-07-22 18:29:04 +02:00
carodej
4ac81f1ceb fixed urls when external storage is used 2020-07-22 18:12:26 +02:00
carodej
032f4f357a set smtp as default in setup wizard 2020-07-22 10:13:04 +02:00
290 changed files with 34225 additions and 12017 deletions

View File

@@ -6,8 +6,12 @@ APP_URL=http://localhost
APP_DEMO=false
LOG_CHANNEL=stack
SCOUT_DRIVER=tntsearch
SCOUT_QUEUE=true
FILESYSTEM_DRIVER=
CHUNK_SIZE=128
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
@@ -18,7 +22,7 @@ DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
QUEUE_CONNECTION=database
SESSION_DRIVER=file
SESSION_LIFETIME=120

3
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/app/Console/Commands/SetupDevelopmentEnvironment.php
/node_modules
/public/hot
/public/storage
@@ -11,8 +12,10 @@
.env.backup
.phpunit.result.cache
.phpstorm.meta.php
.vscode/
_ide_helper.php
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
prettier.json

3
.htaccess Normal file
View File

@@ -0,0 +1,3 @@
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]

File diff suppressed because it is too large Load Diff

174
README.md
View File

@@ -1,31 +1,28 @@
![logo](https://vuefilemanager.com/assets/images/vuefilemanager-horizontal-logo.svg)
# Private Cloud Storage Build on Laravel & Vue.js
## 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.
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!
- [Become a backer or sponsor on Patreon](https://www.patreon.com/vuefilemanager)
- [One-time donation via PayPal](https://www.paypal.me/peterpapp)
- [Purchase Licence on CodeCanyon](https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986)
## Contents
- [Installation](#installation)
- [Server Requirements](#server-requirements)
- [Installation](#installation)
- [PHP Configuration](#php-configuration)
- [Chunk Upload](#chunk-upload)
- [Upgrade Guide](#upgrade-guide)
- [Common Instructions](#common-instructions)
- [Update from 1.7.12 to 1.8](#update-from-1712-to-18)
- [Update from 1.7.10 to 1.7.11](#update-from-1710-to-1711)
- [Update from 1.7.8 to 1.7.9](#update-from-178-to-179)
- [Update from 1.7.x to 1.7.8](#update-from-17x-to-178)
- [Update from 1.6.x to 1.7](#update-from-16x-to-17)
- [Nginx Configuration](#nginx-configuration)
- [Apache Configuration](#apache-configuration)
- [Recover Failed Installation](#installation-failed)
- [Update VueFileManager from 1.6.x to 1.7 ](#update-vuefilemanager-from-16x-to-17)
- [Payments](#payments)
- [Get your active plans](#get-your-active-plans)
- [Manage Failed Payments](#manage-failed-payments)
- [Tax Rates](#tax-rates)
- [Technical Informations](#technical-informations)
- [For Developers](#for-developers)
- [Developers](#developers)
- [Running development environment on your localhost](#running-development-environment-on-your-localhost)
- [Supported Storages](#supported-storages)
- [How to Create New Language](#how-to-create-new-language)
- [Others](#others)
@@ -46,12 +43,12 @@ But, it can't be done without you, development is more and more complicated and
- Nginx or Apache
**These PHP Extensions are required:**
- GD
- BCMath
- PDO
- SQLite
- Ctype
- Fileinfo
- JSON
@@ -59,37 +56,113 @@ But, it can't be done without you, development is more and more complicated and
- OpenSSL
- Tokenizer
- XML
- Exif
## Installation
Copy project files to web root folder of your domain. It's mostly located in `html`, `www` or `public_html` folder name.
#### 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.
Then change your **public directory** for your domain. It should be changed to /public directory in the app.
#### 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.
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.
![Domain Root](https://vuefilemanager.com/assets/images/domain-root.jpg)
#### 3. Check your .env file
Make sure `.env` file was uploaded. This type of file can be hidden in default.
#### 3.1 When you install from GitHub
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.
```
composer install
```
#### 4. Set write permissions
Set `755` permission (CHMOD) to these file and folders directory within all children subdirectories:
- /bootstrap/cache
- /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.
At first step you have to verify your purchase code. **Subscription service with stripe payments is available only for Extended License.**
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.
#### 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.
#### 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
```
## 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.
```
memory_limit = 512M
upload_max_filesize = 1024M
post_max_size = 1024M
upload_max_filesize = 128M
post_max_size = 128M
max_file_uploads = 50
max_execution_time = 3600
```
## 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.
## 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!`
These instructions is applicable for all updates. Please follow this step:
- Just rewrite all project files with new excluded `/.env` file and `/storage` folder. These items must be preserved!
### Update from 1.7.12 to 1.8
- Before upload new files to your hosting, log in to VueFileManager as Admin. After uploading new files on your webhosting, visit this url `your-domain.com/service/upgrade-database` for upgrading your database.
- Just rewrite all project files with new, excluded /.env file and /storage folder. These items must be preserved!
- set **QUEUE_CONNECTION** to **database** in your **.env** file
- Clear cache in your administration panel - Settings / Application / Clear Cache
If you are upgrading from GitHub, don't forget run `composer install` to install new vendors.
### Update from 1.7.10 to 1.7.11
Before upload new files to your hosting, log in to VueFileManager as Admin. After uploading new files on your webhosting, visit this url `your-domain.com/service/upgrade-database` for upgrading your database.
### Update from 1.7.8 to 1.7.9
After rewrited old files with new files, log in as admin to the app and go to `your-domain.com/service/upgrade-database`. This will upgrade your database on the background.
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
```
### Update from 1.7.x to 1.7.8
For those who have installed VueFileManager via git or any other repository synchronization tool, dont't forget after updated code run `composer update` command to update your vendors.
### Update from 1.6.x to 1.7
For those, who purchase extended licence, place these lines at the end of your `/.env` file:
```
CASHIER_LOGGER=stack
CASHIER_CURRENCY=
STRIPE_KEY=
STRIPE_SECRET=
STRIPE_WEBHOOK_SECRET=
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment
```
Then go to https://your-domain.com/upgrade and follow the setup wizard instructions.
## Nginx Configuration
If you running VueFileManager undex Nginx, don't forget set this value in your `nginx.conf` file:
```
@@ -151,35 +224,6 @@ Make sure you have enabled mod_rewrite. There is an example config for running V
</VirtualHost>
```
## Installation Failed
What to do when installation fail and you can't continue, at first, try to fix issue why installation fail. Probably missing PHP extension or permissions wasn't set correctly.
At worst scenarios, to reset Setup Wizard, delete all tables in your previously created database, delete content of `/storage/framework/cache`. Then replace content in your `.env` file from `.env.example` file.
After these steps, installation will be reseted.
## Update VueFileManager from 1.6.x to 1.7
`Don't forget create backup of your database and storage before make any changes in your production application.`
For those, who purchase extended licence, place these lines at the end of your `/.env` file:
```
CASHIER_LOGGER=stack
CASHIER_CURRENCY=
STRIPE_KEY=
STRIPE_SECRET=
STRIPE_WEBHOOK_SECRET=
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment
```
Then follow this steps:
- Make sure you have PHP >= 7.2.5 version
- Make a backup of the .env config file located on your server.
- Upload and replace all the files on your server with what's inside the app folder.
- Restore your `.env` config file on your server.
- Go to https://your-domain.com/upgrade and follow the setup wizard instructions.
# 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`.
@@ -197,16 +241,15 @@ You are able to manage tax rates. When adding a new tax rate, if no Region is sp
Just log in to your stripe dashboard, and you will find taxes under `Dashboard / Products / Tax Rates`.
# Technical Informations
## For Developers
Installation process on your localhost is the same. But, there are some good hints.
# Developers
## Running development environment on your localhost
When you download repository from GitHub, you have to rename your `.env.example` file to `.env`. Then run this command in your terminal to install vendors:
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.
```
composer install
```
After successfully installation with setup wizard, you have to set your `APP_ENV` to local mode, in default, it's in production mode.
Set your `APP_ENV` to local mode, in default, it's in production mode.
```
APP_ENV=local
```
@@ -216,21 +259,29 @@ Also, to debug application, set `APP_DEBUG` on true:
APP_DEBUG=true
```
To start server on your localhost, run this command
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.
```
php artisan serve
```
To develop your front-end, you have to install npm modules by this command:
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:
```
npm install
```
To compiles and hot-reloads for development. Then run this command:
To compiles and hot-reloads for front-end development. Then run this command:
```
npm run hot
```
To compiles for production, run this command
To compiles for production build, run this command
```
npm run prod
```
@@ -312,6 +363,15 @@ The following support channels are available at your fingertips:
- [CodeCanyon support message](https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986/support)
- [GitHub repository](https://vuefilemanager.com/github-access)
## 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.
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)
- [Become a Patreon](https://www.patreon.com/vuefilemanager)
- [One-time donation via PayPal](https://www.paypal.me/peterpapp)
## Security Vulnerabilities
If you discover a security vulnerability within this project, please send an e-mail to [peterpapp@makingcg.com](peterpapp@makingcg.com). All security vulnerabilities will be promptly addressed.

File diff suppressed because it is too large Load Diff

View File

@@ -1,125 +0,0 @@
<?php
namespace App\Console\Commands;
use App\User;
use App\UserSettings;
use Illuminate\Console\Command;
class SetupDevEnvironment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'setup:dev';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Setting production environment';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Setting up production environment');
$this->migrateDatabase();
$this->generateKey();
$this->createPassportKeys();
$this->createPassportClientPassword();
$this->createPassportClientPersonal();
$this->createDefaultUser();
$this->info('Everything is done, congratulations! 🥳🥳🥳');
}
/**
* Migrate database
*/
public function generateKey()
{
$this->call('key:generate');
}
/**
* Migrate database
*/
public function migrateDatabase()
{
$this->call('migrate:fresh');
$this->call('db:seed');
}
/**
* Create Passport Encryption keys
*/
public function createPassportKeys()
{
$this->call('passport:keys', [
'--force' => true
]);
}
/**
* Create Password grant client
*/
public function createPassportClientPassword()
{
$this->call('passport:client', [
'--password' => true,
'--name' => 'vuefilemanager',
]);
$this->alert('Please copy these first password grant Client ID & Client secret above to your /.env file.');
}
/**
* Create Personal access client
*/
public function createPassportClientPersonal()
{
$this->call('passport:client', [
'--personal' => true,
'--name' => 'shared',
]);
}
/**
* Create Default User
*/
public function createDefaultUser()
{
$user = User::create([
'name' => 'Jane Doe',
'email' => 'howdy@hi5ve.digital',
'role' => 'admin',
'password' => \Hash::make('vuefilemanager'),
]);
// Create settings
$settings = UserSettings::create([
'user_id' => $user->id
]);
$this->info('Test user created. Email: ' . $user->email . ' Password: vuefilemanager');
}
}

View File

@@ -1,101 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SetupProductionEnvironment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'setup:prod';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Setting production environment';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Setting up production environment');
$this->migrateDatabase();
$this->generateKey();
$this->createPassportKeys();
$this->createPassportClientPassword();
$this->createPassportClientPersonal();
$this->info('Everything is done, congratulations! 🥳🥳🥳');
}
/**
* Migrate database
*/
public function generateKey()
{
$this->call('key:generate');
}
/**
* Migrate database
*/
public function migrateDatabase()
{
$this->call('migrate:fresh');
}
/**
* Create Passport Encryption keys
*/
public function createPassportKeys()
{
$this->call('passport:keys', [
'--force' => true
]);
}
/**
* Create Password grant client
*/
public function createPassportClientPassword()
{
$this->call('passport:client', [
'--password' => true,
'--name' => 'vuefilemanager',
]);
$this->alert('Please copy these first password grant Client ID & Client secret above to your /.env file.');
}
/**
* Create Personal access client
*/
public function createPassportClientPersonal()
{
$this->call('passport:client', [
'--personal' => true,
'--name' => 'shared',
]);
}
}

View File

@@ -1,107 +0,0 @@
<?php
namespace App\Console\Commands;
use App\User;
use App\UserSettings;
use Illuminate\Console\Command;
class UpgradeApp extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'upgrade:app {version}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Upgrade application to new version';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Upgrading your application to version ' . $this->argument('version'));
$this->call('down');
// Version 1.7
if ($this->argument('version') === 'v1.7') {
$this->version_1_7();
}
// Version 1.6
if ($this->argument('version') === 'v1.6') {
$this->version_1_6();
}
$this->call('up');
$this->info('Your application was upgraded! 🥳🥳🥳');
}
/**
* Upgrade script to version 1.7
*/
public function version_1_7() {
// Migrate new tables and changes
$this->call('migrate');
$this->call('rinvex:migrate:subscriptions');
/*$this->call('db:seed', [
'--class' => 'PaymentGatewaysSeeder'
]);*/
}
/**
* Upgrade script to version 1.6
*/
public function version_1_6() {
// Migrate new tables and changes
$this->call('migrate');
// Create user settings records
$this->info('Updating users options...');
User::all()->each(function ($user) {
$this->info('Update user with id: ' . $user->id);
UserSettings::create(['user_id' => $user->id]);
});
$this->info('Updating user options is done!');
// Set up admin
$email = $this->ask('Which user would you like set up as admin? Please type user email');
$admin = User::where('email', $email)->first();
if (! $admin) {
$email = $this->ask('We can\'t find user with this email, please try it again');
$admin = User::where('email', $email)->first();
}
// Save new role for selected user
$admin->role = 'admin';
$admin->save();
$this->info('Admin was set up successfully');
}
}

View File

@@ -3,9 +3,14 @@
namespace App\Console;
use App\Console\Commands\Deploy;
// use App\Console\Commands\SetupDevelopmentEnvironment;
use App\Console\Commands\SetupDevEnvironment;
use App\Console\Commands\SetupProductionEnvironment;
use App\Console\Commands\UpgradeApp;
use App\Share;
use App\Zip;
use Carbon\Carbon;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -17,22 +22,30 @@ class Kernel extends ConsoleKernel
* @var array
*/
protected $commands = [
SetupProductionEnvironment::class,
SetupDevEnvironment::class,
UpgradeApp::class,
Deploy::class,
// SetupDevelopmentEnvironment::class,
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
$schedule->call(function () {
$this->delete_expired_shared_links();
})->everyMinute();
$schedule->call(function () {
$this->delete_old_zips();
})->everySixHours();
// Run queue jobs every minute
$schedule->command('queue:work --tries=3')
->everyMinute()
->withoutOverlapping();
}
/**
@@ -42,8 +55,46 @@ class Kernel extends ConsoleKernel
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
$this->load(__DIR__ . '/Commands');
require base_path('routes/console.php');
}
/**
* Delete old zips
*/
protected function delete_old_zips(): void
{
// Get all zips
$zips = Zip::where('created_at', '<=', Carbon::now()->subDay()->toDateTimeString())->get();
$zips->each(function ($zip) {
// Delete zip file
\Storage::disk('local')->delete('zip/' . $zip->basename);
// Delete zip record
$zip->delete();
});
}
/**
* Get and delete expired shared links
*/
protected function delete_expired_shared_links(): void
{
// Get all shares with expiration time
$shares = Share::whereNotNull('expire_in')->get();
$shares->each(function ($share) {
// Get dates
$created_at = Carbon::parse($share->created_at);
// If time was over, then delete share record
if ($created_at->diffInHours(Carbon::now()) >= $share->expire_in) {
$share->delete();
}
});
}
}

View File

@@ -9,6 +9,7 @@ use Illuminate\Support\Str;
use Laravel\Scout\Searchable;
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
use \Illuminate\Database\Eloquent\SoftDeletes;
use Kyslik\ColumnSortable\Sortable;
/**
* App\FileManagerFile
@@ -52,10 +53,13 @@ use \Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFile withTrashed()
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFile withoutTrashed()
* @mixin \Eloquent
* @property array|null $metadata
* @method static \Illuminate\Database\Eloquent\Builder|FileManagerFile sortable($defaultParameters = null)
* @method static \Illuminate\Database\Eloquent\Builder|FileManagerFile whereMetadata($value)
*/
class FileManagerFile extends Model
{
use Searchable, SoftDeletes;
use Searchable, SoftDeletes , Sortable;
public $public_access = null;
@@ -67,6 +71,20 @@ class FileManagerFile extends Model
'file_url'
];
protected $casts = [
'metadata' => 'array',
];
/**
* Sortable columns
*
* @var string[]
*/
public $sortable = [
'name',
'created_at',
];
/**
* Set routes with public access
*
@@ -84,7 +102,7 @@ class FileManagerFile extends Model
*/
public function getCreatedAtAttribute()
{
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __('vuefilemanager.time'));
}
/**
@@ -96,7 +114,7 @@ class FileManagerFile extends Model
{
if (!$this->attributes['deleted_at']) return null;
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __('vuefilemanager.time'));
}
/**
@@ -145,15 +163,19 @@ class FileManagerFile extends Model
*/
public function getFileUrlAttribute()
{
// Get file from s3
// Get file from external storage
if (is_storage_driver(['s3', 'spaces', 'wasabi', 'backblaze'])) {
$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=' . $this->attributes['name'] . '.' . $this->attributes['mimetype'],
'ResponseContentDisposition' => 'attachment; filename=' . $file_pretty_name,
];
return Storage::temporaryUrl('file-manager/' . $this->attributes['basename'], now()->addDay(), $header);

View File

@@ -11,6 +11,7 @@ use RecursiveArrayIterator;
use RecursiveIteratorIterator;
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
use \Illuminate\Database\Eloquent\SoftDeletes;
use Kyslik\ColumnSortable\Sortable;
/**
* App\FileManagerFolder
@@ -58,10 +59,11 @@ use \Illuminate\Database\Eloquent\SoftDeletes;
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFolder withTrashed()
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFolder withoutTrashed()
* @mixin \Eloquent
* @method static \Illuminate\Database\Eloquent\Builder|FileManagerFolder sortable($defaultParameters = null)
*/
class FileManagerFolder extends Model
{
use Searchable, SoftDeletes;
use Searchable, SoftDeletes , Sortable;
protected $guarded = [
'id'
@@ -71,6 +73,20 @@ class FileManagerFolder extends Model
'items', 'trashed_items'
];
protected $casts = [
'icon_emoji' => 'object',
];
/**
* Sortable columns
*
* @var string[]
*/
public $sortable = [
'name',
'created_at',
];
/**
* Index folder
*
@@ -121,7 +137,7 @@ class FileManagerFolder extends Model
*/
public function getCreatedAtAttribute()
{
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __('vuefilemanager.time'));
}
/**
@@ -133,7 +149,7 @@ class FileManagerFolder extends Model
{
if (! $this->attributes['deleted_at']) return null;
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __('vuefilemanager.time'));
}
/**

View File

@@ -60,7 +60,7 @@ class DashboardController extends Controller
public function new_registrations()
{
return new UsersCollection(
User::take(7)->orderByDesc('created_at')->get()
User::sortable(['created_at' => 'desc'])->paginate(10)
);
}
}

View File

@@ -19,7 +19,7 @@ class PagesController extends Controller
public function index()
{
return new PageCollection(
Page::all()
Page::sortable()->paginate(10)
);
}

View File

@@ -153,7 +153,7 @@ class PlanController extends Controller
$subscribers = Subscription::where('stripe_plan', $id)->pluck('user_id');
return new UsersCollection(
User::findMany($subscribers)
User::sortable()->findMany($subscribers)
);
}
}

View File

@@ -85,8 +85,8 @@ class UserController extends Controller
{
$user = User::find($id);
if (! $user->stripeId()) {
return response('User is not stripe customer', 404);
if (! $user->stripeId() || ! $user->subscription('main')) {
return response('User doesn\'t have any subscription.', 404);
}
return new UserSubscription(
@@ -102,7 +102,7 @@ class UserController extends Controller
public function users()
{
return new UsersCollection(
User::all()
User::sortable(['created_at', 'DESC'])->paginate('20')
);
}
@@ -227,7 +227,7 @@ class UserController extends Controller
}
// Validate user name
if ($user->name !== $request->name) abort(403);
if ($user->name !== $request->input('data.name')) abort(403);
$shares = Share::where('user_id', $user->id)->get();

View File

@@ -3,11 +3,15 @@
namespace App\Http\Controllers;
use App\Content;
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Requests\PublicPages\SendMessageRequest;
use App\Http\Resources\PageResource;
use App\Http\Tools\Demo;
use App\Mail\SendSupportForm;
use App\Page;
use App\Setting;
use App\User;
use Artisan;
use Doctrine\DBAL\Driver\PDOException;
use Illuminate\Http\Request;
@@ -22,6 +26,7 @@ class AppFunctionsController extends Controller
* @var array
*/
private $whitelist = [
'section_features',
'footer_content',
'get_started_description',
'get_started_title',
@@ -40,7 +45,7 @@ class AppFunctionsController extends Controller
'section_get_started',
'section_pricing_content',
'section_feature_boxes',
'section_features',
'allow_homepage',
];
/**
@@ -59,7 +64,7 @@ class AppFunctionsController extends Controller
$users_table = Schema::hasTable('users');
// If settings table don't exist, then run migrations
if ($users_table && ! $settings_table) {
if ($users_table && !$settings_table) {
Artisan::call('migrate', [
'--force' => true
]);
@@ -71,7 +76,7 @@ class AppFunctionsController extends Controller
// Get connection string
if ($upgraded && $upgraded->value !== '1.7') {
$connection = 'quiet-update';
} else if (! $upgraded) {
} else if (!$upgraded) {
$connection = 'quiet-update';
} else {
$connection = $this->get_setup_status();
@@ -95,6 +100,68 @@ class AppFunctionsController extends Controller
->with('installation', $connection);
}
/**
* Get og site for web crawlers
*
* @param $token
*/
public function og_site($token)
{
// Get all settings
$settings = Setting::all();
// Get shared token
$shared = get_shared($token);
// Get user
$user = User::findOrFail($shared->user_id);
// Handle single file
if ($shared->type === 'file') {
// Get file record
$file = FileManagerFile::where('user_id', $shared->user_id)
->where('unique_id', $shared->item_id)
->first();
if ($file->thumbnail) {
$file->setPublicUrl($token);
}
$metadata = [
'is_protected' => $shared->protected,
'url' => url('/shared', ['token' => $token]),
'user' => $user->name,
'name' => $file->name,
'size' => $file->filesize,
'thumbnail' => $file->thumbnail ? $file->thumbnail : null,
];
}
// Handle single file
if ($shared->type === 'folder') {
// Get file record
$folder = FileManagerFolder::where('user_id', $shared->user_id)
->where('unique_id', $shared->item_id)
->first();
$metadata = [
'is_protected' => $shared->protected,
'url' => url('/shared', ['token' => $token]),
'user' => $user->name,
'name' => $folder->name,
'size' => $folder->items,
'thumbnail' => null,
];
}
// Return view
return view("og-view")
->with('settings', json_decode($settings->pluck('value', 'name')->toJson()))
->with('metadata', $metadata);
}
/**
* Check if setup wizard was passed
*
@@ -164,4 +231,31 @@ class AppFunctionsController extends Controller
return Setting::where('name', $column)->pluck('value', 'name');
}
/**
* Clear application cache
*/
public function flush_cache()
{
// Check if is demo
if (env('APP_DEMO')) {
return Demo::response_204();
}
Artisan::call('cache:clear');
Artisan::call('config:clear');
Artisan::call('config:cache');
}
/**
* Get Emojis List from the server
*
* @return $emojisList
*/
public function get_emojis_list()
{
$emojisList = json_decode(file_get_contents(public_path('assets/emojis.json'), true));
return collect([$emojisList]);
}
}

View File

@@ -3,8 +3,11 @@
namespace App\Http\Controllers;
use App\FileManagerFolder;
use App\Http\Tools\Editor;
use App\Http\Tools\Guardian;
use App\Share;
use App\User;
use App\Zip;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
@@ -13,7 +16,11 @@ use Illuminate\Http\Request;
use App\FileManagerFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Http\Exceptions\HttpResponseException;
use Madnest\Madzipper\Facades\Madzipper;
use Response;
use League\Flysystem\FileNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class FileAccessController extends Controller
{
@@ -84,9 +91,63 @@ class FileAccessController extends Controller
$this->check_file_access($shared, $file);
}
// Store user download size
$request->user()->record_download((int)$file->getRawOriginal('filesize'));
return $this->download_file($file);
}
/**
* Get generated zip for user
*
* @param $id
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function get_zip($id)
{
$zip = Zip::where('id', $id)
->where('user_id', Auth::id())
->first();
$zip_path = 'zip/' . $zip->basename;
$header = [
"Content-Type" => 'application/zip',
"Content-Length" => Storage::disk('local')->size($zip_path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::disk('local')->size($zip_path),
"Content-Disposition" => "attachment; filename=" . $zip->basename,
];
return Storage::disk('local')->download($zip_path, $zip->basename, $header);
}
/**
* Get generated zip for guest
*
* @param $id
* @param $token
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function get_zip_public($id, $token)
{
$zip = Zip::where('id', $id)
->where('shared_token', $token)
->first();
$zip_path = 'zip/' . $zip->basename;
$header = [
"Content-Type" => 'application/zip',
"Content-Length" => Storage::disk('local')->size($zip_path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::disk('local')->size($zip_path),
"Content-Disposition" => "attachment; filename=" . $zip->basename,
];
return Storage::disk('local')->download($zip_path, $zip->basename, $header);
}
/**
* Get file public
*
@@ -101,7 +162,7 @@ class FileAccessController extends Controller
$shared = get_shared($token);
// Abort if shared is protected
if ($shared->protected) {
if ((int)$shared->protected) {
abort(403, "Sorry, you don't have permission");
}
@@ -113,6 +174,9 @@ class FileAccessController extends Controller
// Check file access
$this->check_file_access($shared, $file);
// Store user download size
User::find($shared->user_id)->record_download((int)$file->getRawOriginal('filesize'));
return $this->download_file($file);
}
@@ -154,7 +218,7 @@ class FileAccessController extends Controller
$shared = get_shared($token);
// Abort if thumbnail is protected
if ($shared->protected) {
if ((int)$shared->protected) {
abort(403, "Sorry, you don't have permission");
}
@@ -197,8 +261,7 @@ class FileAccessController extends Controller
*/
private function download_file($file)
{
// Format pretty filename
$file_pretty_name = $file->name . '.' . $file->mimetype;
$file_pretty_name = get_pretty_name($file->basename, $file->name, $file->mimetype);
// Get file path
$path = '/file-manager/' . $file->basename;
@@ -206,15 +269,15 @@ class FileAccessController extends Controller
// Check if file exist
if (!Storage::exists($path)) abort(404);
$header = [
"Content-Type" => Storage::mimeType($path),
"Content-Length" => Storage::size($path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::size($path),
$headers = [
"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=" . $file_pretty_name,
];
// Get file
return Storage::download($path, $file_pretty_name, $header);
return response()->download(storage_path('/app/file-manager/') . $file->basename, $file_pretty_name, $headers);
}
/**

View File

@@ -36,6 +36,7 @@ class BrowseController extends Controller
->with(['parent'])
->where('user_id', $user_id)
->whereIn('unique_id', filter_folders_ids($folders_trashed))
->sortable()
->get();
// Get files trashed
@@ -43,6 +44,7 @@ class BrowseController extends Controller
->with(['parent'])
->where('user_id', $user_id)
->whereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'unique_id'))))
->sortable()
->get();
// Collect folders and files to single array
@@ -69,14 +71,16 @@ class BrowseController extends Controller
->pluck('item_id');
// Get folders and files
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->whereIn('unique_id', $folder_ids)
->sortable()
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->whereIn('unique_id', $file_ids)
->sortable()
->get();
// Collect folders and files to single array
@@ -91,7 +95,9 @@ class BrowseController extends Controller
public function latest() {
// Get User
$user = User::with(['latest_uploads'])
$user = User::with(['latest_uploads' => function($query) {
$query->sortable(['created_at' => 'desc']);
}])
->where('id', Auth::id())
->first();
@@ -106,8 +112,11 @@ class BrowseController extends Controller
public function participant_uploads() {
// Get User
$uploads = FileManagerFile::with(['parent'])->where('user_id', Auth::id())
->whereUserScope('editor')->orderBy('created_at', 'DESC')->get();
$uploads = FileManagerFile::with(['parent'])
->where('user_id', Auth::id())
->whereUserScope('editor')
->sortable()
->get();
return $uploads;
}
@@ -132,12 +141,14 @@ class BrowseController extends Controller
->with('parent')
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->sortable()
->get();
$files = FileManagerFile::onlyTrashed()
->with('parent')
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->sortable()
->get();
// Collect folders and files to single array
@@ -145,15 +156,16 @@ class BrowseController extends Controller
}
// Get folders and files
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->sortable()
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->orderBy('created_at', 'DESC')
->sortable()
->get();
// Collect folders and files to single array
@@ -170,6 +182,7 @@ class BrowseController extends Controller
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', 0)
->where('user_id', Auth::id())
->sortable()
->get(['id', 'parent_id', 'unique_id', 'name']);
return [
@@ -192,33 +205,17 @@ class BrowseController extends Controller
{
// Get user
$user_id = Auth::id();
$query = remove_accents($request->input('query'));
// Search files id db
$searched_files = FileManagerFile::search($request->input('query'))
$searched_files = FileManagerFile::search($query)
->where('user_id', $user_id)
->get();
$searched_folders = FileManagerFolder::search($request->input('query'))
$searched_folders = FileManagerFolder::search($query)
->where('user_id', $user_id)
->get();
// Collect folders and files to single array
return collect([$searched_folders, $searched_files])->collapse();
}
/**
* Get file record
*
* @param $unique_id
* @return mixed
*/
public function file_detail($unique_id)
{
// Get user id
$user_id = Auth::id();
return FileManagerFile::with(['shared:token,id,item_id,permission,protected'])
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
}
}

View File

@@ -10,10 +10,12 @@ use App\Http\Requests\FileFunctions\UploadRequest;
use App\Http\Tools\Demo;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use App\Http\Tools\Guardian;
use App\Http\Tools\Editor;
use App\FileManagerFolder;
use App\FileManagerFile;
use Exception;
@@ -113,6 +115,12 @@ class EditItemsController extends Controller
}
}
// If request have a change folder icon values set the folder icon
if ($request->type === 'folder' && $request->filled('folder_icon')) {
Editor::set_folder_icon($request->folder_icon, $unique_id);
}
// Rename Item
return Editor::rename_item($request, $unique_id);
}
@@ -149,6 +157,12 @@ class EditItemsController extends Controller
Guardian::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('folder_icon')) {
Editor::set_folder_icon($request->folder_icon, $unique_id, $shared);
}
// Rename item
$item = Editor::rename_item($request, $unique_id, $shared);
@@ -168,40 +182,43 @@ class EditItemsController extends Controller
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function user_delete_item(DeleteItemRequest $request, $unique_id)
public function user_delete_item(DeleteItemRequest $request)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
// Check permission to delete item for authenticated editor
if ($request->user()->tokenCan('editor')) {
foreach ($request->input('data') as $file) {
$unique_id = $file['unique_id'];
// Prevent force delete for non-master users
if ($request->force_delete) abort('401');
// Check permission to delete item for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Prevent force delete for non-master users
if ($file['force_delete']) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get file|folder item
$item = get_item($request->type, $unique_id, Auth::id());
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
// Get file|folder item
$item = get_item($file['type'], $unique_id, Auth::id());
// Check access to requested directory
if ($file['type'] === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
}
// Delete item
Editor::delete_item($file, $unique_id);
}
// Delete item
Editor::delete_item($request, $unique_id);
// Return response
return response(null, 204);
}
@@ -214,7 +231,7 @@ class EditItemsController extends Controller
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function guest_delete_item(DeleteItemRequest $request, $unique_id, $token)
public function guest_delete_item(DeleteItemRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
@@ -227,25 +244,28 @@ class EditItemsController extends Controller
// Check shared permission
if (!is_editor($shared)) abort(403);
// Get file|folder item
$item = get_item($request->type, $unique_id, $shared->user_id);
foreach ($request->input('data') as $file) {
$unique_id = $file['unique_id'];
// Check access to requested item
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
// Get file|folder item
$item = get_item($file['type'], $unique_id, $shared->user_id);
// Check access to requested item
if ($file['type'] === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
// Delete item
Editor::delete_item($file, $unique_id, $shared);
}
// Delete item
Editor::delete_item($request, $unique_id, $shared);
// Return response
return response(null, 204);
}
/**
* Delete file for authenticated master|editor user
* Upload file for authenticated master|editor user
*
* @param UploadRequest $request
* @return FileManagerFile|Model
@@ -308,21 +328,19 @@ class EditItemsController extends Controller
return $new_file;
}
/**
* Move item for authenticated master|editor user
/**
* User download folder via zip
*
* @param MoveItemRequest $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
* @return string
*/
public function user_move(MoveItemRequest $request, $unique_id)
public function user_zip_folder(Request $request,$unique_id)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
// Check permission to upload for authenticated editor
// Get user id
$user_id = Auth::id();
// Check permission to download for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
@@ -332,11 +350,172 @@ class EditItemsController extends Controller
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($request->to_unique_id, $shared);
Guardian::check_item_access($unique_id, $shared);
}
// Get folder
$folder = FileManagerFolder::whereUserId($user_id)
->where('unique_id', $unique_id);
if (! $folder->exists()) {
abort(404, 'Requested folder doesn\'t exists.');
}
$zip = Editor::zip_folder($unique_id);
// Get file
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 200);
}
/**
* Guest download folder via zip
*
* @param Request $request
* @param $unique_id
* @param $token
* @return string
*/
public function guest_zip_folder($unique_id, $token)
{
// Get shared record
$shared = get_shared($token);
// Check access to requested folder
Guardian::check_item_access($unique_id, $shared);
// Get folder
$folder = FileManagerFolder::whereUserId($shared->user_id)
->where('unique_id', $unique_id);
if (! $folder->exists()) {
abort(404, 'Requested folder doesn\'t exists.');
}
$zip = Editor::zip_folder($unique_id, $shared);
// Get file
return response([
'url' => route('zip_public', [
'id' => $zip->id,
'token' => $shared->token,
]),
'name' => $zip->basename,
], 200);
}
/**
* User download multiple files via zip
*
* @param Request $request
* @return string
*/
public function user_zip_multiple_files(Request $request)
{
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
$file_parent_folders = FileManagerFile::whereUserId(Auth::id())
->whereIn('unique_id', $request->input('files'))
->get()
->pluck('folder_id')
->toArray();
// Check access to requested directory
Guardian::check_item_access($file_parent_folders, $shared);
}
// Get requested files
$files = FileManagerFile::whereUserId(Auth::id())
->whereIn('unique_id', $request->input('files'))
->get();
$zip = Editor::zip_files($files);
// Get file
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 200);
}
/**
* Guest download multiple files via zip
*
* @param Request $request
* @param $token
* @return string
*/
public function guest_zip_multiple_files(Request $request, $token)
{
// Get shared record
$shared = get_shared($token);
$file_parent_folders = FileManagerFile::whereUserId($shared->user_id)
->whereIn('unique_id', $request->input('files'))
->get()
->pluck('folder_id')
->toArray();
// Check access to requested directory
Guardian::check_item_access($file_parent_folders, $shared);
// Get requested files
$files = FileManagerFile::whereUserId($shared->user_id)
->whereIn('unique_id', $request->input('files'))
->get();
$zip = Editor::zip_files($files, $shared);
// Get file
return response([
'url' => route('zip_public', [
'id' => $zip->id,
'token' => $shared->token,
]),
'name' => $zip->basename,
], 200);
}
/**
* Move item for authenticated master|editor user
*
* @param MoveItemRequest $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function user_move(MoveItemRequest $request)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
$to_unique_id = $request->input('to_unique_id');
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($to_unique_id, $shared);
}
// Move item
Editor::move($request, $unique_id);
Editor::move($request, $to_unique_id);
return response('Done!', 204);
}
@@ -349,11 +528,14 @@ class EditItemsController extends Controller
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function guest_move(MoveItemRequest $request, $unique_id, $token)
public function guest_move(MoveItemRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
//Unique id of Folder where move
$to_unique_id = $request->input('to_unique_id');
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
@@ -362,23 +544,28 @@ class EditItemsController extends Controller
// Check shared permission
if (!is_editor($shared)) abort(403);
$moving_unique_id = $unique_id;
foreach ($request->input('items') as $item) {
if ($request->from_type !== 'folder') {
$file = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $shared->user_id)
->firstOrFail();
$unique_id = $item['unique_id'];
$moving_unique_id = $unique_id;
$moving_unique_id = $file->folder_id;
if ($item['type'] !== 'folder') {
$file = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $shared->user_id)
->firstOrFail();
$moving_unique_id = $file->folder_id;
}
// Check access to requested item
Guardian::check_item_access([
$to_unique_id, $moving_unique_id
], $shared);
}
// Check access to requested item
Guardian::check_item_access([
$request->to_unique_id, $moving_unique_id
], $shared);
// Move item
Editor::move($request, $unique_id, $shared);
Editor::move($request, $to_unique_id, $shared);
return response('Done!', 204);
}

View File

@@ -20,16 +20,18 @@ class FavouriteController extends Controller
public function store(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
$validator = Validator::make($request->input('folders'), [
'*.unique_id' => 'required|integer',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
foreach($request->input('folders') as $item) {
// Get user & folder
$user = Auth::user();
$folder = FileManagerFolder::where('unique_id', $request->unique_id)->first();
$folder = FileManagerFolder::where('unique_id', $item['unique_id'])->first();
if (is_demo($user->id)) {
return Demo::favourites($user);
@@ -39,8 +41,9 @@ class FavouriteController extends Controller
if ($folder->user_id !== $user->id) abort(403);
// Add folder to user favourites
$user->favourite_folders()->syncWithoutDetaching($request->unique_id);
$user->favourite_folders()->syncWithoutDetaching($item['unique_id']);
}
// Return updated favourites
return $user->favourite_folders;
}

View File

@@ -5,14 +5,18 @@ namespace App\Http\Controllers\FileFunctions;
use App\Http\Requests\Share\CreateShareRequest;
use App\Http\Requests\Share\UpdateShareRequest;
use App\Http\Resources\ShareResource;
use App\Notifications\SharedSendViaEmail;
use App\Zip;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Str;
use App\Share;
use Validator;
class ShareController extends Controller
{
@@ -51,12 +55,23 @@ class ShareController extends Controller
'protected' => $request->isPassword,
'permission' => $request->permission,
'item_id' => $request->unique_id,
'expire_in' => $request->expiration,
'user_id' => Auth::id(),
'token' => $token,
];
// Return created shared record
return new ShareResource(Share::create($options));
$share = new ShareResource(Share::create($options));
// Send shared link via email
if ($request->has('emails')) {
foreach ($request->emails as $email) {
Notification::route('mail', $email)->notify(new SharedSendViaEmail($token));
}
}
return $share;
}
/**
@@ -77,6 +92,7 @@ class ShareController extends Controller
$shared->update([
'permission' => $request->permission,
'protected' => $request->protected,
'expire_in' => $request->expiration,
'password' => $request->password ? Hash::make($request->password) : $shared->password,
]);
@@ -91,17 +107,53 @@ class ShareController extends Controller
* @return ResponseFactory|\Illuminate\Http\Response
* @throws \Exception
*/
public function destroy($token)
public function destroy(Request $request)
{
// Get sharing record
$shared = Share::where('token', $token)
->where('user_id', Auth::id())
->firstOrFail();
foreach ($request->input('tokens') as $token) {
// Delete shared record
$shared->delete();
// 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();
}
}
// Done
return response('Done!', 204);
}
/**
* Send shared link via email to recipients
*
* @param $token
* @param $request
*/
public function shared_send_via_email(Request $request, $token)
{
// 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

@@ -59,12 +59,12 @@ class TrashController extends Controller
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function restore(Request $request, $unique_id)
public function restore(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'type' => 'required|string',
'to_home' => 'boolean',
$validator = Validator::make($request->input('data'), [
'*.type' => 'required|string',
'*.unique_id' => 'integer',
]);
// Return error
@@ -77,38 +77,41 @@ class TrashController extends Controller
return Demo::response_204();
}
// Get folder
if ($request->type === 'folder') {
foreach($request->input('data') as $restore_item) {
// Get folder
$item = FileManagerFolder::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
if ($restore_item['type'] === 'folder') {
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->parent_id = 0;
$item->save();
// Get folder
$item = FileManagerFolder::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $restore_item['unique_id'])
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->parent_id = 0;
$item->save();
}
} else {
// Get item
$item = FileManagerFile::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $restore_item['unique_id'])
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->folder_id = 0;
$item->save();
}
}
} else {
// Get item
$item = FileManagerFile::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->folder_id = 0;
$item->save();
}
// Restore Item
$item->restore();
}
// Restore Item
$item->restore();
// Return response
return response('Done!', 204);
}

View File

@@ -466,19 +466,16 @@ class SetupWizardController extends Controller
]);
// Create legal pages and index content
if ($request->license === 'Extended') {
$pages = collect(config('content.pages'));
$content = $request->license === 'Extended' ? collect(config('content.content_extended')) : collect(config('content.content_regular'));
$pages = collect(config('vuefilemanager.pages'));
$content = collect(config('vuefilemanager.content'));
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
}
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
// Retrieve access token
$response = Route::dispatch(self::make_login_request($request));

View File

@@ -7,120 +7,119 @@ use App\Page;
use App\Setting;
use Artisan;
use Illuminate\Http\Request;
use Schema;
class UpgradeAppController extends Controller
{
/**
* Upgrade account from 1.6 to 1.7
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
* Start maintenance mode
*/
public function upgrade(Request $request)
public function up() {
$command = Artisan::call('up');
if ($command === 0) {
echo 'System is in production mode';
}
}
/**
* End maintenance mode
*/
public function down() {
$command = Artisan::call('down');
if ($command === 0) {
echo 'System is in maintenance mode';
}
}
/**
* Upgrade database
*/
public function upgrade()
{
$upgraded = Setting::where('name', 'latest_upgrade')->first();
/*
* Upgrade user_settings & file_manager_folders table
*
* @since v1.8.1
*/
if (! Schema::hasColumn('user_settings', 'timezone') && ! Schema::hasColumn('file_manager_folders', 'icon_color')) {
if ($upgraded && $upgraded->value === '1.7') abort(401);
$this->upgrade_database();
// Create legal pages and index content
if ($request->license === 'Extended') {
// Create legal pages and index content for regular license
if (get_setting('license') === 'Regular') {
$pages = collect(config('vuefilemanager.pages'));
$content = collect(config('vuefilemanager.content'));
$pages = collect(config('content.pages'));
$content = collect(config('content.content_regular'));
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$content->each(function ($content) {
Setting::updateOrCreate($content);
});
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
$pages->each(function ($page) {
Page::updateOrCreate($page);
});
}
}
// Store Logo
if ($request->hasFile('logo')) {
$logo = store_system_image($request->file('logo'), 'system');
/*
* Upgrade expire_in in shares table
*
* @since v1.8
*/
if (! Schema::hasTable('traffic') && ! Schema::hasTable('zips') && ! Schema::hasTable('jobs')) {
$this->upgrade_database();
}
/*
* Upgrade expire_in in shares table
*
* @since v1.8
*/
if (! Schema::hasTable('traffic') && ! Schema::hasTable('zips') && ! Schema::hasTable('jobs')) {
$this->upgrade_database();
}
// Store Logo horizontal
if ($request->hasFile('logo_horizontal')) {
$logo_horizontal = store_system_image($request->file('logo_horizontal'), 'system');
/*
* Upgrade expire_in in shares table
*
* @since v1.7.9
*/
if (! Schema::hasColumn('shares', 'expire_in')) {
$this->upgrade_database();
}
// Store favicon
if ($request->hasFile('favicon')) {
$favicon = store_system_image($request->file('favicon'), 'system');
}
/*
* Upgrade expire_in in shares table
*
* @since v1.7.11
*/
if (! Schema::hasColumn('file_manager_files', 'metadata')) {
// Get options
$settings = collect([
[
'name' => 'setup_wizard_database',
'value' => 1,
],
[
'name' => 'setup_wizard_success',
'value' => 1,
],
[
'name' => 'license',
'value' => $request->license,
],
[
'name' => 'purchase_code',
'value' => $request->purchase_code,
],
[
'name' => 'app_title',
'value' => $request->title,
],
[
'name' => 'app_description',
'value' => $request->description,
],
[
'name' => 'app_logo',
'value' => $request->hasFile('logo') ? $logo : null,
],
[
'name' => 'app_logo_horizontal',
'value' => $request->hasFile('logo_horizontal') ? $logo_horizontal : null,
],
[
'name' => 'app_favicon',
'value' => $request->hasFile('favicon') ? $favicon : null,
],
[
'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 ? $request->defaultStorage : 5,
],
[
'name' => 'latest_upgrade',
'value' => '1.7',
],
$this->upgrade_database();
}
}
/**
* @return int|mixed
*/
private function upgrade_database()
{
$command = Artisan::call('migrate', [
'--force' => true
]);
// Store options
$settings->each(function ($col) {
Setting::updateOrCreate(['name' => $col['name']], $col);
});
if ($command === 0) {
echo 'Operation was successful.';
}
return response('Done', 200);
if ($command === 1) {
echo 'Operation failed.';
}
return $command;
}
}

View File

@@ -5,7 +5,10 @@ namespace App\Http\Controllers;
use App\Http\Tools\Demo;
use App\Setting;
use Artisan;
use Stripe;
use Cartalyst\Stripe\Exception\UnauthorizedException;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
class SettingController extends Controller
{
@@ -77,42 +80,77 @@ class SettingController extends Controller
return Demo::response_204();
}
// Get options
$mail = collect([
[
'name' => 'MAIL_DRIVER',
'value' => $request->input('driver'),
],
[
'name' => 'MAIL_HOST',
'value' => $request->input('host'),
],
[
'name' => 'MAIL_PORT',
'value' => $request->input('port'),
],
[
'name' => 'MAIL_USERNAME',
'value' => $request->input('username'),
],
[
'name' => 'MAIL_PASSWORD',
'value' => $request->input('password'),
],
[
'name' => 'MAIL_ENCRYPTION',
'value' => $request->input('encryption'),
],
setEnvironmentValue([
'MAIL_DRIVER' => $request->input('driver'),
'MAIL_HOST' => $request->input('host'),
'MAIL_PORT' => $request->input('port'),
'MAIL_USERNAME' => $request->input('username'),
'MAIL_PASSWORD' => $request->input('password'),
'MAIL_ENCRYPTION' => $request->input('encryption'),
]);
// Store mail options
$mail->each(function ($col) {
setEnvironmentValue($col['name'], $col['value']);
});
// 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)
{
// Get stripe status
$is_stripe = get_setting('payments_configured');
// Check setup status
if ($is_stripe) abort(401, 'Gone');
// Create stripe instance
$stripe = Stripe::make($request->secret, '2020-03-02');
// Try to get stripe account details
try {
$stripe->account()->details();
} catch (UnauthorizedException $e) {
throw new HttpException(401, $e->getMessage());
}
// Get options
$settings = collect([
[
'name' => 'stripe_currency',
'value' => $request->currency,
],
[
'name' => 'payments_configured',
'value' => 1,
],
[
'name' => 'payments_active',
'value' => 1,
],
]);
// Store options
$settings->each(function ($col) {
Setting::updateOrCreate(['name' => $col['name']], $col);
});
// 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');
}
}

View File

@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use App\Http\Requests\Share\AuthenticateShareRequest;
use App\Http\Resources\ShareResource;
use App\Http\Tools\Guardian;
use App\Setting;
use http\Env\Response;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Cookie;
@@ -42,14 +43,14 @@ class FileSharingController extends Controller
Cookie::queue('shared_access_token', '', -1);
// Set cookies
if ($shared->protected) {
if ((int) $shared->protected) {
// Set shared token
Cookie::queue('shared_token', $token, 43200);
}
// Check if shared is image file and then show it
if ($shared->type === 'file' && ! $shared->protected) {
if ($shared->type === 'file' && ! (int) $shared->protected) {
$image = FileManagerFile::where('user_id', $shared->user_id)
->where('type', 'image')
@@ -57,12 +58,20 @@ class FileSharingController extends Controller
->first();
if ($image) {
// Store user download size
User::find($shared->user_id)->record_download((int) $image->getRawOriginal('filesize'));
return $this->show_image($image);
}
}
// Get all settings
$settings = Setting::all();
// Return page index
return view("index");
return view("index")
->with('settings', $settings ? json_decode($settings->pluck('value', 'name')->toJson()) : null);
}
/**
@@ -160,7 +169,7 @@ class FileSharingController extends Controller
$shared = Share::where(DB::raw('BINARY `token`'), $token)->firstOrFail();
// Abort if folder is protected
if ($shared->protected) {
if ((int) $shared->protected) {
abort(403, "Sorry, you don't have permission");
}
@@ -191,7 +200,7 @@ class FileSharingController extends Controller
$shared = Share::where(DB::raw('BINARY `token`'), $token)->firstOrFail();
// Abort if file is protected
if ($shared->protected) {
if ((int) $shared->protected) {
abort(403, "Sorry, you don't have permission");
}
@@ -242,6 +251,7 @@ class FileSharingController extends Controller
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->where('user_id', $shared->user_id)
->sortable()
->get(['id', 'parent_id', 'unique_id', 'name']);
// Return folder tree
@@ -272,6 +282,7 @@ class FileSharingController extends Controller
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->where('user_id', $shared->user_id)
->sortable()
->get(['id', 'parent_id', 'unique_id', 'name']);
// Return folder tree
@@ -341,7 +352,7 @@ class FileSharingController extends Controller
$shared = get_shared($token);
// Abort if folder is protected
if ($shared->protected) {
if ((int) $shared->protected) {
abort(403, "Sorry, you don't have permission");
}
@@ -394,10 +405,12 @@ class FileSharingController extends Controller
{
$folders = FileManagerFolder::where('user_id', $shared->user_id)
->where('parent_id', $unique_id)
->sortable()
->get();
$files = FileManagerFile::where('user_id', $shared->user_id)
->where('folder_id', $unique_id)
->sortable()
->get();
return [$folders, $files];

View File

@@ -107,7 +107,15 @@ class AccountController extends Controller
*/
public function update_user_settings(Request $request)
{
// TODO: validation
// Validate request
$validator = Validator::make($request->all(), [
'name' => 'string',
'value' => 'string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user
$user = Auth::user();

View File

@@ -2,6 +2,7 @@
use App\FileManagerFile;
use App\FileManagerFolder;
use App\User;
use App\Setting;
use App\Share;
use ByteUnits\Metric;
@@ -19,11 +20,11 @@ use Intervention\Image\ImageManagerStatic as Image;
*/
function obfuscate_email($email)
{
$em = explode("@",$email);
$name = implode('@', array_slice($em, 0, count($em)-1));
$len = floor(strlen($name)/2);
$em = explode("@", $email);
$name = implode('@', array_slice($em, 0, count($em) - 1));
$len = floor(strlen($name) / 2);
return substr($name,0, $len) . str_repeat('*', $len) . "@" . end($em);
return substr($name, 0, $len) . str_repeat('*', $len) . "@" . end($em);
}
/**
@@ -160,10 +161,10 @@ function get_storage()
function is_storage_driver($driver)
{
if (is_array($driver)) {
return in_array(config('filesystem.default'), $driver);
return in_array(config('filesystems.default'), $driver);
}
return config('filesystem.default') === $driver;
return config('filesystems.default') === $driver;
}
/**
@@ -355,6 +356,36 @@ function format_gigabytes($gigabytes)
}
}
/**
* Format string to formated megabytes string
*
* @param $megabytes
* @return string
*/
function format_megabytes($megabytes)
{
if ($megabytes >= 1000) {
return $megabytes / 1000 . 'GB';
}
if ($megabytes >= 1000000) {
return $megabytes / 1000000 . 'TB';
}
return $megabytes . 'MB';
}
/**
* Convert megabytes to bytes
*
* @param $megabytes
* @return int|string
*/
function format_bytes($megabytes)
{
return Metric::megabytes($megabytes)->numberOfBytes();
}
/**
* Get storage usage in percent
*
@@ -464,10 +495,10 @@ function format_date($date, $format = '%d. %B. %Y, %H:%M')
* @param $file
* @return string
*/
function get_file_type($file)
function get_file_type($file_mimetype)
{
// Get mimetype from file
$mimetype = explode('/', $file->getMimeType());
$mimetype = explode('/', $file_mimetype);
switch ($mimetype[0]) {
case 'image':
@@ -482,4 +513,292 @@ function get_file_type($file)
default:
return 'file';
}
}
}
/**
* Get file type from mimetype
*
* @param $mimetype
* @return mixed
*/
function get_file_type_from_mimetype($mimetype)
{
return explode('/', $mimetype)[1];
}
/**
* Format pretty name file
*
* @param $basename
* @param $name
* @param $mimetype
* @return string
*/
function get_pretty_name($basename, $name, $mimetype)
{
$file_extension = substr(strrchr($basename, '.'), 1);
if (strpos($name, $file_extension) !== false) {
return $name;
}
if ($file_extension) {
return $name . '.' . $file_extension;
}
return $name . '.' . $mimetype;
}
/**
* Get exif data from jpeg image
*
* @param $file
* @return array
*/
function get_image_meta_data($file)
{
if (get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') {
try {
// Try to get the exif data
return mb_convert_encoding(Image::make($file->getRealPath())->exif(),'UTF8', 'UTF8');
} catch ( \Exception $e) {
return null;
}
}
}
/**
* Check if app is in dev mode
*
* @return bool
*/
function is_dev()
{
return env('APP_ENV') === 'local' ? true : false;
}
/**
* @param $str
* @return bool
*/
function seems_utf8($str)
{
$length = strlen($str);
for ($i=0; $i < $length; $i++) {
$c = ord($str[$i]);
if ($c < 0x80) $n = 0; # 0bbbbbbb
elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
else return false; # Does not match any model
for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
return false;
}
}
return true;
}
/**
* Converts all accent characters to ASCII characters.
*
* If there are no accent characters, then the string given is just returned.
*
* @param string $string Text that might have accent characters
* @return string Filtered string with replaced "nice" characters.
*/
function remove_accents($string) {
if ( !preg_match('/[\x80-\xff]/', $string) )
return $string;
if (seems_utf8($string)) {
$chars = array(
// Decompositions for Latin-1 Supplement
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
chr(195).chr(191) => 'y',
// Decompositions for Latin Extended-A
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
// Euro Sign
chr(226).chr(130).chr(172) => 'E',
// GBP (Pound) Sign
chr(194).chr(163) => '');
$string = strtr($string, $chars);
} else {
// Assume ISO-8859-1 if not UTF-8
$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
.chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
.chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
.chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
.chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
.chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
.chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
.chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
.chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
.chr(252).chr(253).chr(255);
$chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
$string = strtr($string, $chars['in'], $chars['out']);
$double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
$double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
$string = str_replace($double_chars['in'], $double_chars['out'], $string);
}
return $string;
}
/**
* Get all files from folder and get their folder location in VueFileManager directories
*
* @param $folders
* @param null $files
* @param array $path
* @return array
*/
function get_files_for_zip($folders, $files, $path = [])
{
// Return file list
if (!isset($folders->folders)) {
return $files->unique()->values()->all();
}
// Push file path
array_push($path, $folders->name);
// Push file to collection
$folders->files->each(function ($file) use ($files, $path) {
$files->push([
'name' => $file->name,
'basename' => $file->basename,
'folder_path' => implode('/', $path),
]);
});
// Get all children folders and folders within
if ($folders->folders->isNotEmpty()) {
$folders->folders->map(function ($folder) use ($files, $path) {
return get_files_for_zip($folder, $files, $path);
});
}
return get_files_for_zip($folders->folders->first(), $files, $path);
}
/**
* Set time by user timezone GMT
*
* @param $time
* @return int
*/
function set_time_by_user_timezone($time)
{
$user = Auth::user();
if($user) {
// Get the value of timezone if user have some
$time_zone = intval($user->settings->timezone * 60 ?? null);
return Carbon::parse($time)->addMinutes($time_zone ?? null);
}
return Carbon::parse($time);
}

View File

@@ -12,6 +12,8 @@ class CheckForMaintenanceMode extends Middleware
* @var array
*/
protected $except = [
//
'/service/upgrade-database',
'/service/down',
'/service/up',
];
}

View File

@@ -24,7 +24,7 @@ class DeleteUserRequest extends FormRequest
public function rules()
{
return [
'name' => 'required|string|max:255',
'data.name' => 'required|string|max:255',
];
}
}

View File

@@ -25,8 +25,9 @@ class DeleteItemRequest extends FormRequest
public function rules()
{
return [
'type' => 'required|string',
'force_delete' => 'required|boolean',
'data[*].force_delete' => 'required|boolean',
'data[*].type' => 'required|string',
'data[*].unique_id' => 'required|integer'
];
}
}

View File

@@ -25,8 +25,9 @@ class MoveItemRequest extends FormRequest
public function rules()
{
return [
'to_unique_id' => 'required|integer',
'from_type' => 'required|string',
'to_unique_id' => 'required|integer',
'items[*].type' => 'required|string',
'items[*].unique_id' => 'required|integer',
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Http\Requests\FileFunctions;
use App\Rules\MimetypeBlacklistValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
@@ -26,7 +27,7 @@ class UploadRequest extends FormRequest
{
return [
'parent_id' => 'required|integer',
'file' => 'required|file',
'file' => ['required','file' , new MimetypeBlacklistValidation]
];
}
}

View File

@@ -28,8 +28,10 @@ class CreateShareRequest extends FormRequest
'isPassword' => 'required|boolean',
'unique_id' => 'required|integer',
'type' => 'required|string',
'expiration' => 'integer|nullable',
'permission' => 'string',
'password' => 'string',
'emails.*' => 'email'
];
}
}

View File

@@ -27,6 +27,7 @@ class UpdateShareRequest extends FormRequest
return [
'protected' => 'required|boolean',
'permission' => 'nullable|string',
'expiration' => 'integer|nullable',
'password' => 'string',
];
}

View File

@@ -46,7 +46,7 @@ class StoreUpgradeAccountRequest extends FormRequest
'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' => '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',

View File

@@ -20,8 +20,9 @@ class ShareResource extends JsonResource
'type' => 'shares',
'attributes' => [
'permission' => $this->permission,
'protected' => $this->protected,
'item_id' => $this->item_id,
'protected' => (int) $this->protected,
'item_id' => (int) $this->item_id,
'expire_in' => (int) $this->expire_in,
'token' => $this->token,
'link' => $this->link,
'type' => $this->type,

View File

@@ -23,17 +23,17 @@ class UserResource extends JsonResource
'id' => (string)$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,
'name' => $this->name,
'email' => env('APP_DEMO') ? obfuscate_email($this->email) : $this->email,
'avatar' => $this->avatar,
'role' => $this->role,
'created_at_formatted' => format_date($this->created_at, '%d. %B. %Y'),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'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,
'name' => $this->name,
'email' => env('APP_DEMO') ? obfuscate_email($this->email) : $this->email,
'avatar' => $this->avatar,
'role' => $this->role,
'created_at_formatted' => format_date($this->created_at, '%d. %B. %Y'),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
],
'relationships' => [
@@ -76,7 +76,16 @@ class UserResource extends JsonResource
'folders' => $this->folder_tree
],
],
]
],
'timezone' => [
'data' => [
'id' => '1',
'type' => 'timezone',
'attributes' => [
'timezone' =>$this->settings->timezone
],
]
],
]
];
}

View File

@@ -102,7 +102,7 @@ class Demo
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$thumbnail = null;
$filesize = $file->getSize();
$filetype = get_file_type($file);
$filetype = get_file_type($file->getMimeType());
return [
'id' => random_int(1000, 9999),

View File

@@ -8,15 +8,210 @@ use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\User;
use App\Zip;
use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
use League\Flysystem\FileNotFoundException;
use Madnest\Madzipper\Facades\Madzipper;
use Symfony\Component\HttpKernel\Exception\HttpException;
class Editor
{
/**
* Store folder icon
*
* @param $folder_icon
* @param $unique_id
* @param $shared
*/
public static function set_folder_icon($folder_icon, $unique_id, $shared = null)
{
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Get folder
$folder = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
// Set default folder icon
if ($folder_icon === 'default') {
$folder->icon_emoji = null;
$folder->icon_color = null;
}
// If request have emoji set folder icon emoji
if (isset($folder_icon['emoji'])) {
$folder->icon_emoji = $folder_icon['emoji'];
$folder->icon_color = null;
}
// If request have color set folder icon color
if (isset($folder_icon['color'])) {
$folder->icon_emoji = null;
$folder->icon_color = $folder_icon['color'];
}
// Save changes
$folder->save();
}
/**
* Zip requested folder
*
* @param $unique_id
* @param $shared
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public static function zip_folder($unique_id, $shared = null)
{
// Get folder
$requested_folder = FileManagerFolder::with(['folders.files', 'files'])
->where('unique_id', $unique_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');
// Create zip directory
if (!$disk_local->exists('zip')) {
$disk_local->makeDirectory('zip');
}
// Move file to local storage
if (!is_storage_driver('local')) {
// Create temp directory
if (!$disk_local->exists('temp')) {
$disk_local->makeDirectory('temp');
}
foreach ($files as $file) {
try {
$disk_local->put('temp/' . $file['basename'], Storage::get('file-manager/' . $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';
$zip_path = 'zip/' . $zip_name;
// Create zip
$zip = Madzipper::make(storage_path() . '/app/' . $zip_path);
// Get files folder on local storage drive
$files_folder = is_storage_driver('local') ? 'file-manager' : 'temp';
// Add files to zip
foreach ($files as $file) {
$zip->folder($file['folder_path'])->addString($file['name'], File::get(storage_path() . '/app/' . $files_folder . '/' . $file['basename']));
}
// 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 static function zip_files($files, $shared = null)
{
// Local storage instance
$disk_local = Storage::disk('local');
// Create zip directory
if (!$disk_local->exists('zip')) {
$disk_local->makeDirectory('zip');
}
// Move file to local storage from external storage service
if (!is_storage_driver('local')) {
// Create temp directory
if (!$disk_local->exists('temp')) {
$disk_local->makeDirectory('temp');
}
foreach ($files as $file) {
try {
$disk_local->put('temp/' . $file['basename'], Storage::get('file-manager/' . $file['basename']));
} catch (FileNotFoundException $e) {
throw new HttpException(404, 'File not found');
}
}
}
// Get zip path
$zip_name = Str::random(16) . '.zip';
$zip_path = 'zip/' . $zip_name;
// Create zip
$zip = Madzipper::make(storage_path() . '/app/' . $zip_path);
// Get files folder on local storage drive
$files_directory = is_storage_driver('local') ? 'file-manager' : 'temp';
// Add files to zip
$files->each(function ($file) use ($zip, $files_directory) {
$zip->addString($file['name'] . '.' . $file['mimetype'], File::get(storage_path() . '/app/' . $files_directory . '/' . $file['basename']));
});
// 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
*
@@ -30,11 +225,12 @@ class Editor
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$name = $request->has('name') ? $request->input('name') : 'New Folder';
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
$unique_id = get_unique_id();
// Create folder
$folder = FileManagerFolder::create([
'parent_id' => $request->parent_id,
'unique_id' => get_unique_id(),
'unique_id' => $unique_id,
'user_scope' => $user_scope,
'user_id' => $user_id,
'type' => 'folder',
@@ -79,13 +275,13 @@ class Editor
* @param null $shared
* @throws \Exception
*/
public static function delete_item($request, $unique_id, $shared = null)
public static function delete_item($file, $unique_id, $shared = null)
{
// Get user id
$user = is_null($shared) ? Auth::user() : User::findOrFail($shared->user_id);
// Delete folder
if ($request->type === 'folder') {
if ($file['type'] === 'folder') {
// Get folder
$folder = FileManagerFolder::withTrashed()
@@ -106,7 +302,7 @@ class Editor
}
// Force delete children files
if ($request->force_delete) {
if ($file['force_delete']) {
// Get children folder ids
$child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id');
@@ -135,7 +331,7 @@ class Editor
}
// Soft delete items
if (!$request->force_delete) {
if (!$file['force_delete']) {
// Remove folder from user favourites
$user->favourite_folders()->detach($unique_id);
@@ -146,10 +342,10 @@ class Editor
}
// Delete item
if ($request->type !== 'folder') {
if ($file['type'] !== 'folder') {
// Get file
$file = FileManagerFile::withTrashed()
$item = FileManagerFile::withTrashed()
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
@@ -166,23 +362,63 @@ class Editor
}
// Force delete file
if ($request->force_delete) {
if ($file['force_delete']) {
// Delete file
Storage::delete('/file-manager/' . $file->basename);
Storage::delete('/file-manager/' . $item->basename);
// Delete thumbnail if exist
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getRawOriginal('thumbnail'));
if ($item->thumbnail) Storage::delete('/file-manager/' . $item->getRawOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
$item->forceDelete();
}
// Soft delete file
if (!$request->force_delete) {
if (!$file['force_delete']) {
// Soft delete file
$file->delete();
$item->delete();
}
}
}
/**
* Move folder or file to new location
*
* @param $request
* @param $unique_id
* @param null $shared
*/
public static function move($request, $to_unique_id, $shared = null)
{
// Get user id
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
foreach ($request->input('items') as $item) {
$unique_id = $item['unique_id'];
if ($item['type'] === 'folder') {
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'parent_id' => $to_unique_id
]);
} else {
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'folder_id' => $to_unique_id
]);
}
}
}
@@ -198,110 +434,275 @@ class Editor
public static function upload($request, $shared = null)
{
// Get parent_id from request
$folder_id = $request->parent_id === 0 ? 0 : $request->parent_id;
$file = $request->file('file');
// Get user data
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
$user_storage_used = user_storage_percentage($user_id, $file->getSize());
// Check or create directories
self::check_directories(['chunks', 'file-manager']);
// Get storage limitation setup
$storage_limitation = get_setting('storage_limitation');
// File name
$user_file_name = basename('chunks/' . substr($file->getClientOriginalName(), 17), '.part');
$disk_file_name = basename('chunks/' . $file->getClientOriginalName(), '.part');
$temp_filename = $file->getClientOriginalName();
// Check if user can upload
if ($storage_limitation && $user_storage_used >= 100) {
abort(423, 'You exceed your storage limit!');
// File Path
$file_path = config('filesystems.disks.local.root') . '/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');
$unique_id = get_unique_id();
// Get user data
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$user_id = is_null($shared) ? Auth::id() : $shared->user_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
self::check_user_storage_capacity($user_id, $file_size, $temp_filename);
// Create thumbnail
$thumbnail = self::get_image_thumbnail('chunks/' . $temp_filename, $disk_file_name);
// Move finished file from chunk to file-manager directory
$disk_local->move('chunks/' . $temp_filename, 'file-manager/' . $disk_file_name);
// Move files to external storage
if (!is_storage_driver(['local'])) {
// Clear failed uploads if exists
self::clear_failed_files();
// Move file to external storage service
self::move_to_external_storage($disk_file_name, $thumbnail);
}
// Store file
$options = [
'mimetype' => get_file_type_from_mimetype($file_mimetype),
'type' => get_file_type($file_mimetype),
'folder_id' => $request->parent_id,
'metadata' => $metadata,
'name' => $user_file_name,
'unique_id' => $unique_id,
'basename' => $disk_file_name,
'user_scope' => $user_scope,
'thumbnail' => $thumbnail,
'filesize' => $file_size,
'user_id' => $user_id,
];
// Store user upload size
if ($request->user()) {
// If upload a loged user
$request->user()->record_upload($file_size);
} else {
// If upload guest
User::find($shared->user_id)->record_upload($file_size);
}
// Return new file
return FileManagerFile::create($options);
}
}
// File
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$filetype = get_file_type($file);
$filesize = $file->getSize();
$directory = 'file-manager';
$thumbnail = null;
/**
* Clear failed files
*/
private static function clear_failed_files()
{
$local_disk = Storage::disk('local');
// create directory if not exist
if (!Storage::exists($directory)) {
Storage::makeDirectory($directory);
// Get all files from storage
$files = collect([
$local_disk->allFiles('file-manager'),
$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(Carbon::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);
}
});
}
/**
* Move file to external storage if is set
*
* @param string $filename
* @param string|null $thumbnail
*/
private static function move_to_external_storage(string $filename, ?string $thumbnail): void
{
$disk_local = Storage::disk('local');
foreach ([$filename, $thumbnail] as $file) {
// Check if file exist
if (!$file) continue;
// Get file size
$filesize = $disk_local->size('file-manager/' . $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.
$uploader = new MultipartUploader($client, config('filesystems.disks.local.root') . '/file-manager/' . $file, [
'bucket' => $adapter->getBucket(),
'key' => 'file-manager/' . $file
]);
try {
// Upload content
$uploader->upload();
} catch (MultipartUploadException $e) {
// Write error log
Log::error($e->getMessage());
// Delete file after error
$disk_local->delete('file-manager/' . $file);
throw new HttpException(409, $e->getMessage());
}
} else {
// Stream file object to s3
Storage::putFileAs('file-manager', config('filesystems.disks.local.root') . '/file-manager/' . $file, $file, 'private');
}
// Delete file after upload
$disk_local->delete('file-manager/' . $file);
}
}
// Store to disk
Storage::putFileAs($directory, $file, $filename, 'private');
/**
* Check if directories 'chunks' and 'file-manager exist', if no, then create
*
* @param $directories
*/
private static function check_directories($directories): void
{
foreach ($directories as $directory) {
// Create image thumbnail
if (in_array($file->getMimeType(), ['image/gif', 'image/jpeg', 'image/jpg', 'image/png', 'image/webp'])) {
if (!Storage::disk('local')->exists($directory)) {
Storage::disk('local')->makeDirectory($directory);
}
if (!is_storage_driver(['local'])) {
if (!Storage::exists($directory)) {
Storage::makeDirectory($directory);
}
}
}
}
/**
* Create thumbnail for images
*
* @param string $file_path
* @param string $filename
* @param $file
* @return string|null
*/
private static function get_image_thumbnail(string $file_path, string $filename)
{
$local_disk = Storage::disk('local');
// Create thumbnail from image
if (in_array($local_disk->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($file->getRealPath())->orientate();
$image = Image::make(config('filesystems.disks.local.root') . '/' . $file_path)->orientate();
// Resize image
$image->resize(564, null, function ($constraint) {
$image->resize(512, null, function ($constraint) {
$constraint->aspectRatio();
})->stream();
// Store thumbnail to disk
Storage::put($directory . '/' . $thumbnail, $image);
$local_disk->put('file-manager/' . $thumbnail, $image);
}
} elseif ($file->getMimeType() == 'image/svg+xml') {
// Return thumbnail as svg file
if ($local_disk->mimeType($file_path) === 'image/svg+xml') {
$thumbnail = $filename;
}
// Store file
$options = [
'name' => pathinfo($file->getClientOriginalName())['filename'],
'mimetype' => $file->getClientOriginalExtension(),
'unique_id' => get_unique_id(),
'user_scope' => $user_scope,
'folder_id' => $folder_id,
'thumbnail' => $thumbnail,
'basename' => $filename,
'filesize' => $filesize,
'type' => $filetype,
'user_id' => $user_id,
];
// Return new file
return FileManagerFile::create($options);
return $thumbnail ?? null;
}
/**
* Move folder or file to new location
* Check if user has enough space to upload file
*
* @param $request
* @param $unique_id
* @param null $shared
* @param $user_id
* @param int $file_size
* @param $temp_filename
*/
public static function move($request, $unique_id, $shared = null)
private static function check_user_storage_capacity($user_id, int $file_size, $temp_filename): void
{
// Get user id
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Get user storage percentage and get storage_limitation setting
$user_storage_used = user_storage_percentage($user_id, $file_size);
$storage_limitation = get_setting('storage_limitation');
if ($request->from_type === 'folder') {
// Check if user can upload
if ($storage_limitation && $user_storage_used >= 100) {
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
// Delete file
Storage::disk('local')->delete('chunks/' . $temp_filename);
$item->update([
'parent_id' => $request->to_unique_id
]);
} else {
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'folder_id' => $request->to_unique_id
]);
// Abort uploading
abort(423, 'You exceed your storage limit!');
}
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Auth;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class SharedSendViaEmail extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* @param $token
*/
public function __construct($token)
{
$this->token = $token;
$this->user = Auth::user();
}
/**
* 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)
{
return (new MailMessage)
->subject(__('vuefilemanager.shared_link_email_subject' , ['user' => $this->user->name]))
->greeting(__('vuefilemanager.shared_link_email_greeting'))
->line(__('vuefilemanager.shared_link_email_user', ['user' => $this->user->name, 'email' => $this->user->email]))
->action(__('vuefilemanager.shared_link_email_link'), url('/shared', ['token' => $this->token]));
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

View File

@@ -3,9 +3,42 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Kyslik\ColumnSortable\Sortable;
/**
* App\Page
*
* @property int $id
* @property int $visibility
* @property string $title
* @property string $slug
* @property string $content
* @method static \Illuminate\Database\Eloquent\Builder|Page newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Page newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Page query()
* @method static \Illuminate\Database\Eloquent\Builder|Page sortable($defaultParameters = null)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereContent($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|Page whereVisibility($value)
* @mixin \Eloquent
*/
class Page extends Model
{
use Sortable;
/**
* Sortable columns
*
* @var string[]
*/
public $sortable = [
'title',
'slug',
'visibility',
];
public $timestamps = false;
protected $guarded = ['id'];

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class MimetypeBlacklistValidation implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
$mimetype_blacklist = explode(',' ,get_setting('mimetypes_blacklist'));
$file_mimetype = explode('/' ,$value->getMimeType());
return !array_intersect($file_mimetype , $mimetype_blacklist);
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
abort (415,'Type of this mime type is not allowed.');
}
}

View File

@@ -202,7 +202,7 @@ class StripeService
$product = $this->stripe->products()->find($plan['product']);
// Push data to $plan container
if ($product['active']) {
if ($product['active'] && isset($product['metadata']['capacity'])) {
array_push($plans, [
'plan' => $plan,
'product' => $product,
@@ -234,7 +234,7 @@ class StripeService
$product = $this->stripe->products()->find($plan['product']);
// Push data to $plan container
if ($product['active']) {
if ($product['active'] && isset($product['metadata']['capacity'])) {
array_push($plans, [
'plan' => $plan,
'product' => $product,
@@ -380,6 +380,8 @@ class StripeService
*/
public function getInvoices()
{
return $this->stripe->invoices()->all();
return $this->stripe->invoices()->all([
'limit' => 20
]);
}
}

View File

@@ -4,6 +4,20 @@ namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* App\Setting
*
* @property int $id
* @property string $name
* @property string|null $value
* @method static \Illuminate\Database\Eloquent\Builder|Setting newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Setting newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Setting query()
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereValue($value)
* @mixin \Eloquent
*/
class Setting extends Model
{
public $timestamps = false;

View File

@@ -3,6 +3,8 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Notifications\SharedSendViaEmail;
use Illuminate\Notifications\Notifiable;
/**
* App\Share
@@ -32,9 +34,13 @@ use Illuminate\Database\Eloquent\Model;
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereUserId($value)
* @mixin \Eloquent
* @property int|null $expire_in
* @method static \Illuminate\Database\Eloquent\Builder|Share whereExpireIn($value)
*/
class Share extends Model
{
use Notifiable;
protected $guarded = ['id'];
protected $appends = ['link'];
@@ -44,8 +50,8 @@ class Share extends Model
*
* @return string
*/
public function getLinkAttribute() {
public function getLinkAttribute()
{
return url('/shared', ['token' => $this->attributes['token']]);
}
}

30
app/Traffic.php Normal file
View File

@@ -0,0 +1,30 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* App\Traffic
*
* @property int $id
* @property int $user_id
* @property int $upload
* @property int $download
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|Traffic newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Traffic newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Traffic query()
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereDownload($value)
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereUpload($value)
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereUserId($value)
* @mixin \Eloquent
*/
class Traffic extends Model
{
protected $fillable = ['user_id', 'upload', 'download'];
}

View File

@@ -5,14 +5,13 @@ namespace App;
use App\Notifications\ResetPassword;
use App\Notifications\ResetUserPasswordNotification;
use ByteUnits\Metric;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;
use Laravel\Cashier\Billable;
use Laravel\Passport\HasApiTokens;
use Kyslik\ColumnSortable\Sortable;
use Rinvex\Subscriptions\Traits\HasSubscriptions;
/**
@@ -75,10 +74,11 @@ use Rinvex\Subscriptions\Traits\HasSubscriptions;
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereRole($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereStripeId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereTrialEndsAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User sortable($defaultParameters = null)
*/
class User extends Authenticatable
{
use HasApiTokens, Notifiable, Billable;
use HasApiTokens, Notifiable, Billable, Sortable;
protected $guarded = ['id', 'role'];
@@ -113,6 +113,19 @@ class User extends Authenticatable
'used_capacity', 'storage'
];
/**
* Sortable columns
*
* @var string[]
*/
public $sortable = [
'id',
'name',
'role',
'created_at',
'storage_capacity',
];
/**
* Get tax rate id for user
*
@@ -145,10 +158,10 @@ class User extends Authenticatable
$is_storage_limit = $storage_limitation ? $storage_limitation : 1;
// Get user storage usage
if (! $is_storage_limit) {
if (!$is_storage_limit) {
return [
'used' => $this->used_capacity,
'used' => $this->used_capacity,
'used_formatted' => Metric::bytes($this->used_capacity)->format(),
];
}
@@ -182,9 +195,12 @@ class User extends Authenticatable
*/
public function getFolderTreeAttribute()
{
return FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected'])
// Get sorting setup
return FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('parent_id', 0)
->where('user_id', $this->id)
->sortable()
->get();
}
@@ -197,7 +213,6 @@ class User extends Authenticatable
{
// Get avatar from external storage
if ($this->attributes['avatar'] && is_storage_driver(['s3', 'spaces', 'wasabi', 'backblaze'])) {
return Storage::temporaryUrl($this->attributes['avatar'], now()->addDay());
}
@@ -241,6 +256,46 @@ class User extends Authenticatable
$this->notify(new ResetPassword($token));
}
/**
* Record user upload filesize
*
* @param $file_size
*/
public function record_upload($file_size)
{
$now = Carbon::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 = Carbon::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
*
@@ -248,7 +303,7 @@ class User extends Authenticatable
*/
public function favourite_folders()
{
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected');
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected,expire_in');
}
/**
@@ -258,7 +313,7 @@ class User extends Authenticatable
*/
public function latest_uploads()
{
return $this->hasMany(FileManagerFile::class)->with(['parent'])->orderBy('created_at', 'DESC')->take(40);
return $this->hasMany(FileManagerFile::class)->with(['parent'])->take(40);
}
/**

View File

@@ -4,6 +4,34 @@ namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* App\UserSettings
*
* @property int $id
* @property int $user_id
* @property int $storage_capacity
* @property string|null $billing_name
* @property string|null $billing_address
* @property string|null $billing_state
* @property string|null $billing_city
* @property string|null $billing_postal_code
* @property string|null $billing_country
* @property string|null $billing_phone_number
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings query()
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingAddress($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingCity($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingCountry($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingName($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingPhoneNumber($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingPostalCode($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingState($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereStorageCapacity($value)
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereUserId($value)
* @mixin \Eloquent
*/
class UserSettings extends Model
{
public $timestamps = false;

27
app/Zip.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Zip extends Model
{
protected $guarded = ['id'];
public $incrementing = false;
protected $keyType = 'string';
/**
* Generate uuid
*/
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->id = (string)Str::uuid();
});
}
}

View File

@@ -15,6 +15,8 @@
"fruitcake/laravel-cors": "^1.0",
"gabrielelana/byte-units": "^0.5.0",
"intervention/image": "^2.5",
"jaybizzle/laravel-crawler-detect": "^1.2",
"kyslik/column-sortable": "^6.3",
"laravel/cashier": "^12.0",
"laravel/framework": "^7.0",
"laravel/passport": "^8.4",
@@ -23,6 +25,7 @@
"laravel/ui": "^2.0",
"league/flysystem-aws-s3-v3": "^1.0",
"league/flysystem-cached-adapter": "^1.0",
"madnest/madzipper": "^1.1",
"teamtnt/laravel-scout-tntsearch-driver": "^8.3"
},
"require-dev": {

1589
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -165,6 +165,7 @@ return [
TeamTNT\Scout\TNTSearchScoutServiceProvider::class,
Intervention\Image\ImageServiceProvider::class,
Laravel\Passport\PassportServiceProvider::class,
Madnest\Madzipper\MadzipperServiceProvider::class,
/*
* Package Service Providers...
@@ -231,6 +232,8 @@ return [
'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,
],
'deploy_secret' => env('APP_DEPLOY_SECRET'),

172
config/content.php Normal file
View File

@@ -0,0 +1,172 @@
<?php
return [
'pages' => [
[
'visibility' => 0,
'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' => 0,
'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' => 0,
'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' => 0,
],
[
'name' => 'section_feature_boxes',
'value' => 0,
],
[
'name' => 'section_get_started',
'value' => 0,
],
[
'name' => 'header_title',
'value' => 'Simple <span style="color: #41B883">&</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 style="color: #41B883">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 style="color: #41B883">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,
],
],
'content_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 style="color: #41B883">&</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 style="color: #41B883">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 style="color: #41B883;">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 style="color: #41B883">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>',
],
],
];

View File

@@ -41,7 +41,7 @@ return [
|
*/
'queue' => env('SCOUT_QUEUE', false),
'queue' => env('SCOUT_QUEUE', true),
/*
|--------------------------------------------------------------------------

View File

@@ -2,105 +2,8 @@
return [
'version' => '1.7',
'version' => '1.8.2',
'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.',
],
[
'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.',
],
[
'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.',
],
],
'content' => [
[
'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 style="color: #41B883">&</span> Powerfull Personal Cloud Storage',
],
[
'name' => 'header_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
],
[
'name' => 'features_title',
'value' => 'The Fastest Growing <span style="color: #41B883">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. Trully 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 style="color: #41B883;">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. Trully freedom.',
],
[
'name' => 'get_started_title',
'value' => 'Ready to Get <span style="color: #41B883">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. Trully freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2020 Simple & Powerfull Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
],
],
];
// Define size of chunk uploaded by MB. E.g. integer 128 means chunk size will be 128MB.
'chunk_size' => env('CHUNK_SIZE', '128'),
];

View File

@@ -0,0 +1,20 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\FileManagerFile;
use Faker\Generator as Faker;
use Illuminate\Support\Carbon;
$factory->define(FileManagerFile::class, function (Faker $faker) {
return [
'unique_id' => $faker->randomDigit,
'user_id' => 0,
'folder_id' => 0,
'name' => $faker->firstName,
'basename' => $faker->lastName,
'user_scope' => 'master',
'updated_at' => Carbon::now(),
'created_at' => Carbon::now()
];
});

View File

@@ -0,0 +1,17 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\FileManagerFolder;
use Faker\Generator as Faker;
$factory->define(FileManagerFolder::class, function (Faker $faker) {
return [
'id' => $faker->randomDigit,
'unique_id' => $faker->randomDigit,
'user_id' => 1,
'parent_id' => 0,
'name' => $faker->sentence,
'type' => 'folder',
];
});

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddExpirationAtAttributeToSharesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('shares', function (Blueprint $table) {
$table->integer('expire_in')->after('password')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('shares', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddExifDataToFileManagerFilesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('file_manager_files', function (Blueprint $table) {
$table->longText('metadata')->after('type')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('file_manager_files', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTrafficTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('traffic', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id');
$table->bigInteger('upload')->default(0);
$table->bigInteger('download')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('traffic');
}
}

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateJobsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue')->index();
$table->longText('payload');
$table->unsignedTinyInteger('attempts');
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('jobs');
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateZipsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('zips', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->bigInteger('user_id');
$table->string('shared_token')->nullable();
$table->text('basename');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('zips');
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddTimezoneToUserSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('user_settings', function (Blueprint $table) {
$table->decimal('timezone', 10, 1)->after('billing_phone_number')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('user_settings', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddFolderIconOptionsToFileManagerFoldersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('file_manager_folders', function (Blueprint $table) {
$table->string('icon_color')->after('user_scope')->nullable();
$table->string('icon_emoji')->after('icon_color')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('file_manager_folders', function (Blueprint $table) {
//
});
}
}

View File

@@ -31,11 +31,11 @@ class ContentSeeder extends Seeder
],
[
'name' => 'header_title',
'value' => 'Simple <span style="color: #41B883">&</span> Powerfull Personal Cloud Storage',
'value' => 'Simple <span style="color: #41B883">&</span> Powerful Personal Cloud Storage',
],
[
'name' => 'header_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'features_title',
@@ -43,7 +43,7 @@ class ContentSeeder extends Seeder
],
[
'name' => 'features_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'feature_title_1',
@@ -75,7 +75,7 @@ class ContentSeeder extends Seeder
],
[
'name' => 'pricing_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'get_started_title',
@@ -83,11 +83,11 @@ class ContentSeeder extends Seeder
],
[
'name' => 'get_started_description',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Trully freedom.',
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
],
[
'name' => 'footer_content',
'value' => '© 2020 Simple & Powerfull Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
'value' => '© 2020 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
],
]);

70
env.testing Normal file
View File

@@ -0,0 +1,70 @@
APP_NAME=vueFileManager
APP_ENV=local
APP_KEY=base64:v+s0R2C5q8jYySj3uwrKA8KH8c9JBIZTdXqB2ytk4j8=
APP_DEBUG=true
APP_URL=http://localhost
APP_DEMO=false
LOG_CHANNEL=stack
DB_CONNECTION=sqlite
DB_HOST=null
DB_PORT=null
DB_DATABASE=database/database.sqlite
DB_USERNAME=null
DB_PASSWORD=null
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=sty
MAIL_PORT=3254
MAIL_USERNAME=Milos
MAIL_PASSWORD=milos123
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="${MAIL_USERNAME}"
MAIL_FROM_NAME="${MAIL_USERNAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=
AWS_BUCKET=
DO_SPACES_KEY=
DO_SPACES_SECRET=
DO_SPACES_ENDPOINT=
DO_SPACES_REGION=
DO_SPACES_BUCKET=
WASABI_KEY=
WASABI_SECRET=
WASABI_ENDPOINT=
WASABI_REGION=
WASABI_BUCKET=
BACKBLAZE_KEY=
BACKBLAZE_SECRET=
BACKBLAZE_ENDPOINT=
BACKBLAZE_REGION=
BACKBLAZE_BUCKET=
PASSPORT_CLIENT_ID=1
PASSPORT_CLIENT_SECRET=TqSdKJUbCbC7g5To3Clriw9BMblef0nIdEaI81Q5
APP_DEPLOY_SECRET=
CASHIER_LOGGER=stack
CASHIER_CURRENCY=
STRIPE_KEY=
STRIPE_SECRET=
STRIPE_WEBHOOK_SECRET=
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment

432
package-lock.json generated
View File

@@ -952,24 +952,24 @@
}
},
"@fortawesome/fontawesome-common-types": {
"version": "0.2.29",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.29.tgz",
"integrity": "sha512-cY+QfDTbZ7XVxzx7jxbC98Oxr/zc7R2QpTLqTxqlfyXDrAJjzi/xUIqAUsygELB62JIrbsWxtSRhayKFkGI7MA=="
"version": "0.2.30",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.30.tgz",
"integrity": "sha512-TsRwpTuKwFNiPhk1UfKgw7zNPeV5RhNp2Uw3pws+9gDAkPGKrtjR1y2lI3SYn7+YzyfuNknflpBA1LRKjt7hMg=="
},
"@fortawesome/fontawesome-svg-core": {
"version": "1.2.29",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.29.tgz",
"integrity": "sha512-xmPmP2t8qrdo8RyKihTkGb09RnZoc+7HFBCnr0/6ZhStdGDSLeEd7ajV181+2W29NWIFfylO13rU+s3fpy3cnA==",
"version": "1.2.30",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.30.tgz",
"integrity": "sha512-E3sAXATKCSVnT17HYmZjjbcmwihrNOCkoU7dVMlasrcwiJAHxSKeZ+4WN5O+ElgO/FaYgJmASl8p9N7/B/RttA==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.29"
"@fortawesome/fontawesome-common-types": "^0.2.30"
}
},
"@fortawesome/free-solid-svg-icons": {
"version": "5.13.1",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.1.tgz",
"integrity": "sha512-LQH/0L1p4+rqtoSHa9qFYR84hpuRZKqaQ41cfBQx8b68p21zoWSekTAeA54I/2x9VlCHDLFlG74Nmdg4iTPQOg==",
"version": "5.14.0",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.14.0.tgz",
"integrity": "sha512-M933RDM8cecaKMWDSk3FRYdnzWGW7kBBlGNGfvqLVwcwhUPNj9gcw+xZMrqBdRqxnSXdl3zWzTCNNGEtFUq67Q==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.29"
"@fortawesome/fontawesome-common-types": "^0.2.30"
}
},
"@fortawesome/vue-fontawesome": {
@@ -993,23 +993,22 @@
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
"dev": true
},
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
"dev": true
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
"integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
"dev": true,
"requires": {
"@types/events": "*",
"@types/minimatch": "*",
"@types/node": "*"
}
},
"@types/json-schema": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
"dev": true
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -1017,9 +1016,9 @@
"dev": true
},
"@types/node": {
"version": "13.11.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.0.tgz",
"integrity": "sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ==",
"version": "14.0.27",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz",
"integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==",
"dev": true
},
"@types/q": {
@@ -3323,9 +3322,9 @@
"dev": true
},
"elliptic": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
"integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
"dev": true,
"requires": {
"bn.js": "^4.4.0",
@@ -3513,9 +3512,9 @@
"dev": true
},
"eventemitter3": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz",
"integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
"integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
"dev": true
},
"events": {
@@ -5065,9 +5064,9 @@
"dev": true
},
"html-entities": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
"integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz",
"integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==",
"dev": true
},
"html-loader": {
@@ -5125,16 +5124,10 @@
}
}
},
"http-parser-js": {
"version": "0.4.10",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz",
"integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=",
"dev": true
},
"http-proxy": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
"integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"dev": true,
"requires": {
"eventemitter3": "^4.0.0",
@@ -5708,9 +5701,9 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jest-worker": {
"version": "25.2.6",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.6.tgz",
"integrity": "sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA==",
"version": "25.5.0",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz",
"integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==",
"dev": true,
"requires": {
"merge-stream": "^2.0.0",
@@ -5996,9 +5989,9 @@
}
},
"lodash": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"lodash._baseassign": {
"version": "3.2.0",
@@ -6099,9 +6092,9 @@
"dev": true
},
"loglevel": {
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz",
"integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==",
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz",
"integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==",
"dev": true
},
"loose-envify": {
@@ -6374,14 +6367,14 @@
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"minipass": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
"integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
@@ -6406,9 +6399,9 @@
}
},
"minipass-pipeline": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz",
"integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
"dev": true,
"requires": {
"minipass": "^3.0.0"
@@ -6443,18 +6436,11 @@
}
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"requires": {
"minimist": "0.0.8"
},
"dependencies": {
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
}
"minimist": "^1.2.5"
}
},
"move-concurrently": {
@@ -6830,10 +6816,14 @@
"dev": true
},
"object-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz",
"integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==",
"dev": true
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
"integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
}
},
"object-keys": {
"version": "1.1.1",
@@ -7298,14 +7288,14 @@
}
},
"portfinder": {
"version": "1.0.25",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz",
"integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==",
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
"integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==",
"dev": true,
"requires": {
"async": "^2.6.2",
"debug": "^3.1.1",
"mkdirp": "^0.5.1"
"mkdirp": "^0.5.5"
},
"dependencies": {
"debug": {
@@ -9163,13 +9153,14 @@
}
},
"sockjs": {
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
"integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
"version": "0.3.20",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz",
"integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==",
"dev": true,
"requires": {
"faye-websocket": "^0.10.0",
"uuid": "^3.0.1"
"uuid": "^3.4.0",
"websocket-driver": "0.6.5"
}
},
"sockjs-client": {
@@ -9290,9 +9281,9 @@
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q=="
},
"spdy": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz",
"integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
"integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
"dev": true,
"requires": {
"debug": "^4.1.0",
@@ -9711,22 +9702,34 @@
}
},
"terser-webpack-plugin": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz",
"integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==",
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz",
"integrity": "sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==",
"dev": true,
"requires": {
"cacache": "^13.0.1",
"find-cache-dir": "^3.2.0",
"jest-worker": "^25.1.0",
"p-limit": "^2.2.2",
"schema-utils": "^2.6.4",
"serialize-javascript": "^2.1.2",
"find-cache-dir": "^3.3.1",
"jest-worker": "^25.4.0",
"p-limit": "^2.3.0",
"schema-utils": "^2.6.6",
"serialize-javascript": "^4.0.0",
"source-map": "^0.6.1",
"terser": "^4.4.3",
"terser": "^4.6.12",
"webpack-sources": "^1.4.3"
},
"dependencies": {
"ajv": {
"version": "6.12.3",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
"integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -9764,18 +9767,18 @@
}
},
"make-dir": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz",
"integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
}
},
"p-limit": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@@ -9811,12 +9814,32 @@
"find-up": "^4.0.0"
}
},
"schema-utils": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.4",
"ajv": "^6.12.2",
"ajv-keywords": "^3.4.1"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"serialize-javascript": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -9824,9 +9847,9 @@
"dev": true
},
"terser": {
"version": "4.6.10",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.10.tgz",
"integrity": "sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA==",
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
"dev": true,
"requires": {
"commander": "^2.20.0",
@@ -9980,6 +10003,53 @@
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"twemoji": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-13.0.1.tgz",
"integrity": "sha512-mrTBq+XpCLM4zm76NJOjLHoQNV9mHdBt3Cba/T5lS1rxn8ArwpqE47mqTocupNlkvcLxoeZJjYSUW0DU5ZwqZg==",
"requires": {
"fs-extra": "^8.0.1",
"jsonfile": "^5.0.0",
"twemoji-parser": "13.0.0",
"universalify": "^0.1.2"
},
"dependencies": {
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"dependencies": {
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"requires": {
"graceful-fs": "^4.1.6"
}
}
}
},
"jsonfile": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz",
"integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==",
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^0.1.2"
}
}
}
},
"twemoji-parser": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.0.0.tgz",
"integrity": "sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ=="
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -10101,8 +10171,7 @@
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"unpipe": {
"version": "1.0.0",
@@ -10283,9 +10352,9 @@
"dev": true
},
"vee-validate": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-3.3.7.tgz",
"integrity": "sha512-s0CfIO8U+YSAzn7q+WnNtPignsndWKQlrbp8qbJ/zCw6QMO/OKDxhFXYRdWeNWRbRktVGCkiIaYktQiY/YL3TQ=="
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-3.3.9.tgz",
"integrity": "sha512-0ibP+8dNU8XitkhcB5UBnVlHdPlUqFx6jGg4vNUN/lw5geVKBvgyo83y7YCvYA5iqQPgCnuQxsx8kTHa0d/Zyw=="
},
"vendors": {
"version": "1.0.4",
@@ -10315,9 +10384,9 @@
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
},
"vue-feather-icons": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vue-feather-icons/-/vue-feather-icons-5.0.0.tgz",
"integrity": "sha512-uvi2l3i0aeRRzG3vX24/AH+8BkcXkSJboAv8XkUZ6aPkEC9n6LXDcKp5/ho+3moVQ9wlga3N6BjL89pmkHBzPw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/vue-feather-icons/-/vue-feather-icons-5.1.0.tgz",
"integrity": "sha512-ZyM2yFGmL9DYLZYHm63KV1zCQOj8czC2LzDSkxoIp9o6zMAOY4yv1FkxbX+XNUwcH3RRrAuvf25Ij7CnUUsQVA==",
"requires": {
"babel-helper-vue-jsx-merge-props": "^2.0.2"
}
@@ -10329,9 +10398,9 @@
"dev": true
},
"vue-i18n": {
"version": "8.18.2",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.18.2.tgz",
"integrity": "sha512-0X5nBTCZAVjlwcrPaYJwNs3iipBBTv0AUHwQUOa8yP3XbQGWKbRHqBb3OhCYtum/IHDD21d/df5Xd2VgyxbxfA=="
"version": "8.21.0",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.21.0.tgz",
"integrity": "sha512-pKBq6Kg5hNacFHMFgPbpYsFlDIMRu4Ew/tpvTWns14CZoCxt7B3tmSNdrLruGMMivnJu1rhhRqsQqT6YwHkuQQ=="
},
"vue-loader": {
"version": "15.9.1",
@@ -10347,9 +10416,9 @@
}
},
"vue-router": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.3.4.tgz",
"integrity": "sha512-SdKRBeoXUjaZ9R/8AyxsdTqkOfMcI5tWxPZOUX5Ie1BTL5rPSZ0O++pbiZCeYeythiZIdLEfkDiQPKIaWk5hDg=="
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz",
"integrity": "sha512-BADg1mjGWX18Dpmy6bOGzGNnk7B/ZA0RxuA6qedY/YJwirMfKXIDzcccmHbQI0A6k5PzMdMloc0ElHfyOoX35A=="
},
"vue-style-loader": {
"version": "4.1.2",
@@ -10702,17 +10771,17 @@
},
"dependencies": {
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
"dev": true
}
}
},
"webpack-dev-server": {
"version": "3.10.3",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz",
"integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==",
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz",
"integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==",
"dev": true,
"requires": {
"ansi-html": "0.0.7",
@@ -10723,33 +10792,39 @@
"debug": "^4.1.1",
"del": "^4.1.1",
"express": "^4.17.1",
"html-entities": "^1.2.1",
"html-entities": "^1.3.1",
"http-proxy-middleware": "0.19.1",
"import-local": "^2.0.0",
"internal-ip": "^4.3.0",
"ip": "^1.1.5",
"is-absolute-url": "^3.0.3",
"killable": "^1.0.1",
"loglevel": "^1.6.6",
"loglevel": "^1.6.8",
"opn": "^5.5.0",
"p-retry": "^3.0.1",
"portfinder": "^1.0.25",
"portfinder": "^1.0.26",
"schema-utils": "^1.0.0",
"selfsigned": "^1.10.7",
"semver": "^6.3.0",
"serve-index": "^1.9.1",
"sockjs": "0.3.19",
"sockjs": "0.3.20",
"sockjs-client": "1.4.0",
"spdy": "^4.0.1",
"spdy": "^4.0.2",
"strip-ansi": "^3.0.1",
"supports-color": "^6.1.0",
"url": "^0.11.0",
"webpack-dev-middleware": "^3.7.2",
"webpack-log": "^2.0.0",
"ws": "^6.2.1",
"yargs": "12.0.5"
"yargs": "^13.3.2"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@@ -10759,18 +10834,61 @@
"ms": "^2.1.1"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
"locate-path": "^3.0.0"
}
},
"is-absolute-url": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
"integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
"dev": true
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"requires": {
"p-limit": "^2.0.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"schema-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
@@ -10788,6 +10906,28 @@
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
},
"dependencies": {
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
@@ -10796,6 +10936,24 @@
"requires": {
"has-flag": "^3.0.0"
}
},
"yargs": {
"version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"requires": {
"cliui": "^5.0.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^13.1.2"
}
}
}
},
@@ -10848,20 +11006,18 @@
}
},
"websocket-driver": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz",
"integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==",
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
"integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=",
"dev": true,
"requires": {
"http-parser-js": ">=0.4.0 <0.4.11",
"safe-buffer": ">=5.1.0",
"websocket-extensions": ">=0.1.1"
}
},
"websocket-extensions": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
"dev": true
},
"which": {

View File

@@ -18,16 +18,17 @@
"vue-template-compiler": "^2.6.11"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.29",
"@fortawesome/free-solid-svg-icons": "^5.13.1",
"@fortawesome/fontawesome-svg-core": "^1.2.30",
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/vue-fontawesome": "^0.1.10",
"lodash": "^4.17.19",
"lodash": "^4.17.20",
"node-sass": "^4.14.1",
"vee-validate": "^3.3.7",
"vue": "^2.6.10",
"vue-feather-icons": "^5.0.0",
"vue-i18n": "^8.18.2",
"vue-router": "^3.3.4",
"twemoji": "^13.0.1",
"vee-validate": "^3.3.9",
"vue": "^2.6.11",
"vue-feather-icons": "^5.1.0",
"vue-i18n": "^8.21.0",
"vue-router": "^3.4.3",
"vuex": "^3.5.1"
}
}

View File

@@ -8,6 +8,7 @@
AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm
<ifModule mod_headers.c>
Header set Connection keep-alive
</ifModule>

14023
public/assets/emojis.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
<svg width="13px" height="15px" viewBox="0 0 13 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="VueFileManager" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="Storage-Alert-Copy" transform="translate(-888.000000, -238.000000)" stroke="#000000" stroke-width="1.6">
<g id="Sorting-Menu" transform="translate(865.000000, 67.000000)">
<g id="alphabet-icon" transform="translate(24.000000, 172.000000)">
<polyline id="Path" points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"></polyline>
<line x1="2.25" y1="8" x2="8.75" y2="8" id="Line-2"></line>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 854 B

View File

@@ -1 +0,0 @@
<svg width="106" height="23" xmlns="http://www.w3.org/2000/svg"><g fill="none"><path d="M23.715 17.145h2.07c.727 0 1.543-.31 1.543-1.227 0-.992-1.113-1.156-1.871-1.156h-1.742v2.383zm0-4.336h1.672c.71 0 1.449-.297 1.449-1.141 0-.875-.828-1.098-1.55-1.098h-1.571v2.239zm-2.313-4.192h3.91c1.836 0 3.836.387 3.836 2.664 0 1.168-.726 1.969-1.808 2.313v.027c1.375.18 2.297 1.2 2.297 2.563 0 2.187-2.075 2.918-3.938 2.918h-4.297V8.617zm13.789 3.051l-1.27 3.258h2.56l-1.29-3.258zm-.886-3.05h1.91l4.558 10.484h-2.605l-.902-2.223h-4.07l-.876 2.223h-2.547l4.532-10.485zM48.54 11.34c-.462-.547-1.13-.856-1.985-.856-1.746 0-3.035 1.418-3.035 3.375 0 1.954 1.289 3.375 2.96 3.375.93 0 1.688-.414 2.16-1.125l1.926 1.434c-.87 1.246-2.351 1.824-3.793 1.824-3.27 0-5.652-2.148-5.652-5.508 0-3.363 2.383-5.507 5.652-5.507 1.172 0 2.653.398 3.543 1.539L48.54 11.34zm3.233-2.723h2.309v4.352l4.07-4.352h3.02l-4.664 4.871 5.066 5.614h-3.226l-4.266-4.977v4.977h-2.309z" fill="#231F20"/><path d="M64.54 17.145h2.073c.727 0 1.54-.31 1.54-1.227 0-.992-1.11-1.156-1.864-1.156h-1.75v2.383zm0-4.336h1.67c.716 0 1.454-.297 1.454-1.141 0-.875-.828-1.098-1.555-1.098h-1.57v2.239zm-2.31-4.192h3.91c1.833 0 3.833.387 3.833 2.664 0 1.168-.727 1.969-1.805 2.313v.027c1.375.18 2.297 1.2 2.297 2.563 0 2.187-2.074 2.918-3.942 2.918H62.23V8.617zm9.54 0h2.312v8.352h4.277v2.133h-6.59z" fill="#646475"/><path d="M82.59 11.668l-1.274 3.258h2.563l-1.29-3.258zm-.887-3.05h1.91l4.559 10.484H85.57l-.906-2.223H80.59l-.871 2.223h-2.547l4.531-10.485zm6.832 8.351l5.317-6.309h-5.125V8.617h7.921v2.043l-5.21 6.309h5.39v2.133h-8.293zm9.82-8.352h7.125v2.133h-4.816v1.953h4.547v2.133h-4.547v2.133h5.082v2.133h-7.39z" fill="#646475"/><path d="M4.555-.027s3.422 2.992 2.957 5.644c-.207 1.18-1.774 3.13-.93 4.98.914 1.997 1.387 5.844-2.723 4.848C-.195 14.465.121 9.5 3.133 6.88 6.187 4.223 5.156 1.3 4.555-.027" fill="#D30035"/><path d="M7.68 8.945c-.227 2.02 2.007 4.032.234 6.766-1.23 1.894.656 4.555 3.078 4.07 2.656-.531 3.313-2.21 3.242-4.16-.093-2.476-1.078-3.164-3.27-5.023-2.37-2.012-.538-5.809-.538-5.809S7.934 6.723 7.68 8.945" fill="#D30035"/><path d="M.465 14.855c.75.922 2.2 2.008 4.976 2.07.84.016.184 1.583 1.864 2.993 1.453 1.223 3.41 1.25 4.457.855.61-.226 1.183-.445.742.122-1.973 2.527-5.399 2.367-7.844 1.453-2.906-1.086-3.637-3.223-4.113-4.555-.512-1.445-.25-3.145-.082-2.938" fill="#D30035"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 KiB

After

Width:  |  Height:  |  Size: 649 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 738 KiB

After

Width:  |  Height:  |  Size: 636 KiB

1
public/chunks/admin-account.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/admin.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-appearance.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-billings.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-email.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-index.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-others.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-payments.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-settings.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/app-setup.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/billings-detail.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/contact-us.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/create-new-password.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/dashboard.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/database.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/dynamic-page.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/environment-setup.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/chunks/files.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
public/chunks/forgotten-password.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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