From 7e2b48aab2c02f6183f1828cea3adfa376c685d2 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Fri, 31 Jan 2020 15:07:39 +0100 Subject: [PATCH] [!!!][FEATURE] Support Content Security Policy Do not use any inline style or javascript anymore. Instead js logic is moved to js file. Information are passed via data attributes. Some options are not respected anymore. That's why this change is breaking. Those options can be considered as obsolete anyway for current state of the art. Those options are: TSConfig: * options.feedit.popupWidth * options.feedit.popupHeight TypoScript: * stdWrap.editIcons.styleAttribute Resolves: #5 --- Classes/FrontendEditPanel.php | 50 ++++++++++++------- Classes/Service/EditToolbarService.php | 2 +- .../Templates/Modules/Settings/Edit.html | 2 +- Resources/Public/JavaScript/Modules/Edit.js | 38 ++++++++++++-- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/Classes/FrontendEditPanel.php b/Classes/FrontendEditPanel.php index 22d4518..d6af844 100644 --- a/Classes/FrontendEditPanel.php +++ b/Classes/FrontendEditPanel.php @@ -96,7 +96,7 @@ class FrontendEditPanel $this->frontendController->set_no_cache('Frontend edit panel is shown', true); $formName = 'TSFE_EDIT_FORM_' . substr($this->frontendController->uniqueHash(), 0, 4); - $formTag = '
'; + $formTag = ''; $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby']; $labelField = $GLOBALS['TCA'][$table]['ctrl']['label']; $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']; @@ -156,16 +156,16 @@ class FrontendEditPanel } $panel = ' - ' . $formTag . $hiddenFieldString . ' - - -
' + ' . $formTag . $hiddenFieldString . ' + + +
' . '
' . $panel . '
' . ($labelTxt ? '
' . sprintf($labelTxt, htmlspecialchars(GeneralUtility::fixed_lgd_cs($dataArr[$labelField], 50))) . '
' : '') . ' -
- '; +
+ '; // Wrap the panel if ($conf['innerWrap']) { @@ -215,7 +215,7 @@ class FrontendEditPanel // Special content is about to be shown, so the cache must be disabled. $this->frontendController->set_no_cache('Display frontend edit icons', true); $iconTitle = $this->cObj->stdWrap($conf['iconTitle'], $conf['iconTitle.']); - $iconImg = '' + $iconImg = '' . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render('inline') . ''; $noView = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0; @@ -317,14 +317,10 @@ class FrontendEditPanel ); } } else { - if ($confirm && $this->backendUser->jsConfirmation(JsConfirmation::FE_EDIT)) { - // Gets htmlspecialchared later - $cf1 = 'if (confirm(' . GeneralUtility::quoteJSvalue($confirm) . ')) {'; - $cf2 = '}'; - } else { - $cf1 = ($cf2 = ''); + if ($confirm && $this->backendUser->jsConfirmation(JsConfirmation::FE_EDIT) === false) { + $confirm = ''; } - $out = '' . $string . ''; + $out = '' . $string . ''; } return $out; } @@ -340,10 +336,10 @@ class FrontendEditPanel */ protected function editPanelLinkWrap_doWrap($string, $url, $additionalClasses = '') { - $width = MathUtility::forceIntegerInRange($this->backendUser->getTSConfig()['options.']['feedit.']['popupWidth'] ?? 690, 690, 5000, 690); - $height = MathUtility::forceIntegerInRange($this->backendUser->getTSConfig()['options.']['feedit.']['popupHeight'] ?? 500, 500, 5000, 500); - $onclick = 'vHWin=window.open(' . GeneralUtility::quoteJSvalue($url . '&returnUrl=' . rawurlencode(PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Html/Close.html')))) . ',\'FEquickEditWindow\',\'width=' . $width . ',height=' . $height . ',status=0,menubar=0,scrollbars=1,resizable=1\');vHWin.focus();return false;'; - return '' . $string . ''; + $classes = 'typo3-editPanel-btn typo3-editPanel-btn-default typo3-feedit-btn-openBackend frontEndEditIconLinks ' . htmlspecialchars($additionalClasses); + return 'getDataAttributes($url) . '>' . + $string . + ''; } /** @@ -395,6 +391,22 @@ class FrontendEditPanel return htmlspecialchars($this->getLanguageService()->getLL($key)); } + /** + * Returns data attributes to call the provided url via JavaScript. + * + * @param string $url The url to call via JavaScript. + * @return string Data attributes without whitespace at beginning or end. + */ + protected function getDataAttributes(string $url): string + { + $t3BeSitenameMd5 = md5('Typo3Backend-' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']); + + return implode(' ', [ + 'data-backendScript="' . $url . '"', + 'data-t3BeSitenameMd5="' . $t3BeSitenameMd5 . '"', + ]); + } + /** * Returns the returnUrl used by TYPO3. Add this as "returnUrl=" to any url that allows the user to go back or close an form. * diff --git a/Classes/Service/EditToolbarService.php b/Classes/Service/EditToolbarService.php index 94d387f..8ee4afe 100644 --- a/Classes/Service/EditToolbarService.php +++ b/Classes/Service/EditToolbarService.php @@ -56,7 +56,7 @@ class EditToolbarService $langAllowed = $this->getBackendUser()->checkLanguageAccess($languageAspect->getId()); $id = $tsfe->id; $returnUrl = GeneralUtility::getIndpEnv('REQUEST_URI'); - $classes = 'typo3-adminPanel-btn typo3-adminPanel-btn-default typo3-adminPanel-btn-openBackend'; + $classes = 'typo3-adminPanel-btn typo3-adminPanel-btn-default typo3-feedit-btn-openBackend'; $output = []; $output[] = '
'; $output[] = '
'; diff --git a/Resources/Private/Templates/Modules/Settings/Edit.html b/Resources/Private/Templates/Modules/Settings/Edit.html index 5433086..43e80cc 100644 --- a/Resources/Private/Templates/Modules/Settings/Edit.html +++ b/Resources/Private/Templates/Modules/Settings/Edit.html @@ -9,7 +9,7 @@ value: display.displayIcons }" debug="false"/> {toolbar} diff --git a/Resources/Public/JavaScript/Modules/Edit.js b/Resources/Public/JavaScript/Modules/Edit.js index 48d6381..7bf5b25 100644 --- a/Resources/Public/JavaScript/Modules/Edit.js +++ b/Resources/Public/JavaScript/Modules/Edit.js @@ -7,12 +7,12 @@ this.Element && function(ElementPrototype) { } }(Element.prototype); -function editModuleOnClickHandler(event) { +function openBackendHandler(event) { event.preventDefault(); var element = event.target; if (element.tagName !== 'A') { - element = element.closest('A.typo3-adminPanel-btn-openBackend'); + element = element.closest('a.typo3-feedit-btn-openBackend'); } var vHWin = window.open(element.getAttribute('data-backendScript'), element.getAttribute('data-t3BeSitenameMd5')); @@ -20,12 +20,40 @@ function editModuleOnClickHandler(event) { return false; } +function submitFormHandler(event) { + event.preventDefault(); + var element = event.target; + + if (element.tagName !== 'A') { + element = element.closest('a.typo3-feedit-btn-submitForm'); + } + + var execute = true; + var form = document[element.getAttribute('data-feedit-formname')]; + var confirmText = element.getAttribute('data-feedit-confirm'); + + if (confirmText) { + execute = confirm(confirmText); + } + + if (execute) { + form.querySelector('.typo3-feedit-cmd').value = element.getAttribute('data-feedit-cmd'); + form.submit(); + } + + return false; +} + function initializeEditModule() { - var editModuleBtnsOpenBackend = document.querySelectorAll('.typo3-adminPanel-btn-openBackend'); + var editModuleBtnsOpenBackend = document.querySelectorAll('.typo3-feedit-btn-openBackend'); for (var i = 0, len = editModuleBtnsOpenBackend.length; i < len; i++ ) { - editModuleBtnsOpenBackend[i].addEventListener('click', editModuleOnClickHandler); + editModuleBtnsOpenBackend[i].addEventListener('click', openBackendHandler); + } + + var editModuleBtnsSubmitForm = document.querySelectorAll('.typo3-feedit-btn-submitForm'); + for (var i = 0, len = editModuleBtnsSubmitForm.length; i < len; i++ ) { + editModuleBtnsSubmitForm[i].addEventListener('click', submitFormHandler); } } - window.addEventListener('load', initializeEditModule, false);