diff options
Diffstat (limited to 'apps/theming/src/mixins/admin/TextValueMixin.js')
-rw-r--r-- | apps/theming/src/mixins/admin/TextValueMixin.js | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/apps/theming/src/mixins/admin/TextValueMixin.js b/apps/theming/src/mixins/admin/TextValueMixin.js index 4cce8bb301a..94d63ce1c8c 100644 --- a/apps/theming/src/mixins/admin/TextValueMixin.js +++ b/apps/theming/src/mixins/admin/TextValueMixin.js @@ -1,23 +1,6 @@ /** - * @copyright 2022 Christopher Ng <chrng8@gmail.com> - * - * @author Christopher Ng <chrng8@gmail.com> - * - * @license AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ import axios from '@nextcloud/axios' @@ -38,25 +21,56 @@ export default { data() { return { + /** @type {string|boolean} */ localValue: this.value, } }, + computed: { + valueToPost() { + if (this.type === 'url') { + // if this is already encoded just make sure there is no doublequote (HTML XSS) + // otherwise simply URL encode + return this.isUrlEncoded(this.localValue) + ? this.localValue.replaceAll('"', '%22') + : encodeURI(this.localValue) + } + // Convert boolean to string as server expects string value + if (typeof this.localValue === 'boolean') { + return this.localValue ? 'yes' : 'no' + } + return this.localValue + }, + }, + methods: { + /** + * Check if URL is percent-encoded + * @param {string} url The URL to check + * @return {boolean} + */ + isUrlEncoded(url) { + try { + return decodeURI(url) !== url + } catch { + return false + } + }, + async save() { this.reset() const url = generateUrl('/apps/theming/ajax/updateStylesheet') - // Convert boolean to string as server expects string value - const valueToPost = this.localValue === true ? 'yes' : this.localValue === false ? 'no' : this.localValue + try { await axios.post(url, { setting: this.name, - value: valueToPost, + value: this.valueToPost, }) this.$emit('update:value', this.localValue) this.handleSuccess() } catch (e) { - this.errorMessage = e.response.data.data?.message + console.error('Failed to save changes', e) + this.errorMessage = e.response?.data.data?.message } }, @@ -64,10 +78,14 @@ export default { this.reset() const url = generateUrl('/apps/theming/ajax/undoChanges') try { - await axios.post(url, { + const { data } = await axios.post(url, { setting: this.name, }) - this.$emit('update:value', this.defaultValue) + + if (data.data.value) { + this.$emit('update:defaultValue', data.data.value) + } + this.$emit('update:value', data.data.value || this.defaultValue) this.handleSuccess() } catch (e) { this.errorMessage = e.response.data.data?.message |