From a7ca3a7557d48fed4e5c19ca677c2a34e2f1eb66 Mon Sep 17 00:00:00 2001 From: Tim Fischbach Date: Fri, 28 Jun 2024 16:37:16 +0200 Subject: [PATCH] Allow opening external privacy settings via privacy link This is an ugly workaround to allow triggering a global function that displays a consent layer. This wants to be an official JS API instead someday. But since Pageflow itself currently does not have a concept of external consent, today is not that day. REDMINE-20765 --- app/helpers/pageflow/entries_helper.rb | 5 ++- .../defaultNavigation/LegalInfoLink-spec.js | 31 ++++++++++++++++++ .../defaultNavigation/LegalInfoLink.js | 16 ++++++++++ spec/helpers/pageflow/entries_helper_spec.rb | 32 ++++++++++++++++--- 4 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 entry_types/scrolled/package/spec/widgets/defaultNavigation/LegalInfoLink-spec.js diff --git a/app/helpers/pageflow/entries_helper.rb b/app/helpers/pageflow/entries_helper.rb index 9eed212c0b..19752f0389 100644 --- a/app/helpers/pageflow/entries_helper.rb +++ b/app/helpers/pageflow/entries_helper.rb @@ -61,6 +61,8 @@ def ensure_entry_with_revision(entry) def entry_privacy_link_url(entry) return unless entry.site.privacy_link_url.present? + return entry.site.privacy_link_url if entry.site.privacy_link_url.start_with?('javascript:') + "#{entry.site.privacy_link_url}?lang=#{entry.locale}" end @@ -102,7 +104,8 @@ def entry_global_links(entry) if entry.site.privacy_link_url.present? links << link_to(I18n.t('pageflow.public.privacy_notice'), entry_privacy_link_url(entry), - target: '_blank', + target: + entry.site.privacy_link_url.start_with?('javascript:') ? nil : '_blank', tabindex: 2, class: 'privacy') end diff --git a/entry_types/scrolled/package/spec/widgets/defaultNavigation/LegalInfoLink-spec.js b/entry_types/scrolled/package/spec/widgets/defaultNavigation/LegalInfoLink-spec.js new file mode 100644 index 0000000000..12e5a7e5b8 --- /dev/null +++ b/entry_types/scrolled/package/spec/widgets/defaultNavigation/LegalInfoLink-spec.js @@ -0,0 +1,31 @@ +import React from 'react'; + +import {LegalInfoLink} from 'widgets/defaultNavigation/LegalInfoLink'; + +import {render} from '@testing-library/react'; +import '@testing-library/jest-dom/extend-expect'; + +describe('LegalInfoLink', () => { + it('renders target blank by default', () => { + const {getByRole} = render( + + ); + + expect(getByRole('link')).toHaveTextContent('Copyright'); + expect(getByRole('link')).toHaveAttribute('href', 'https://example.com'); + expect(getByRole('link')).toHaveAttribute('target', '_blank'); + expect(getByRole('link')).toHaveAttribute('rel', 'noreferrer noopener'); + }); + + it('supports javascript url scheme', () => { + const {getByRole} = render( + // eslint-disable-next-line no-script-url + + ) + + expect(getByRole('link')).toHaveTextContent('Copyright'); + expect(getByRole('link')).toHaveAttribute('href', '#privacySettings'); + expect(getByRole('link')).not.toHaveAttribute('target'); + expect(getByRole('link')).not.toHaveAttribute('rel'); + }); +}); diff --git a/entry_types/scrolled/package/src/widgets/defaultNavigation/LegalInfoLink.js b/entry_types/scrolled/package/src/widgets/defaultNavigation/LegalInfoLink.js index 8be81f5347..054c25c040 100644 --- a/entry_types/scrolled/package/src/widgets/defaultNavigation/LegalInfoLink.js +++ b/entry_types/scrolled/package/src/widgets/defaultNavigation/LegalInfoLink.js @@ -2,6 +2,22 @@ import React from 'react'; import styles from "./LegalInfoMenu.module.css"; export function LegalInfoLink(props) { + // eslint-disable-next-line no-script-url + if (props.url === 'javascript:pageflowDisplayPrivacySettings()' && props.label) { + return ( +
+ { + window.pageflowDisplayPrivacySettings(); + event.preventDefault(); + }} + className={styles.legalInfoLink} + dangerouslySetInnerHTML={{__html: props.label}}> + +
+ ) + } + return (
{props.label && props.url && diff --git a/spec/helpers/pageflow/entries_helper_spec.rb b/spec/helpers/pageflow/entries_helper_spec.rb index 1e5414ab6d..f665db4025 100644 --- a/spec/helpers/pageflow/entries_helper_spec.rb +++ b/spec/helpers/pageflow/entries_helper_spec.rb @@ -178,10 +178,10 @@ module Pageflow describe '#entry_privacy_link_url' do it 'uses configured url and locale' do site = create(:site, - privacy_link_url: 'https://example.com/privacy') + privacy_link_url: 'https://example.com/privacy') entry = PublishedEntry.new(create(:entry, :published, - site: site, + site:, published_revision_attributes: { locale: 'de' })) @@ -201,6 +201,16 @@ module Pageflow expect(result).to be_nil end + + it 'supports javascript scheme' do + site = create(:site, + privacy_link_url: 'javascript:triggerConsentLayer()') + entry = PublishedEntry.new(create(:entry, :published, site:)) + + result = helper.entry_privacy_link_url(entry) + + expect(result).to eq('javascript:triggerConsentLayer()') + end end describe '#entry_file_rights' do @@ -368,17 +378,29 @@ module Pageflow it 'includes privacy link if configured' do site = create(:site, - privacy_link_url: 'https://example.com/privacy') + privacy_link_url: 'https://example.com/privacy') entry = PublishedEntry.new(create(:entry, :published, - site: site, + site:, published_revision_attributes: { locale: 'de' })) result = helper.entry_global_links(entry) - expect(result).to have_selector('a[href="https://example.com/privacy?lang=de"]') + expect(result) + .to have_selector('a[target="_blank"][href="https://example.com/privacy?lang=de"]') + end + + it 'supports javascript scheme for privacy link' do + site = create(:site, + privacy_link_url: 'javascript:triggerConsentLayer()') + entry = PublishedEntry.new(create(:entry, :published, site:)) + + result = helper.entry_global_links(entry) + + expect(result) + .to have_selector('a:not([target])[href="javascript:triggerConsentLayer()"]') end end end