rails_consent 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 19e1554e153f613453261717b4d18b77bc83664efe9e35fb178553d45802ad97
4
+ data.tar.gz: df90bf179fe78aab0df69a290aa097c40bdedc21295d24523e6db492e53bd7be
5
+ SHA512:
6
+ metadata.gz: 35f2aaa9ed70c1a70e79769b0f45d03be70bddf0abf3e3ff9e5441867a6c1ddc8ef7d7c51c56dc6aa8547ddaf911a616f1083ebdb7f519e3893267f8e9cf2d1b
7
+ data.tar.gz: 24b811e64f10bdaaf9aab27aa48a130430caf7fb93576b99a07bb1b1a527eac8fe54b15453f1718c8ade2ab3538d437d02d568289d49d08d4b18d11ab3c8d6b8
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ - Relaxed the development baseline to Ruby 3.4.7 and Rails 7.1+
6
+ - Simplified the gem contract so consent persistence stays in the host application
7
+ - Refreshed the documentation application into a richer documentation-first Rails app with enhanced live consent demos
8
+
9
+ ## 0.1.0
10
+
11
+ - Initial release of `rails_consent`
12
+ - Added the Rails Engine, helpers, generators, templates, JavaScript runtime, specs, and the documentation application
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,35 @@
1
+ # Contributing
2
+
3
+ Thanks for considering a contribution to `rails_consent`.
4
+
5
+ ## Development Setup
6
+
7
+ 1. Install the bundle:
8
+
9
+ ```bash
10
+ bundle install
11
+ ```
12
+
13
+ 2. Run the test suite:
14
+
15
+ ```bash
16
+ bundle exec rspec
17
+ ```
18
+
19
+ 3. Verify changes against the public documentation site and reference integration before opening a pull request.
20
+
21
+ ## Contribution Guidelines
22
+
23
+ - Keep consent behavior in the library and presentation choices in the host app whenever possible.
24
+ - Add or update specs around the public contract of the gem.
25
+ - Favor extension points over one-off conditionals.
26
+ - Avoid introducing database persistence to the gem itself.
27
+ - Update documentation and examples when public behavior changes.
28
+
29
+ ## Pull Requests
30
+
31
+ Please include:
32
+
33
+ - A clear description of the problem and the chosen solution
34
+ - Tests covering the public behavior you changed
35
+ - Documentation updates when relevant
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dhairya Gabhawala
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,264 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/dhairyagabha/rails_consent/main/.github/assets/rails-consent-lockup.png" alt="Rails Consent" width="420">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://rubygems.org/gems/rails_consent">
7
+ <img src="https://img.shields.io/gem/v/rails_consent.svg" alt="RubyGems version">
8
+ </a>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://rails-consent.dhairyagabhawala.com">Documentation</a>
13
+ ·
14
+ <a href="https://rails-consent.dhairyagabhawala.com/docs/example-integrations">See the demo</a>
15
+ ·
16
+ <a href="https://github.com/dhairyagabha/rails_consent/blob/main/CHANGELOG.md">Changelog</a>
17
+ ·
18
+ <a href="https://rubygems.org/gems/rails_consent">RubyGems</a>
19
+ ·
20
+ <a href="https://github.com/dhairyagabha/rails_consent">GitHub</a>
21
+ </p>
22
+
23
+ # Rails Consent
24
+
25
+ `rails_consent` is a Rails engine for cookie consent in Rails applications, built around locale-backed categories, a built-in signed cookie flow, small helper APIs, and a minimal JavaScript runtime.
26
+
27
+ ## Features
28
+
29
+ - Cookie consent banner and preferences modal
30
+ - Built-in signed cookie persistence with optional `:db` storage hooks
31
+ - Locale-backed category definitions and interface copy
32
+ - Helpers for views, controllers, and layouts
33
+ - Minimal browser runtime with lifecycle events and a small client-side API
34
+ - Overrideable templates without copying runtime assets
35
+ - Importmap and Turbo-friendly integration
36
+
37
+ ## Installation
38
+
39
+ Add the gem to your Rails app:
40
+
41
+ ```ruby
42
+ gem "rails_consent"
43
+ ```
44
+
45
+ Then install it:
46
+
47
+ ```bash
48
+ bundle install
49
+ bin/rails generate rails_consent:install
50
+ ```
51
+
52
+ The installer creates:
53
+
54
+ - `config/initializers/rails_consent.rb`
55
+ - `config/locales/rails_consent.en.yml`
56
+
57
+ In the default `:cookie` mode, that generated setup is enough to render the UI and persist consent through a signed Rails cookie.
58
+
59
+ ## Define Categories and Copy
60
+
61
+ Rails Consent keeps banner copy, modal copy, and category definitions in one locale file:
62
+
63
+ ```yaml
64
+ en:
65
+ rails_consent:
66
+ banner:
67
+ eyebrow: Privacy settings
68
+ title: Review cookie choices
69
+ description: Necessary cookies stay enabled. Optional categories can be updated at any time.
70
+ accept_all: Allow all
71
+ reject_optional: Reject optional
72
+ manage_preferences: Privacy preferences
73
+ modal:
74
+ eyebrow: Cookie preferences
75
+ title: Review cookie categories
76
+ save_preferences: Save settings
77
+ categories:
78
+ necessary:
79
+ label: Necessary
80
+ required: true
81
+ description: Essential cookies required for site functionality
82
+ analytics:
83
+ label: Analytics
84
+ required: false
85
+ description: Used to understand visitor behavior
86
+ marketing:
87
+ label: Marketing
88
+ required: false
89
+ description: Used for advertising and remarketing
90
+ ```
91
+
92
+ Display order follows the locale file order.
93
+
94
+ ## Configure Rails Consent
95
+
96
+ The initializer defines where consent lives, how the banner behaves by default, and how category checks should resolve:
97
+
98
+ ```ruby
99
+ RailsConsent.configure do |config|
100
+ config.storage = :cookie
101
+ config.banner_position = :bottom
102
+ config.prompt_dismissible = true
103
+ config.cookie_name = "rails_consent_preferences"
104
+ config.cookie_expiration_days = 180
105
+ # config.cookie_same_site = :lax
106
+ # config.cookie_http_only = true
107
+ # config.cookie_secure = ->(request) { request.ssl? || Rails.env.production? }
108
+ config.consent_resolver = RailsConsent::DefaultConsentResolver.new
109
+ end
110
+ ```
111
+
112
+ `consent_resolver` is required. Start with `RailsConsent::DefaultConsentResolver.new` when each optional category maps directly to a boolean consent decision, then replace it when your application needs additional rules.
113
+
114
+ ## Render the Consent UI
115
+
116
+ Load the gem assets in your layout and keep the banner mounted near the bottom of the page:
117
+
118
+ ```erb
119
+ <head>
120
+ <%= rails_consent_assets %>
121
+ </head>
122
+
123
+ <body>
124
+ <%= yield %>
125
+ <%= rails_consent_banner %>
126
+ </body>
127
+ ```
128
+
129
+ `rails_consent_assets` loads only the gem's core runtime assets: `rails_consent.js` and the minimal `rails_consent/application.css` stylesheet used for runtime visibility utilities.
130
+
131
+ If one page needs different behavior, override it locally:
132
+
133
+ ```erb
134
+ <%= rails_consent_banner position: :top, dismissible: false %>
135
+ ```
136
+
137
+ ## Reopen Preferences Later
138
+
139
+ Use the shared helper anywhere you want to reopen the preferences modal:
140
+
141
+ ```erb
142
+ <%= rails_consent_preferences_button "Privacy preferences", class: "footer-button" %>
143
+ ```
144
+
145
+ That helper is a good fit for footers, privacy pages, and account settings screens.
146
+
147
+ ## Gate Optional Behavior
148
+
149
+ Use `consent_given?` anywhere you need to align server-rendered behavior with the current consent state:
150
+
151
+ ```erb
152
+ <% if consent_given?(:analytics) %>
153
+ <%= render "analytics_script" %>
154
+ <% end %>
155
+ ```
156
+
157
+ The public helper surface is:
158
+
159
+ ```ruby
160
+ rails_consent_assets
161
+ rails_consent_banner
162
+ rails_consent_preferences_button
163
+ consent_given?(:analytics)
164
+ consent_preferences
165
+ consent_recorded?
166
+ reset_consent!
167
+ ```
168
+
169
+ ## Client-side API
170
+
171
+ Rails Consent also exposes a small browser API through `window.RailsConsent`:
172
+
173
+ ```javascript
174
+ window.RailsConsent.preferences()
175
+ window.RailsConsent.consentGiven("analytics")
176
+ window.RailsConsent.consentRecorded()
177
+ window.RailsConsent.sessionId()
178
+ window.RailsConsent.openPreferences()
179
+ ```
180
+
181
+ Lifecycle events are dispatched on `document` so host apps can react without modifying the gem runtime:
182
+
183
+ - `rails-consent:banner-shown`
184
+ - `rails-consent:preferences-opened`
185
+ - `rails-consent:preferences-saved`
186
+ - `rails-consent:preferences-updated`
187
+ - `rails-consent:accepted-all`
188
+ - `rails-consent:rejected-optional`
189
+ - `rails-consent:dismissed`
190
+
191
+ ## Storage Modes
192
+
193
+ ### Signed Cookie Storage
194
+
195
+ `config.storage = :cookie` uses the built-in persistence route and a signed cookie payload keyed by category name. This is the default integration path.
196
+
197
+ If you want to wrap the built-in cookie flow without replacing it, provide `cookie_reader`, `cookie_writer`, or `cookie_destroyer` hooks around `RailsConsent::CookieStore`.
198
+
199
+ ### Database-backed Storage
200
+
201
+ When consent should live alongside a user or account record, switch only the storage hooks:
202
+
203
+ ```ruby
204
+ RailsConsent.configure do |config|
205
+ config.storage = :db
206
+ config.banner_position = :bottom
207
+ config.prompt_dismissible = true
208
+ config.consent_resolver = RailsConsent::DefaultConsentResolver.new
209
+
210
+ config.preferences_provider = ->(context:, **) do
211
+ context.current_user&.consent_preferences || {}
212
+ end
213
+
214
+ config.preferences_writer = ->(preferences:, context:, **) do
215
+ user = context.current_user
216
+ raise "current_user is required for db-backed consent" unless user
217
+
218
+ user.update!(consent_preferences: preferences)
219
+ user.consent_preferences
220
+ end
221
+
222
+ config.preferences_destroyer = ->(context:, **) do
223
+ context.current_user&.update!(consent_preferences: {})
224
+ end
225
+ end
226
+ ```
227
+
228
+ Most applications pair that initializer with a JSON or JSONB column such as `users.consent_preferences`.
229
+
230
+ ## Customize Presentation
231
+
232
+ Override any shipped partial from your host app by creating:
233
+
234
+ ```text
235
+ app/views/rails_consent/_banner.html.erb
236
+ app/views/rails_consent/_preferences_modal.html.erb
237
+ app/views/rails_consent/_category_toggle.html.erb
238
+ app/views/rails_consent/_cookie_table.html.erb
239
+ ```
240
+
241
+ Keep wording changes in locale YAML when the markup stays the same. Reach for template overrides only when the structure itself needs to change.
242
+
243
+ ## Troubleshooting
244
+
245
+ - If the banner never appears, confirm `rails_consent_banner` is mounted in your layout and consent has not already been recorded.
246
+ - If the UI opens without styles or behavior, confirm `rails_consent_assets` is loaded in `<head>`.
247
+ - If boot fails with a configuration error, compare your initializer to the generated file and restore any required lines that were removed.
248
+ - If a custom category never enables, review `consent_resolver` after changing `config/locales/rails_consent.en.yml`.
249
+ - If `:db` mode does not persist updates, confirm `preferences_provider`, `preferences_writer`, and `preferences_destroyer` are all configured and return hashes keyed by category name.
250
+ - If client-side integrations cannot read consent, keep `rails_consent_banner` mounted on the page so `window.RailsConsent` has a rendered boundary to read from.
251
+
252
+ ## Documentation
253
+
254
+ Full guides, live demos, and integration examples are available at:
255
+
256
+ - https://rails-consent.dhairyagabhawala.com/
257
+
258
+ ## Contributing
259
+
260
+ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for development and contribution guidelines.
261
+
262
+ ## License
263
+
264
+ Released under the MIT license. See [`LICENSE`](LICENSE).
@@ -0,0 +1,2 @@
1
+ //= link rails_consent/application.css
2
+ //= link rails_consent.js