minfraud 2.4.0 → 2.6.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 +4 -4
- data/CHANGELOG.md +44 -0
- data/README.dev.md +26 -2
- data/README.md +3 -3
- data/lib/minfraud/components/email.rb +279 -6
- data/lib/minfraud/components/payment.rb +1 -0
- data/lib/minfraud/components/report/transaction.rb +40 -8
- data/lib/minfraud/model/address.rb +1 -1
- data/lib/minfraud/model/credit_card.rb +1 -1
- data/lib/minfraud/model/device.rb +1 -1
- data/lib/minfraud/model/disposition.rb +1 -1
- data/lib/minfraud/model/email.rb +1 -1
- data/lib/minfraud/model/email_domain.rb +1 -1
- data/lib/minfraud/model/error.rb +1 -1
- data/lib/minfraud/model/factors.rb +1 -1
- data/lib/minfraud/model/geoip2_location.rb +1 -1
- data/lib/minfraud/model/insights.rb +16 -1
- data/lib/minfraud/model/ip_address.rb +1 -1
- data/lib/minfraud/model/ip_risk_reason.rb +1 -1
- data/lib/minfraud/model/issuer.rb +1 -1
- data/lib/minfraud/model/phone.rb +49 -0
- data/lib/minfraud/model/score_ip_address.rb +1 -1
- data/lib/minfraud/model/shipping_address.rb +1 -1
- data/lib/minfraud/model/subscores.rb +1 -1
- data/lib/minfraud/model/warning.rb +1 -1
- data/lib/minfraud/validates.rb +13 -0
- data/lib/minfraud/version.rb +1 -1
- data/minfraud.gemspec +1 -1
- metadata +4 -9
- data/.github/dependabot.yml +0 -11
- data/.github/workflows/release.yml +0 -28
- data/.github/workflows/rubocop.yml +0 -18
- data/.github/workflows/test.yml +0 -36
- data/.gitignore +0 -9
- data/dev-bin/release.sh +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d7569d3a79d640e8ecd0a2fe83996701e2d378bac780a2e0ee7e40ea0651136
|
4
|
+
data.tar.gz: 799568df38549e698099950480c8f88e8a395df2214cfd47beb830c9f1c42a85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f49ac7777a332043c94e1c73d5cfb34e1caa27477eeebc23ebb31b97929d3012378f40ebd78ca6662982d2ef3fc1f5f6f40862169e381ceb6f710e79c8e5a411
|
7
|
+
data.tar.gz: 40b65dd1c1eba11d44bb0fc82e0df0e67b943ed43b521198d5c4c4bc81fe2aa79077cc6d4ca86cf873e25f0930e0f7f77b49e4ff68b1b49919cc0d5e92da8b05
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,49 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v2.6.0 (2024-07-08)
|
4
|
+
|
5
|
+
* Updated the validation for the Report Transactions API to make the
|
6
|
+
`ip_address` parameter optional. Now the `tag` and at least one of the
|
7
|
+
following parameters must be supplied: `ip_address`, `maxmind_id`,
|
8
|
+
`minfraud_id`, `transaction_id`.
|
9
|
+
* Updated the validation for the Report Transactions API to check that
|
10
|
+
`ip_address`, `maxmind_id`, and `minfraud_id` contain valid values.
|
11
|
+
* Added `billing_phone` and `shipping_phone` attributes to the minFraud
|
12
|
+
Insights and Factors response models. These contain objects with
|
13
|
+
information about the respective phone numbers. Please see [our developer
|
14
|
+
site](https://dev.maxmind.com/minfraud/api-documentation/responses/) for
|
15
|
+
more information.
|
16
|
+
* Added the processor `:payconex` to `Minfraud::Components::Payment`.
|
17
|
+
|
18
|
+
## v2.5.0 (2024-04-16)
|
19
|
+
|
20
|
+
* Equivalent domain names are now normalized when `hash_address` is used.
|
21
|
+
For example, `googlemail.com` will become `gmail.com`.
|
22
|
+
* Periods are now removed from `gmail.com` email address local parts when
|
23
|
+
`hash_address` is used. For example, `f.o.o@gmail.com` will become
|
24
|
+
`foo@gmail.com`.
|
25
|
+
* Fastmail alias subdomain email addresses are now normalized when
|
26
|
+
`hash_address` is used. For example, `alias@user.fastmail.com` will
|
27
|
+
become `user@fastmail.com`.
|
28
|
+
* Additional `yahoo.com` email addresses now have aliases removed from
|
29
|
+
their local part when `hash_address` is used. For example,
|
30
|
+
`foo-bar@yahoo.com` will become `foo@yahoo.com` for additional
|
31
|
+
`yahoo.com` domains.
|
32
|
+
* Duplicate `.com`s are now removed from email domain names when
|
33
|
+
`hash_address` is used. For example, `example.com.com` will become
|
34
|
+
`example.com`.
|
35
|
+
* Certain TLD typos are now normalized when `hash_address` is used. For
|
36
|
+
example, `example.comcom` will become `example.com`.
|
37
|
+
* Additional `gmail.com` domain names with leading digits are now
|
38
|
+
normalized when `hash_address` is used. For example, `100gmail.com` will
|
39
|
+
become `gmail.com`.
|
40
|
+
* Additional `gmail.com` typos are now normalized when `hash_address` is
|
41
|
+
used. For example, `gmali.com` will become `gmail.com`.
|
42
|
+
* When `hash_address` is used, all trailing periods are now removed from an
|
43
|
+
email address domain. Previously only a single period was removed.
|
44
|
+
* When `hash_address` is used, the local part of an email address is now
|
45
|
+
normalized to NFC.
|
46
|
+
|
3
47
|
## v2.4.0 (2024-01-12)
|
4
48
|
|
5
49
|
* Ruby 2.7+ is now required. If you're using Ruby 2.5 or 2.6, please use
|
data/README.dev.md
CHANGED
@@ -1,4 +1,28 @@
|
|
1
|
+
# Prereqs
|
2
|
+
|
3
|
+
* You must have a local Ruby environment that can run the tests
|
4
|
+
via `rake`.
|
5
|
+
* You must have the [GitHub CLI tool (gh)](https://cli.github.com/)
|
6
|
+
installed, in your path, and logged into an account that can
|
7
|
+
make GitHub releases on the repo.
|
8
|
+
* Your environment also must have `bash`, `git`, `perl`, and `sed`
|
9
|
+
available.
|
10
|
+
|
1
11
|
# How to release
|
2
12
|
|
3
|
-
|
4
|
-
|
13
|
+
* Review open issues and PRs to see if anything needs to be addressed
|
14
|
+
before release.
|
15
|
+
* Create a branch e.g. `horgh/release` and switch to it.
|
16
|
+
* `main` is protected.
|
17
|
+
* Set the release version and release date in `CHANGELOG.md`. Be sure
|
18
|
+
the version follows [Semantic Versioning](https://semver.org/).
|
19
|
+
* Commit these changes.
|
20
|
+
* Run `dev-bin/release.sh`.
|
21
|
+
* Verify the release on the GitHub Releases page.
|
22
|
+
* If everything goes well, the authorized releasers will receive an email
|
23
|
+
to review the pending deployment. If you are an authorized releaser,
|
24
|
+
you will need to approve the release deployment run. If you are not,
|
25
|
+
you will have to wait for an authorized releaser to do so.
|
26
|
+
* Double check it looks okay at https://rubygems.org/gems/minfraud and
|
27
|
+
https://www.rubydoc.info/gems/minfraud.
|
28
|
+
* Make a PR and get it merged.
|
data/README.md
CHANGED
@@ -208,9 +208,9 @@ channel is used to improve the accuracy of their fraud detection
|
|
208
208
|
algorithms.
|
209
209
|
|
210
210
|
To use the Report Transaction API, create a
|
211
|
-
`Minfraud::Components::Report::Transaction` object.
|
212
|
-
|
213
|
-
set, as shown below.
|
211
|
+
`Minfraud::Components::Report::Transaction` object. A valid tag and at least
|
212
|
+
one of the following are required parameters: ip_address, maxmind_id,
|
213
|
+
minfraud_id, transaction_id. Additional parameters may be set, as shown below.
|
214
214
|
|
215
215
|
If the report is successful, nothing is returned. If the report fails, an
|
216
216
|
exception will be thrown.
|
@@ -88,43 +88,316 @@ module Minfraud
|
|
88
88
|
local_part, domain = address.split('@', 2)
|
89
89
|
return nil if !local_part || !domain
|
90
90
|
|
91
|
+
local_part = local_part.unicode_normalize(:nfc)
|
92
|
+
|
91
93
|
domain = clean_domain(domain)
|
92
94
|
|
93
|
-
if domain
|
95
|
+
if YAHOO_DOMAINS.key?(domain)
|
94
96
|
local_part.sub!(/\A([^-]+)-.*\z/, '\1')
|
95
97
|
else
|
96
98
|
local_part.sub!(/\A([^+]+)\+.*\z/, '\1')
|
97
99
|
end
|
98
100
|
|
101
|
+
if domain == 'gmail.com'
|
102
|
+
local_part.gsub!('.', '')
|
103
|
+
end
|
104
|
+
|
105
|
+
domain_parts = domain.split('.')
|
106
|
+
if domain_parts.length > 2
|
107
|
+
possible_domain = domain_parts[1..].join('.')
|
108
|
+
if FASTMAIL_DOMAINS.key?(possible_domain)
|
109
|
+
domain = possible_domain
|
110
|
+
if local_part != ''
|
111
|
+
local_part = domain_parts[0]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
99
116
|
"#{local_part}@#{domain}"
|
100
117
|
end
|
101
118
|
|
102
119
|
TYPO_DOMAINS = {
|
103
120
|
# gmail.com
|
104
|
-
'
|
105
|
-
'636gmail.com' => 'gmail.com',
|
121
|
+
'gmai.com' => 'gmail.com',
|
106
122
|
'gamil.com' => 'gmail.com',
|
107
|
-
'
|
123
|
+
'gmali.com' => 'gmail.com',
|
108
124
|
'gmial.com' => 'gmail.com',
|
109
125
|
'gmil.com' => 'gmail.com',
|
126
|
+
'gmaill.com' => 'gmail.com',
|
127
|
+
'gmailm.com' => 'gmail.com',
|
128
|
+
'gmailo.com' => 'gmail.com',
|
129
|
+
'gmailyhoo.com' => 'gmail.com',
|
110
130
|
'yahoogmail.com' => 'gmail.com',
|
111
131
|
# outlook.com
|
112
132
|
'putlook.com' => 'outlook.com',
|
113
133
|
}.freeze
|
114
134
|
private_constant :TYPO_DOMAINS
|
115
135
|
|
136
|
+
TYPO_TLDS = {
|
137
|
+
'comm' => 'com',
|
138
|
+
'commm' => 'com',
|
139
|
+
'commmm' => 'com',
|
140
|
+
'comn' => 'com',
|
141
|
+
|
142
|
+
'cbm' => 'com',
|
143
|
+
'ccm' => 'com',
|
144
|
+
'cdm' => 'com',
|
145
|
+
'cem' => 'com',
|
146
|
+
'cfm' => 'com',
|
147
|
+
'cgm' => 'com',
|
148
|
+
'chm' => 'com',
|
149
|
+
'cim' => 'com',
|
150
|
+
'cjm' => 'com',
|
151
|
+
'ckm' => 'com',
|
152
|
+
'clm' => 'com',
|
153
|
+
'cmm' => 'com',
|
154
|
+
'cnm' => 'com',
|
155
|
+
'cpm' => 'com',
|
156
|
+
'cqm' => 'com',
|
157
|
+
'crm' => 'com',
|
158
|
+
'csm' => 'com',
|
159
|
+
'ctm' => 'com',
|
160
|
+
'cum' => 'com',
|
161
|
+
'cvm' => 'com',
|
162
|
+
'cwm' => 'com',
|
163
|
+
'cxm' => 'com',
|
164
|
+
'cym' => 'com',
|
165
|
+
'czm' => 'com',
|
166
|
+
|
167
|
+
'col' => 'com',
|
168
|
+
'con' => 'com',
|
169
|
+
|
170
|
+
'dom' => 'com',
|
171
|
+
'don' => 'com',
|
172
|
+
'som' => 'com',
|
173
|
+
'son' => 'com',
|
174
|
+
'vom' => 'com',
|
175
|
+
'von' => 'com',
|
176
|
+
'xom' => 'com',
|
177
|
+
'xon' => 'com',
|
178
|
+
|
179
|
+
'clam' => 'com',
|
180
|
+
'colm' => 'com',
|
181
|
+
'comcom' => 'com',
|
182
|
+
}.freeze
|
183
|
+
private_constant :TYPO_TLDS
|
184
|
+
|
185
|
+
EQUIVALENT_DOMAINS = {
|
186
|
+
'googlemail.com' => 'gmail.com',
|
187
|
+
'pm.me' => 'protonmail.com',
|
188
|
+
'proton.me' => 'protonmail.com',
|
189
|
+
'yandex.by' => 'yandex.ru',
|
190
|
+
'yandex.com' => 'yandex.ru',
|
191
|
+
'yandex.kz' => 'yandex.ru',
|
192
|
+
'yandex.ua' => 'yandex.ru',
|
193
|
+
'ya.ru' => 'yandex.ru',
|
194
|
+
}.freeze
|
195
|
+
private_constant :EQUIVALENT_DOMAINS
|
196
|
+
|
197
|
+
FASTMAIL_DOMAINS = {
|
198
|
+
'123mail.org' => true,
|
199
|
+
'150mail.com' => true,
|
200
|
+
'150ml.com' => true,
|
201
|
+
'16mail.com' => true,
|
202
|
+
'2-mail.com' => true,
|
203
|
+
'4email.net' => true,
|
204
|
+
'50mail.com' => true,
|
205
|
+
'airpost.net' => true,
|
206
|
+
'allmail.net' => true,
|
207
|
+
'bestmail.us' => true,
|
208
|
+
'cluemail.com' => true,
|
209
|
+
'elitemail.org' => true,
|
210
|
+
'emailcorner.net' => true,
|
211
|
+
'emailengine.net' => true,
|
212
|
+
'emailengine.org' => true,
|
213
|
+
'emailgroups.net' => true,
|
214
|
+
'emailplus.org' => true,
|
215
|
+
'emailuser.net' => true,
|
216
|
+
'eml.cc' => true,
|
217
|
+
'f-m.fm' => true,
|
218
|
+
'fast-email.com' => true,
|
219
|
+
'fast-mail.org' => true,
|
220
|
+
'fastem.com' => true,
|
221
|
+
'fastemail.us' => true,
|
222
|
+
'fastemailer.com' => true,
|
223
|
+
'fastest.cc' => true,
|
224
|
+
'fastimap.com' => true,
|
225
|
+
'fastmail.cn' => true,
|
226
|
+
'fastmail.co.uk' => true,
|
227
|
+
'fastmail.com' => true,
|
228
|
+
'fastmail.com.au' => true,
|
229
|
+
'fastmail.de' => true,
|
230
|
+
'fastmail.es' => true,
|
231
|
+
'fastmail.fm' => true,
|
232
|
+
'fastmail.fr' => true,
|
233
|
+
'fastmail.im' => true,
|
234
|
+
'fastmail.in' => true,
|
235
|
+
'fastmail.jp' => true,
|
236
|
+
'fastmail.mx' => true,
|
237
|
+
'fastmail.net' => true,
|
238
|
+
'fastmail.nl' => true,
|
239
|
+
'fastmail.org' => true,
|
240
|
+
'fastmail.se' => true,
|
241
|
+
'fastmail.to' => true,
|
242
|
+
'fastmail.tw' => true,
|
243
|
+
'fastmail.uk' => true,
|
244
|
+
'fastmail.us' => true,
|
245
|
+
'fastmailbox.net' => true,
|
246
|
+
'fastmessaging.com' => true,
|
247
|
+
'fea.st' => true,
|
248
|
+
'fmail.co.uk' => true,
|
249
|
+
'fmailbox.com' => true,
|
250
|
+
'fmgirl.com' => true,
|
251
|
+
'fmguy.com' => true,
|
252
|
+
'ftml.net' => true,
|
253
|
+
'h-mail.us' => true,
|
254
|
+
'hailmail.net' => true,
|
255
|
+
'imap-mail.com' => true,
|
256
|
+
'imap.cc' => true,
|
257
|
+
'imapmail.org' => true,
|
258
|
+
'inoutbox.com' => true,
|
259
|
+
'internet-e-mail.com' => true,
|
260
|
+
'internet-mail.org' => true,
|
261
|
+
'internetemails.net' => true,
|
262
|
+
'internetmailing.net' => true,
|
263
|
+
'jetemail.net' => true,
|
264
|
+
'justemail.net' => true,
|
265
|
+
'letterboxes.org' => true,
|
266
|
+
'mail-central.com' => true,
|
267
|
+
'mail-page.com' => true,
|
268
|
+
'mailandftp.com' => true,
|
269
|
+
'mailas.com' => true,
|
270
|
+
'mailbolt.com' => true,
|
271
|
+
'mailc.net' => true,
|
272
|
+
'mailcan.com' => true,
|
273
|
+
'mailforce.net' => true,
|
274
|
+
'mailftp.com' => true,
|
275
|
+
'mailhaven.com' => true,
|
276
|
+
'mailingaddress.org' => true,
|
277
|
+
'mailite.com' => true,
|
278
|
+
'mailmight.com' => true,
|
279
|
+
'mailnew.com' => true,
|
280
|
+
'mailsent.net' => true,
|
281
|
+
'mailservice.ms' => true,
|
282
|
+
'mailup.net' => true,
|
283
|
+
'mailworks.org' => true,
|
284
|
+
'ml1.net' => true,
|
285
|
+
'mm.st' => true,
|
286
|
+
'myfastmail.com' => true,
|
287
|
+
'mymacmail.com' => true,
|
288
|
+
'nospammail.net' => true,
|
289
|
+
'ownmail.net' => true,
|
290
|
+
'petml.com' => true,
|
291
|
+
'postinbox.com' => true,
|
292
|
+
'postpro.net' => true,
|
293
|
+
'proinbox.com' => true,
|
294
|
+
'promessage.com' => true,
|
295
|
+
'realemail.net' => true,
|
296
|
+
'reallyfast.biz' => true,
|
297
|
+
'reallyfast.info' => true,
|
298
|
+
'rushpost.com' => true,
|
299
|
+
'sent.as' => true,
|
300
|
+
'sent.at' => true,
|
301
|
+
'sent.com' => true,
|
302
|
+
'speedpost.net' => true,
|
303
|
+
'speedymail.org' => true,
|
304
|
+
'ssl-mail.com' => true,
|
305
|
+
'swift-mail.com' => true,
|
306
|
+
'the-fastest.net' => true,
|
307
|
+
'the-quickest.com' => true,
|
308
|
+
'theinternetemail.com' => true,
|
309
|
+
'veryfast.biz' => true,
|
310
|
+
'veryspeedy.net' => true,
|
311
|
+
'warpmail.net' => true,
|
312
|
+
'xsmail.com' => true,
|
313
|
+
'yepmail.net' => true,
|
314
|
+
'your-mail.com' => true,
|
315
|
+
}.freeze
|
316
|
+
private_constant :FASTMAIL_DOMAINS
|
317
|
+
|
318
|
+
YAHOO_DOMAINS = {
|
319
|
+
'y7mail.com' => true,
|
320
|
+
'yahoo.at' => true,
|
321
|
+
'yahoo.be' => true,
|
322
|
+
'yahoo.bg' => true,
|
323
|
+
'yahoo.ca' => true,
|
324
|
+
'yahoo.cl' => true,
|
325
|
+
'yahoo.co.id' => true,
|
326
|
+
'yahoo.co.il' => true,
|
327
|
+
'yahoo.co.in' => true,
|
328
|
+
'yahoo.co.kr' => true,
|
329
|
+
'yahoo.co.nz' => true,
|
330
|
+
'yahoo.co.th' => true,
|
331
|
+
'yahoo.co.uk' => true,
|
332
|
+
'yahoo.co.za' => true,
|
333
|
+
'yahoo.com' => true,
|
334
|
+
'yahoo.com.ar' => true,
|
335
|
+
'yahoo.com.au' => true,
|
336
|
+
'yahoo.com.br' => true,
|
337
|
+
'yahoo.com.co' => true,
|
338
|
+
'yahoo.com.hk' => true,
|
339
|
+
'yahoo.com.hr' => true,
|
340
|
+
'yahoo.com.mx' => true,
|
341
|
+
'yahoo.com.my' => true,
|
342
|
+
'yahoo.com.pe' => true,
|
343
|
+
'yahoo.com.ph' => true,
|
344
|
+
'yahoo.com.sg' => true,
|
345
|
+
'yahoo.com.tr' => true,
|
346
|
+
'yahoo.com.tw' => true,
|
347
|
+
'yahoo.com.ua' => true,
|
348
|
+
'yahoo.com.ve' => true,
|
349
|
+
'yahoo.com.vn' => true,
|
350
|
+
'yahoo.cz' => true,
|
351
|
+
'yahoo.de' => true,
|
352
|
+
'yahoo.dk' => true,
|
353
|
+
'yahoo.ee' => true,
|
354
|
+
'yahoo.es' => true,
|
355
|
+
'yahoo.fi' => true,
|
356
|
+
'yahoo.fr' => true,
|
357
|
+
'yahoo.gr' => true,
|
358
|
+
'yahoo.hu' => true,
|
359
|
+
'yahoo.ie' => true,
|
360
|
+
'yahoo.in' => true,
|
361
|
+
'yahoo.it' => true,
|
362
|
+
'yahoo.lt' => true,
|
363
|
+
'yahoo.lv' => true,
|
364
|
+
'yahoo.nl' => true,
|
365
|
+
'yahoo.no' => true,
|
366
|
+
'yahoo.pl' => true,
|
367
|
+
'yahoo.pt' => true,
|
368
|
+
'yahoo.ro' => true,
|
369
|
+
'yahoo.se' => true,
|
370
|
+
'yahoo.sk' => true,
|
371
|
+
'ymail.com' => true,
|
372
|
+
}.freeze
|
373
|
+
private_constant :YAHOO_DOMAINS
|
374
|
+
|
116
375
|
def clean_domain(domain)
|
117
376
|
domain = domain.strip
|
118
377
|
|
119
|
-
|
120
|
-
domain.sub!(/\.\z/, '')
|
378
|
+
domain.sub!(/\.+\z/, '')
|
121
379
|
|
122
380
|
domain = SimpleIDN.to_ascii(domain)
|
123
381
|
|
382
|
+
domain.sub!(/(?:\.com){2,}$/, '.com')
|
383
|
+
domain.sub!(/^\d+(?:gmail?\.com)$/, 'gmail.com')
|
384
|
+
|
385
|
+
idx = domain.rindex('.')
|
386
|
+
if !idx.nil?
|
387
|
+
tld = domain[idx + 1..]
|
388
|
+
if TYPO_TLDS.key?(tld)
|
389
|
+
domain = "#{domain[0, idx]}.#{TYPO_TLDS[tld]}"
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
124
393
|
if TYPO_DOMAINS.key?(domain)
|
125
394
|
domain = TYPO_DOMAINS[domain]
|
126
395
|
end
|
127
396
|
|
397
|
+
if EQUIVALENT_DOMAINS.key?(domain)
|
398
|
+
domain = EQUIVALENT_DOMAINS[domain]
|
399
|
+
end
|
400
|
+
|
128
401
|
domain
|
129
402
|
end
|
130
403
|
end
|
@@ -8,9 +8,13 @@ module Minfraud
|
|
8
8
|
# @see https://dev.maxmind.com/minfraud/report-a-transaction?lang=en
|
9
9
|
class Transaction < Base
|
10
10
|
include ::Minfraud::Enum
|
11
|
+
include ::Minfraud::Validates
|
11
12
|
|
12
13
|
# The IP address of the customer placing the order. This should be
|
13
|
-
# passed as a string like "152.216.7.110".
|
14
|
+
# passed as a string like "152.216.7.110". This field is not required
|
15
|
+
# if you provide at least one of the transaction's minfraud_id,
|
16
|
+
# maxmind_id, or transaction_id. You are encouraged to provide it, if
|
17
|
+
# possible.
|
14
18
|
#
|
15
19
|
# @return [String, nil]
|
16
20
|
attr_accessor :ip_address
|
@@ -34,16 +38,19 @@ module Minfraud
|
|
34
38
|
|
35
39
|
# A unique eight character string identifying a minFraud Standard or
|
36
40
|
# Premium request. These IDs are returned in the maxmindID field of a
|
37
|
-
# response for a successful minFraud request. This field is not
|
38
|
-
#
|
41
|
+
# response for a successful minFraud request. This field is not required
|
42
|
+
# if you provide at least one of the transaction's ip_address,
|
43
|
+
# minfraud_id, or transaction_id. You are encouraged to provide it, if
|
44
|
+
# possible.
|
39
45
|
#
|
40
46
|
# @return [String, nil]
|
41
47
|
attr_accessor :maxmind_id
|
42
48
|
|
43
49
|
# A UUID that identifies a minFraud Score, minFraud Insights, or
|
44
50
|
# minFraud Factors request. This ID is returned at /id in the response.
|
45
|
-
# This field is not required
|
46
|
-
#
|
51
|
+
# This field is not required if you provide at least one of the
|
52
|
+
# transaction's ip_address, maxmind_id, or transaction_id. You are
|
53
|
+
# encouraged to provide it, if possible.
|
47
54
|
#
|
48
55
|
# @return [String, nil]
|
49
56
|
attr_accessor :minfraud_id
|
@@ -56,9 +63,10 @@ module Minfraud
|
|
56
63
|
# @return [String, nil]
|
57
64
|
attr_accessor :notes
|
58
65
|
|
59
|
-
# The transaction ID you originally passed to minFraud. This field
|
60
|
-
# not required
|
61
|
-
#
|
66
|
+
# The transaction ID you originally passed to minFraud. This field
|
67
|
+
# is not required if you provide at least one of the transaction's
|
68
|
+
# ip_address, maxmind_id, or minfraud_id. You are encouraged to
|
69
|
+
# provide it, if possible.
|
62
70
|
#
|
63
71
|
# @return [String, nil]
|
64
72
|
attr_accessor :transaction_id
|
@@ -73,6 +81,30 @@ module Minfraud
|
|
73
81
|
@notes = params[:notes]
|
74
82
|
@transaction_id = params[:transaction_id]
|
75
83
|
self.tag = params[:tag]
|
84
|
+
|
85
|
+
validate
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def validate
|
91
|
+
return if !Minfraud.enable_validation
|
92
|
+
|
93
|
+
validate_ip('ip_address', @ip_address)
|
94
|
+
validate_string('maxmind_id', 8, @maxmind_id)
|
95
|
+
validate_uuid('minfraud_id', @minfraud_id)
|
96
|
+
|
97
|
+
if ip_address.nil? &&
|
98
|
+
(minfraud_id.nil? || empty_uuid(minfraud_id)) &&
|
99
|
+
(maxmind_id.nil? || maxmind_id.empty?) &&
|
100
|
+
(transaction_id.nil? || transaction_id.empty?)
|
101
|
+
raise ArgumentError, 'At least one of the following is required: ip_address, minfraud_id, maxmind_id, transaction_id.'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def empty_uuid(value)
|
106
|
+
stripped_value = value.to_s.gsub('-', '')
|
107
|
+
stripped_value == '0' * 32
|
76
108
|
end
|
77
109
|
end
|
78
110
|
end
|
data/lib/minfraud/model/email.rb
CHANGED
data/lib/minfraud/model/error.rb
CHANGED
@@ -5,6 +5,7 @@ require 'minfraud/model/credit_card'
|
|
5
5
|
require 'minfraud/model/device'
|
6
6
|
require 'minfraud/model/email'
|
7
7
|
require 'minfraud/model/ip_address'
|
8
|
+
require 'minfraud/model/phone'
|
8
9
|
require 'minfraud/model/score'
|
9
10
|
require 'minfraud/model/shipping_address'
|
10
11
|
|
@@ -18,6 +19,12 @@ module Minfraud
|
|
18
19
|
# @return [Minfraud::Model::BillingAddress]
|
19
20
|
attr_reader :billing_address
|
20
21
|
|
22
|
+
# An object containing minFraud data related to the billing phone
|
23
|
+
# number used in the transaction.
|
24
|
+
#
|
25
|
+
# @return [Minfraud::Model::Phone]
|
26
|
+
attr_reader :billing_phone
|
27
|
+
|
21
28
|
# An object containing minFraud data about the credit card used in the
|
22
29
|
# transaction.
|
23
30
|
#
|
@@ -48,13 +55,20 @@ module Minfraud
|
|
48
55
|
# @return [Minfraud::Model::ShippingAddress]
|
49
56
|
attr_reader :shipping_address
|
50
57
|
|
58
|
+
# An object containing minFraud data related to the shipping phone
|
59
|
+
# number used in the transaction.
|
60
|
+
#
|
61
|
+
# @return [Minfraud::Model::Phone]
|
62
|
+
attr_reader :shipping_phone
|
63
|
+
|
51
64
|
# @!visibility private
|
52
65
|
def initialize(record, locales)
|
53
|
-
super
|
66
|
+
super
|
54
67
|
|
55
68
|
@billing_address = Minfraud::Model::BillingAddress.new(
|
56
69
|
get('billing_address')
|
57
70
|
)
|
71
|
+
@billing_phone = Minfraud::Model::Phone.new(get('billing_phone'))
|
58
72
|
@credit_card = Minfraud::Model::CreditCard.new(get('credit_card'))
|
59
73
|
@device = Minfraud::Model::Device.new(get('device'))
|
60
74
|
@email = Minfraud::Model::Email.new(get('email'))
|
@@ -62,6 +76,7 @@ module Minfraud
|
|
62
76
|
@shipping_address = Minfraud::Model::ShippingAddress.new(
|
63
77
|
get('shipping_address')
|
64
78
|
)
|
79
|
+
@shipping_phone = Minfraud::Model::Phone.new(get('shipping_phone'))
|
65
80
|
end
|
66
81
|
end
|
67
82
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minfraud/model/abstract'
|
4
|
+
|
5
|
+
module Minfraud
|
6
|
+
module Model
|
7
|
+
# Model with information about the billing or shipping phone number.
|
8
|
+
class Phone < Abstract
|
9
|
+
# The two-character ISO 3166-1 country code for the country associated
|
10
|
+
# with the phone number.
|
11
|
+
#
|
12
|
+
# @return [String, nil]
|
13
|
+
attr_reader :country
|
14
|
+
|
15
|
+
# This is true if the phone number is a Voice over Internet Protocol
|
16
|
+
# (VoIP) number allocated by a regulator. It is false if the phone
|
17
|
+
# number is not a VoIP number allocated by a regulator. The attribute
|
18
|
+
# is nil when a valid phone number has not been provided or we do not
|
19
|
+
# have data for the phone number.
|
20
|
+
#
|
21
|
+
# @return [Boolean, nil]
|
22
|
+
attr_reader :is_voip
|
23
|
+
|
24
|
+
# The name of the original network operator associated with the phone
|
25
|
+
# number. This attribute does not reflect phone numbers that have been
|
26
|
+
# ported from the original operator to another, nor does it identify
|
27
|
+
# mobile virtual network operators.
|
28
|
+
#
|
29
|
+
# @return [String, nil]
|
30
|
+
attr_reader :network_operator
|
31
|
+
|
32
|
+
# One of the following values: fixed or mobile. Additional values may
|
33
|
+
# be added in the future.
|
34
|
+
#
|
35
|
+
# @return [String, nil]
|
36
|
+
attr_reader :number_type
|
37
|
+
|
38
|
+
# @!visibility private
|
39
|
+
def initialize(record)
|
40
|
+
super
|
41
|
+
|
42
|
+
@country = get('country')
|
43
|
+
@is_voip = get('is_voip')
|
44
|
+
@network_operator = get('network_operator')
|
45
|
+
@number_type = get('number_type')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/minfraud/validates.rb
CHANGED
@@ -24,6 +24,19 @@ module Minfraud
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def validate_uuid(field, value)
|
28
|
+
return if !value
|
29
|
+
|
30
|
+
stripped_value = value.to_s.gsub('-', '')
|
31
|
+
|
32
|
+
# Define a regex pattern for a valid UUID without dashes
|
33
|
+
uuid_regex = /\A[0-9a-f]{32}\z/i
|
34
|
+
|
35
|
+
unless uuid_regex.match(stripped_value)
|
36
|
+
raise InvalidInputError, "The #{field} value is not valid. It must be a UUID string."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
27
40
|
def validate_subdivision_code(field, value)
|
28
41
|
return if !value
|
29
42
|
|
data/lib/minfraud/version.rb
CHANGED
data/minfraud.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
|
18
18
|
spec.required_ruby_version = '>= 2.7.0'
|
19
19
|
|
20
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^.gitignore$|^(?:\.github|dev-bin|spec)/}) }
|
21
21
|
spec.bindir = 'exe'
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ['lib']
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minfraud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kushnir.yb
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-07-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: connection_pool
|
@@ -156,11 +156,6 @@ executables: []
|
|
156
156
|
extensions: []
|
157
157
|
extra_rdoc_files: []
|
158
158
|
files:
|
159
|
-
- ".github/dependabot.yml"
|
160
|
-
- ".github/workflows/release.yml"
|
161
|
-
- ".github/workflows/rubocop.yml"
|
162
|
-
- ".github/workflows/test.yml"
|
163
|
-
- ".gitignore"
|
164
159
|
- ".rspec"
|
165
160
|
- ".rubocop.yml"
|
166
161
|
- CHANGELOG.md
|
@@ -172,7 +167,6 @@ files:
|
|
172
167
|
- Rakefile
|
173
168
|
- bin/console
|
174
169
|
- bin/setup
|
175
|
-
- dev-bin/release.sh
|
176
170
|
- lib/minfraud.rb
|
177
171
|
- lib/minfraud/assessments.rb
|
178
172
|
- lib/minfraud/components/account.rb
|
@@ -209,6 +203,7 @@ files:
|
|
209
203
|
- lib/minfraud/model/ip_address.rb
|
210
204
|
- lib/minfraud/model/ip_risk_reason.rb
|
211
205
|
- lib/minfraud/model/issuer.rb
|
206
|
+
- lib/minfraud/model/phone.rb
|
212
207
|
- lib/minfraud/model/score.rb
|
213
208
|
- lib/minfraud/model/score_ip_address.rb
|
214
209
|
- lib/minfraud/model/shipping_address.rb
|
@@ -239,7 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
239
234
|
- !ruby/object:Gem::Version
|
240
235
|
version: '0'
|
241
236
|
requirements: []
|
242
|
-
rubygems_version: 3.5.
|
237
|
+
rubygems_version: 3.5.11
|
243
238
|
signing_key:
|
244
239
|
specification_version: 4
|
245
240
|
summary: Ruby API for the minFraud Score, Insights, Factors, and Report Transactions
|
data/.github/dependabot.yml
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
name: Release
|
2
|
-
|
3
|
-
on:
|
4
|
-
workflow_dispatch:
|
5
|
-
pull_request:
|
6
|
-
push:
|
7
|
-
branches:
|
8
|
-
- main
|
9
|
-
release:
|
10
|
-
types:
|
11
|
-
- published
|
12
|
-
|
13
|
-
jobs:
|
14
|
-
push:
|
15
|
-
if: github.event_name == 'release' && github.event.action == 'published'
|
16
|
-
runs-on: ubuntu-latest
|
17
|
-
environment: release
|
18
|
-
permissions:
|
19
|
-
id-token: write
|
20
|
-
steps:
|
21
|
-
- uses: actions/checkout@v4
|
22
|
-
- name: Set up Ruby
|
23
|
-
uses: ruby/setup-ruby@v1
|
24
|
-
with:
|
25
|
-
bundler-cache: true
|
26
|
-
ruby-version: ruby
|
27
|
-
|
28
|
-
- uses: rubygems/release-gem@v1
|
@@ -1,18 +0,0 @@
|
|
1
|
-
name: Run rubocop
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
pull_request:
|
6
|
-
schedule:
|
7
|
-
- cron: '4 0 * * SUN'
|
8
|
-
|
9
|
-
jobs:
|
10
|
-
rubocop:
|
11
|
-
runs-on: ubuntu-latest
|
12
|
-
steps:
|
13
|
-
- uses: actions/checkout@v4
|
14
|
-
- uses: ruby/setup-ruby@v1
|
15
|
-
with:
|
16
|
-
ruby-version: 3.3
|
17
|
-
- run: bundle install
|
18
|
-
- run: bundle exec rake -t rubocop
|
data/.github/workflows/test.yml
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
name: Run tests
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
pull_request:
|
6
|
-
schedule:
|
7
|
-
- cron: '4 1 * * SUN'
|
8
|
-
|
9
|
-
jobs:
|
10
|
-
test:
|
11
|
-
runs-on: ${{ matrix.os }}
|
12
|
-
strategy:
|
13
|
-
fail-fast: false
|
14
|
-
matrix:
|
15
|
-
os: [ubuntu-latest, windows-latest, macos-latest]
|
16
|
-
version:
|
17
|
-
[
|
18
|
-
2.7,
|
19
|
-
'3.0',
|
20
|
-
3.1,
|
21
|
-
3.2,
|
22
|
-
3.3,
|
23
|
-
jruby,
|
24
|
-
]
|
25
|
-
exclude:
|
26
|
-
- os: windows-latest
|
27
|
-
version: jruby
|
28
|
-
steps:
|
29
|
-
- uses: actions/checkout@v4
|
30
|
-
with:
|
31
|
-
submodules: true
|
32
|
-
- uses: ruby/setup-ruby@v1
|
33
|
-
with:
|
34
|
-
ruby-version: ${{ matrix.version }}
|
35
|
-
- run: bundle install
|
36
|
-
- run: bundle exec rake -t spec
|
data/.gitignore
DELETED
data/dev-bin/release.sh
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -eu -o pipefail
|
4
|
-
|
5
|
-
changelog=$(cat CHANGELOG.md)
|
6
|
-
|
7
|
-
regex='
|
8
|
-
## v([0-9]+\.[0-9]+\.[0-9]+) \(([0-9]{4}-[0-9]{2}-[0-9]{2})\)
|
9
|
-
|
10
|
-
((.|
|
11
|
-
)*)
|
12
|
-
'
|
13
|
-
|
14
|
-
if [[ ! $changelog =~ $regex ]]; then
|
15
|
-
echo "Could not find date line in change log!"
|
16
|
-
exit 1
|
17
|
-
fi
|
18
|
-
|
19
|
-
version="${BASH_REMATCH[1]}"
|
20
|
-
date="${BASH_REMATCH[2]}"
|
21
|
-
notes="$(echo "${BASH_REMATCH[3]}" | sed -n -E '/^## v[0-9]+\.[0-9]+\.[0-9]+/,$!p')"
|
22
|
-
|
23
|
-
echo "$notes"
|
24
|
-
if [[ "$date" != "$(date +"%Y-%m-%d")" ]]; then
|
25
|
-
echo "$date is not today!"
|
26
|
-
exit 1
|
27
|
-
fi
|
28
|
-
|
29
|
-
tag="v$version"
|
30
|
-
|
31
|
-
if [ -n "$(git status --porcelain)" ]; then
|
32
|
-
echo ". is not clean." >&2
|
33
|
-
exit 1
|
34
|
-
fi
|
35
|
-
|
36
|
-
perl -pi -e "s/(?<=VERSION = \').+?(?=\')/$version/g" lib/minfraud/version.rb
|
37
|
-
|
38
|
-
echo $"Test results:"
|
39
|
-
|
40
|
-
rake
|
41
|
-
|
42
|
-
echo $'\nDiff:'
|
43
|
-
git diff
|
44
|
-
|
45
|
-
echo $'\nRelease notes:'
|
46
|
-
echo "$notes"
|
47
|
-
|
48
|
-
read -e -p "Commit changes and push to origin? " should_push
|
49
|
-
|
50
|
-
if [ "$should_push" != "y" ]; then
|
51
|
-
echo "Aborting"
|
52
|
-
exit 1
|
53
|
-
fi
|
54
|
-
|
55
|
-
git commit -m "Update for $tag" -a
|
56
|
-
|
57
|
-
git push
|
58
|
-
|
59
|
-
gh release create --target "$(git branch --show-current)" -t "$version" -n "$notes" "$tag"
|