fivo_cookie_consent 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.nvmrc +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.windsurfrules +76 -0
- data/CHANGELOG.md +64 -0
- data/LICENSE.txt +21 -0
- data/README.md +524 -0
- data/Rakefile +11 -0
- data/app/assets/javascripts/fivo_cookie_consent.js +924 -0
- data/app/assets/stylesheets/fivo_cookie_consent.scss +654 -0
- data/app/helpers/rails_cookies_gdpr/application_helper.rb +156 -0
- data/app/views/rails_cookies_gdpr/_banner.html.erb +27 -0
- data/app/views/rails_cookies_gdpr/_modal.html.erb +123 -0
- data/config/database.yml +6 -0
- data/db/test.sqlite3 +0 -0
- data/db/test.sqlite3-shm +0 -0
- data/db/test.sqlite3-wal +0 -0
- data/lib/fivo_cookie_consent/configuration.rb +141 -0
- data/lib/fivo_cookie_consent/engine.rb +31 -0
- data/lib/fivo_cookie_consent/railtie.rb +18 -0
- data/lib/fivo_cookie_consent/version.rb +5 -0
- data/lib/fivo_cookie_consent.rb +16 -0
- data/lib/generators/fivo_cookie_consent/install_generator.rb +144 -0
- data/scratchpad.md +315 -0
- data/yarn.lock +4 -0
- metadata +190 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsCookiesGdpr
|
|
4
|
+
# Main helper module for GDPR cookie consent functionality
|
|
5
|
+
module ApplicationHelper
|
|
6
|
+
# Renders the GDPR cookie consent banner with server-side cookie data
|
|
7
|
+
# @return [String] HTML markup for the cookie consent banner and modal
|
|
8
|
+
def gdpr_cookie_banner
|
|
9
|
+
render partial: 'rails_cookies_gdpr/banner'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Detects server-side cookies that JavaScript cannot access (HttpOnly)
|
|
13
|
+
# @return [Hash] Hash of categorized server-side cookies
|
|
14
|
+
def detect_server_side_cookies
|
|
15
|
+
cookies_data = {
|
|
16
|
+
necessary: []
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return cookies_data unless respond_to?(:request) && request
|
|
20
|
+
|
|
21
|
+
# Ensure Rails sets a real session cookie for this response.
|
|
22
|
+
# Accessing +session.id+ forces session creation if it does not exist yet.
|
|
23
|
+
session.id
|
|
24
|
+
|
|
25
|
+
# Determine the session cookie key configured for the app
|
|
26
|
+
session_key = Rails.application.config.session_options[:key] || '_session'
|
|
27
|
+
session_keys = [session_key, '_session'].uniq
|
|
28
|
+
|
|
29
|
+
session_keys.each do |key|
|
|
30
|
+
cookies_data[:necessary] << {
|
|
31
|
+
name: key,
|
|
32
|
+
duration: 'Session',
|
|
33
|
+
description: 'Speichert Sitzungsdaten für die Funktionalität der Website',
|
|
34
|
+
server_side: true
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Detect CSRF token cookie (only if present)
|
|
39
|
+
csrf_cookie_name = 'csrf_token'
|
|
40
|
+
if request.cookies[csrf_cookie_name]
|
|
41
|
+
cookies_data[:necessary] << {
|
|
42
|
+
name: csrf_cookie_name,
|
|
43
|
+
duration: 'Session',
|
|
44
|
+
description: 'Schutz vor Cross-Site Request Forgery (CSRF) Angriffen',
|
|
45
|
+
server_side: true
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Check for other common Rails cookies if they already exist
|
|
50
|
+
rails_cookies = [
|
|
51
|
+
{ name: '_rails_session', description: 'Rails Sitzungsdaten' },
|
|
52
|
+
{ name: 'authenticity_token', description: 'Rails Authentifizierungstoken' },
|
|
53
|
+
{ name: '_session_id', description: 'Sitzungs-Identifikator' }
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
rails_cookies.each do |cookie_info|
|
|
57
|
+
next unless request.cookies[cookie_info[:name]]
|
|
58
|
+
|
|
59
|
+
cookies_data[:necessary] << {
|
|
60
|
+
name: cookie_info[:name],
|
|
61
|
+
duration: 'Session',
|
|
62
|
+
description: cookie_info[:description],
|
|
63
|
+
server_side: true
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
cookies_data
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Returns a JSON string of detected server-side cookies that is safe to embed
|
|
71
|
+
# inside an HTML attribute. Rely on Rails’ automatic HTML escaping instead
|
|
72
|
+
# of marking the string as +html_safe+, otherwise the attribute would break
|
|
73
|
+
# because the quotes inside the JSON would not be escaped, resulting in
|
|
74
|
+
# invalid markup and a subsequent JSON.parse() error in the browser.
|
|
75
|
+
#
|
|
76
|
+
# @return [String] Escaped JSON string
|
|
77
|
+
def server_cookies_json
|
|
78
|
+
detect_server_side_cookies.to_json
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def gdpr_consent_mode_defaults(functionality: true, security: true)
|
|
82
|
+
analytics_default = functionality ? 'granted' : 'denied'
|
|
83
|
+
functionality_default = functionality ? 'granted' : 'denied'
|
|
84
|
+
security_default = security ? 'granted' : 'denied'
|
|
85
|
+
|
|
86
|
+
script = <<~JS
|
|
87
|
+
window.dataLayer = window.dataLayer || [];
|
|
88
|
+
function gtag(){ dataLayer.push(arguments); }
|
|
89
|
+
gtag('consent', 'default', {
|
|
90
|
+
ad_storage: 'denied',
|
|
91
|
+
analytics_storage: '#{analytics_default}',
|
|
92
|
+
functionality_storage: '#{functionality_default}',
|
|
93
|
+
security_storage: '#{security_default}',
|
|
94
|
+
personalization_storage: 'denied'
|
|
95
|
+
});
|
|
96
|
+
document.addEventListener('gdpr:accept', function(event) {
|
|
97
|
+
var detail = event && event.detail || {};
|
|
98
|
+
var categories = detail.categories || [];
|
|
99
|
+
var analyticsGranted = categories.indexOf('analytics') !== -1;
|
|
100
|
+
var marketingGranted = categories.indexOf('marketing') !== -1;
|
|
101
|
+
var functionalGranted = categories.indexOf('functional') !== -1;
|
|
102
|
+
gtag('consent', 'update', {
|
|
103
|
+
ad_storage: marketingGranted ? 'granted' : 'denied',
|
|
104
|
+
analytics_storage: analyticsGranted ? 'granted' : 'denied',
|
|
105
|
+
functionality_storage: functionalGranted ? 'granted' : 'denied'
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
document.addEventListener('gdpr:decline', function() {
|
|
109
|
+
gtag('consent', 'update', {
|
|
110
|
+
ad_storage: 'denied',
|
|
111
|
+
analytics_storage: 'denied',
|
|
112
|
+
functionality_storage: 'denied'
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
JS
|
|
116
|
+
|
|
117
|
+
content_tag(:script, script.html_safe)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def gdpr_lazy_load_tag(name, **options)
|
|
121
|
+
name_sym = name.to_sym
|
|
122
|
+
config = RailsCookiesGdpr.configuration
|
|
123
|
+
registered = config.respond_to?(:registered_scripts) ? RailsCookiesGdpr.registered_scripts[name_sym] : {}
|
|
124
|
+
merged = (registered || {}).merge(options)
|
|
125
|
+
|
|
126
|
+
category = (merged[:category] || :analytics).to_s
|
|
127
|
+
attrs = { type: 'text/plain', 'data-gdpr-category': category }
|
|
128
|
+
|
|
129
|
+
case name_sym
|
|
130
|
+
when :gtm
|
|
131
|
+
gtm_id = merged[:id] || merged[:gtm_id]
|
|
132
|
+
return '' unless gtm_id
|
|
133
|
+
attrs['data-gdpr-src'] = "https://www.googletagmanager.com/gtm.js?id=#{gtm_id}"
|
|
134
|
+
attrs['data-gdpr-async'] = 'true'
|
|
135
|
+
when :ga4, :gtag
|
|
136
|
+
measurement_id = merged[:id] || merged[:measurement_id]
|
|
137
|
+
return '' unless measurement_id
|
|
138
|
+
attrs['data-gdpr-src'] = "https://www.googletagmanager.com/gtag/js?id=#{measurement_id}"
|
|
139
|
+
attrs['data-gdpr-async'] = 'true'
|
|
140
|
+
else
|
|
141
|
+
src = merged[:src]
|
|
142
|
+
attrs['data-gdpr-src'] = src if src
|
|
143
|
+
attrs['data-gdpr-async'] = 'true' if merged[:async]
|
|
144
|
+
attrs['data-gdpr-defer'] = 'true' if merged[:defer]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
inline_code = merged[:inline_code]
|
|
148
|
+
|
|
149
|
+
if inline_code
|
|
150
|
+
content_tag(:script, inline_code.html_safe, attrs)
|
|
151
|
+
else
|
|
152
|
+
content_tag(:script, '', attrs)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<div id="gdpr-cookie-banner" class="gdpr-banner" style="display: none;" data-server-cookies="<%= server_cookies_json %>">
|
|
2
|
+
<div class="gdpr-banner__container">
|
|
3
|
+
<div class="gdpr-banner__content">
|
|
4
|
+
<div class="gdpr-banner__text">
|
|
5
|
+
<h3 class="gdpr-banner__title">Cookie-Einstellungen</h3>
|
|
6
|
+
<p class="gdpr-banner__description">
|
|
7
|
+
Wir verwenden Cookies, um Ihnen die bestmögliche Nutzung unserer Website zu ermöglichen.
|
|
8
|
+
Einige Cookies sind für das Funktionieren der Website erforderlich, während andere uns helfen,
|
|
9
|
+
die Website zu verbessern und Ihnen personalisierte Inhalte anzuzeigen.
|
|
10
|
+
</p>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="gdpr-banner__actions">
|
|
13
|
+
<button type="button" class="gdpr-banner__btn gdpr-banner__btn--secondary" data-action="decline">
|
|
14
|
+
Alles ablehnen
|
|
15
|
+
</button>
|
|
16
|
+
<button type="button" class="gdpr-banner__btn gdpr-banner__btn--link" data-action="settings">
|
|
17
|
+
Einstellungen ändern
|
|
18
|
+
</button>
|
|
19
|
+
<button type="button" class="gdpr-banner__btn gdpr-banner__btn--primary" data-action="accept">
|
|
20
|
+
Alle akzeptieren
|
|
21
|
+
</button>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<%= render partial: "rails_cookies_gdpr/modal" %>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<div id="gdpr-cookie-modal" class="gdpr-modal" style="display: none;" role="dialog" aria-labelledby="gdpr-modal-title" aria-modal="true">
|
|
2
|
+
<div class="gdpr-modal__backdrop" data-action="close-modal"></div>
|
|
3
|
+
<div class="gdpr-modal__container">
|
|
4
|
+
<div class="gdpr-modal__header">
|
|
5
|
+
<h2 id="gdpr-modal-title" class="gdpr-modal__title">Cookie-Einstellungen verwalten</h2>
|
|
6
|
+
<button type="button" class="gdpr-modal__close" data-action="close-modal" aria-label="Modal schließen">
|
|
7
|
+
<span aria-hidden="true">×</span>
|
|
8
|
+
</button>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="gdpr-modal__body">
|
|
12
|
+
<p class="gdpr-modal__description">
|
|
13
|
+
Wählen Sie aus, welche Cookies Sie zulassen möchten. Sie können diese Einstellungen jederzeit ändern.
|
|
14
|
+
Weitere Informationen finden Sie in unserer
|
|
15
|
+
<a href="<%= RailsCookiesGdpr.configuration.privacy_url %>" target="_blank" rel="noopener">Datenschutzerklärung</a>.
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<div class="gdpr-modal__categories">
|
|
19
|
+
<!-- Necessary cookies (always enabled) -->
|
|
20
|
+
<div class="gdpr-modal__category" data-category-section="necessary">
|
|
21
|
+
<div class="gdpr-modal__category-header" data-category="necessary">
|
|
22
|
+
<div class="gdpr-modal__category-title-wrapper">
|
|
23
|
+
<span class="gdpr-modal__chevron" aria-expanded="false" role="button" tabindex="0" aria-label="Cookie-Liste anzeigen">▶</span>
|
|
24
|
+
<h3 class="gdpr-modal__category-title">Notwendige Cookies</h3>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="gdpr-modal__toggle gdpr-modal__toggle--disabled">
|
|
27
|
+
<input type="checkbox" id="gdpr-necessary" checked disabled>
|
|
28
|
+
<label for="gdpr-necessary" class="gdpr-modal__toggle-label">
|
|
29
|
+
<span class="gdpr-modal__toggle-slider"></span>
|
|
30
|
+
</label>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<p class="gdpr-modal__category-description">
|
|
34
|
+
Diese Cookies sind für das ordnungsgemäße Funktionieren der Website erforderlich und können nicht deaktiviert werden.
|
|
35
|
+
</p>
|
|
36
|
+
<div class="gdpr-modal__empty-state" style="display: none;">
|
|
37
|
+
<p class="gdpr-modal__empty-text">Keine Cookies gesetzt</p>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="gdpr-modal__cookie-list" style="display: none;"></div>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<!-- Analytics cookies -->
|
|
43
|
+
<div class="gdpr-modal__category" data-category-section="analytics">
|
|
44
|
+
<div class="gdpr-modal__category-header" data-category="analytics">
|
|
45
|
+
<div class="gdpr-modal__category-title-wrapper">
|
|
46
|
+
<span class="gdpr-modal__chevron" aria-expanded="false" role="button" tabindex="0" aria-label="Cookie-Liste anzeigen">▶</span>
|
|
47
|
+
<h3 class="gdpr-modal__category-title"><%= RailsCookiesGdpr.configuration.analytics_label %></h3>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="gdpr-modal__toggle">
|
|
50
|
+
<input type="checkbox" id="gdpr-analytics" data-category="analytics">
|
|
51
|
+
<label for="gdpr-analytics" class="gdpr-modal__toggle-label">
|
|
52
|
+
<span class="gdpr-modal__toggle-slider"></span>
|
|
53
|
+
</label>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<p class="gdpr-modal__category-description">
|
|
57
|
+
Diese Cookies helfen uns zu verstehen, wie Besucher mit unserer Website interagieren,
|
|
58
|
+
indem sie Informationen anonym sammeln und melden.
|
|
59
|
+
</p>
|
|
60
|
+
<div class="gdpr-modal__empty-state" style="display: none;">
|
|
61
|
+
<p class="gdpr-modal__empty-text">Keine Cookies gesetzt</p>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="gdpr-modal__cookie-list" style="display: none;"></div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<!-- Marketing cookies -->
|
|
67
|
+
<div class="gdpr-modal__category" data-category-section="marketing">
|
|
68
|
+
<div class="gdpr-modal__category-header" data-category="marketing">
|
|
69
|
+
<div class="gdpr-modal__category-title-wrapper">
|
|
70
|
+
<span class="gdpr-modal__chevron" aria-expanded="false" role="button" tabindex="0" aria-label="Cookie-Liste anzeigen">▶</span>
|
|
71
|
+
<h3 class="gdpr-modal__category-title"><%= RailsCookiesGdpr.configuration.marketing_label %></h3>
|
|
72
|
+
</div>
|
|
73
|
+
<div class="gdpr-modal__toggle">
|
|
74
|
+
<input type="checkbox" id="gdpr-marketing" data-category="marketing">
|
|
75
|
+
<label for="gdpr-marketing" class="gdpr-modal__toggle-label">
|
|
76
|
+
<span class="gdpr-modal__toggle-slider"></span>
|
|
77
|
+
</label>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<p class="gdpr-modal__category-description">
|
|
81
|
+
Diese Cookies werden verwendet, um Ihnen relevante Werbung und Marketing-Kommunikation zu zeigen.
|
|
82
|
+
</p>
|
|
83
|
+
<div class="gdpr-modal__empty-state" style="display: none;">
|
|
84
|
+
<p class="gdpr-modal__empty-text">Keine Cookies gesetzt</p>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="gdpr-modal__cookie-list" style="display: none;"></div>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<!-- Functional cookies -->
|
|
90
|
+
<div class="gdpr-modal__category" data-category-section="functional">
|
|
91
|
+
<div class="gdpr-modal__category-header" data-category="functional">
|
|
92
|
+
<div class="gdpr-modal__category-title-wrapper">
|
|
93
|
+
<span class="gdpr-modal__chevron" aria-expanded="false" role="button" tabindex="0" aria-label="Cookie-Liste anzeigen">▶</span>
|
|
94
|
+
<h3 class="gdpr-modal__category-title"><%= RailsCookiesGdpr.configuration.functional_label %></h3>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="gdpr-modal__toggle">
|
|
97
|
+
<input type="checkbox" id="gdpr-functional" data-category="functional">
|
|
98
|
+
<label for="gdpr-functional" class="gdpr-modal__toggle-label">
|
|
99
|
+
<span class="gdpr-modal__toggle-slider"></span>
|
|
100
|
+
</label>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<p class="gdpr-modal__category-description">
|
|
104
|
+
Diese Cookies ermöglichen erweiterte Funktionalitäten und Personalisierung der Website.
|
|
105
|
+
</p>
|
|
106
|
+
<div class="gdpr-modal__empty-state" style="display: none;">
|
|
107
|
+
<p class="gdpr-modal__empty-text">Keine Cookies gesetzt</p>
|
|
108
|
+
</div>
|
|
109
|
+
<div class="gdpr-modal__cookie-list" style="display: none;"></div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div class="gdpr-modal__footer">
|
|
115
|
+
<button type="button" class="gdpr-modal__btn gdpr-modal__btn--secondary" data-action="decline-all">
|
|
116
|
+
Alles ablehnen
|
|
117
|
+
</button>
|
|
118
|
+
<button type="button" class="gdpr-modal__btn gdpr-modal__btn--primary" data-action="save-preferences">
|
|
119
|
+
Einstellungen speichern
|
|
120
|
+
</button>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
data/config/database.yml
ADDED
data/db/test.sqlite3
ADDED
|
Binary file
|
data/db/test.sqlite3-shm
ADDED
|
Binary file
|
data/db/test.sqlite3-wal
ADDED
|
File without changes
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FivoCookieConsent
|
|
4
|
+
# Configuration class for customizing cookie consent settings
|
|
5
|
+
class Configuration
|
|
6
|
+
attr_accessor :analytics_label, :marketing_label, :functional_label, :privacy_url, :cookie_lifespan,
|
|
7
|
+
:cookie_patterns, :registered_scripts
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@analytics_label = 'Analyse-Cookies'
|
|
11
|
+
@marketing_label = 'Marketing-Cookies'
|
|
12
|
+
@functional_label = 'Präferenz-Cookies'
|
|
13
|
+
@privacy_url = '/datenschutz'
|
|
14
|
+
@cookie_lifespan = 365 # days
|
|
15
|
+
@cookie_patterns = default_cookie_patterns
|
|
16
|
+
@registered_scripts = default_registered_scripts
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# Default cookie patterns for categorization
|
|
22
|
+
def default_cookie_patterns
|
|
23
|
+
{
|
|
24
|
+
necessary: [
|
|
25
|
+
/^_session_/,
|
|
26
|
+
/^session_/,
|
|
27
|
+
/^csrf_token/,
|
|
28
|
+
/^authenticity_token/,
|
|
29
|
+
/^_rails_/,
|
|
30
|
+
/^gdpr_cookie_consent$/
|
|
31
|
+
],
|
|
32
|
+
analytics: [
|
|
33
|
+
/^_ga/,
|
|
34
|
+
/^_gid/,
|
|
35
|
+
/^_gat/,
|
|
36
|
+
/^_gtag/,
|
|
37
|
+
/^__utm/,
|
|
38
|
+
/^_dc_gtm_/,
|
|
39
|
+
/^_hjid/,
|
|
40
|
+
/^_hjFirstSeen/,
|
|
41
|
+
/^_hj/
|
|
42
|
+
],
|
|
43
|
+
marketing: [
|
|
44
|
+
/^_fbp/,
|
|
45
|
+
/^_fbc/,
|
|
46
|
+
/^fr$/,
|
|
47
|
+
/^tr$/,
|
|
48
|
+
/^_pinterest_/,
|
|
49
|
+
/^_pin_unauth/,
|
|
50
|
+
/^__Secure-3PAPISID/,
|
|
51
|
+
/^__Secure-3PSID/,
|
|
52
|
+
/^NID$/,
|
|
53
|
+
/^IDE$/
|
|
54
|
+
],
|
|
55
|
+
functional: [
|
|
56
|
+
/^_locale/,
|
|
57
|
+
/^language/,
|
|
58
|
+
/^theme/,
|
|
59
|
+
/^preferences/,
|
|
60
|
+
/^_user_settings/,
|
|
61
|
+
/^_ui_/
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def default_registered_scripts
|
|
67
|
+
FivoCookieConsent.default_registered_scripts
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class << self
|
|
72
|
+
attr_writer :configuration
|
|
73
|
+
|
|
74
|
+
# Get current configuration instance
|
|
75
|
+
# @return [Configuration] The current configuration
|
|
76
|
+
def configuration
|
|
77
|
+
@configuration ||= Configuration.new
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Configure the gem with a block
|
|
81
|
+
# @yield [Configuration] The configuration instance
|
|
82
|
+
# @example
|
|
83
|
+
# FivoCookieConsent.configure do |config|
|
|
84
|
+
# config.analytics_label = "Custom Analytics"
|
|
85
|
+
# end
|
|
86
|
+
def configure
|
|
87
|
+
yield(configuration)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def register_script(name, options = {})
|
|
91
|
+
configuration.registered_scripts ||= {}
|
|
92
|
+
configuration.registered_scripts[name.to_sym] = options
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def registered_scripts
|
|
96
|
+
configuration.registered_scripts || {}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def default_registered_scripts
|
|
100
|
+
{
|
|
101
|
+
gtm: { category: :analytics },
|
|
102
|
+
ga4: { category: :analytics },
|
|
103
|
+
gtag: { category: :analytics },
|
|
104
|
+
recaptcha: { category: :functional },
|
|
105
|
+
hotjar: { category: :analytics },
|
|
106
|
+
fb_pixel: { category: :marketing }
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Alias for backwards compatibility with the expected namespace
|
|
113
|
+
module RailsCookiesGdpr
|
|
114
|
+
class << self
|
|
115
|
+
# Configure method for RailsCookiesGdpr namespace
|
|
116
|
+
# @yield [FivoCookieConsent::Configuration] The configuration instance
|
|
117
|
+
def configure(&block)
|
|
118
|
+
FivoCookieConsent.configure(&block)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Get configuration from FivoCookieConsent
|
|
122
|
+
# @return [FivoCookieConsent::Configuration] The current configuration
|
|
123
|
+
def configuration
|
|
124
|
+
FivoCookieConsent.configuration
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Get cookie patterns for categorization
|
|
128
|
+
# @return [Hash] Cookie patterns hash with categories as keys
|
|
129
|
+
def cookie_patterns
|
|
130
|
+
configuration.cookie_patterns
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def register_script(name, options = {})
|
|
134
|
+
FivoCookieConsent.register_script(name, options)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def registered_scripts
|
|
138
|
+
FivoCookieConsent.registered_scripts
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Fix for Rails 7.0 Logger compatibility issue
|
|
4
|
+
require 'logger'
|
|
5
|
+
|
|
6
|
+
# Ensure Logger is available before ActiveSupport tries to use it
|
|
7
|
+
Logger.class unless defined?(Logger)
|
|
8
|
+
begin
|
|
9
|
+
require 'rails/engine'
|
|
10
|
+
rescue LoadError
|
|
11
|
+
# Rails not available
|
|
12
|
+
return
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module FivoCookieConsent
|
|
16
|
+
class Engine < ::Rails::Engine
|
|
17
|
+
isolate_namespace RailsCookiesGdpr
|
|
18
|
+
|
|
19
|
+
# Configure paths for autoloading
|
|
20
|
+
config.autoload_paths += %W[
|
|
21
|
+
#{root}/app/controllers
|
|
22
|
+
#{root}/app/helpers
|
|
23
|
+
#{root}/app/models
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
# Include helpers only after code is loaded (works with Rails 7.0+)
|
|
27
|
+
config.to_prepare do
|
|
28
|
+
ActionController::Base.helper RailsCookiesGdpr::ApplicationHelper if defined?(ActionController::Base)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'rails/railtie'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
return
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module FivoCookieConsent
|
|
10
|
+
class Railtie < Rails::Railtie
|
|
11
|
+
# Load helpers into ActionController AFTER ActionController is ready
|
|
12
|
+
initializer 'fivo_cookie_consent.load_helpers' do
|
|
13
|
+
ActiveSupport.on_load :action_controller do
|
|
14
|
+
helper RailsCookiesGdpr::ApplicationHelper
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
require_relative 'fivo_cookie_consent/version'
|
|
6
|
+
require_relative 'fivo_cookie_consent/configuration'
|
|
7
|
+
|
|
8
|
+
# Only load Rails components when Rails is available
|
|
9
|
+
if defined?(Rails)
|
|
10
|
+
require_relative 'fivo_cookie_consent/railtie'
|
|
11
|
+
require_relative 'fivo_cookie_consent/engine'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module FivoCookieConsent
|
|
15
|
+
class Error < StandardError; end
|
|
16
|
+
end
|