diff options
Diffstat (limited to 'apps/theming/src/mixins/admin/TextValueMixin.js')
-rw-r--r-- | apps/theming/src/mixins/admin/TextValueMixin.js | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/apps/theming/src/mixins/admin/TextValueMixin.js b/apps/theming/src/mixins/admin/TextValueMixin.js index f550884628a..94d63ce1c8c 100644 --- a/apps/theming/src/mixins/admin/TextValueMixin.js +++ b/apps/theming/src/mixins/admin/TextValueMixin.js @@ -21,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 } }, |