reputable 0.1.13 → 0.1.14
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/reputable/rails.rb +12 -2
- data/lib/reputable/version.rb +1 -1
- data/lib/reputable.rb +79 -9
- metadata +2 -3
- data/reputable.gemspec +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c71694602b9f9eb25537c91c895503e068d59f36b9fbafcefcb7104acacd945f
|
|
4
|
+
data.tar.gz: 95fabaa4a264c471b46957b781b49cef0cda4205ab35d312ebb85497d9a88657
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4a8f05f1bc68354e88b6591873de564f4dbc56531209d7b00781536d23303d969447f05f76bd040b8e078efc836c8697ef1894342168e93c1c5592eb3af62639
|
|
7
|
+
data.tar.gz: dcd56a2d35fb3d162ffe0813e336212ce61d3e57a6e64d94303f9198b62849211e24879a7302073d4f1e0d3fa90ad765edc0ce6e941951e38a9a67c4dfb6f5fe
|
data/Gemfile.lock
CHANGED
data/lib/reputable/rails.rb
CHANGED
|
@@ -159,9 +159,19 @@ module Reputable
|
|
|
159
159
|
)
|
|
160
160
|
return if reputable_verified?(session_key: session_key)
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
# Check for new format (reputable_s) or legacy format (reputable_signature)
|
|
163
|
+
if params[:reputable_s] || params[:reputable_signature]
|
|
163
164
|
if Reputable.verify_redirect_return(params)
|
|
164
|
-
|
|
165
|
+
# For new format, decode payload to get status
|
|
166
|
+
# For legacy format, use reputable_status directly
|
|
167
|
+
status = if params[:reputable_r]
|
|
168
|
+
decoded = Reputable.decode_reputable_response(params)
|
|
169
|
+
decoded&.dig("status")
|
|
170
|
+
else
|
|
171
|
+
params[:reputable_status]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
if status == "pass"
|
|
165
175
|
session[session_key] = Time.now.to_i
|
|
166
176
|
return
|
|
167
177
|
end
|
data/lib/reputable/version.rb
CHANGED
data/lib/reputable.rb
CHANGED
|
@@ -181,9 +181,77 @@ module Reputable
|
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
# Verify the signature of a redirect return
|
|
184
|
+
# Supports both new format (reputable_r + reputable_s) and legacy format
|
|
184
185
|
# @param params [Hash] Request query parameters
|
|
185
|
-
# @return [Boolean] true if valid
|
|
186
|
+
# @return [Boolean] true if valid signature check
|
|
186
187
|
def verify_redirect_return(params)
|
|
188
|
+
keys = configuration.trusted_keys
|
|
189
|
+
if keys.nil? || keys.empty?
|
|
190
|
+
logger&.warn "Reputable: Missing trusted_keys, cannot verify redirect"
|
|
191
|
+
return false
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Detect format: new (reputable_r) vs legacy (reputable_status)
|
|
195
|
+
if params["reputable_r"] && params["reputable_s"]
|
|
196
|
+
verify_new_format(params, keys)
|
|
197
|
+
elsif params["reputable_status"] && params["reputable_signature"]
|
|
198
|
+
verify_legacy_format(params, keys)
|
|
199
|
+
else
|
|
200
|
+
false
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Decode the new reputable_r payload
|
|
205
|
+
# @param params [Hash] Request query parameters
|
|
206
|
+
# @return [Hash, nil] Decoded payload with normalized keys, or nil if invalid
|
|
207
|
+
def decode_reputable_response(params)
|
|
208
|
+
encoded = params["reputable_r"]
|
|
209
|
+
return nil unless encoded
|
|
210
|
+
|
|
211
|
+
begin
|
|
212
|
+
json = base64url_decode(encoded)
|
|
213
|
+
payload = JSON.parse(json)
|
|
214
|
+
|
|
215
|
+
# Return normalized hash with full key names
|
|
216
|
+
{
|
|
217
|
+
"version" => payload["v"],
|
|
218
|
+
"status" => payload["s"],
|
|
219
|
+
"session_id" => payload["sid"],
|
|
220
|
+
"outcome" => payload["o"],
|
|
221
|
+
"ignore_analytics" => payload["i"],
|
|
222
|
+
"country" => payload["c"],
|
|
223
|
+
"challenge_passed" => payload["cp"]
|
|
224
|
+
}.compact
|
|
225
|
+
rescue StandardError => e
|
|
226
|
+
logger&.warn "Reputable: Failed to decode response: #{e.message}"
|
|
227
|
+
nil
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
private
|
|
232
|
+
|
|
233
|
+
def verify_new_format(params, keys)
|
|
234
|
+
encoded_payload = params["reputable_r"]
|
|
235
|
+
signature = params["reputable_s"]
|
|
236
|
+
|
|
237
|
+
return false unless encoded_payload && signature
|
|
238
|
+
|
|
239
|
+
begin
|
|
240
|
+
# Decode to get the JSON string (this is what was signed)
|
|
241
|
+
json_payload = base64url_decode(encoded_payload)
|
|
242
|
+
|
|
243
|
+
# Verify signature against JSON string
|
|
244
|
+
keys.any? do |key|
|
|
245
|
+
expected_signature = OpenSSL::HMAC.hexdigest("SHA256", key, json_payload)
|
|
246
|
+
secure_compare(expected_signature, signature)
|
|
247
|
+
end
|
|
248
|
+
rescue StandardError => e
|
|
249
|
+
logger&.warn "Reputable: Failed to verify new format: #{e.message}"
|
|
250
|
+
false
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def verify_legacy_format(params, keys)
|
|
187
255
|
status = params["reputable_status"]
|
|
188
256
|
session_id = params["reputable_session_id"]
|
|
189
257
|
signature = params["reputable_signature"]
|
|
@@ -194,14 +262,7 @@ module Reputable
|
|
|
194
262
|
|
|
195
263
|
return false unless status && session_id && signature
|
|
196
264
|
|
|
197
|
-
keys = configuration.trusted_keys
|
|
198
|
-
if keys.nil? || keys.empty?
|
|
199
|
-
logger&.warn "Reputable: Missing trusted_keys, cannot verify redirect"
|
|
200
|
-
return false
|
|
201
|
-
end
|
|
202
|
-
|
|
203
265
|
# Reconstruct data string: status:sessionId:outcome:ignoreAnalytics:country:challengePassed
|
|
204
|
-
# Note: optional params default to empty strings if missing in reconstruction logic on server
|
|
205
266
|
data_parts = [
|
|
206
267
|
status,
|
|
207
268
|
session_id,
|
|
@@ -213,12 +274,21 @@ module Reputable
|
|
|
213
274
|
|
|
214
275
|
data = data_parts.join(":")
|
|
215
276
|
|
|
216
|
-
# Iterate through all trusted keys to find a match
|
|
217
277
|
keys.any? do |key|
|
|
218
278
|
expected_signature = OpenSSL::HMAC.hexdigest("SHA256", key, data)
|
|
219
279
|
secure_compare(expected_signature, signature)
|
|
220
280
|
end
|
|
221
281
|
end
|
|
282
|
+
|
|
283
|
+
def base64url_encode(str)
|
|
284
|
+
Base64.urlsafe_encode64(str).gsub("=", "")
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def base64url_decode(str)
|
|
288
|
+
# Add padding if needed
|
|
289
|
+
padded = str + "=" * ((4 - str.length % 4) % 4)
|
|
290
|
+
Base64.urlsafe_decode64(padded)
|
|
291
|
+
end
|
|
222
292
|
|
|
223
293
|
private
|
|
224
294
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: reputable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.14
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Reputable
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: redis
|
|
@@ -137,7 +137,6 @@ files:
|
|
|
137
137
|
- lib/reputable/reputation.rb
|
|
138
138
|
- lib/reputable/tracker.rb
|
|
139
139
|
- lib/reputable/version.rb
|
|
140
|
-
- reputable.gemspec
|
|
141
140
|
homepage: https://github.com/reputable-click/reputable-rb
|
|
142
141
|
licenses:
|
|
143
142
|
- MIT
|
data/reputable.gemspec
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "lib/reputable/version"
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = "reputable"
|
|
7
|
-
spec.version = Reputable::VERSION
|
|
8
|
-
spec.authors = ["Reputable"]
|
|
9
|
-
spec.email = ["support@reputable.click"]
|
|
10
|
-
|
|
11
|
-
spec.summary = "Ruby client for Reputable - bot detection and reputation scoring"
|
|
12
|
-
spec.description = "Track requests and manage IP reputation through Redis/Dragonfly integration with Reputable"
|
|
13
|
-
spec.homepage = "https://github.com/reputable-click/reputable-rb"
|
|
14
|
-
spec.license = "MIT"
|
|
15
|
-
spec.required_ruby_version = ">= 2.7.0"
|
|
16
|
-
|
|
17
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
|
18
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
|
19
|
-
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
20
|
-
|
|
21
|
-
spec.files = Dir.chdir(__dir__) do
|
|
22
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
23
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)}) || f.end_with?(".gem")
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
spec.bindir = "exe"
|
|
27
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
28
|
-
spec.require_paths = ["lib"]
|
|
29
|
-
|
|
30
|
-
spec.add_dependency "redis", ">= 4.0", "< 6.0"
|
|
31
|
-
spec.add_dependency "connection_pool", "~> 2.2"
|
|
32
|
-
|
|
33
|
-
spec.add_development_dependency "bundler", "~> 2.0"
|
|
34
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
|
35
|
-
spec.add_development_dependency "rspec", "~> 3.12"
|
|
36
|
-
spec.add_development_dependency "rack", "~> 2.0"
|
|
37
|
-
spec.add_development_dependency "rubocop", "~> 1.0"
|
|
38
|
-
end
|