diff --git a/public/mix-manifest.json b/public/mix-manifest.json
index 958f7d06..2f8ffa23 100644
--- a/public/mix-manifest.json
+++ b/public/mix-manifest.json
@@ -63,14 +63,14 @@
"/chunks/plan-settings.js": "/chunks/plan-settings.js?id=8a959e196d628d0efc4b",
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=7eff560fea52770a642f",
"/chunks/plans.js": "/chunks/plans.js?id=854c232c29d88c5b541a",
- "/chunks/platform.js": "/chunks/platform.js?id=d6b426d84871fc636e9e",
+ "/chunks/platform.js": "/chunks/platform.js?id=c3427a1bceb2bbf9f738",
"/chunks/platform~chunks/shared.js": "/chunks/platform~chunks/shared.js?id=440568dcf151d51d2486",
"/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js": "/chunks/platform~chunks/shared~chunks/shared-with-me~chunks/team-folders.js?id=7d983dfdc91de607d737",
"/chunks/profile.js": "/chunks/profile.js?id=8688d9c7ff850e6989e6",
"/chunks/profile~chunks/settings-password.js": "/chunks/profile~chunks/settings-password.js?id=dfa4128d68360d5e1b3b",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=9e948882ae2315eb6132",
"/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=8577d4c771602671b38a",
- "/chunks/settings.js": "/chunks/settings.js?id=548f24fc6d666c9db1a8",
+ "/chunks/settings.js": "/chunks/settings.js?id=4466d97a0211f77d9317",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=b6eb94764cc7b47f835e",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=76b45c336e8e12b23e81",
"/chunks/settings~chunks/settings-password.js": "/chunks/settings~chunks/settings-password.js?id=aafc9cd6aa47b01bc25a",
@@ -113,5 +113,90 @@
"/chunks/settings.35f000715b5a03522346.hot-update.js": "/chunks/settings.35f000715b5a03522346.hot-update.js",
"/chunks/settings.51d3c0571252e4f23ff1.hot-update.js": "/chunks/settings.51d3c0571252e4f23ff1.hot-update.js",
"/chunks/settings.255054593b1cd7f654d3.hot-update.js": "/chunks/settings.255054593b1cd7f654d3.hot-update.js",
- "/chunks/settings.2438d1c93de4d0c45c67.hot-update.js": "/chunks/settings.2438d1c93de4d0c45c67.hot-update.js"
+ "/chunks/settings.2438d1c93de4d0c45c67.hot-update.js": "/chunks/settings.2438d1c93de4d0c45c67.hot-update.js",
+ "/chunks/platform.5811795aa26f29d23f5b.hot-update.js": "/chunks/platform.5811795aa26f29d23f5b.hot-update.js",
+ "/chunks/platform.8c481bcdc638d27a4a84.hot-update.js": "/chunks/platform.8c481bcdc638d27a4a84.hot-update.js",
+ "/chunks/platform.2c801c878d2302c04b04.hot-update.js": "/chunks/platform.2c801c878d2302c04b04.hot-update.js",
+ "/chunks/platform.6ae437c53d3355af934e.hot-update.js": "/chunks/platform.6ae437c53d3355af934e.hot-update.js",
+ "/chunks/platform.8a1132d7879b623a0ee4.hot-update.js": "/chunks/platform.8a1132d7879b623a0ee4.hot-update.js",
+ "/js/main.34827559ca00fbb7f164.hot-update.js": "/js/main.34827559ca00fbb7f164.hot-update.js",
+ "/js/main.11ddf2d8a48a946eb9b9.hot-update.js": "/js/main.11ddf2d8a48a946eb9b9.hot-update.js",
+ "/js/main.c81f24a0fd629af6c208.hot-update.js": "/js/main.c81f24a0fd629af6c208.hot-update.js",
+ "/js/main.07d32454f0bd3299c3bb.hot-update.js": "/js/main.07d32454f0bd3299c3bb.hot-update.js",
+ "/js/main.deef2a5be87c2f0386e1.hot-update.js": "/js/main.deef2a5be87c2f0386e1.hot-update.js",
+ "/js/main.7e7cfb75cc4b9255a594.hot-update.js": "/js/main.7e7cfb75cc4b9255a594.hot-update.js",
+ "/js/main.e31064a188136858221e.hot-update.js": "/js/main.e31064a188136858221e.hot-update.js",
+ "/js/main.5295702a8639b61805ac.hot-update.js": "/js/main.5295702a8639b61805ac.hot-update.js",
+ "/js/main.1663362fc2afa6e6c7fd.hot-update.js": "/js/main.1663362fc2afa6e6c7fd.hot-update.js",
+ "/js/main.b7f439a45efadc0d09c9.hot-update.js": "/js/main.b7f439a45efadc0d09c9.hot-update.js",
+ "/js/main.ab2d94da6e88e19834fc.hot-update.js": "/js/main.ab2d94da6e88e19834fc.hot-update.js",
+ "/js/main.d1bac7303de2752f8f2a.hot-update.js": "/js/main.d1bac7303de2752f8f2a.hot-update.js",
+ "/js/main.fa4020861f2256c1a814.hot-update.js": "/js/main.fa4020861f2256c1a814.hot-update.js",
+ "/js/main.49e61ab55a7999ac2d7c.hot-update.js": "/js/main.49e61ab55a7999ac2d7c.hot-update.js",
+ "/js/main.9a3d34d1573f5a360549.hot-update.js": "/js/main.9a3d34d1573f5a360549.hot-update.js",
+ "/js/main.a09414329bcddae0193d.hot-update.js": "/js/main.a09414329bcddae0193d.hot-update.js",
+ "/js/main.9af992eb88a9c439a7ab.hot-update.js": "/js/main.9af992eb88a9c439a7ab.hot-update.js",
+ "/js/main.583d206005a97f6eaede.hot-update.js": "/js/main.583d206005a97f6eaede.hot-update.js",
+ "/js/main.1a94a099a196d5dd94a7.hot-update.js": "/js/main.1a94a099a196d5dd94a7.hot-update.js",
+ "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~29ecd2dd.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~29ecd2dd.js?id=6a9136010589fefae8c1",
+ "/js/main.4280084333a6f807e55e.hot-update.js": "/js/main.4280084333a6f807e55e.hot-update.js",
+ "/chunks/admin~chunks/app-language~chunks/dashboard~chunks/files~chunks/invoices~chunks/my-shared-item~3b21240c.4280084333a6f807e55e.hot-update.js": "/chunks/admin~chunks/app-language~chunks/dashboard~chunks/files~chunks/invoices~chunks/my-shared-item~3b21240c.4280084333a6f807e55e.hot-update.js",
+ "/chunks/admin~chunks/platform~chunks/settings~chunks/shared.4280084333a6f807e55e.hot-update.js": "/chunks/admin~chunks/platform~chunks/settings~chunks/shared.4280084333a6f807e55e.hot-update.js",
+ "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~217928f6.4280084333a6f807e55e.hot-update.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~217928f6.4280084333a6f807e55e.hot-update.js",
+ "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~5acee76d.4280084333a6f807e55e.hot-update.js": "/chunks/app-appearance~chunks/app-billings~chunks/app-email~chunks/app-index~chunks/app-others~chunks~5acee76d.4280084333a6f807e55e.hot-update.js",
+ "/chunks/app-language.4280084333a6f807e55e.hot-update.js": "/chunks/app-language.4280084333a6f807e55e.hot-update.js",
+ "/chunks/billing.4280084333a6f807e55e.hot-update.js": "/chunks/billing.4280084333a6f807e55e.hot-update.js",
+ "/chunks/dashboard~chunks/invoices~chunks/pages~chunks/plans~chunks/subscriptions.4280084333a6f807e55e.hot-update.js": "/chunks/dashboard~chunks/invoices~chunks/pages~chunks/plans~chunks/subscriptions.4280084333a6f807e55e.hot-update.js",
+ "/chunks/homepage.4280084333a6f807e55e.hot-update.js": "/chunks/homepage.4280084333a6f807e55e.hot-update.js",
+ "/chunks/installation-disclaimer.4280084333a6f807e55e.hot-update.js": "/chunks/installation-disclaimer.4280084333a6f807e55e.hot-update.js",
+ "/chunks/invitation.4280084333a6f807e55e.hot-update.js": "/chunks/invitation.4280084333a6f807e55e.hot-update.js",
+ "/chunks/page-edit.4280084333a6f807e55e.hot-update.js": "/chunks/page-edit.4280084333a6f807e55e.hot-update.js",
+ "/chunks/plan.4280084333a6f807e55e.hot-update.js": "/chunks/plan.4280084333a6f807e55e.hot-update.js",
+ "/chunks/plan-create/fixed.4280084333a6f807e55e.hot-update.js": "/chunks/plan-create/fixed.4280084333a6f807e55e.hot-update.js",
+ "/chunks/plan-create/metered.4280084333a6f807e55e.hot-update.js": "/chunks/plan-create/metered.4280084333a6f807e55e.hot-update.js",
+ "/chunks/plan-delete.4280084333a6f807e55e.hot-update.js": "/chunks/plan-delete.4280084333a6f807e55e.hot-update.js",
+ "/chunks/profile~chunks/settings-password.4280084333a6f807e55e.hot-update.js": "/chunks/profile~chunks/settings-password.4280084333a6f807e55e.hot-update.js",
+ "/chunks/settings-storage.4280084333a6f807e55e.hot-update.js": "/chunks/settings-storage.4280084333a6f807e55e.hot-update.js",
+ "/chunks/shared.4280084333a6f807e55e.hot-update.js": "/chunks/shared.4280084333a6f807e55e.hot-update.js",
+ "/chunks/shared-with-me~chunks/team-folders.4280084333a6f807e55e.hot-update.js": "/chunks/shared-with-me~chunks/team-folders.4280084333a6f807e55e.hot-update.js",
+ "/chunks/shared/single-file.4280084333a6f807e55e.hot-update.js": "/chunks/shared/single-file.4280084333a6f807e55e.hot-update.js",
+ "/chunks/sign-in.4280084333a6f807e55e.hot-update.js": "/chunks/sign-in.4280084333a6f807e55e.hot-update.js",
+ "/chunks/subscription-plans.4280084333a6f807e55e.hot-update.js": "/chunks/subscription-plans.4280084333a6f807e55e.hot-update.js",
+ "/chunks/subscriptions.4280084333a6f807e55e.hot-update.js": "/chunks/subscriptions.4280084333a6f807e55e.hot-update.js",
+ "/chunks/upgrade-billing~chunks/upgrade-plan.4280084333a6f807e55e.hot-update.js": "/chunks/upgrade-billing~chunks/upgrade-plan.4280084333a6f807e55e.hot-update.js",
+ "/chunks/user.4280084333a6f807e55e.hot-update.js": "/chunks/user.4280084333a6f807e55e.hot-update.js",
+ "/chunks/user-create.4280084333a6f807e55e.hot-update.js": "/chunks/user-create.4280084333a6f807e55e.hot-update.js",
+ "/chunks/user-subscription.4280084333a6f807e55e.hot-update.js": "/chunks/user-subscription.4280084333a6f807e55e.hot-update.js",
+ "/chunks/users.4280084333a6f807e55e.hot-update.js": "/chunks/users.4280084333a6f807e55e.hot-update.js",
+ "/js/main.759fcc4e53d2dc10eef7.hot-update.js": "/js/main.759fcc4e53d2dc10eef7.hot-update.js",
+ "/js/main.8c791a358db3536d409d.hot-update.js": "/js/main.8c791a358db3536d409d.hot-update.js",
+ "/js/main.56620b989bbce3ae0875.hot-update.js": "/js/main.56620b989bbce3ae0875.hot-update.js",
+ "/chunks/platform.68f9a7490063bdd5f3ab.hot-update.js": "/chunks/platform.68f9a7490063bdd5f3ab.hot-update.js",
+ "/chunks/platform.9fc7bcf362c1d4bbfc81.hot-update.js": "/chunks/platform.9fc7bcf362c1d4bbfc81.hot-update.js",
+ "/chunks/platform.ee93be9965a1cfa152fc.hot-update.js": "/chunks/platform.ee93be9965a1cfa152fc.hot-update.js",
+ "/chunks/platform.133e1026a756d3035944.hot-update.js": "/chunks/platform.133e1026a756d3035944.hot-update.js",
+ "/chunks/platform.6fcf086c7a4c1331a53c.hot-update.js": "/chunks/platform.6fcf086c7a4c1331a53c.hot-update.js",
+ "/js/main.f16a33ff7d5847b98266.hot-update.js": "/js/main.f16a33ff7d5847b98266.hot-update.js",
+ "/js/main.5f3afd688212022fb58a.hot-update.js": "/js/main.5f3afd688212022fb58a.hot-update.js",
+ "/js/main.007eb43910450b32c805.hot-update.js": "/js/main.007eb43910450b32c805.hot-update.js",
+ "/js/main.76d40e551720ac111fd9.hot-update.js": "/js/main.76d40e551720ac111fd9.hot-update.js",
+ "/js/main.b7babb7b19f9b09ca98d.hot-update.js": "/js/main.b7babb7b19f9b09ca98d.hot-update.js",
+ "/js/main.08e4f30c97bcc3a942e8.hot-update.js": "/js/main.08e4f30c97bcc3a942e8.hot-update.js",
+ "/js/main.fea58478d3dfe9206fed.hot-update.js": "/js/main.fea58478d3dfe9206fed.hot-update.js",
+ "/js/main.8881265f32669ed95bfb.hot-update.js": "/js/main.8881265f32669ed95bfb.hot-update.js",
+ "/chunks/settings.1eda8247e148c5d51d4d.hot-update.js": "/chunks/settings.1eda8247e148c5d51d4d.hot-update.js",
+ "/chunks/settings.d9d981a7197ff398ee22.hot-update.js": "/chunks/settings.d9d981a7197ff398ee22.hot-update.js",
+ "/chunks/platform.a7c645c2c8ceda4ae3f7.hot-update.js": "/chunks/platform.a7c645c2c8ceda4ae3f7.hot-update.js",
+ "/js/main.9fbff94db8eb20332da7.hot-update.js": "/js/main.9fbff94db8eb20332da7.hot-update.js",
+ "/js/main.959620b85c3df6282a5f.hot-update.js": "/js/main.959620b85c3df6282a5f.hot-update.js",
+ "/js/main.b8fe9507703cfb75e859.hot-update.js": "/js/main.b8fe9507703cfb75e859.hot-update.js",
+ "/js/main.a48539de27bb23dd5904.hot-update.js": "/js/main.a48539de27bb23dd5904.hot-update.js",
+ "/js/main.c2d0f57bdad53abf3859.hot-update.js": "/js/main.c2d0f57bdad53abf3859.hot-update.js",
+ "/js/main.9eb9d2d7d97cc33f46f7.hot-update.js": "/js/main.9eb9d2d7d97cc33f46f7.hot-update.js",
+ "/js/main.272640c4f5959835aa61.hot-update.js": "/js/main.272640c4f5959835aa61.hot-update.js",
+ "/js/main.287b5ae535954f8ed89c.hot-update.js": "/js/main.287b5ae535954f8ed89c.hot-update.js",
+ "/js/main.51906e2db8a6c36f5304.hot-update.js": "/js/main.51906e2db8a6c36f5304.hot-update.js",
+ "/js/main.c09b0f39fe6d0b43515b.hot-update.js": "/js/main.c09b0f39fe6d0b43515b.hot-update.js",
+ "/js/main.de28ca938da3825e62b3.hot-update.js": "/js/main.de28ca938da3825e62b3.hot-update.js",
+ "/js/main.be91e0ed3d68ecb1af06.hot-update.js": "/js/main.be91e0ed3d68ecb1af06.hot-update.js"
}
diff --git a/resources/js/App.vue b/resources/js/App.vue
index 1bd33963..1bd2d408 100644
--- a/resources/js/App.vue
+++ b/resources/js/App.vue
@@ -9,6 +9,13 @@
+
+
+
+ {{ $t('Your functionality is restricted. Please review your billing settings.') }}
+
+
+
@@ -41,7 +48,9 @@ export default {
},
computed: {
...mapGetters([
- 'isDarkMode'
+ 'isLimitedUser',
+ 'isDarkMode',
+ 'user',
]),
},
watch: {
diff --git a/resources/js/components/Others/TwoFactorRecoveryCodesPopup.vue b/resources/js/components/Others/TwoFactorRecoveryCodesPopup.vue
index c38d8cf1..8536e3c5 100644
--- a/resources/js/components/Others/TwoFactorRecoveryCodesPopup.vue
+++ b/resources/js/components/Others/TwoFactorRecoveryCodesPopup.vue
@@ -143,9 +143,6 @@ export default {
if ('two-factor-recovery-codes' === name)
this.getRecoveryCodes()
})
- },
- destroyed() {
- events.$off('popup:open')
}
}
diff --git a/resources/js/helpers/functionHelpers.js b/resources/js/helpers/functionHelpers.js
index d0ce9999..cdfb1747 100644
--- a/resources/js/helpers/functionHelpers.js
+++ b/resources/js/helpers/functionHelpers.js
@@ -1,6 +1,6 @@
+import {debounce, isArray, orderBy} from "lodash"
import i18n from '/resources/js/i18n/index'
import store from '../store/index'
-import {debounce, isArray, orderBy} from "lodash";
import {events} from '../bus'
import axios from 'axios'
diff --git a/resources/js/helpers/itemHelpers.js b/resources/js/helpers/itemHelpers.js
index 1f7b9564..eef0e6a4 100644
--- a/resources/js/helpers/itemHelpers.js
+++ b/resources/js/helpers/itemHelpers.js
@@ -1,16 +1,18 @@
-import {events} from "../bus";
+import i18n from '/resources/js/i18n/index'
+import store from '../store/index'
+import {events} from '../bus'
const itemHelpers = {
install(Vue) {
Vue.prototype.$emptyTrash = function () {
- this.$store.dispatch('emptyTrash')
+ store.dispatch('emptyTrash')
}
Vue.prototype.$emptyTrashQuietly = function () {
- this.$store.dispatch('emptyTrashQuietly')
+ store.dispatch('emptyTrashQuietly')
}
Vue.prototype.$shareCancel = function () {
- this.$store.dispatch('shareCancel')
+ store.dispatch('shareCancel')
}
Vue.prototype.$renameFileOrFolder = function (entry) {
@@ -22,16 +24,16 @@ const itemHelpers = {
}
Vue.prototype.$createFolder = function () {
- this.$store.dispatch('createFolder', {
- name: this.$t('popup_create_folder.folder_default_name')
+ store.dispatch('createFolder', {
+ name: i18n.t('popup_create_folder.folder_default_name')
})
}
Vue.prototype.$downloadSelection = function (item) {
- let clipboard = this.$store.getters.clipboard
+ let clipboard = store.getters.clipboard
if (clipboard.length > 1 || (clipboard.length === 1 && clipboard[0].data.type === 'folder'))
- this.$store.dispatch('downloadZip')
+ store.dispatch('downloadZip')
else {
Vue.prototype.$downloadFile(item.data.attributes.file_url, item.data.attributes.name + '.' + item.data.attributes.mimetype)
}
@@ -39,8 +41,8 @@ const itemHelpers = {
Vue.prototype.$dissolveTeamFolder = function (folder) {
events.$emit('confirm:open', {
- title: this.$t('Are you sure you want to dissolve this team?'),
- message: this.$t('All team members will lose access to your files and existing folder will be moved into your "Files" section.'),
+ title: i18n.t('Are you sure you want to dissolve this team?'),
+ message: i18n.t('All team members will lose access to your files and existing folder will be moved into your "Files" section.'),
action: {
id: folder.data.id,
operation: 'dissolve-team-folder',
@@ -50,8 +52,8 @@ const itemHelpers = {
Vue.prototype.$detachMeFromTeamFolder = function (folder) {
events.$emit('confirm:open', {
- title: this.$t('Are you sure you want to leave this team?'),
- message: this.$t("You will don't have access to the files and all your previously uploaded content will be part of this Team Folder you are leaving."),
+ title: i18n.t('Are you sure you want to leave this team?'),
+ message: i18n.t("You will don't have access to the files and all your previously uploaded content will be part of this Team Folder you are leaving."),
action: {
id: folder.data.id,
operation: 'leave-team-folder',
@@ -72,25 +74,25 @@ const itemHelpers = {
}
Vue.prototype.$removeFavourite = function (folder) {
- this.$store.dispatch('removeFromFavourites', folder)
+ store.dispatch('removeFromFavourites', folder)
}
Vue.prototype.$deleteFileOrFolder = function (entry) {
- if (!this.$store.getters.clipboard.includes(entry)) {
- this.$store.dispatch('deleteItem', entry)
+ if (!store.getters.clipboard.includes(entry)) {
+ store.dispatch('deleteItem', entry)
}
- if (this.$store.getters.clipboard.includes(entry)) {
- this.$store.dispatch('deleteItem')
+ if (store.getters.clipboard.includes(entry)) {
+ store.dispatch('deleteItem')
}
}
Vue.prototype.$restoreFileOrFolder = function (entry) {
- if (!this.$store.getters.clipboard.includes(entry))
- this.$store.dispatch('restoreItem', entry)
+ if (!store.getters.clipboard.includes(entry))
+ store.dispatch('restoreItem', entry)
- if (this.$store.getters.clipboard.includes(entry))
- this.$store.dispatch('restoreItem', null)
+ if (store.getters.clipboard.includes(entry))
+ store.dispatch('restoreItem', null)
}
Vue.prototype.$shareFileOrFolder = function (entry) {
diff --git a/resources/js/store/modules/fileFunctions.js b/resources/js/store/modules/fileFunctions.js
index 35b6d95c..0324f798 100644
--- a/resources/js/store/modules/fileFunctions.js
+++ b/resources/js/store/modules/fileFunctions.js
@@ -117,7 +117,12 @@ const actions = {
dispatch('getAppData')
})
- .catch(() => Vue.prototype.$isSomethingWrong())
+ .catch(error => {
+ events.$emit('alert:open', {
+ title: error.response.data.message,
+ message: i18n.t('popup_error.message')
+ })
+ })
},
renameItem: ({commit, getters, dispatch}, data) => {
@@ -222,13 +227,16 @@ const actions = {
'413': {
title: i18n.t('popup_paylod_error.title'),
message: i18n.t('popup_paylod_error.message')
- }
+ },
+ '401': {
+ title: error.response.data.message,
+ },
}
events.$emit('alert:open', {
emoji: '😬😬😬',
title: messages[error.response.status]['title'],
- message: messages[error.response.status]['message']
+ message: messages[error.response.status]['message'] || null
})
commit('PROCESSING_FILE', false)
diff --git a/resources/js/store/modules/userAuth.js b/resources/js/store/modules/userAuth.js
index 2f5fbd66..8d7ef4a4 100644
--- a/resources/js/store/modules/userAuth.js
+++ b/resources/js/store/modules/userAuth.js
@@ -143,6 +143,7 @@ const mutations = {
}
const getters = {
+ isLimitedUser: state => state.user && state.user.data.relationships.failedPayments && state.user.data.relationships.failedPayments.data.length === 3,
permission: state => state.permission,
user: state => state.user,
}
diff --git a/resources/js/views/Platform.vue b/resources/js/views/Platform.vue
index 972499e7..52dc42d3 100644
--- a/resources/js/views/Platform.vue
+++ b/resources/js/views/Platform.vue
@@ -110,7 +110,8 @@
},
computed: {
...mapGetters([
- 'isVisibleSidebar'
+ 'isVisibleSidebar',
+ 'isLimitedUser',
])
},
data() {
diff --git a/src/App/Limitations/Engines/FixedBillingLimitationEngine.php b/src/App/Limitations/Engines/FixedBillingLimitationEngine.php
index 694250b6..27603078 100644
--- a/src/App/Limitations/Engines/FixedBillingLimitationEngine.php
+++ b/src/App/Limitations/Engines/FixedBillingLimitationEngine.php
@@ -15,8 +15,7 @@ class FixedBillingLimitationEngine implements LimitationEngine
);
// Check if storage usage exceed predefined capacity
- return ! ($usedPercentage >= 100)
- ;
+ return ! ($usedPercentage >= 100);
}
public function canDownload(User $user): bool
diff --git a/src/App/Limitations/Engines/MeteredBillingLimitationEngine.php b/src/App/Limitations/Engines/MeteredBillingLimitationEngine.php
index 5a0c1142..b3cc26b3 100644
--- a/src/App/Limitations/Engines/MeteredBillingLimitationEngine.php
+++ b/src/App/Limitations/Engines/MeteredBillingLimitationEngine.php
@@ -9,21 +9,18 @@ class MeteredBillingLimitationEngine implements LimitationEngine
public function canUpload(User $user, int $fileSize = 0): bool
{
// Disable upload when user has more than 3 failed payments
- return ! ($user->failedPayments()->count() >= 3)
- ;
+ return ! ($user->failedPayments()->count() >= 3);
}
public function canDownload(User $user): bool
{
- // Disable upload when user has more than 3 failed payments
- return ! ($user->failedPayments()->count() >= 3)
- ;
+ // Disable download when user has more than 3 failed payments
+ return ! ($user->failedPayments()->count() >= 3);
}
public function canCreateFolder(User $user): bool
{
- // Disable upload when user has more than 3 failed payments
- return ! ($user->failedPayments()->count() >= 3)
- ;
+ // Disable create folder when user has more than 3 failed payments
+ return ! ($user->failedPayments()->count() >= 3);
}
}
diff --git a/src/App/Users/Exceptions/InvalidUserActionException.php b/src/App/Users/Exceptions/InvalidUserActionException.php
new file mode 100644
index 00000000..ce69f62e
--- /dev/null
+++ b/src/App/Users/Exceptions/InvalidUserActionException.php
@@ -0,0 +1,10 @@
+driver()
- ->$method($this, ...$parameters);
- }
-
- return parent::__call($method, $parameters);
- }
-
/**
* Get user used storage details
*/
@@ -211,6 +200,17 @@ class User extends Authenticatable implements MustVerifyEmail
$this->notify(new ResetPassword($token));
}
+ public function __call($method, $parameters)
+ {
+ if (str_starts_with($method, 'can')) {
+ return resolve(LimitationManager::class)
+ ->driver()
+ ->$method($this, ...$parameters);
+ }
+
+ return parent::__call($method, $parameters);
+ }
+
protected static function boot()
{
parent::boot();
diff --git a/src/Domain/Files/Actions/UploadFileAction.php b/src/Domain/Files/Actions/UploadFileAction.php
index 32774bad..c52d6760 100644
--- a/src/Domain/Files/Actions/UploadFileAction.php
+++ b/src/Domain/Files/Actions/UploadFileAction.php
@@ -1,6 +1,7 @@
canUpload($fileSize)) {
Storage::disk('local')->delete("chunks/$chunkName");
- abort(423, 'You exceed your storage limit!');
+ throw new InvalidUserActionException();
}
// Move finished file from chunk to file-manager directory
diff --git a/src/Domain/Files/Controllers/UploadFileController.php b/src/Domain/Files/Controllers/UploadFileController.php
index ef250dc9..602794b8 100644
--- a/src/Domain/Files/Controllers/UploadFileController.php
+++ b/src/Domain/Files/Controllers/UploadFileController.php
@@ -1,6 +1,7 @@
fakeUploadFile)($request);
}
- $file = ($this->uploadFiles)($request);
+ try {
+ $file = ($this->uploadFiles)($request);
- return response(new FileResource($file), 201);
+ return response(new FileResource($file), 201);
+ } catch (InvalidUserActionException $e) {
+ return response([
+ 'type' => 'error',
+ 'message' => $e->getMessage(),
+ ], 401);
+ }
}
}
diff --git a/src/Domain/Folders/Actions/CreateFolderAction.php b/src/Domain/Folders/Actions/CreateFolderAction.php
index 38944630..5edd2d58 100644
--- a/src/Domain/Folders/Actions/CreateFolderAction.php
+++ b/src/Domain/Folders/Actions/CreateFolderAction.php
@@ -5,24 +5,35 @@ use Domain\Sharing\Models\Share;
use Domain\Folders\Models\Folder;
use Illuminate\Support\Facades\Auth;
use Domain\Folders\Requests\CreateFolderRequest;
+use App\Users\Exceptions\InvalidUserActionException;
class CreateFolderAction
{
/**
* Create new folder
+ *
+ * @throws InvalidUserActionException
*/
public function __invoke(
CreateFolderRequest $request,
?Share $shared = null,
): Folder|array {
+ // Get user model
+ $user = $shared
+ ? $shared->user
+ : Auth::user();
+
+ // Check if user can create folder
+ if (! $user->canCreateFolder()) {
+ throw new InvalidUserActionException();
+ }
+
/*
- * check if exist parent team folder, if yes,
- * then get folder to detect whether it is team_folder
+ * Check if exist parent team folder, if yes,
+ * then get the latest parent folder to detect whether it is team_folder
*/
if ($request->has('parent_id')) {
- $isTeamFolder = Folder::find(
- $request->input('parent_id')
- )
+ $isTeamFolder = Folder::find($request->input('parent_id'))
->getLatestParent()
->team_folder;
}
@@ -34,7 +45,7 @@ class CreateFolderAction
'color' => $request->input('color') ?? null,
'emoji' => $request->input('emoji') ?? null,
'author' => $shared ? 'visitor' : 'user',
- 'user_id' => $shared ? $shared->user_id : Auth::id(),
+ 'user_id' => $user->id,
'team_folder' => $isTeamFolder ?? false,
]);
}
diff --git a/src/Domain/Folders/Controllers/CreateFolderController.php b/src/Domain/Folders/Controllers/CreateFolderController.php
index 17a675ca..34374fda 100644
--- a/src/Domain/Folders/Controllers/CreateFolderController.php
+++ b/src/Domain/Folders/Controllers/CreateFolderController.php
@@ -7,6 +7,7 @@ use Domain\Folders\Resources\FolderResource;
use Domain\Folders\Actions\CreateFolderAction;
use Domain\Folders\Requests\CreateFolderRequest;
use Support\Demo\Actions\FakeCreateFolderAction;
+use App\Users\Exceptions\InvalidUserActionException;
class CreateFolderController extends Controller
{
@@ -28,8 +29,17 @@ class CreateFolderController extends Controller
return response(new FolderResource($fakeFolder), 201);
}
- $folder = ($this->createFolder)($request);
+ try {
+ // Create new folder
+ $folder = ($this->createFolder)($request);
- return response(new FolderResource($folder), 201);
+ // Return new folder
+ return response(new FolderResource($folder), 201);
+ } catch (InvalidUserActionException $e) {
+ return response([
+ 'type' => 'error',
+ 'message' => $e->getMessage(),
+ ], 401);
+ }
}
}
diff --git a/src/Domain/Folders/Controllers/VisitorCreateFolderController.php b/src/Domain/Folders/Controllers/VisitorCreateFolderController.php
index 75ea94d9..d4dee71f 100644
--- a/src/Domain/Folders/Controllers/VisitorCreateFolderController.php
+++ b/src/Domain/Folders/Controllers/VisitorCreateFolderController.php
@@ -4,9 +4,11 @@ namespace Domain\Folders\Controllers;
use Illuminate\Http\Response;
use Domain\Sharing\Models\Share;
use App\Http\Controllers\Controller;
+use Domain\Folders\Resources\FolderResource;
use Domain\Folders\Actions\CreateFolderAction;
use Domain\Folders\Requests\CreateFolderRequest;
use Support\Demo\Actions\FakeCreateFolderAction;
+use App\Users\Exceptions\InvalidUserActionException;
use Domain\Sharing\Actions\ProtectShareRecordAction;
use Domain\Sharing\Actions\VerifyAccessToItemAction;
@@ -19,7 +21,7 @@ class VisitorCreateFolderController extends Controller
private CreateFolderAction $createFolder,
private ProtectShareRecordAction $protectShareRecord,
private VerifyAccessToItemAction $verifyAccessToItem,
- private FakeCreateFolderAction $fakeCreateFolderAction,
+ private FakeCreateFolderAction $fakeCreateFolder,
) {
}
@@ -28,7 +30,9 @@ class VisitorCreateFolderController extends Controller
Share $shared,
): Response | array {
if (is_demo_account()) {
- return ($this->fakeCreateFolderAction)($request);
+ $fakeFolder = ($this->fakeCreateFolder)($request);
+
+ return response(new FolderResource($fakeFolder), 201);
}
// Check ability to access protected share record
@@ -42,9 +46,18 @@ class VisitorCreateFolderController extends Controller
// Check access to requested directory
($this->verifyAccessToItem)($request->parent_id, $shared);
- // Create folder
- $folder = ($this->createFolder)($request, $shared);
+ try {
+ // Create new folder
+ $folder = ($this->createFolder)($request, $shared);
- return response($folder, 201);
+ // Return new folder
+ return response(new FolderResource($folder), 201);
+ } catch (InvalidUserActionException $e) {
+ // Return error response
+ return response([
+ 'type' => 'error',
+ 'message' => $e->getMessage(),
+ ], 401);
+ }
}
}
diff --git a/tests/App/Limitations/DefaultLimitationTest.php b/tests/App/Limitations/DefaultLimitationTest.php
index 74e3113d..69461224 100644
--- a/tests/App/Limitations/DefaultLimitationTest.php
+++ b/tests/App/Limitations/DefaultLimitationTest.php
@@ -85,4 +85,24 @@ class DefaultLimitationTest extends TestCase
$this->assertEquals(1, $user->limitations->max_storage_amount);
$this->assertEquals(false, $user->canUpload(999999999));
}
+
+ /**
+ * @test
+ */
+ public function it_can_create_new_folder()
+ {
+ $user = User::factory()
+ ->create();
+
+ $this
+ ->actingAs($user)
+ ->postJson('/api/create-folder', [
+ 'name' => 'New Folder',
+ ])
+ ->assertStatus(201);
+
+ $this->assertDatabaseHas('folders', [
+ 'name' => 'New Folder',
+ ]);
+ }
}
diff --git a/tests/App/Limitations/FixedBillingLimitationTest.php b/tests/App/Limitations/FixedBillingLimitationTest.php
index e4024042..e6903b38 100644
--- a/tests/App/Limitations/FixedBillingLimitationTest.php
+++ b/tests/App/Limitations/FixedBillingLimitationTest.php
@@ -46,4 +46,24 @@ class FixedBillingLimitationTest extends TestCase
$this->assertEquals(false, $user->canUpload(999999999));
}
+
+ /**
+ * @test
+ */
+ public function it_can_create_new_folder()
+ {
+ $user = User::factory()
+ ->create();
+
+ $this
+ ->actingAs($user)
+ ->postJson('/api/create-folder', [
+ 'name' => 'New Folder',
+ ])
+ ->assertStatus(201);
+
+ $this->assertDatabaseHas('folders', [
+ 'name' => 'New Folder',
+ ]);
+ }
}
diff --git a/tests/App/Limitations/MeteredBillingLimitationTest.php b/tests/App/Limitations/MeteredBillingLimitationTest.php
index a7826217..9af044d0 100644
--- a/tests/App/Limitations/MeteredBillingLimitationTest.php
+++ b/tests/App/Limitations/MeteredBillingLimitationTest.php
@@ -40,4 +40,45 @@ class MeteredBillingLimitationTest extends TestCase
$this->assertEquals(false, $user->canUpload());
}
+
+ /**
+ * @test
+ */
+ public function it_can_create_new_folder()
+ {
+ $user = User::factory()
+ ->create();
+
+ $this
+ ->actingAs($user)
+ ->postJson('/api/create-folder', [
+ 'name' => 'New Folder',
+ ])
+ ->assertStatus(201);
+
+ $this->assertDatabaseHas('folders', [
+ 'name' => 'New Folder',
+ ]);
+ }
+
+ /**
+ * @test
+ */
+ public function it_cant_create_new_folder_because_user_has_3_failed_payments()
+ {
+ $user = User::factory()
+ ->hasFailedpayments(3)
+ ->create();
+
+ $this
+ ->actingAs($user)
+ ->postJson('/api/create-folder', [
+ 'name' => 'New Folder',
+ ])
+ ->assertStatus(401);
+
+ $this->assertDatabaseMissing('folders', [
+ 'name' => 'New Folder',
+ ]);
+ }
}
diff --git a/tests/Domain/Files/FileTest.php b/tests/Domain/Files/FileTest.php
index 66030bee..e24aefc3 100644
--- a/tests/Domain/Files/FileTest.php
+++ b/tests/Domain/Files/FileTest.php
@@ -126,7 +126,7 @@ class FileTest extends TestCase
'file' => $file,
'parent_id' => null,
'is_last' => 'true',
- ])->assertStatus(423);
+ ])->assertStatus(401);
Storage::disk('local')->assertMissing(
"files/$user->id/fake-file.jpeg"