diff --git a/src/modules/main/sections/MainWrapper.vue b/src/modules/main/sections/MainWrapper.vue index 98d08ba4ba..b2a7387740 100644 --- a/src/modules/main/sections/MainWrapper.vue +++ b/src/modules/main/sections/MainWrapper.vue @@ -42,6 +42,7 @@ import exportTableMixin from '../../../shared/components/ncTable/mixins/exportTa import { useTablesStore } from '../../../store/store.js' import { useDataStore } from '../../../store/data.js' import { computed } from 'vue' +import { showError } from '@nextcloud/dialogs' export default { name: 'MainWrapper', @@ -100,10 +101,23 @@ export default { methods: { ...mapActions(useDataStore, ['removeRows', 'clearState', 'loadColumnsFromBE', 'loadRowsFromBE']), + ...mapActions(useTablesStore, ['validateExportAccess']), createColumn() { emit('tables:column:create', { isView: this.isView, element: this.element }) }, - downloadCSV() { + async downloadCSV() { + const access = await this.validateExportAccess({ + id: this.element.id, + isView: this.isView, + }) + + if (!access?.ok) { + if (access?.reason === 'NO_ACCESS') { + showError(t('tables', 'Your access was revoked. Reload the page to update your permissions.')) + } + return + } + this.downloadCsv(this.rows, this.columns, this.element.title) }, toggleShare() { diff --git a/src/pages/Context.vue b/src/pages/Context.vue index 52a888dafb..ac79bb75c4 100644 --- a/src/pages/Context.vue +++ b/src/pages/Context.vue @@ -55,6 +55,7 @@ import { useTablesStore } from '../store/store.js' import { useDataStore } from '../store/data.js' import ErrorMessage from '../modules/main/partials/ErrorMessage.vue' import displayError, { getNotFoundError, getGenericLoadError } from '../shared/utils/displayError.js' +import { showError } from '@nextcloud/dialogs' export default { components: { @@ -144,7 +145,7 @@ export default { }, methods: { - ...mapActions(useTablesStore, ['loadContext']), + ...mapActions(useTablesStore, ['loadContext', 'validateExportAccess']), ...mapActions(useDataStore, ['loadColumnsFromBE', 'loadRowsFromBE']), async reload() { if (!this.activeContextId) { @@ -236,7 +237,19 @@ export default { createColumn(isView, element) { emit('tables:column:create', { isView, element }) }, - downloadCSV(element, isView) { + async downloadCSV(element, isView) { + const access = await this.validateExportAccess({ + id: element.id, + isView, + }) + + if (!access?.ok) { + if (access?.reason === 'NO_ACCESS') { + showError(t('tables', 'Your access was revoked. Reload the page to update your permissions.')) + } + return + } + const rowId = this.getKey(isView, element.key) const colId = this.getKey(isView, element.key) this.downloadCsv(this.rows[rowId], this.columns[colId], element.title) diff --git a/src/store/store.js b/src/store/store.js index 5a2e1b17eb..3f8dafc2dc 100644 --- a/src/store/store.js +++ b/src/store/store.js @@ -556,6 +556,26 @@ export const useTablesStore = defineStore('store', { return res?.data }, + async validateExportAccess({ id, isView }) { + id = parseInt(id) + + try { + if (isView) { + await axios.get(generateUrl('/apps/tables/view/' + id)) + } else { + await axios.get(generateOcsUrl('/apps/tables/api/2/tables/' + id)) + } + } catch (e) { + if ([401, 403, 404].includes(e?.response?.status)) { + return { ok: false, reason: 'NO_ACCESS' } + } + displayError(e, t('tables', 'Could not verify export permissions.')) + return { ok: false, reason: 'ERROR' } + } + + return { ok: true } + }, + async transferContext({ id, data }) { try { await axios.put(generateOcsUrl('/apps/tables/api/2/contexts/' + id + '/transfer'), data)