trackguard 0.16.1 → 0.17.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4c12f652065f915f2b4b906869a232738d8cf96632e6676f7107e84c442ea9d
4
- data.tar.gz: a50ce6042ea670cb43486972f7a47a8187273aebd2947bd42f2ccfd4aba67225
3
+ metadata.gz: 79ebac148a49b2b6df9f280c3a8e8e624fa82910ccf0e3d4c608a04ac7f73ced
4
+ data.tar.gz: a0a0648dacb35df737e19413603d658b1c015f6e5fa60d0a6adc72da497082da
5
5
  SHA512:
6
- metadata.gz: 4eb185b4afe7cd71d3347afac5d203625a3348ff812647fc3ea6b04cff52bb2ded026d2601d546945900bd5f9a05bb0154fcb78a590ae6f5ec3249f283254b04
7
- data.tar.gz: 18a0b707b1c085cab5c43a7249c4a6ed8bf753ba30a3b1e4e5bee00283381de4f2f511af06651009b587e9eeada7d69a860d4664f914adf92dfd2307e16d84f2
6
+ metadata.gz: 59d2f2a7dde041da4cc0acf29249c77d9f911a76c498f9381293c838a29bd6ac5fec3c875645c7be60b686d77cb99e4731032b45eb7a2a93464dadaac81b04cb
7
+ data.tar.gz: 5c1bf529774f1af5e8a7e83154e7e21b94e468c95702ac00bed7f0b133b85c092359e544e7f2f615d4e364d904e4512d16ad42d42e3c712d8f8dcb4b60cb81ae
@@ -11,11 +11,13 @@ module Trackguard
11
11
  end
12
12
  end
13
13
 
14
+ # rubocop:disable Metrics/AbcSize
14
15
  def flag
15
16
  if @visitor.update(
16
17
  flagged_at: Time.current,
17
18
  flag_reason: params[:flag_reason].presence,
18
- flagged_by: params[:flagged_by].presence || Visitor::FLAGGED_BY.first
19
+ flagged_by: params[:flagged_by].presence || Visitor::FLAGGED_BY.first,
20
+ name: params[:name].presence || BlockedUserAgent.matching_pattern(@visitor.user_agent)
19
21
  )
20
22
  respond_to do |format|
21
23
  format.html { redirect_back_or_to dashboard_path }
@@ -28,6 +30,7 @@ module Trackguard
28
30
  end
29
31
  end
30
32
  end
33
+ # rubocop:enable Metrics/AbcSize
31
34
 
32
35
  def unflag
33
36
  @visitor.update!(flagged_at: nil, flag_reason: nil, flagged_by: nil)
@@ -43,13 +43,15 @@ module Trackguard
43
43
  return if count.zero?
44
44
  return if visitor.whitelisted_ip&.active?
45
45
 
46
+ name = name_from_ua(visitor.user_agent)
47
+
46
48
  if count >= HARD_FLAG_THRESHOLD
47
- flag!(visitor, "#{count} page views in 24h (hard flag threshold)")
49
+ flag!(visitor, "#{count} page views in 24h (hard flag threshold)", name: name)
48
50
  return
49
51
  end
50
52
 
51
53
  if (reason = ua_flag_reason(visitor.user_agent))
52
- flag!(visitor, reason)
54
+ flag!(visitor, reason, name: name)
53
55
  return
54
56
  end
55
57
 
@@ -58,7 +60,7 @@ module Trackguard
58
60
  return if count < MIN_VIEWS
59
61
 
60
62
  if views.all? { |pv| pv.session_id.nil? && pv.referer.nil? && pv.path == "/" }
61
- flag!(visitor, "no session, no referrer, single root hit")
63
+ flag!(visitor, "no session, no referrer, single root hit", name: name)
62
64
  return
63
65
  end
64
66
 
@@ -85,7 +87,7 @@ module Trackguard
85
87
 
86
88
  return if score < FLAG_SCORE_THRESHOLD
87
89
 
88
- flag!(visitor, reasons.join("; "))
90
+ flag!(visitor, reasons.join("; "), name: name)
89
91
  end
90
92
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
91
93
 
@@ -107,7 +109,8 @@ module Trackguard
107
109
  .where("wi.id IS NULL OR wi.expires_at <= ?", Time.current)
108
110
  .distinct
109
111
  .each do |visitor|
110
- flag!(visitor, "trace_id shared across multiple visitors (cross-visitor bot detected)")
112
+ flag!(visitor, "trace_id shared across multiple visitors (cross-visitor bot detected)",
113
+ name: name_from_ua(visitor.user_agent))
111
114
  end
112
115
  end
113
116
 
@@ -115,8 +118,12 @@ module Trackguard
115
118
  "blank or minimal user-agent" if user_agent.blank? || user_agent.to_s.length < 10
116
119
  end
117
120
 
118
- def flag!(visitor, reason)
119
- visitor.update!(flagged_at: Time.current, flag_reason: reason, flagged_by: "claw:auto")
121
+ def flag!(visitor, reason, name: nil)
122
+ visitor.update!(flagged_at: Time.current, flag_reason: reason, flagged_by: "claw:auto", name: name)
123
+ end
124
+
125
+ def name_from_ua(user_agent)
126
+ BlockedUserAgent.matching_pattern(user_agent)
120
127
  end
121
128
 
122
129
  def blank_ratio(views, attr)
@@ -12,5 +12,12 @@ module Trackguard
12
12
  end
13
13
  patterns.any? { |p| user_agent.to_s.downcase.include?(p.downcase) }
14
14
  end
15
+
16
+ def self.matching_pattern(user_agent)
17
+ patterns = Rails.cache.fetch(CACHE_KEY, expires_in: 10.minutes) do
18
+ pluck(:pattern)
19
+ end
20
+ patterns.find { |p| user_agent.to_s.downcase.include?(p.downcase) }
21
+ end
15
22
  end
16
23
  end
@@ -151,6 +151,7 @@
151
151
  <%= hidden_field_tag :id, visitor.id %>
152
152
  <%= f.submit "Flag", class: "tg-btn tg-btn--danger" %>
153
153
  <%= f.text_field :flag_reason, placeholder: "Flag reason (optional)", class: "tg-input", autocomplete: "off" %>
154
+ <%= f.text_field :name, placeholder: "Name (optional, auto-detected if blank)", class: "tg-input", autocomplete: "off" %>
154
155
  <% end %>
155
156
  <% end %>
156
157
  </div>
@@ -175,6 +176,10 @@
175
176
  <span class="tg-dl__term">User agent</span>
176
177
  <span class="tg-dl__def tg-dl__def--break"><%= visitor&.user_agent.presence || "—" %></span>
177
178
  </div>
179
+ <div class="tg-dl__row">
180
+ <span class="tg-dl__term">Name</span>
181
+ <span class="tg-dl__def"><%= visitor&.name.presence || "—" %></span>
182
+ </div>
178
183
  <div class="tg-dl__row">
179
184
  <span class="tg-dl__term">Flag status</span>
180
185
  <% if flagged %>
@@ -63,6 +63,7 @@
63
63
  <%= hidden_field_tag :id, visitor.id %>
64
64
  <%= f.submit "Flag", class: "tg-btn tg-btn--danger" %>
65
65
  <%= f.text_field :flag_reason, placeholder: "Flag reason (optional)", class: "tg-input", autocomplete: "off" %>
66
+ <%= f.text_field :name, placeholder: "Name (optional, auto-detected if blank)", class: "tg-input", autocomplete: "off" %>
66
67
  <% end %>
67
68
  <% end %>
68
69
  </div>
@@ -87,6 +88,10 @@
87
88
  <span class="tg-dl__term">User agent</span>
88
89
  <span class="tg-dl__def tg-dl__def--break"><%= visitor&.user_agent.presence || "—" %></span>
89
90
  </div>
91
+ <div class="tg-dl__row">
92
+ <span class="tg-dl__term">Name</span>
93
+ <span class="tg-dl__def"><%= visitor&.name.presence || "—" %></span>
94
+ </div>
90
95
  <div class="tg-dl__row">
91
96
  <span class="tg-dl__term">Flag status</span>
92
97
  <% if flagged %>
@@ -0,0 +1,5 @@
1
+ class AddNameToTrackguardVisitors < ActiveRecord::Migration[8.0]
2
+ def change
3
+ add_column :trackguard_visitors, :name, :string
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddVisitorName < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
4
+ def change
5
+ add_column :trackguard_visitors, :name, :string
6
+ end
7
+ end
@@ -15,6 +15,10 @@ module Trackguard
15
15
  migration_template "add_trackguard_visits.rb", "db/migrate/add_trackguard_visits.rb"
16
16
  end
17
17
 
18
+ def create_visitor_name_migration_file
19
+ migration_template "add_visitor_name.rb", "db/migrate/add_visitor_name.rb"
20
+ end
21
+
18
22
  def print_next_steps
19
23
  say "\nNext steps:", :green
20
24
  say " 1. rails db:migrate"
@@ -1,3 +1,3 @@
1
1
  module Trackguard
2
- VERSION = "0.16.1".freeze
2
+ VERSION = "0.17.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackguard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Krzysztof Rygielski
@@ -72,8 +72,10 @@ files:
72
72
  - app/views/trackguard/admin/visits/index.html.erb
73
73
  - config/importmap.rb
74
74
  - config/routes.rb
75
+ - db/migrate/20260505191009_add_name_to_trackguard_visitors.rb
75
76
  - lib/generators/trackguard/install_generator.rb
76
77
  - lib/generators/trackguard/templates/add_trackguard_visits.rb
78
+ - lib/generators/trackguard/templates/add_visitor_name.rb
77
79
  - lib/generators/trackguard/templates/create_trackguard_tables.rb
78
80
  - lib/generators/trackguard/upgrade_generator.rb
79
81
  - lib/tasks/trackguard.rake