clickwrap 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 504024fe0e6e146a907899092e9da9fe3f62501a2d2b251cb0f190cc72516860
4
- data.tar.gz: 542284305afe7e79d11e5759ce2c88630982ce7ad0862866a58a50824056b4d8
3
+ metadata.gz: 55f77c92e4ac5400a7c7fba781bd2a592875f3deef59fd8b3c1d6269e302ffc6
4
+ data.tar.gz: f15af7f288d8349bc8cd322b28b472e68bca750a8c17718648d7fa2db3877021
5
5
  SHA512:
6
- metadata.gz: 34500cc2c493a726afa16ed51e592102109bf56750eeb19a67624b85d0565d98ec316f45ac8653ffe2aa6f757c690577d37b34b986c71e8f5cd95fa766648b6c
7
- data.tar.gz: 5ed6946bb7aa2319a3f27b11c40ff79a64d85759353567b1e46be342e7966e7f180eda5be79acf9229c156d5bbcf9397e2ad473184947dce2e64ec577bd615cb
6
+ metadata.gz: fceb30a214fe8e4cdfcc19a775f8082fefe61424eba2e463958240dec07a0c8d099e1d3c6e5e0b9d67bd47eb11a445ee591f4b520c08f847479fbed277f197f2
7
+ data.tar.gz: e8d53673c7a5d9ba553078ace895a187e404b6a486525ee56d362f584e262f3bb9f9000287bf57311b22a40e2049140867f5eefdb300e945a7d69d25ff31dcf4
data/CHANGELOG.md CHANGED
@@ -6,6 +6,97 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.3.1] - 2026-08-20
10
+
11
+ ### Changed — the rest of the collection friction, and the principle behind removing it
12
+
13
+ 0.3.0 made *enabling* request evidence one switch and gave the initializer
14
+ defaults honest gem-supplied purposes. It left the friction standing
15
+ everywhere else: a policy-level `record_ip_address` still read as though it
16
+ wanted a sentence, `record_ip_geolocation` refused to do anything without a
17
+ field list, and the encryption escape hatch still demanded a reason be
18
+ phrased twice. This finishes the job the owner asked for.
19
+
20
+ The principle, in their words: **the host application and its privacy policy
21
+ own *why* data is collected; this gem records *what* was collected, honestly,
22
+ and is nobody's nanny.** Its job is evidence mechanics, not gatekeeping
23
+ collection. Everything below now works exactly as written:
24
+
25
+ ```ruby
26
+ Clickwrap.configure do |config|
27
+ config.record_request_evidence_by_default = true
28
+ config.keep_recorded_ip_addresses_indefinitely!
29
+ config.deliberately_store_request_evidence_unencrypted!
30
+ end
31
+
32
+ Clickwrap.policy :anything do
33
+ agree_to :terms
34
+ record_ip_address
35
+ record_browser_user_agent
36
+ record_ip_geolocation
37
+ end
38
+ ```
39
+
40
+ - **All three `record_` verbs take zero keyword arguments.** `because:`,
41
+ `legal_basis_reference:`, `data_protection_impact_assessment_reference:`,
42
+ `delete_after:`, `retain_until:`, and `encrypted:` are optional in fact and
43
+ not merely in the signature — nothing downstream refuses their absence.
44
+ (`legal_basis_reference` and the DPIA reference never were required anywhere
45
+ in the gem; a test now pins that they never become so.)
46
+ - **`record_ip_geolocation` with no field named records the coarse trio** —
47
+ country, region, city — the same set `record_request_evidence_by_default`
48
+ turns on, and nothing finer. The field keywords moved from `false` to `nil`
49
+ defaults so "did not mention this field" is distinguishable from "named it
50
+ and turned it off". Naming even one field means you are choosing the set
51
+ yourself, and the set is exactly what you named. Naming every field `false`
52
+ is still refused, because calling the verb and disabling everything cannot
53
+ mean anything; `do_not_record_ip_geolocation` is how to say that.
54
+ - **`keep_recorded_{ip_addresses,browser_user_agents,ip_geolocation}_indefinitely!`
55
+ take no arguments at all.**
56
+ - **`deliberately_store_request_evidence_unencrypted!` no longer needs a
57
+ `because:`.** The method NAME is the ceremony: `encrypt_recorded_* = false`
58
+ still cannot be reached without writing that line, and a reviewer still
59
+ finds it in the diff. When the host writes no reason the gem records
60
+ `Vocabulary::DEFAULT_REASON_FOR_STORING_REQUEST_EVIDENCE_UNENCRYPTED`.
61
+ Encryption itself is untouched — on by default for all three categories,
62
+ with a test pinning that the one switch does not weaken it.
63
+ - **The install generator stops refusing an incomplete category.**
64
+ `--record-ip-addresses-by-default` with no reason and no period writes the
65
+ file and simply omits those two lines, so the gem's own defaults apply.
66
+ - The `ReviewedText` placeholder check now only ever applies to text a host
67
+ actually supplied. Absence is never scaffolding.
68
+
69
+ ### Unchanged, deliberately
70
+
71
+ - Reasons that are not about *collection* keep their required `because:`:
72
+ `delete_recorded_ip_address!` and its siblings, `dispose_core_event!`,
73
+ `place_on_legal_hold!` / `release_legal_hold!`, `plan_disposition_for`,
74
+ unredacted receipt export, and the lifecycle verbs. Those record a
75
+ destructive act, an access, or a state change — there the audit trail *is*
76
+ the reason, and there is no honest default for "why did somebody delete
77
+ this".
78
+ - Still refused, because each is the host contradicting themselves rather than
79
+ leaving a blank: scaffolding text the host actually wrote standing in for a
80
+ purpose (including in the installer, where a `TODO` in a shipped initializer
81
+ is worse than no line and the gem would reject it at boot anyway), a
82
+ negative deletion period passed to the installer, a deletion clock declared
83
+ alongside `keep_recorded_..._indefinitely!` for the same category, and
84
+ `record_ip_geolocation` with every field explicitly off.
85
+ - The gem's code default is still record-nothing. Claim boundaries, receipt
86
+ state labeling (`not_configured` / `unavailable` / `recorded` /
87
+ `deleted_after_retention`), and every released receipt format are untouched.
88
+
89
+ ### Documentation
90
+
91
+ - README, `guides/request-evidence.md`, and `guides/naming.md` show the
92
+ zero-keyword forms as the ordinary way to write a policy, with purposes,
93
+ legal bases, and clocks as the upgrade path.
94
+ - `CLAUDE.md` / `AGENTS.md` rule 6 is rewritten around the principle above and
95
+ records the owner directive and its date. What it keeps as non-negotiable:
96
+ never a switch whose NAME hides what it collects, never an overclaim, never
97
+ a blurred receipt state, encryption on by default behind its named call,
98
+ host-supplied scaffolding rejected, and contradictions refused.
99
+
9
100
  ## [0.3.0] - 2026-08-20
10
101
 
11
102
  ### Changed — recording request evidence is one switch, not a checklist
data/README.md CHANGED
@@ -733,7 +733,7 @@ end
733
733
 
734
734
  That records, on every policy: the IP address the request arrived from, the browser user agent it sent, and a coarse country / region / city estimate for that address. Add [`trackdown`](https://github.com/rameerez/trackdown) 0.4+ to your Gemfile and the geolocation half resolves itself — Clickwrap picks up the official adapter with no wiring line, so trackdown plus Cloudflare genuinely is "bundle it and flip the switch".
735
735
 
736
- Nothing else is required, because Clickwrap supplies honest defaults for the parts you did not write:
736
+ Nothing else is required — anywhere, at either level. **Your privacy policy owns the why; the gem records the what, honestly, and is nobody's nanny.** Clickwrap supplies its own defaults for every part you did not write:
737
737
 
738
738
  - **Purpose.** Every recorded field carries one into the receipt. Yours if you wrote one, otherwise Clickwrap's: *"Corroborate who performed each recorded act, from where, on what client — to defend the recorded agreement itself."* The [privacy inventory](#operations) marks which of the two it is reading back (`"purpose_source": "gem_default"` vs `"host"`), so a gem sentence never passes for a decision your team reviewed.
739
739
  - **How long.** No clock means it keeps pace with the evidence it corroborates — the same posture core evidence has had since 0.2.0. A corroboration scheduled to expire before the agreement it corroborates is a scheduled weakening of the record.
@@ -772,7 +772,23 @@ end
772
772
 
773
773
  Two things are still refused, and both are you contradicting yourself rather than leaving a blank: scaffolding text (`"TODO: ask legal"`) standing in for a purpose, and a deletion clock set alongside `keep_recorded_..._indefinitely!` for the same category.
774
774
 
775
- A single regulated surface can also name a field per policy instead of by default:
775
+ ### Per policy, with as much or as little as you want
776
+
777
+ A single surface can name the fields itself instead of inheriting the default. The frictionless form takes no arguments at all:
778
+
779
+ ```ruby
780
+ Clickwrap.policy :withdrawal_authorization do
781
+ authorize :regulated_action, one_time: true, valid_for: 10.minutes
782
+
783
+ record_ip_address
784
+ record_browser_user_agent
785
+ record_ip_geolocation
786
+ end
787
+ ```
788
+
789
+ `record_ip_geolocation` with no field named records the same coarse trio as the switch — country, region, city. Name even one field and you are choosing the set yourself, and the set is exactly what you named.
790
+
791
+ The same declarations with the full record a reviewed team would want:
776
792
 
777
793
  ```ruby
778
794
  Clickwrap.policy :regulated_authorization do
@@ -791,9 +807,11 @@ end
791
807
  Recorded values live in a separately encrypted annex with their own retention, so
792
808
  they can be deleted later without rewriting the core event payload. Core payloads
793
809
  have their own reviewed disposition path and leave a digest-linked tombstone.
794
- Encryption is on by default and turning it off keeps its own ceremony —
795
- `config.deliberately_store_request_evidence_unencrypted!(because: "…")` — because
796
- that one is a real hazard, not paperwork.
810
+ Encryption is on by default for all three categories. Turning it off keeps its
811
+ own ceremony — you cannot reach `encrypt_recorded_ip_addresses = false` without
812
+ first writing `config.deliberately_store_request_evidence_unencrypted!` but the
813
+ ceremony is the method name a reviewer finds in the diff, not a sentence the gem
814
+ makes you type. `because:` there is optional too.
797
815
 
798
816
  For IP geolocation, [`trackdown`](https://github.com/rameerez/trackdown) 0.4 or newer is the official resolver, and Clickwrap uses it automatically when your bundle has it and you named no resolver of your own. Set it explicitly when you want a different provider per policy, or when you are wiring Trackdown's per-request CDN trust:
799
817
 
data/guides/naming.md CHANGED
@@ -291,7 +291,7 @@ object.
291
291
  | `chain_event_history_with`, `anchor_event_history_with`, `timestamp_receipts_with` | one `integrity_level` setting | Three different mechanisms making three different claims. One setting would let a reader infer the strongest from the presence of the weakest |
292
292
  | `after_event_is_committed` | `after_commit` | Says which commit, and reads as a sentence |
293
293
  | `authorize_unredacted_request_evidence_access_with` | `access_control` | Long, and correct. It names exactly which access it authorizes |
294
- | `deliberately_store_request_evidence_unencrypted!(because:)` | `encryption: false` | Turning encryption off should be a sentence a reviewer can find in a diff, with the host's own reason attached not a `false` |
294
+ | `deliberately_store_request_evidence_unencrypted!` | `encryption: false` | Turning encryption off should be a sentence a reviewer can find in a diff not a `false`. The method NAME is the ceremony; its `because:` is optional |
295
295
 
296
296
  The last row is the pattern worth copying. When an option has a consequence somebody should
297
297
  have to think about, make the name carry the thinking.
@@ -310,7 +310,26 @@ Clickwrap.policy :regulated_authorization do
310
310
  end
311
311
  ```
312
312
 
313
- Every keyword there is doing work:
313
+ Every keyword there is doing work, and **every one of them is optional**. The same three
314
+ declarations with nothing at all supplied are valid, and record the same fields:
315
+
316
+ ```ruby
317
+ Clickwrap.policy :frictionless_regulated_authorization do
318
+ authorize :regulated_action, one_time: true, valid_for: 10.minutes
319
+
320
+ record_ip_address
321
+ record_browser_user_agent
322
+ record_ip_geolocation
323
+ retain_with :regulated_evidence
324
+ end
325
+ ```
326
+
327
+ `record_ip_geolocation` with no field named records the coarse trio — country, region, city —
328
+ and nothing finer. Name even one field and the set is exactly what you named; name every field
329
+ `false` and Clickwrap refuses, because calling `record_ip_geolocation` and disabling everything
330
+ cannot mean anything (`do_not_record_ip_geolocation` is how to say that).
331
+
332
+ What each keyword adds when you do supply it:
314
333
 
315
334
  - **`because:`** is the present purpose, in a sentence someone outside engineering can read. It
316
335
  is stored and printed by `bin/rails clickwrap:privacy:inventory`. It is optional: a policy
@@ -319,7 +338,9 @@ Every keyword there is doing work:
319
338
  reviewed. What is refused is scaffolding text — `"TODO: ask legal"` is not a purpose.
320
339
  - **`legal_basis_reference:`** and **`data_protection_impact_assessment_reference:`** are
321
340
  host-supplied pointers to your own reviewed documents. Clickwrap stores them. It does not
322
- read them, validate them, or endorse them.
341
+ read them, validate them, endorse them, or ever require them — nothing in the gem refuses a
342
+ recorded field for want of either, and nothing ever will. Your privacy policy owns the why;
343
+ the gem records the what.
323
344
  - **`delete_after:`** and **`retain_until:`** are both optional. When neither the policy, its
324
345
  retention class, nor the configuration names a schedule, the field keeps pace with the
325
346
  evidence it corroborates — the same posture the core event has — and the annex is stamped
@@ -1227,15 +1227,19 @@ module Clickwrap
1227
1227
  @keep_recorded_request_evidence_indefinitely[category.to_sym]
1228
1228
  end
1229
1229
 
1230
- def deliberately_store_request_evidence_unencrypted!(because:)
1231
- if because.to_s.strip.empty?
1232
- raise ConfigurationError,
1233
- "deliberately_store_request_evidence_unencrypted! needs a `because:` explaining " \
1234
- "the reviewed decision."
1235
- end
1236
-
1230
+ # The named escape hatch for turning encryption off. The ceremony is the
1231
+ # method: you cannot reach `encrypt_recorded_* = false` without writing a
1232
+ # line that says out loud what you are doing, and that line is what a
1233
+ # reviewer finds in a diff. Since 0.3.1 the `because:` is optional — the
1234
+ # gem records its own sentence when you do not write one — because the
1235
+ # host's privacy policy owns the why, and demanding it twice never stopped
1236
+ # anybody who had already typed this method name.
1237
+ #
1238
+ # Encryption itself is unchanged: on by default, for all three categories.
1239
+ def deliberately_store_request_evidence_unencrypted!(because: nil)
1237
1240
  @deliberately_storing_request_evidence_unencrypted = true
1238
- @reason_for_storing_request_evidence_unencrypted = because
1241
+ @reason_for_storing_request_evidence_unencrypted =
1242
+ because.presence || Vocabulary::DEFAULT_REASON_FOR_STORING_REQUEST_EVIDENCE_UNENCRYPTED
1239
1243
  end
1240
1244
 
1241
1245
  def storing_request_evidence_unencrypted? = @deliberately_storing_request_evidence_unencrypted == true
@@ -239,24 +239,34 @@ module Clickwrap
239
239
  @request_evidence[:browser_user_agent] = RequestEvidencePolicy::NOT_RECORDED
240
240
  end
241
241
 
242
- # Each IP-geolocation data field is named separately, because each one is
243
- # a separate decision about what to keep about a person's network
242
+ # Each IP-geolocation data field can be named separately, because each one
243
+ # is a separate decision about what to keep about a person's network
244
244
  # context. `latitude_and_longitude` is one coupled choice: half a
245
245
  # coordinate is not a result. Whatever is enabled, the provider name,
246
246
  # source, estimated status, resolution time, and any accuracy or database
247
247
  # provenance the resolver supplies are stored with it automatically — a
248
248
  # policy cannot keep the coordinates and drop the uncertainty needed to
249
249
  # read them.
250
- def record_ip_geolocation(country: false, region: false, city: false, postal_code: false,
251
- latitude_and_longitude: false, timezone: false, continent: false,
252
- metro_code: false, accuracy_radius_in_kilometers: false,
250
+ #
251
+ # Naming no field at all is the frictionless form:
252
+ #
253
+ # record_ip_geolocation
254
+ #
255
+ # It records the same coarse trio as
256
+ # `config.record_request_evidence_by_default` — country, region, city —
257
+ # and nothing finer, because that is what "IP geolocation" means in this
258
+ # gem when nobody narrows it. Naming even one field means you are
259
+ # choosing the set yourself, and then the set is exactly what you named.
260
+ def record_ip_geolocation(country: nil, region: nil, city: nil, postal_code: nil,
261
+ latitude_and_longitude: nil, timezone: nil, continent: nil,
262
+ metro_code: nil, accuracy_radius_in_kilometers: nil,
253
263
  using: nil, encrypted: nil, delete_after: nil, retain_until: nil,
254
264
  fail_if_unavailable: false, because: nil,
255
265
  legal_basis_reference: nil,
256
266
  data_protection_impact_assessment_reference: nil,
257
267
  **unknown_options)
258
268
  refuse_unknown_options!("record_ip_geolocation", unknown_options)
259
- @ip_geolocation_fields = {
269
+ named = {
260
270
  "country" => country,
261
271
  "region" => region,
262
272
  "city" => city,
@@ -267,6 +277,7 @@ module Clickwrap
267
277
  "metro_code" => metro_code,
268
278
  "accuracy_radius_in_kilometers" => accuracy_radius_in_kilometers
269
279
  }
280
+ @ip_geolocation_fields = default_ip_geolocation_fields_when_none_named(named)
270
281
  @ip_geolocation_resolver_name = using
271
282
 
272
283
  @request_evidence[:ip_geolocation] = RequestEvidencePolicy::Setting.new(
@@ -404,6 +415,20 @@ module Clickwrap
404
415
  end
405
416
  end
406
417
 
418
+ # `nil` means "the policy did not mention this field"; `false` means "the
419
+ # policy named it and turned it off". The distinction is the whole reason
420
+ # the keywords default to nil: a policy that mentions nothing gets the
421
+ # coarse trio, and a policy that explicitly sets every field to false
422
+ # still reaches the coherence check that tells it to say
423
+ # `do_not_record_ip_geolocation` instead.
424
+ def default_ip_geolocation_fields_when_none_named(named)
425
+ return named.transform_values { |value| value == true } if named.any? { |_, value| !value.nil? }
426
+
427
+ Vocabulary::IP_GEOLOCATION_DATA_FIELDS.to_h do |field|
428
+ [field, Vocabulary::COARSE_IP_GEOLOCATION_DATA_FIELDS.include?(field)]
429
+ end
430
+ end
431
+
407
432
  def resolved_ip_geolocation_fields(setting)
408
433
  return {} unless setting.record?
409
434
  return @ip_geolocation_fields if @request_evidence.key?(:ip_geolocation)
@@ -241,8 +241,11 @@ module Clickwrap
241
241
 
242
242
  if ip_geolocation.record? && enabled.empty?
243
243
  raise DefinitionError,
244
- "Policy #{policy_key} calls `record_ip_geolocation` but enables no field. " \
245
- "Name the fields you actually need, for example `country: true`."
244
+ "Policy #{policy_key} calls `record_ip_geolocation` and then turns every field " \
245
+ "off, which cannot mean anything. Name the fields you want, for example " \
246
+ "`country: true`; call `record_ip_geolocation` with no fields at all for the " \
247
+ "coarse country, region, and city; or say `do_not_record_ip_geolocation` if that " \
248
+ "is what you meant."
246
249
  end
247
250
 
248
251
  if ip_geolocation.record? &&
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Clickwrap
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
 
6
6
  # The canonical schema version for receipts, event digests, and presentation
7
7
  # manifests. This is deliberately independent of VERSION: gem releases may
@@ -187,6 +187,15 @@ module Clickwrap
187
187
  DEFAULT_REASON_FOR_KEEPING_REQUEST_EVIDENCE_INDEFINITELY =
188
188
  "Corroboration lives as long as the evidence it corroborates"
189
189
 
190
+ # The reason recorded when a host turns off encryption for request evidence
191
+ # without writing their own. Calling the method is still the ceremony —
192
+ # `deliberately_store_request_evidence_unencrypted!` is a sentence a
193
+ # reviewer finds in a diff and cannot misread — but the gem no longer
194
+ # demands the sentence be phrased twice.
195
+ DEFAULT_REASON_FOR_STORING_REQUEST_EVIDENCE_UNENCRYPTED =
196
+ "The application deliberately stores request evidence unencrypted; the reason lives " \
197
+ "outside Clickwrap"
198
+
190
199
  # Provenance that travels with any stored IP-geolocation result. A policy
191
200
  # cannot keep provider-derived coordinates while stripping the uncertainty
192
201
  # needed to interpret them.
@@ -1160,23 +1160,30 @@ module Clickwrap
1160
1160
  validate_ip_geolocation_resolver_class_name!
1161
1161
  end
1162
1162
 
1163
+ # A missing purpose and a missing deletion period are both fine, and the
1164
+ # generated file simply omits those lines: the gem records its own stated
1165
+ # purpose and keeps the field as long as the evidence it corroborates.
1166
+ # Scaffolding text is the one thing still refused, because a `TODO` the
1167
+ # installer writes into a shipped initializer is worse than no line at
1168
+ # all — the gem would reject it at boot anyway.
1163
1169
  def validate_enabled_category!(label, enabled:, because:, delete_after_days:,
1164
1170
  reason_option:, retention_option:)
1165
1171
  return unless enabled
1166
1172
 
1167
- unless Clickwrap::ReviewedText.present_and_reviewed?(because)
1173
+ if Clickwrap::ReviewedText.placeholder?(because)
1168
1174
  raise Thor::Error,
1169
- "Clickwrap cannot enable #{label} with a blank or scaffolding reason. " \
1170
- "Give the application's reviewed, present-tense reason with " \
1171
- "#{reason_option}=\"...\", or turn that category off. No files were written."
1175
+ "Clickwrap cannot enable #{label} with a scaffolding reason " \
1176
+ "(#{because.inspect}). Give the application's reviewed, present-tense reason " \
1177
+ "with #{reason_option}=\"...\", or omit it entirely and let Clickwrap record " \
1178
+ "its own stated purpose. No files were written."
1172
1179
  end
1173
1180
 
1174
- return if delete_after_days.positive?
1181
+ return unless delete_after_days.negative?
1175
1182
 
1176
1183
  raise Thor::Error,
1177
- "Clickwrap cannot enable #{label} without a positive deletion period. " \
1178
- "Set #{retention_option}=DAYS to the period your application reviewed, or " \
1179
- "turn that category off. No files were written."
1184
+ "#{retention_option} cannot be negative (got #{delete_after_days}). Give the " \
1185
+ "number of days your application reviewed, or omit it and #{label} will keep " \
1186
+ "pace with the evidence it corroborates. No files were written."
1180
1187
  end
1181
1188
 
1182
1189
  def validate_ip_geolocation_coordinates!
@@ -287,19 +287,25 @@ Clickwrap.configure do |config|
287
287
  # event — the historical agreement, declaration, or authorization stays intact
288
288
  # and verifiable without it.
289
289
 
290
- <%- if record_ip_addresses? -%>
290
+ <%- if record_ip_addresses? && reason_for_recording_ip_addresses.present? -%>
291
291
  config.reason_for_recording_ip_addresses_by_default =
292
292
  <%= reason_for_recording_ip_addresses.inspect %>
293
+ <%- end -%>
294
+ <%- if record_ip_addresses? && delete_recorded_ip_addresses_after_days.positive? -%>
293
295
  config.delete_recorded_ip_addresses_after = <%= delete_recorded_ip_addresses_after_days %>.days
294
296
  <%- end -%>
295
- <%- if record_browser_user_agents? -%>
297
+ <%- if record_browser_user_agents? && reason_for_recording_browser_user_agents.present? -%>
296
298
  config.reason_for_recording_browser_user_agents_by_default =
297
299
  <%= reason_for_recording_browser_user_agents.inspect %>
300
+ <%- end -%>
301
+ <%- if record_browser_user_agents? && delete_recorded_browser_user_agents_after_days.positive? -%>
298
302
  config.delete_recorded_browser_user_agents_after = <%= delete_recorded_browser_user_agents_after_days %>.days
299
303
  <%- end -%>
300
- <%- if any_ip_geolocation_field? -%>
304
+ <%- if any_ip_geolocation_field? && reason_for_recording_ip_geolocation.present? -%>
301
305
  config.reason_for_recording_ip_geolocation_by_default =
302
306
  <%= reason_for_recording_ip_geolocation.inspect %>
307
+ <%- end -%>
308
+ <%- if any_ip_geolocation_field? && delete_recorded_ip_geolocation_after_days.positive? -%>
303
309
  config.delete_recorded_ip_geolocation_after = <%= delete_recorded_ip_geolocation_after_days %>.days
304
310
  <%- end -%>
305
311
  <%- if records_any_request_evidence? -%>
@@ -332,8 +338,9 @@ Clickwrap.configure do |config|
332
338
  # Turning one of these off puts the raw value in plain text in your database,
333
339
  # and therefore in every ordinary backup and database dump. It is allowed,
334
340
  # because some applications have a reviewed reason, but it is never a quiet
335
- # one-character change: Clickwrap refuses `false` until you have said why in
336
- # `config.deliberately_store_request_evidence_unencrypted!(because: "…")`.
341
+ # one-character change: Clickwrap refuses `false` until you have written
342
+ # `config.deliberately_store_request_evidence_unencrypted!` above it. Writing
343
+ # that line IS the whole ceremony — its `because:` is optional.
337
344
  #
338
345
  # config.encrypt_recorded_ip_addresses = true
339
346
  # config.encrypt_recorded_browser_user_agents = true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clickwrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rameerez