fix: product pages no longer serve one visitor's back link to everyone
The "back to search results" link took ?ref= as it came and was cached with the page, which ignores ref: the first visitor of a product page set the link for every later one, and a javascript: URL in ref put script into the page for all of them (verified locally). The page now always renders the link hidden and without a target; the backlink Stimulus controller fills in the visitor's own ?ref= and shows it, only for URLs of the same origin. The label stays "zurück zum Suchergebnis": refs only come from the search, and the old check (strpos() !== -1) always picked that label anyway. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
b428ce9086
commit
170e14dae5
3 files changed
+29
-12
No files matched your search
@@ -91,10 +91,6 @@ class ProductController extends ActionController
|
||||
$isProductWithGroupInquiryForm = ($concept !== null) && \in_array($concept->getUid(), $groupInquiryFormConceptUids);
|
||||
$nonBookableInfo = $product->getNonBookableInfo();
|
||||
|
||||
// Assemble backlink
|
||||
$backlinkUrl = $this->request->getQueryParams()['ref'] ?? null;
|
||||
$backLinkLabel = strpos((string)$backlinkUrl, 'suche') !== -1 ? 'zurück zum Suchergebnis' : 'zurück';
|
||||
|
||||
$this->view->assignMultiple([
|
||||
'hotel' => $hotel,
|
||||
'product' => $product,
|
||||
@@ -106,8 +102,6 @@ class ProductController extends ActionController
|
||||
'currentPageUid' => $this->request->getAttribute('frontend.page.information')->getId(),
|
||||
'dateFrom' => $dateFrom,
|
||||
'dateTo' => $dateTo,
|
||||
'referringUrl' => $backlinkUrl,
|
||||
'backlinkLabel' => $backLinkLabel,
|
||||
'nonBookableInfo' => $nonBookableInfo,
|
||||
'pickupsOverview' => $this->pickupOverviewService->getOverview($product, $hotel),
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Controller } from '@hotwired/stimulus'
|
||||
|
||||
// The page is cached alike for every visitor, so the link back to the visitor's own search is
|
||||
// taken from ?ref= here, and only when it points to this site: anything else, javascript: URLs
|
||||
// included, has a different origin
|
||||
export default class extends Controller {
|
||||
|
||||
connect() {
|
||||
const ref = new URLSearchParams(window.location.search).get('ref')
|
||||
if (null === ref) {
|
||||
return
|
||||
}
|
||||
let url
|
||||
try {
|
||||
url = new URL(ref, window.location.href)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
if (url.origin !== window.location.origin) {
|
||||
return
|
||||
}
|
||||
this.element.href = url.href
|
||||
this.element.classList.remove('hidden')
|
||||
}
|
||||
}
|
||||
@@ -55,12 +55,10 @@
|
||||
</div>
|
||||
</f:if>
|
||||
</div>
|
||||
<f:if condition="{referringUrl}">
|
||||
<a href="{referringUrl}" class="button bg-button button--small mt-8">
|
||||
{ep:icon(icon: 'chevron-left', class: 'w-4 h-4 text-white')}
|
||||
<span>{backlinkLabel}</span>
|
||||
</a>
|
||||
</f:if>
|
||||
<a class="button bg-button button--small mt-8 hidden" data-controller="backlink">
|
||||
{ep:icon(icon: 'chevron-left', class: 'w-4 h-4 text-white')}
|
||||
<span>zurück zum Suchergebnis</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<f:render partial="Badge" arguments="{badge: product.badge}"/>
|
||||
|
||||
Reference in new issue
Block a user