Skip to content

Commit

Permalink
Security release v2.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Helmut Hackbarth authored and Helmut Hackbarth committed Nov 20, 2023
1 parent 286f432 commit 0aa4575
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 58 deletions.
67 changes: 48 additions & 19 deletions Classes/Controller/ConsentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

namespace T3S\ContentConsent\Controller;

use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use Psr\Http\Message\ResponseInterface;


/*
* This file is part of the TYPO3 extension content_consent.
*
Expand All @@ -18,6 +19,18 @@
class ConsentController extends ActionController
{

protected $fileRepository;
protected $assetHelper;
protected $connectionPool;

public function __construct(
FileRepository $fileRepository,
ContentObjectRenderer $contentObjectRenderer
) {
$this->fileRepository = $fileRepository;
$this->contentObjectRenderer = $contentObjectRenderer;
}

/**
* action index
*
Expand All @@ -33,32 +46,30 @@ public function indexAction(): ResponseInterface
$type = 0;
$currentRecord = $this->request->getAttribute('currentContentObject')->data['uid'];

if ( $this->settings['consent']['cookie']
if ( $this->settings['consent']['cookie']
&& isset($_COOKIE['t3scontentconsent_'.$currentRecord])
&& $_COOKIE['t3scontentconsent_'.$currentRecord] == 'allow' ) {

$contentConsent = TRUE;

} else {

$fileRepository = GeneralUtility::makeInstance(FileRepository::class);

// Custom thumbnail
if ( !empty($this->settings['consent']['thumbnail']) ) {

$relatedCustomThumbnails = $fileRepository->findByRelation('tt_content', 'settings.consent.thumbnail', $currentRecord);
$relatedCustomThumbnails = $this->fileRepository->findByRelation('tt_content', 'settings.consent.thumbnail', $currentRecord);
$customThumbnail = !empty($relatedCustomThumbnails[0]) ? $relatedCustomThumbnails[0] : [];
$defaultThumbnail = [];
if ( empty($customThumbnail) ) {
// if media is hidden -> use default
$defaultThumbnail = $fileRepository->findByRelation('tt_content', 'assets', (int) $this->settings['consent']['contentByUid'])[0];
$defaultThumbnail = $this->fileRepository->findByRelation('tt_content', 'assets', (int) $this->settings['consent']['contentByUid'])[0];
}
}

// Default thumbnail
if ( !empty($this->settings['consent']['defaultThumbnail']) ) {

$relatedDefaultThumbnails = $fileRepository->findByRelation('tt_content', 'assets', (int) $this->settings['consent']['contentByUid']);
$relatedDefaultThumbnails = $this->fileRepository->findByRelation('tt_content', 'assets', (int) $this->settings['consent']['contentByUid']);
if ( !empty($relatedDefaultThumbnails[0]) ) {
$defaultThumbnail = $relatedDefaultThumbnails[0];
$properties = $defaultThumbnail->getOriginalFile()->getProperties();
Expand All @@ -71,6 +82,8 @@ public function indexAction(): ResponseInterface
$defaultThumbnail = [];
}
}

$hash = GeneralUtility::hmac($this->settings['consent']['contentByUid'], self::class);

$assignedValues = [
'currentRecord' => $currentRecord,
Expand All @@ -79,6 +92,7 @@ public function indexAction(): ResponseInterface
'type' => $type,
'customThumbnail' => $customThumbnail,
'defaultThumbnail' => $defaultThumbnail,
'hash' => $hash,
'typeNum' => (int) $this->settings['ajaxTypeNum']
];
$this->view->assignMultiple($assignedValues);
Expand All @@ -87,30 +101,45 @@ public function indexAction(): ResponseInterface
}



/**
* Displays the selected content with ajax
*
*/
public function ajaxAction(): ResponseInterface
{
$success = FALSE;
$post = $this->request->getParsedBody();

if ( !empty($post['cookies'])) {
$cookieExpire = $this->settings['cookieExpire'] ? (int)$this->settings['cookieExpire'] : 30;
setcookie('t3scontentconsent_'.(int)$post['currentRecord'], 'allow', time() + (86400 * $cookieExpire), '/');
if (!empty($post)) {
$expected = GeneralUtility::hmac($post['contentByUid'], self::class);
$success = hash_equals($expected, $post['hash']);
}

$conf ['tables'] = 'tt_content';
$conf ['source'] = $post['contentByUid'];
$conf ['dontCheckPid'] = 1;
if (!empty($success)) {

if ( !empty($post['cookies'])) {
$cookieExpire = $this->settings['cookieExpire'] ? (int)$this->settings['cookieExpire'] : 30;
setcookie('t3scontentconsent_'.(int)$post['currentRecord'], 'allow', time() + (86400 * $cookieExpire), '/');
}

$cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
$data = $cObj->cObjGetSingle('RECORDS', $conf);
$conf ['tables'] = 'tt_content';
$conf ['source'] = (int)$post['contentByUid'];
$conf ['dontCheckPid'] = 1;

return $this->responseFactory->createResponse()
->withHeader('Content-Type', 'application/json')
->withBody($this->streamFactory->createStream($data));
$data = $this->contentObjectRenderer->cObjGetSingle('RECORDS', $conf);

return $this->responseFactory->createResponse()
->withHeader('Content-Type', 'application/text')
->withBody($this->streamFactory->createStream($data));

} else {

$data = '<div class="alert alert-danger" role="alert">No Success!</div>';
return $this->responseFactory->createResponse()
->withHeader('Content-Type', 'application/text')
->withBody($this->streamFactory->createStream('Bad call'));
}
}


}
34 changes: 16 additions & 18 deletions Resources/Private/Templates/Consent/Index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<f:layout name="Default" />
<f:section name="content">
<f:flashMessages />
<div id="content-{settings.consent.contentByUid}" class="w-100 card border-0 rounded-0{f:if(condition: settings.consent.autoSize, then: ' {settings.consent.autoSize}')}" >
<div id="content-{settings.consent.contentByUid}" class="w-100 card border-0 rounded-0{f:if(condition: settings.consent.autoSize, then: ' {settings.consent.autoSize}')}" data-hash="{hash}" >
<f:if condition="{contentConsent}">
<f:then>
<f:cObject typoscriptObjectPath="lib.contentByUid" data="{settings.consent.contentByUid}" />
Expand Down Expand Up @@ -38,23 +38,21 @@
</div>
</f:then>
<f:else>

<f:if condition="{defaultThumbnail.originalFile.properties.identifier}">
<f:then>
<div class="t3s-content-consent{f:if(condition: settings.consent.extraClass, then: ' {settings.consent.extraClass}')}"
style="background: url({f:uri.image(image: '{defaultThumbnail}')}) no-repeat center; background-size: cover;
{f:if(condition: settings.consent.height, then: ' min-height: {settings.consent.height}px')}">
<f:render section="Overlay" arguments="{_all}" />
</div>
</f:then>
<f:else>
<div class="t3s-content-consent{f:if(condition: settings.consent.extraClass, then: ' {settings.consent.extraClass}')}"
style="{f:if(condition: settings.consent.height, then: ' min-height: {settings.consent.height}px')}">
<f:render section="Overlay" arguments="{_all}" />
</div>
</f:else>
</f:if>

<f:if condition="{defaultThumbnail.originalFile.properties.identifier}">
<f:then>
<div class="t3s-content-consent{f:if(condition: settings.consent.extraClass, then: ' {settings.consent.extraClass}')}"
style="background: url({f:uri.image(image: '{defaultThumbnail}')}) no-repeat center; background-size: cover;
{f:if(condition: settings.consent.height, then: ' min-height: {settings.consent.height}px')}">
<f:render section="Overlay" arguments="{_all}" />
</div>
</f:then>
<f:else>
<div class="t3s-content-consent{f:if(condition: settings.consent.extraClass, then: ' {settings.consent.extraClass}')}"
style="{f:if(condition: settings.consent.height, then: ' min-height: {settings.consent.height}px')}">
<f:render section="Overlay" arguments="{_all}" />
</div>
</f:else>
</f:if>
</f:else>
</f:if>
</f:else>
Expand Down
8 changes: 4 additions & 4 deletions Resources/Public/Scripts/contentconsent.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

function ajaxConsentCall(contentByUid, currentRecord, cookies)
function ajaxConsentCall(contentByUid, currentRecord, cookies)
{
let resultContainer = document.getElementById('content-'+contentByUid)
let resultContainer = document.getElementById('content-'+contentByUid),
hash = resultContainer.getAttribute('data-hash'),
button = document.getElementById('trigger-button-'+contentByUid),
url = button.dataset.url,
ajaxCall = new XMLHttpRequest();
Expand All @@ -18,6 +19,5 @@ function ajaxConsentCall(contentByUid, currentRecord, cookies)

ajaxCall.open('POST', url);
ajaxCall.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajaxCall.send('contentByUid='+contentByUid+'&currentRecord='+currentRecord+'&cookies='+cookies);
ajaxCall.send('contentByUid='+contentByUid+'&currentRecord='+currentRecord+'&cookies='+cookies+'&hash='+hash);
}

53 changes: 36 additions & 17 deletions ext_emconf.php
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
<?php

$EM_CONF[$_EXTKEY] = [
'title' => 'Content Consent',
'description' => 'Provides a content consent plugin to load any content elements and custom plugins by ajax without jQuery! So you can include Google Maps, YouTube- or Vimeo videos GDPR/DSGVO compliant. Best used with Bootstrap 5',
'category' => 'plugin',
'author' => 'Helmut Hackbarth',
'author_email' => 'typo3@t3solution.de',
'state' => 'stable',
'clearCacheOnLoad' => 0,
'version' => '2.0.1',
'constraints' => [
'depends' => [
'typo3' => '12.4.0-12.9.99',
],
'conflicts' => [],
'suggests' => [],
],
];
/***************************************************************
* Extension Manager/Repository config file for ext "content_consent".
*
* Auto generated 02-10-2023 10:17
*
* Manual updates:
* Only the data in the array - everything else is removed by next
* writing. "version" and "dependencies" must not be touched!
***************************************************************/

$EM_CONF[$_EXTKEY] = array (
'title' => 'Content Consent',
'description' => 'Provides a content consent plugin to load any content elements and custom plugins by ajax without jQuery! So you can include Google Maps, YouTube- or Vimeo videos GDPR/DSGVO compliant. Best used with Bootstrap 5',
'category' => 'plugin',
'version' => '2.0.2',
'state' => 'stable',
'uploadfolder' => false,
'clearcacheonload' => false,
'author' => 'Helmut Hackbarth',
'author_email' => 'typo3@t3solution.de',
'author_company' => NULL,
'constraints' =>
array (
'depends' =>
array (
'typo3' => '12.4.0-12.9.99',
),
'conflicts' =>
array (
),
'suggests' =>
array (
),
),
);

0 comments on commit 0aa4575

Please sign in to comment.