clickwrap 0.0.0 → 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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +90 -0
  3. data/CHANGELOG.md +612 -0
  4. data/README.md +830 -1204
  5. data/SECURITY.md +33 -0
  6. data/app/assets/stylesheets/clickwrap.css +241 -0
  7. data/app/controllers/clickwrap/application_controller.rb +79 -0
  8. data/app/controllers/clickwrap/captures_controller.rb +145 -0
  9. data/app/controllers/clickwrap/document_versions_controller.rb +71 -0
  10. data/app/controllers/clickwrap/receipts_controller.rb +115 -0
  11. data/app/controllers/clickwrap/withdrawals_controller.rb +60 -0
  12. data/app/helpers/clickwrap/engine_helper.rb +97 -0
  13. data/app/views/clickwrap/captures/show.html.erb +34 -0
  14. data/app/views/clickwrap/receipts/index.html.erb +38 -0
  15. data/app/views/clickwrap/receipts/show.html.erb +91 -0
  16. data/app/views/clickwrap/shared/_error_summary.html.erb +39 -0
  17. data/app/views/clickwrap/shared/_fields.html.erb +100 -0
  18. data/app/views/clickwrap/shared/_statement.html.erb +105 -0
  19. data/app/views/clickwrap/withdrawals/new.html.erb +30 -0
  20. data/config/locales/en.yml +160 -0
  21. data/config/locales/es.yml +138 -0
  22. data/config/routes.rb +41 -0
  23. data/exe/clickwrap +374 -0
  24. data/guides/README.md +30 -0
  25. data/guides/accessibility.md +249 -0
  26. data/guides/consent-and-lifecycle.md +299 -0
  27. data/guides/integrating.md +610 -0
  28. data/guides/integrity.md +212 -0
  29. data/guides/migrating.md +335 -0
  30. data/guides/naming.md +320 -0
  31. data/guides/organizations.md +320 -0
  32. data/guides/receipts-and-verification.md +415 -0
  33. data/guides/request-evidence.md +512 -0
  34. data/guides/retention-and-legal-holds.md +438 -0
  35. data/lib/clickwrap/actor_proxy.rb +147 -0
  36. data/lib/clickwrap/anonymous_actor.rb +47 -0
  37. data/lib/clickwrap/authority.rb +174 -0
  38. data/lib/clickwrap/canonical_json.rb +216 -0
  39. data/lib/clickwrap/capture/event_builder.rb +220 -0
  40. data/lib/clickwrap/capture/presentation_verifier.rb +521 -0
  41. data/lib/clickwrap/capture.rb +650 -0
  42. data/lib/clickwrap/configuration.rb +1129 -0
  43. data/lib/clickwrap/controller_helpers.rb +758 -0
  44. data/lib/clickwrap/current_state.rb +282 -0
  45. data/lib/clickwrap/digest.rb +125 -0
  46. data/lib/clickwrap/doctor.rb +418 -0
  47. data/lib/clickwrap/document_definition.rb +255 -0
  48. data/lib/clickwrap/document_renderer.rb +83 -0
  49. data/lib/clickwrap/document_renderers/markdown.rb +175 -0
  50. data/lib/clickwrap/document_renderers/markdown_rails.rb +126 -0
  51. data/lib/clickwrap/dsl/policy_builder.rb +462 -0
  52. data/lib/clickwrap/dsl/retention_builder.rb +89 -0
  53. data/lib/clickwrap/durable_commit_callback.rb +37 -0
  54. data/lib/clickwrap/engine.rb +184 -0
  55. data/lib/clickwrap/errors.rb +181 -0
  56. data/lib/clickwrap/form_builder_extensions.rb +341 -0
  57. data/lib/clickwrap/front_matter.rb +67 -0
  58. data/lib/clickwrap/identifier.rb +112 -0
  59. data/lib/clickwrap/import/external_receipt.rb +241 -0
  60. data/lib/clickwrap/import/fine_print.rb +290 -0
  61. data/lib/clickwrap/import/legacy.rb +450 -0
  62. data/lib/clickwrap/integrations/organizations_authority.rb +81 -0
  63. data/lib/clickwrap/integrity/anchor.rb +130 -0
  64. data/lib/clickwrap/integrity/attestation_reconciler.rb +114 -0
  65. data/lib/clickwrap/integrity/attestor.rb +221 -0
  66. data/lib/clickwrap/integrity/chain.rb +313 -0
  67. data/lib/clickwrap/integrity/timestamp.rb +143 -0
  68. data/lib/clickwrap/ip_geolocation/location.rb +112 -0
  69. data/lib/clickwrap/ip_geolocation/null_resolver.rb +35 -0
  70. data/lib/clickwrap/ip_geolocation/resolver.rb +97 -0
  71. data/lib/clickwrap/ip_geolocation/static_resolver.rb +107 -0
  72. data/lib/clickwrap/ip_geolocation/trackdown_resolver.rb +330 -0
  73. data/lib/clickwrap/ip_geolocation.rb +16 -0
  74. data/lib/clickwrap/lifecycle.rb +534 -0
  75. data/lib/clickwrap/linter.rb +382 -0
  76. data/lib/clickwrap/localized_text.rb +101 -0
  77. data/lib/clickwrap/macros.rb +203 -0
  78. data/lib/clickwrap/models/application_record.rb +20 -0
  79. data/lib/clickwrap/models/chain_head.rb +79 -0
  80. data/lib/clickwrap/models/concerns/has_clickwraps.rb +55 -0
  81. data/lib/clickwrap/models/disposition_plan.rb +208 -0
  82. data/lib/clickwrap/models/document.rb +46 -0
  83. data/lib/clickwrap/models/document_version.rb +163 -0
  84. data/lib/clickwrap/models/event.rb +743 -0
  85. data/lib/clickwrap/models/event_document.rb +79 -0
  86. data/lib/clickwrap/models/event_statement.rb +92 -0
  87. data/lib/clickwrap/models/external_action.rb +150 -0
  88. data/lib/clickwrap/models/integrity_attestation.rb +90 -0
  89. data/lib/clickwrap/models/legal_hold.rb +81 -0
  90. data/lib/clickwrap/models/policy_revision.rb +115 -0
  91. data/lib/clickwrap/models/presentation.rb +59 -0
  92. data/lib/clickwrap/models/receipt_access.rb +53 -0
  93. data/lib/clickwrap/models/recording_sequence.rb +21 -0
  94. data/lib/clickwrap/models/request_evidence.rb +378 -0
  95. data/lib/clickwrap/models/statement_identity_lock.rb +38 -0
  96. data/lib/clickwrap/models/statement_state.rb +130 -0
  97. data/lib/clickwrap/pending_receipt.rb +177 -0
  98. data/lib/clickwrap/policy.rb +283 -0
  99. data/lib/clickwrap/presentation_manifest.rb +210 -0
  100. data/lib/clickwrap/presenter.rb +716 -0
  101. data/lib/clickwrap/privacy.rb +419 -0
  102. data/lib/clickwrap/protected_outcome.rb +120 -0
  103. data/lib/clickwrap/receipt.rb +606 -0
  104. data/lib/clickwrap/receipt_html.rb +235 -0
  105. data/lib/clickwrap/receipt_verifier.rb +978 -0
  106. data/lib/clickwrap/reference.rb +44 -0
  107. data/lib/clickwrap/registration.rb +236 -0
  108. data/lib/clickwrap/registry.rb +54 -0
  109. data/lib/clickwrap/remediation_token.rb +155 -0
  110. data/lib/clickwrap/request_evidence_extractor.rb +590 -0
  111. data/lib/clickwrap/request_evidence_policy.rb +261 -0
  112. data/lib/clickwrap/retention/applier.rb +231 -0
  113. data/lib/clickwrap/retention/disposition.rb +221 -0
  114. data/lib/clickwrap/retention/planner.rb +502 -0
  115. data/lib/clickwrap/retention_class.rb +97 -0
  116. data/lib/clickwrap/reviewed_text.rb +28 -0
  117. data/lib/clickwrap/schema_requirements.rb +196 -0
  118. data/lib/clickwrap/services/authorize_external_action.rb +149 -0
  119. data/lib/clickwrap/services/load_policies.rb +69 -0
  120. data/lib/clickwrap/services/publish_documents.rb +251 -0
  121. data/lib/clickwrap/services/validate_policy_references.rb +166 -0
  122. data/lib/clickwrap/statement.rb +248 -0
  123. data/lib/clickwrap/subject_fingerprint.rb +28 -0
  124. data/lib/clickwrap/submission.rb +169 -0
  125. data/lib/clickwrap/system_actor.rb +31 -0
  126. data/lib/clickwrap/test_helpers.rb +676 -0
  127. data/lib/clickwrap/testing.rb +211 -0
  128. data/lib/clickwrap/trusted_proxy_configuration.rb +92 -0
  129. data/lib/clickwrap/verification.rb +504 -0
  130. data/lib/clickwrap/version.rb +12 -1
  131. data/lib/clickwrap/view_helpers.rb +190 -0
  132. data/lib/clickwrap/vocabulary.rb +294 -0
  133. data/lib/clickwrap.rb +497 -7
  134. data/lib/generators/clickwrap/document_generator.rb +164 -0
  135. data/lib/generators/clickwrap/hardening_generator.rb +177 -0
  136. data/lib/generators/clickwrap/install_generator.rb +1287 -0
  137. data/lib/generators/clickwrap/link_generator.rb +56 -0
  138. data/lib/generators/clickwrap/policy_generator.rb +118 -0
  139. data/lib/generators/clickwrap/templates/clickwrap_hardening.rb.erb +256 -0
  140. data/lib/generators/clickwrap/templates/clickwrap_policies.rb.erb +192 -0
  141. data/lib/generators/clickwrap/templates/create_clickwrap_external_action_tables.rb.erb +128 -0
  142. data/lib/generators/clickwrap/templates/create_clickwrap_integrity_tables.rb.erb +157 -0
  143. data/lib/generators/clickwrap/templates/create_clickwrap_presentation_tables.rb.erb +160 -0
  144. data/lib/generators/clickwrap/templates/create_clickwrap_request_evidence_tables.rb.erb +180 -0
  145. data/lib/generators/clickwrap/templates/create_clickwrap_retention_tables.rb.erb +174 -0
  146. data/lib/generators/clickwrap/templates/create_clickwrap_tables.rb.erb +568 -0
  147. data/lib/generators/clickwrap/templates/initializer.rb.erb +439 -0
  148. data/lib/generators/clickwrap/templates/link_clickwrap_event_migration.rb.erb +12 -0
  149. data/lib/generators/clickwrap/templates/policy.rb.erb +31 -0
  150. data/lib/generators/clickwrap/templates/policy_test.rb.erb +56 -0
  151. data/lib/generators/clickwrap/templates/privacy.md.erb +58 -0
  152. data/lib/generators/clickwrap/templates/terms.md.erb +49 -0
  153. data/lib/generators/clickwrap/upgrade_generator.rb +50 -0
  154. data/lib/generators/clickwrap/views_generator.rb +101 -0
  155. data/lib/tasks/clickwrap.rake +569 -0
  156. metadata +311 -16
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+ require "rails/generators/active_record"
5
+
6
+ module Clickwrap
7
+ module Generators
8
+ # `rails generate clickwrap:upgrade` — the schema changes a newer release
9
+ # needs, as NEW migrations.
10
+ #
11
+ # This generator exists because of a promise: a released migration is never
12
+ # edited underneath an installed application. Editing one would change the
13
+ # schema that existing evidence was written under while leaving that evidence
14
+ # in place, and a receipt whose table no longer means what it meant is worth
15
+ # less than no receipt at all. So upgrades add migrations, and the files you
16
+ # already ran stay exactly as they were.
17
+ #
18
+ # At 0.1.0 there is nothing to upgrade from. This generator says so and
19
+ # creates nothing, rather than writing an empty migration to look busy.
20
+ class UpgradeGenerator < Rails::Generators::Base
21
+ include ActiveRecord::Generators::Migration
22
+
23
+ source_root File.expand_path("templates", __dir__)
24
+ desc "Create the migrations needed to move an installed app to this release"
25
+
26
+ def self.next_migration_number(dir)
27
+ ActiveRecord::Generators::Base.next_migration_number(dir)
28
+ end
29
+
30
+ def create_upgrade_migrations
31
+ say "\n☑️ clickwrap #{Clickwrap::VERSION} has no upgrade migrations.", :green
32
+ say "\n0.1.0 is the first release, so there is no earlier schema to move from and"
33
+ say "nothing was created."
34
+ say "\nIf you are installing clickwrap for the first time, you want:"
35
+ say " bin/rails generate clickwrap:install"
36
+ say "\nWhen a later release needs a schema change, this generator will add NEW"
37
+ say "migrations for it and report exactly what they do. Your existing migration"
38
+ say "files stay untouched, and evidence written under them goes on verifying —"
39
+ say "every released receipt format keeps a golden fixture, and a new format means"
40
+ say "a new explicit schema and verifier rather than a quiet reinterpretation.\n"
41
+ end
42
+
43
+ private
44
+
45
+ def migration_version
46
+ "[#{ActiveRecord::VERSION::STRING.to_f}]"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module Clickwrap
6
+ module Generators
7
+ # `rails generate clickwrap:views` — eject the engine's overridable templates
8
+ # into the HOST app so they can be restyled. This is the Devise move
9
+ # (`rails g devise:views`), and it works for the same boring Rails reason:
10
+ # the host app's `app/views` sits AHEAD of any engine's view paths in the
11
+ # lookup chain, so a file copied to e.g.
12
+ # `app/views/clickwrap/captures/show.html.erb` SHADOWS the gem's bundled
13
+ # default automatically — no config, no registration. Delete your copy and
14
+ # the gem's default comes back. Upgrade the gem and your ejected copies are
15
+ # untouched (re-run only if you WANT the new defaults).
16
+ #
17
+ # `source_root` points at the engine's own `app/views`, so `directory` copies
18
+ # the exact templates the engine renders.
19
+ #
20
+ # One thing does not eject with the markup: the evidence contract. The
21
+ # controls are initially unselected, the document links come before the
22
+ # submit action, and the call to action recorded in the manifest is the one
23
+ # the person can actually press. Restyle freely, but a copy that preselects a
24
+ # control or moves the links below the button changes what the receipt is
25
+ # describing — and the development linter will say so.
26
+ #
27
+ # The same goes for the composed line. `presentation.combined` is one control
28
+ # answering several statements, and the manifest signs which ones; render it
29
+ # and then iterate `presentation.itemized_statements`, never `statements`, or
30
+ # the page offers a second control for a statement the one control already
31
+ # covers. The linter reports that too.
32
+ class ViewsGenerator < Rails::Generators::Base
33
+ source_root File.expand_path("../../../app/views", __dir__)
34
+
35
+ desc "Copy clickwrap's overridable views into your app so you can restyle them"
36
+
37
+ class_option :views, type: :array,
38
+ desc: "Which view groups to copy (defaults to all of them)"
39
+
40
+ def copy_views
41
+ return say_nothing_to_copy if available_groups.empty?
42
+
43
+ requested_groups.each do |group|
44
+ unless available_groups.include?(group)
45
+ say " No `#{group}` views ship with this release. Available: " \
46
+ "#{available_groups.join(", ")}.", :yellow
47
+ next
48
+ end
49
+
50
+ directory "clickwrap/#{group}", "app/views/clickwrap/#{group}"
51
+ end
52
+ end
53
+
54
+ def show_styling_tip
55
+ return if available_groups.empty?
56
+
57
+ say "\n🎨 Views copied — they are yours now, and the gem's originals stay put for"
58
+ say " reference. Tailwind, Bootstrap, ViewComponent, Phlex, and plain ERB all"
59
+ say " work; classes you add here are picked up by your build automatically,"
60
+ say " because the files now live in app/views."
61
+ say "\n Worth keeping while you restyle: explicit labels, visible keyboard focus,"
62
+ say " conventional high-contrast links, `aria-invalid`/`aria-describedby` error"
63
+ say " relationships, meaning that does not depend on color alone, and validation"
64
+ say " that still works with no JavaScript."
65
+ say "\n And keep the shape: render `presentation.combined` as ONE control, then"
66
+ say " iterate `presentation.itemized_statements` — never `statements`, or you offer"
67
+ say " a second box for a statement the first one already answers.\n"
68
+ end
69
+
70
+ private
71
+
72
+ def requested_groups
73
+ requested = Array(options[:views]).map(&:to_s).reject(&:empty?)
74
+ requested.any? ? requested : available_groups
75
+ end
76
+
77
+ # Read from the engine rather than hardcoded, so this generator keeps
78
+ # working as the engine's surfaces change and never offers a group that
79
+ # does not exist.
80
+ def available_groups
81
+ @available_groups ||= begin
82
+ root = File.join(self.class.source_root.to_s, "clickwrap")
83
+
84
+ if File.directory?(root)
85
+ Dir.children(root).select { |entry| File.directory?(File.join(root, entry)) }.sort
86
+ else
87
+ []
88
+ end
89
+ end
90
+ end
91
+
92
+ def say_nothing_to_copy
93
+ say "\n This release of clickwrap ships no ejectable views, so nothing was copied.", :yellow
94
+ say " `form.clickwrap` renders the controls and the submit action either way. For a"
95
+ say " fully custom surface, ask the presenter for primitives instead of recreating"
96
+ say " hidden inputs:"
97
+ say " presentation = Clickwrap.present(:signup, actor: current_user, ...)"
98
+ end
99
+ end
100
+ end
101
+ end