Merge pull request #7 from DanielSiepmann/feature/4-support-csp

[!!!][FEATURE] Support Content Security Policy
This commit is contained in:
Benni Mack 2020-03-18 20:49:51 +01:00 committed by GitHub
commit 0310e56a01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 26 deletions

View file

@ -96,7 +96,7 @@ class FrontendEditPanel
$this->frontendController->set_no_cache('Frontend edit panel is shown', true); $this->frontendController->set_no_cache('Frontend edit panel is shown', true);
$formName = 'TSFE_EDIT_FORM_' . substr($this->frontendController->uniqueHash(), 0, 4); $formName = 'TSFE_EDIT_FORM_' . substr($this->frontendController->uniqueHash(), 0, 4);
$formTag = '<form name="' . $formName . '" id ="' . $formName . '" action="' . htmlspecialchars($this->getReturnUrl($dataArr['uid'] ?? null)) . '" method="post" enctype="multipart/form-data" onsubmit="return TBE_EDITOR.checkSubmit(1);">'; $formTag = '<form name="' . $formName . '" id ="' . $formName . '" action="' . htmlspecialchars($this->getReturnUrl($dataArr['uid'] ?? null)) . '" method="post" enctype="multipart/form-data">';
$sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby']; $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby'];
$labelField = $GLOBALS['TCA'][$table]['ctrl']['label']; $labelField = $GLOBALS['TCA'][$table]['ctrl']['label'];
$hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']; $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
@ -157,7 +157,7 @@ class FrontendEditPanel
$panel = '<!-- BE_USER Edit Panel: --> $panel = '<!-- BE_USER Edit Panel: -->
' . $formTag . $hiddenFieldString . ' ' . $formTag . $hiddenFieldString . '
<input type="hidden" name="TSFE_EDIT[cmd]" value="" /> <input type="hidden" class="typo3-feedit-cmd" name="TSFE_EDIT[cmd]" value="" />
<input type="hidden" name="TSFE_EDIT[record]" value="' . $currentRecord . '" /> <input type="hidden" name="TSFE_EDIT[record]" value="' . $currentRecord . '" />
<div class="typo3-editPanel">' <div class="typo3-editPanel">'
. '<div class="typo3-editPanel-btn-group">' . '<div class="typo3-editPanel-btn-group">'
@ -215,7 +215,7 @@ class FrontendEditPanel
// Special content is about to be shown, so the cache must be disabled. // Special content is about to be shown, so the cache must be disabled.
$this->frontendController->set_no_cache('Display frontend edit icons', true); $this->frontendController->set_no_cache('Display frontend edit icons', true);
$iconTitle = $this->cObj->stdWrap($conf['iconTitle'], $conf['iconTitle.']); $iconTitle = $this->cObj->stdWrap($conf['iconTitle'], $conf['iconTitle.']);
$iconImg = '<span title="' . htmlspecialchars($iconTitle, ENT_COMPAT, 'UTF-8', false) . '" style="' . ($conf['styleAttribute'] ? htmlspecialchars($conf['styleAttribute']) : '') . '">' $iconImg = '<span title="' . htmlspecialchars($iconTitle, ENT_COMPAT, 'UTF-8', false) . '" >'
. $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render('inline') . $this->iconFactory->getIcon('actions-document-open', Icon::SIZE_SMALL)->render('inline')
. '</span>'; . '</span>';
$noView = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0; $noView = GeneralUtility::_GP('ADMCMD_view') ? 1 : 0;
@ -317,14 +317,10 @@ class FrontendEditPanel
); );
} }
} else { } else {
if ($confirm && $this->backendUser->jsConfirmation(JsConfirmation::FE_EDIT)) { if ($confirm && $this->backendUser->jsConfirmation(JsConfirmation::FE_EDIT) === false) {
// Gets htmlspecialchared later $confirm = '';
$cf1 = 'if (confirm(' . GeneralUtility::quoteJSvalue($confirm) . ')) {';
$cf2 = '}';
} else {
$cf1 = ($cf2 = '');
} }
$out = '<a href="#" class="typo3-editPanel-btn typo3-editPanel-btn-default" onclick="' . htmlspecialchars($cf1 . 'document.' . $formName . '[\'TSFE_EDIT[cmd]\'].value=\'' . $cmd . '\'; document.' . $formName . '.submit();' . $cf2 . ' return false;') . '">' . $string . '</a>'; $out = '<a href="#" class="typo3-editPanel-btn typo3-editPanel-btn-default typo3-feedit-btn-submitForm" data-feedit-confirm="' . htmlspecialchars($confirm) . '" data-feedit-formname="' . htmlspecialchars($formName) . '" data-feedit-cmd="' . htmlspecialchars($cmd) . '">' . $string . '</a>';
} }
return $out; return $out;
} }
@ -340,10 +336,10 @@ class FrontendEditPanel
*/ */
protected function editPanelLinkWrap_doWrap($string, $url, $additionalClasses = '') protected function editPanelLinkWrap_doWrap($string, $url, $additionalClasses = '')
{ {
$width = MathUtility::forceIntegerInRange($this->backendUser->getTSConfig()['options.']['feedit.']['popupWidth'] ?? 690, 690, 5000, 690); $classes = 'typo3-editPanel-btn typo3-editPanel-btn-default typo3-feedit-btn-openBackend frontEndEditIconLinks ' . htmlspecialchars($additionalClasses);
$height = MathUtility::forceIntegerInRange($this->backendUser->getTSConfig()['options.']['feedit.']['popupHeight'] ?? 500, 500, 5000, 500); return '<a href="#" class="' . $classes . '" ' . $this->getDataAttributes($url) . '>' .
$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;'; $string .
return '<a href="#" class="typo3-editPanel-btn typo3-editPanel-btn-default frontEndEditIconLinks ' . htmlspecialchars($additionalClasses) . '" onclick="' . htmlspecialchars($onclick) . '">' . $string . '</a>'; '</a>';
} }
/** /**
@ -395,6 +391,22 @@ class FrontendEditPanel
return htmlspecialchars($this->getLanguageService()->getLL($key)); 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. * Returns the returnUrl used by TYPO3. Add this as "returnUrl=" to any url that allows the user to go back or close an form.
* *

View file

@ -56,7 +56,7 @@ class EditToolbarService
$langAllowed = $this->getBackendUser()->checkLanguageAccess($languageAspect->getId()); $langAllowed = $this->getBackendUser()->checkLanguageAccess($languageAspect->getId());
$id = $tsfe->id; $id = $tsfe->id;
$returnUrl = GeneralUtility::getIndpEnv('REQUEST_URI'); $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[] = '<div class="typo3-adminPanel-form-group">'; $output[] = '<div class="typo3-adminPanel-form-group">';
$output[] = ' <div class="typo3-adminPanel-btn-group" role="group">'; $output[] = ' <div class="typo3-adminPanel-btn-group" role="group">';

View file

@ -9,7 +9,7 @@
value: display.displayIcons }" debug="false"/> value: display.displayIcons }" debug="false"/>
<f:format.raw>{toolbar}</f:format.raw> <f:format.raw>{toolbar}</f:format.raw>
<div class="typo3-adminPanel-form-group"> <div class="typo3-adminPanel-form-group">
<a class="typo3-adminPanel-btn typo3-adminPanel-btn-default typo3-adminPanel-btn-openBackend" href="#" data-t3BeSitenameMd5="{script.t3BeSitenameMd5}" data-backendScript="{script.backendScript}"> <a class="typo3-adminPanel-btn typo3-adminPanel-btn-default typo3-feedit-btn-openBackend" href="#" data-t3BeSitenameMd5="{script.t3BeSitenameMd5}" data-backendScript="{script.backendScript}">
<f:translate key="LLL:EXT:feedit/Resources/Private/Language/locallang_edit.xlf:openAB"/> <f:translate key="LLL:EXT:feedit/Resources/Private/Language/locallang_edit.xlf:openAB"/>
</a> </a>
</div> </div>

View file

@ -7,12 +7,12 @@ this.Element && function(ElementPrototype) {
} }
}(Element.prototype); }(Element.prototype);
function editModuleOnClickHandler(event) { function openBackendHandler(event) {
event.preventDefault(); event.preventDefault();
var element = event.target; var element = event.target;
if (element.tagName !== 'A') { 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')); var vHWin = window.open(element.getAttribute('data-backendScript'), element.getAttribute('data-t3BeSitenameMd5'));
@ -20,12 +20,40 @@ function editModuleOnClickHandler(event) {
return false; return false;
} }
function initializeEditModule() { function submitFormHandler(event) {
var editModuleBtnsOpenBackend = document.querySelectorAll('.typo3-adminPanel-btn-openBackend'); event.preventDefault();
for (var i = 0, len = editModuleBtnsOpenBackend.length; i < len; i++ ) { var element = event.target;
editModuleBtnsOpenBackend[i].addEventListener('click', editModuleOnClickHandler);
} 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-feedit-btn-openBackend');
for (var i = 0, len = editModuleBtnsOpenBackend.length; i < len; i++ ) {
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); window.addEventListener('load', initializeEditModule, false);