Skip to content

Commit cdd0208

Browse files
authored
Merge pull request #1656 from nextcloud/restrict-protocols
enh: Restrict text link protocols
2 parents d60cff2 + 85fb752 commit cdd0208

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

src/modules/modals/CreateRow.vue

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
type="error">
1818
{{ t('tables', '"{columnTitle}" should not be empty', { columnTitle: column.title }) }}
1919
</NcNoteCard>
20+
<NcNoteCard v-if="row[column.id] && column.type === 'text-link' && !isValidUrlProtocol(row[column.id])"
21+
type="error">
22+
{{ t('tables', 'Invalid protocol. Allowed: {allowed}', {allowed: allowedProtocols.join(', ')}) }}
23+
</NcNoteCard>
2024
</div>
2125
<div class="row">
2226
<div class="fix-col-4 space-T end">
@@ -25,7 +29,7 @@
2529
{{ t('tables', 'Add more') }}
2630
</NcCheckboxRadioSwitch>
2731
</div>
28-
<NcButton v-if="!localLoading" class="primary" :aria-label="t('tables', 'Save row')" :disabled="hasEmptyMandatoryRows" data-cy="createRowSaveButton" @click="actionConfirm()">
32+
<NcButton v-if="!localLoading" class="primary" :aria-label="t('tables', 'Save row')" :disabled="hasEmptyMandatoryRows || hasInvalidUrlProtocol" data-cy="createRowSaveButton" @click="actionConfirm()">
2933
{{ t('tables', 'Save') }}
3034
</NcButton>
3135
</div>
@@ -43,6 +47,7 @@ import { translate as t } from '@nextcloud/l10n'
4347
import rowHelper from '../../shared/components/ncTable/mixins/rowHelper.js'
4448
import { useDataStore } from '../../store/data.js'
4549
import { mapActions } from 'pinia'
50+
import { ALLOWED_PROTOCOLS } from '../../shared/constants.js'
4651
4752
export default {
4853
name: 'CreateRow',
@@ -77,6 +82,7 @@ export default {
7782
row: {},
7883
localLoading: false,
7984
addNewAfterSave: false,
85+
allowedProtocols: ALLOWED_PROTOCOLS,
8086
}
8187
},
8288
computed: {
@@ -86,6 +92,9 @@ export default {
8692
hasEmptyMandatoryRows() {
8793
return this.checkMandatoryFields(this.row)
8894
},
95+
hasInvalidUrlProtocol() {
96+
return this.nonMetaColumns.some(col => col.type === 'text-link' && !this.isValidUrlProtocol(this.row[col.id]))
97+
},
8998
},
9099
watch: {
91100
showModal() {

src/modules/modals/EditRow.vue

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
type="error">
1818
{{ t('tables', '"{columnTitle}" should not be empty', { columnTitle: column.title }) }}
1919
</NcNoteCard>
20+
<NcNoteCard v-if="localRow[column.id] && column.type === 'text-link' && !isValidUrlProtocol(localRow[column.id])"
21+
type="error">
22+
{{ t('tables', 'Invalid protocol. Allowed: {allowed}', {allowed: allowedProtocols.join(', ')}) }}
23+
</NcNoteCard>
2024
</div>
2125
<div class="row">
2226
<div class="fix-col-4 space-T" :class="{'justify-between': showDeleteButton, 'end': !showDeleteButton}">
@@ -35,7 +39,7 @@
3539
</div>
3640
<NcButton v-if="canUpdateData(element) && !localLoading" :aria-label="t('tables', 'Save')" type="primary"
3741
data-cy="editRowSaveButton"
38-
:disabled="hasEmptyMandatoryRows"
42+
:disabled="hasEmptyMandatoryRows || hasInvalidUrlProtocol"
3943
@click="actionConfirm">
4044
{{ t('tables', 'Save') }}
4145
</NcButton>
@@ -57,6 +61,7 @@ import rowHelper from '../../shared/components/ncTable/mixins/rowHelper.js'
5761
import { mapActions } from 'pinia'
5862
import { useTablesStore } from '../../store/store.js'
5963
import { useDataStore } from '../../store/data.js'
64+
import { ALLOWED_PROTOCOLS } from '../../shared/constants.js'
6065
6166
export default {
6267
name: 'EditRow',
@@ -94,6 +99,7 @@ export default {
9499
localRow: null,
95100
prepareDeleteRow: false,
96101
localLoading: false,
102+
allowedProtocols: ALLOWED_PROTOCOLS,
97103
}
98104
},
99105
computed: {
@@ -106,6 +112,9 @@ export default {
106112
hasEmptyMandatoryRows() {
107113
return this.checkMandatoryFields(this.localRow)
108114
},
115+
hasInvalidUrlProtocol() {
116+
return this.nonMetaColumns.some(col => col.type === 'text-link' && !this.isValidUrlProtocol(this.localRow[col.id]))
117+
},
109118
},
110119
watch: {
111120
row() {

src/shared/components/ncTable/mixins/rowHelper.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55
import { ColumnTypes } from './columnHandler.js'
6+
import { ALLOWED_PROTOCOLS } from '../../../constants.js'
7+
68
export default {
79
methods: {
810
isValueValidForColumn(value, column) {
@@ -35,5 +37,15 @@ export default {
3537
})
3638
return mandatoryFieldsEmpty
3739
},
40+
41+
isValidUrlProtocol(value) {
42+
value = JSON.parse(value ?? '{}')
43+
try {
44+
const parsedUrl = new URL(value?.value)
45+
return ALLOWED_PROTOCOLS.includes(parsedUrl.protocol)
46+
} catch (e) {
47+
return false
48+
}
49+
},
3850
},
3951
}

src/shared/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ export const NAV_ENTRY_MODE = {
3131
// NAV_ENTRY_MODE_RECIPIENTS: 1, // nav bar entry for share recipients, but not the owner. Currently unused.
3232
NAV_ENTRY_MODE_ALL: 2, // nav bar entry for everybody
3333
}
34+
35+
export const ALLOWED_PROTOCOLS = ['http:', 'https:']

0 commit comments

Comments
 (0)