dregs 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +27 -0
- data/LICENSE +21 -0
- data/README.md +247 -0
- data/SECURITY.md +36 -0
- data/lib/dregs/client.rb +402 -0
- data/lib/dregs/errors.rb +143 -0
- data/lib/dregs/identities.rb +91 -0
- data/lib/dregs/models.rb +520 -0
- data/lib/dregs/version.rb +6 -0
- data/lib/dregs/webhooks.rb +144 -0
- data/lib/dregs.rb +38 -0
- data/sig/dregs.rbs +286 -0
- metadata +64 -0
data/sig/dregs.rbs
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Signatures for the public surface of the Dregs SDK. Validated in CI with `rbs validate`, so a
|
|
2
|
+
# method that changes shape here without changing there is caught.
|
|
3
|
+
|
|
4
|
+
module Dregs
|
|
5
|
+
VERSION: String
|
|
6
|
+
|
|
7
|
+
def self.new: (**untyped options) -> Client
|
|
8
|
+
|
|
9
|
+
class Error < StandardError
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class ConnectionError < Error
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class TimeoutError < ConnectionError
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class WebhookVerificationError < Error
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class APIError < Error
|
|
22
|
+
attr_reader status_code: Integer
|
|
23
|
+
attr_reader body: untyped
|
|
24
|
+
attr_reader request_id: String?
|
|
25
|
+
attr_reader api_message: String
|
|
26
|
+
|
|
27
|
+
def initialize: (String message, status_code: Integer, ?body: untyped, ?request_id: String?) -> void
|
|
28
|
+
def to_s: () -> String
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class BadRequestError < APIError
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class AuthenticationError < APIError
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class QuotaExceededError < APIError
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class PermissionDeniedError < APIError
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class NotFoundError < APIError
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class RateLimitError < APIError
|
|
47
|
+
attr_reader retry_after: Float?
|
|
48
|
+
|
|
49
|
+
def initialize: (
|
|
50
|
+
String message,
|
|
51
|
+
?status_code: Integer,
|
|
52
|
+
?body: untyped,
|
|
53
|
+
?request_id: String?,
|
|
54
|
+
?retry_after: Float?
|
|
55
|
+
) -> void
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class ServerError < APIError
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
module Errors
|
|
62
|
+
STATUS_ERRORS: Hash[Integer, Class]
|
|
63
|
+
|
|
64
|
+
def self.for_status: (Integer status_code) -> Class
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
module Category
|
|
68
|
+
HUMANITY: Symbol
|
|
69
|
+
AUTHENTICITY: Symbol
|
|
70
|
+
UNIQUENESS: Symbol
|
|
71
|
+
BEHAVIOR: Symbol
|
|
72
|
+
ALL: Array[Symbol]
|
|
73
|
+
|
|
74
|
+
def self.parse: (untyped value) -> Symbol?
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
module Parsing
|
|
78
|
+
def self?.time: (untyped value) -> Time?
|
|
79
|
+
def self?.hash_or_empty: (untyped value) -> Hash[untyped, untyped]
|
|
80
|
+
def self?.array_or_empty: (untyped value) -> Array[untyped]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class TrackResult
|
|
84
|
+
attr_reader status: String?
|
|
85
|
+
attr_reader id: String?
|
|
86
|
+
attr_reader fingerprint: String?
|
|
87
|
+
attr_reader raw: Hash[untyped, untyped]
|
|
88
|
+
|
|
89
|
+
def initialize: (status: String?, id: String?, fingerprint: String?, ?raw: Hash[untyped, untyped]) -> void
|
|
90
|
+
def accepted?: () -> bool
|
|
91
|
+
def self.from_api: (untyped payload) -> TrackResult
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
class Badge
|
|
95
|
+
attr_reader slug: String?
|
|
96
|
+
attr_reader name: String?
|
|
97
|
+
attr_reader type: String?
|
|
98
|
+
attr_reader explanation: String?
|
|
99
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
100
|
+
attr_reader raw: Hash[untyped, untyped]
|
|
101
|
+
|
|
102
|
+
def initialize: (
|
|
103
|
+
slug: String?,
|
|
104
|
+
name: String?,
|
|
105
|
+
type: String?,
|
|
106
|
+
explanation: String?,
|
|
107
|
+
?metadata: Hash[untyped, untyped],
|
|
108
|
+
?raw: Hash[untyped, untyped]
|
|
109
|
+
) -> void
|
|
110
|
+
|
|
111
|
+
def self.from_api: (untyped payload) -> Badge
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
class Observation
|
|
115
|
+
attr_reader category: Symbol?
|
|
116
|
+
attr_reader id: String?
|
|
117
|
+
attr_reader label: String?
|
|
118
|
+
attr_reader explanation: String?
|
|
119
|
+
attr_reader value: Float?
|
|
120
|
+
attr_reader confidence: Float?
|
|
121
|
+
attr_reader weight: Float?
|
|
122
|
+
attr_reader metadata: Hash[untyped, untyped]
|
|
123
|
+
attr_reader raw: Hash[untyped, untyped]
|
|
124
|
+
|
|
125
|
+
def initialize: (
|
|
126
|
+
category: Symbol?,
|
|
127
|
+
id: String?,
|
|
128
|
+
label: String?,
|
|
129
|
+
explanation: String?,
|
|
130
|
+
value: Float?,
|
|
131
|
+
confidence: Float?,
|
|
132
|
+
weight: Float?,
|
|
133
|
+
?metadata: Hash[untyped, untyped],
|
|
134
|
+
?raw: Hash[untyped, untyped]
|
|
135
|
+
) -> void
|
|
136
|
+
|
|
137
|
+
def self.from_api: (untyped payload) -> Observation
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
class Score
|
|
141
|
+
attr_reader category: Symbol?
|
|
142
|
+
attr_reader value: Integer?
|
|
143
|
+
attr_reader observations: Array[Observation]
|
|
144
|
+
attr_reader raw: Hash[untyped, untyped]
|
|
145
|
+
|
|
146
|
+
def initialize: (
|
|
147
|
+
category: Symbol?,
|
|
148
|
+
value: Integer?,
|
|
149
|
+
?observations: Array[Observation],
|
|
150
|
+
?raw: Hash[untyped, untyped]
|
|
151
|
+
) -> void
|
|
152
|
+
|
|
153
|
+
def self.from_api: (untyped payload) -> Score
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class Scores
|
|
157
|
+
include Enumerable[Score]
|
|
158
|
+
|
|
159
|
+
attr_reader to_a: Array[Score]
|
|
160
|
+
|
|
161
|
+
def initialize: (?Array[Score] scores) -> void
|
|
162
|
+
def each: () { (Score) -> void } -> self
|
|
163
|
+
| () -> Enumerator[Score, Scores]
|
|
164
|
+
def size: () -> Integer
|
|
165
|
+
def length: () -> Integer
|
|
166
|
+
def empty?: () -> bool
|
|
167
|
+
def []: (Integer index) -> Score?
|
|
168
|
+
def get: (Symbol category) -> Score?
|
|
169
|
+
def humanity: () -> Integer?
|
|
170
|
+
def authenticity: () -> Integer?
|
|
171
|
+
def uniqueness: () -> Integer?
|
|
172
|
+
def behavior: () -> Integer?
|
|
173
|
+
def self.from_api: (untyped payload) -> Scores
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
class Identity
|
|
177
|
+
attr_reader id: String?
|
|
178
|
+
attr_reader display_name: String?
|
|
179
|
+
attr_reader display_email: String?
|
|
180
|
+
attr_reader display_username: String?
|
|
181
|
+
attr_reader humanity_score: Integer?
|
|
182
|
+
attr_reader authenticity_score: Integer?
|
|
183
|
+
attr_reader uniqueness_score: Integer?
|
|
184
|
+
attr_reader behavior_score: Integer?
|
|
185
|
+
attr_reader created_at: Time?
|
|
186
|
+
attr_reader updated_at: Time?
|
|
187
|
+
attr_reader last_tracked_at: Time?
|
|
188
|
+
attr_reader last_scored_at: Time?
|
|
189
|
+
attr_reader disregarded: bool
|
|
190
|
+
attr_reader badges: Array[Badge]
|
|
191
|
+
attr_reader data: Hash[untyped, untyped]
|
|
192
|
+
attr_reader raw: Hash[untyped, untyped]
|
|
193
|
+
|
|
194
|
+
def initialize: (Hash[Symbol, untyped] attributes) -> void
|
|
195
|
+
def disregarded?: () -> bool
|
|
196
|
+
def scores: () -> Scores
|
|
197
|
+
def self.from_api: (untyped payload) -> Identity
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
class Analysis
|
|
201
|
+
attr_reader id: Integer?
|
|
202
|
+
attr_reader identity_id: String?
|
|
203
|
+
attr_reader scores: Scores
|
|
204
|
+
attr_reader event_count: Integer?
|
|
205
|
+
attr_reader device_count: Integer?
|
|
206
|
+
attr_reader duration_millis: Integer?
|
|
207
|
+
attr_reader started_at: Time?
|
|
208
|
+
attr_reader finished_at: Time?
|
|
209
|
+
attr_reader raw: Hash[untyped, untyped]
|
|
210
|
+
|
|
211
|
+
def initialize: (Hash[Symbol, untyped] attributes) -> void
|
|
212
|
+
def observations: () -> Array[Observation]
|
|
213
|
+
def self.from_api: (untyped payload) -> Analysis
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
class Identities
|
|
217
|
+
def initialize: (Client client) -> void
|
|
218
|
+
def get: (String identity_id) -> Identity
|
|
219
|
+
def scores: (String identity_id) -> Scores
|
|
220
|
+
def analysis: (String identity_id) -> Analysis
|
|
221
|
+
def analyze: (String identity_id) -> nil
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
class Client
|
|
225
|
+
DEFAULT_BASE_URL: String
|
|
226
|
+
DEFAULT_TIMEOUT: Integer
|
|
227
|
+
DEFAULT_MAX_RETRIES: Integer
|
|
228
|
+
SECRET_KEY_ENV: String
|
|
229
|
+
BASE_URL_ENV: String
|
|
230
|
+
RETRY_STATUSES: Array[Integer]
|
|
231
|
+
MAX_BACKOFF_SECONDS: Float
|
|
232
|
+
STATUS_RATE_LIMITED: String
|
|
233
|
+
STATUS_QUOTA_EXCEEDED: String
|
|
234
|
+
|
|
235
|
+
attr_reader base_url: String
|
|
236
|
+
attr_reader max_retries: Integer
|
|
237
|
+
attr_reader timeout: Numeric
|
|
238
|
+
attr_reader identities: Identities
|
|
239
|
+
|
|
240
|
+
def initialize: (
|
|
241
|
+
?secret_key: String?,
|
|
242
|
+
?base_url: String?,
|
|
243
|
+
?timeout: Numeric,
|
|
244
|
+
?max_retries: Integer
|
|
245
|
+
) -> void
|
|
246
|
+
|
|
247
|
+
def track: (
|
|
248
|
+
String event_type,
|
|
249
|
+
identity: String,
|
|
250
|
+
?data: Hash[untyped, untyped],
|
|
251
|
+
?identity_data: Hash[untyped, untyped],
|
|
252
|
+
?event_id: String?,
|
|
253
|
+
?timestamp: (Time | String)?,
|
|
254
|
+
?source: String?
|
|
255
|
+
) -> TrackResult
|
|
256
|
+
|
|
257
|
+
def request: (Symbol method, String path, ?body: Hash[untyped, untyped]?) -> untyped
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
module Webhooks
|
|
261
|
+
SIGNATURE_HEADER: String
|
|
262
|
+
TIMESTAMP_HEADER: String
|
|
263
|
+
EVENT_HEADER: String
|
|
264
|
+
DEFAULT_TOLERANCE_SECONDS: Integer
|
|
265
|
+
|
|
266
|
+
def self?.compute_signature: (payload: String, secret: String) -> String
|
|
267
|
+
|
|
268
|
+
def self?.verify_signature: (payload: String, signature: String?, secret: String?) -> bool
|
|
269
|
+
|
|
270
|
+
def self?.verify: (
|
|
271
|
+
payload: String,
|
|
272
|
+
signature: String?,
|
|
273
|
+
secret: String?,
|
|
274
|
+
?tolerance: Numeric?,
|
|
275
|
+
?now: Time?
|
|
276
|
+
) -> Hash[untyped, untyped]
|
|
277
|
+
|
|
278
|
+
def self?.parse: (String payload) -> Hash[untyped, untyped]
|
|
279
|
+
|
|
280
|
+
def self?.check_freshness: (
|
|
281
|
+
Hash[untyped, untyped] event,
|
|
282
|
+
tolerance: Numeric,
|
|
283
|
+
now: Time?
|
|
284
|
+
) -> void
|
|
285
|
+
end
|
|
286
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dregs
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dregs
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-09-24 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: |
|
|
14
|
+
The official Ruby client for Dregs, which scores the users of your application for fraud and
|
|
15
|
+
abuse across four categories: humanity, authenticity, uniqueness, and behavior. Send events
|
|
16
|
+
from your backend, read back the scores and the observations behind them.
|
|
17
|
+
email:
|
|
18
|
+
- support@dregs.com
|
|
19
|
+
executables: []
|
|
20
|
+
extensions: []
|
|
21
|
+
extra_rdoc_files: []
|
|
22
|
+
files:
|
|
23
|
+
- CHANGELOG.md
|
|
24
|
+
- LICENSE
|
|
25
|
+
- README.md
|
|
26
|
+
- SECURITY.md
|
|
27
|
+
- lib/dregs.rb
|
|
28
|
+
- lib/dregs/client.rb
|
|
29
|
+
- lib/dregs/errors.rb
|
|
30
|
+
- lib/dregs/identities.rb
|
|
31
|
+
- lib/dregs/models.rb
|
|
32
|
+
- lib/dregs/version.rb
|
|
33
|
+
- lib/dregs/webhooks.rb
|
|
34
|
+
- sig/dregs.rbs
|
|
35
|
+
homepage: https://dregs.com
|
|
36
|
+
licenses:
|
|
37
|
+
- MIT
|
|
38
|
+
metadata:
|
|
39
|
+
homepage_uri: https://dregs.com
|
|
40
|
+
documentation_uri: https://dregs.com/manual/api/
|
|
41
|
+
source_code_uri: https://github.com/dregs-sdk/dregs-sdk-ruby
|
|
42
|
+
bug_tracker_uri: https://github.com/dregs-sdk/dregs-sdk-ruby/issues
|
|
43
|
+
changelog_uri: https://github.com/dregs-sdk/dregs-sdk-ruby/blob/main/CHANGELOG.md
|
|
44
|
+
rubygems_mfa_required: 'true'
|
|
45
|
+
post_install_message:
|
|
46
|
+
rdoc_options: []
|
|
47
|
+
require_paths:
|
|
48
|
+
- lib
|
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 3.1.0
|
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '0'
|
|
59
|
+
requirements: []
|
|
60
|
+
rubygems_version: 3.5.22
|
|
61
|
+
signing_key:
|
|
62
|
+
specification_version: 4
|
|
63
|
+
summary: Ruby SDK for Dregs, the fraud and abuse scoring service.
|
|
64
|
+
test_files: []
|