reputable 0.1.2 → 0.1.3
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/README.md +77 -0
- data/lib/reputable/configuration.rb +28 -2
- data/lib/reputable/version.rb +1 -1
- data/lib/reputable.rb +28 -9
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca78832e420ad0cacad0c44bbfbf2a682f1b9f702bbaf8aa07a44e4e04d7d53b
|
|
4
|
+
data.tar.gz: 9e15f534984a4e3d67560a98cbede0c596d02d30fb7f7171b380b043b0781384
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 23832e31d409bb3316c33c931e6207f24eb2ea078c2fa79d3d0c4618e4ffd3359f525d0c6b090344bb5d8e79cf9fdc714752ae09180ce973dd353d93015afb6c
|
|
7
|
+
data.tar.gz: 9eb4a989b111a493e7555672057946c2928251a1112e7b75e011bf7183c329ee3b9c6c6cb0e34a163d3803cb5956321b443b25f2d9fcbfca5c90ad16b73cd766
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -135,6 +135,11 @@ Reputable.configure do |config|
|
|
|
135
135
|
REMOTE_ADDR
|
|
136
136
|
]
|
|
137
137
|
|
|
138
|
+
# Verification Configuration
|
|
139
|
+
# Supports comma-separated list in REPUTABLE_TRUSTED_KEYS or single key in REPUTABLE_TRUSTED_KEY
|
|
140
|
+
config.trusted_keys = ENV['REPUTABLE_TRUSTED_KEYS']&.split(',') || ENV['REPUTABLE_TRUSTED_KEY']
|
|
141
|
+
config.verification_base_url = ENV['REPUTABLE_VERIFY_URL'] # URL of your Reputable API verify endpoint
|
|
142
|
+
|
|
138
143
|
# Error callback (optional)
|
|
139
144
|
config.on_error = ->(error, context) {
|
|
140
145
|
# Report to your error tracking service
|
|
@@ -359,6 +364,78 @@ Reputable.lookup_reputation(:ip, request.ip)
|
|
|
359
364
|
|
|
360
365
|
---
|
|
361
366
|
|
|
367
|
+
## User Verification & Trust Flow
|
|
368
|
+
|
|
369
|
+
When you identify a suspicious user (e.g., high risk score or specific tag), you can redirect them to the Reputable verification page. This page performs advanced browser checks and challenges (CAPTCHA) if necessary.
|
|
370
|
+
|
|
371
|
+
### 1. Generating a Signed Redirect URL
|
|
372
|
+
|
|
373
|
+
To effectively hand off verification handling to Reputable, generate a signed verification URL:
|
|
374
|
+
|
|
375
|
+
```ruby
|
|
376
|
+
# In your controller
|
|
377
|
+
if suspicious_activity_detected?
|
|
378
|
+
redirect_url = Reputable.verification_url(
|
|
379
|
+
return_url: request.original_url, # Where to send them back after verification
|
|
380
|
+
failure_url: root_url, # Optional: where to send if they fail/garbage token
|
|
381
|
+
session_id: session.id # Optional: link specific session
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
redirect_to redirect_url
|
|
385
|
+
end
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### 2. Handling the Return Redirect
|
|
389
|
+
|
|
390
|
+
When the user passes verification (or is determined to be already trusted/clean), they are immediately redirected back to your `return_url` with signed parameters.
|
|
391
|
+
|
|
392
|
+
**Middleware (Automatic Handling):**
|
|
393
|
+
If you are using `Reputable::Middleware` (recommended), this is handled automatically. The middleware detects the return parameters, verifies the signature, and sets `env['reputable.verified'] = true`.
|
|
394
|
+
|
|
395
|
+
```ruby
|
|
396
|
+
# In your controller
|
|
397
|
+
if request.env['reputable.verified']
|
|
398
|
+
# User just passed verification!
|
|
399
|
+
# You might want to graduate them to trusted status locally
|
|
400
|
+
trust_current_ip(reason: 'interactive_verification')
|
|
401
|
+
end
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**Manual Verification:**
|
|
405
|
+
If you need to verify manually (e.g., custom controller logic):
|
|
406
|
+
|
|
407
|
+
```ruby
|
|
408
|
+
# In your controller action (the return_url target)
|
|
409
|
+
if params[:reputable_signature]
|
|
410
|
+
if Reputable.verify_redirect_return(params)
|
|
411
|
+
# Signature is VALID. Meaning Reputable actually sent this user back.
|
|
412
|
+
|
|
413
|
+
# Inspect outcomes
|
|
414
|
+
status = params[:reputable_status] # 'pass', 'fail'
|
|
415
|
+
outcome = params[:reputable_outcome] # 'trusted_verified', 'trusted_behavior', 'unknown'
|
|
416
|
+
country = params[:reputable_country] # 'US', 'DE', etc.
|
|
417
|
+
|
|
418
|
+
if status == 'pass'
|
|
419
|
+
# Grant access
|
|
420
|
+
end
|
|
421
|
+
else
|
|
422
|
+
# Invalid signature - potential tampering attempt!
|
|
423
|
+
render plain: "Verification failed", status: 403
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**Return Parameters:**
|
|
429
|
+
The return URL will contain:
|
|
430
|
+
- `reputable_status`: `pass` or `fail`
|
|
431
|
+
- `reputable_session_id`: The session ID you provided
|
|
432
|
+
- `reputable_outcome`: The specific reputation outcome (e.g., `trusted_verified`)
|
|
433
|
+
- `reputable_ignore_analytics`: 'true'/'false' flag
|
|
434
|
+
- `reputable_country`: ISO country code
|
|
435
|
+
- `reputable_signature`: HMAC-SHA256 signature of the above
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
362
439
|
## Resilience & Failsafe Features
|
|
363
440
|
|
|
364
441
|
### Never Breaks Your App
|
|
@@ -14,7 +14,7 @@ module Reputable
|
|
|
14
14
|
:default_ttls, :pool_size, :pool_timeout,
|
|
15
15
|
:connect_timeout, :read_timeout, :write_timeout,
|
|
16
16
|
:ssl_params, :trusted_proxies, :ip_header_priority,
|
|
17
|
-
:on_error, :
|
|
17
|
+
:on_error, :trusted_keys, :verification_base_url
|
|
18
18
|
|
|
19
19
|
# Default TTLs in seconds (0 = forever)
|
|
20
20
|
DEFAULT_TTLS = {
|
|
@@ -63,10 +63,36 @@ module Reputable
|
|
|
63
63
|
@trusted_proxies = nil # Additional trusted proxy IPs/ranges
|
|
64
64
|
@ip_header_priority = DEFAULT_IP_HEADERS.dup
|
|
65
65
|
@on_error = nil # Optional error callback: ->(error, context) { ... }
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
# Support multiple trusted keys (comma-separated), fallback to old secret key env var
|
|
68
|
+
@trusted_keys = []
|
|
69
|
+
if ENV["REPUTABLE_TRUSTED_KEYS"]
|
|
70
|
+
@trusted_keys = ENV["REPUTABLE_TRUSTED_KEYS"].split(",").map(&:strip)
|
|
71
|
+
elsif ENV["REPUTABLE_TRUSTED_KEY"]
|
|
72
|
+
@trusted_keys = [ENV["REPUTABLE_TRUSTED_KEY"]]
|
|
73
|
+
elsif ENV["REPUTABLE_SECRET_KEY"]
|
|
74
|
+
@trusted_keys = [ENV["REPUTABLE_SECRET_KEY"]]
|
|
75
|
+
end
|
|
67
76
|
@verification_base_url = ENV.fetch("REPUTABLE_VERIFY_URL", "https://api.reputable.click/_reputable/verify")
|
|
68
77
|
end
|
|
69
78
|
|
|
79
|
+
# Alias for backward compatibility
|
|
80
|
+
def secret_key
|
|
81
|
+
@trusted_keys.first
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def secret_key=(key)
|
|
85
|
+
@trusted_keys = [key]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def trusted_keys=(keys)
|
|
89
|
+
@trusted_keys = Array(keys)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def trusted_keys
|
|
93
|
+
@trusted_keys
|
|
94
|
+
end
|
|
95
|
+
|
|
70
96
|
# Check if Reputable is enabled (can be disabled via ENV)
|
|
71
97
|
def enabled?
|
|
72
98
|
env_value = ENV["REPUTABLE_ENABLED"]
|
data/lib/reputable/version.rb
CHANGED
data/lib/reputable.rb
CHANGED
|
@@ -127,12 +127,15 @@ module Reputable
|
|
|
127
127
|
|
|
128
128
|
# Generate a signed verification URL
|
|
129
129
|
def verification_url(return_url:, failure_url: nil, session_id: nil)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
logger&.warn "Reputable: Missing
|
|
130
|
+
keys = configuration.trusted_keys
|
|
131
|
+
if keys.nil? || keys.empty?
|
|
132
|
+
logger&.warn "Reputable: Missing trusted_keys, cannot generate verification URL"
|
|
133
133
|
return return_url
|
|
134
134
|
end
|
|
135
135
|
|
|
136
|
+
# Use the first key for signing new requests
|
|
137
|
+
secret = keys.first
|
|
138
|
+
|
|
136
139
|
base_url = configuration.verification_base_url
|
|
137
140
|
|
|
138
141
|
# JWT Header
|
|
@@ -165,19 +168,35 @@ module Reputable
|
|
|
165
168
|
status = params["reputable_status"]
|
|
166
169
|
session_id = params["reputable_session_id"]
|
|
167
170
|
signature = params["reputable_signature"]
|
|
171
|
+
outcome = params["reputable_outcome"]
|
|
172
|
+
ignore_analytics = params["reputable_ignore_analytics"]
|
|
173
|
+
country = params["reputable_country"] || ""
|
|
168
174
|
|
|
169
175
|
return false unless status && session_id && signature
|
|
170
176
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
logger&.warn "Reputable: Missing
|
|
177
|
+
keys = configuration.trusted_keys
|
|
178
|
+
if keys.nil? || keys.empty?
|
|
179
|
+
logger&.warn "Reputable: Missing trusted_keys, cannot verify redirect"
|
|
174
180
|
return false
|
|
175
181
|
end
|
|
176
182
|
|
|
177
|
-
data
|
|
178
|
-
|
|
183
|
+
# Reconstruct data string: status:sessionId:outcome:ignoreAnalytics:country
|
|
184
|
+
# Note: optional params default to empty strings if missing in reconstruction logic on server
|
|
185
|
+
data_parts = [
|
|
186
|
+
status,
|
|
187
|
+
session_id,
|
|
188
|
+
outcome || "",
|
|
189
|
+
ignore_analytics.nil? ? "" : ignore_analytics,
|
|
190
|
+
country
|
|
191
|
+
]
|
|
192
|
+
|
|
193
|
+
data = data_parts.join(":")
|
|
179
194
|
|
|
180
|
-
|
|
195
|
+
# Iterate through all trusted keys to find a match
|
|
196
|
+
keys.any? do |key|
|
|
197
|
+
expected_signature = OpenSSL::HMAC.hexdigest("SHA256", key, data)
|
|
198
|
+
secure_compare(expected_signature, signature)
|
|
199
|
+
end
|
|
181
200
|
end
|
|
182
201
|
|
|
183
202
|
private
|
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.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Reputable
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-12-
|
|
11
|
+
date: 2025-12-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: redis
|