is-antibot 1.6.0 → 1.6.2
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.
- package/package.json +1 -1
- package/src/index.js +16 -15
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "is-antibot",
|
|
3
3
|
"description": "Identify if a response is an antibot challenge from CloudFlare, Akamai, DataDome, Vercel, PerimeterX, Shape Security, and more, including CAPTCHA providers like reCAPTCHA and hCaptcha.",
|
|
4
4
|
"homepage": "https://github.com/microlinkhq/is-antibot",
|
|
5
|
-
"version": "1.6.
|
|
5
|
+
"version": "1.6.2",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./src/index.js"
|
|
8
8
|
},
|
package/src/index.js
CHANGED
|
@@ -20,7 +20,7 @@ const createGetHeader = headers =>
|
|
|
20
20
|
const createTestPattern = value => {
|
|
21
21
|
if (!value) return () => false
|
|
22
22
|
const lowerValue = value.toLowerCase()
|
|
23
|
-
return
|
|
23
|
+
return pattern => {
|
|
24
24
|
if (pattern instanceof RegExp) {
|
|
25
25
|
try {
|
|
26
26
|
return pattern.test(value)
|
|
@@ -28,14 +28,6 @@ const createTestPattern = value => {
|
|
|
28
28
|
return false
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
if (isRegex) {
|
|
33
|
-
try {
|
|
34
|
-
return new RegExp(pattern, 'i').test(value)
|
|
35
|
-
} catch {
|
|
36
|
-
return false
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
31
|
return lowerValue.includes(pattern.toLowerCase())
|
|
40
32
|
}
|
|
41
33
|
}
|
|
@@ -393,12 +385,13 @@ const detect = ({ headers = {}, html = '', url = '', statusCode } = {}) => {
|
|
|
393
385
|
}
|
|
394
386
|
|
|
395
387
|
// Reddit: blocked requests are served as HTML challenge pages.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
388
|
+
if (parseUrl(url).domain === 'reddit.com') {
|
|
389
|
+
if (statusCode === 403) {
|
|
390
|
+
return byStatusCode('reddit')
|
|
391
|
+
}
|
|
392
|
+
if (hasAnyHtml([/blocked by network security\./i])) {
|
|
393
|
+
return byHtml('reddit')
|
|
394
|
+
}
|
|
402
395
|
}
|
|
403
396
|
|
|
404
397
|
// LinkedIn: status 999 is LinkedIn's dedicated bot-detection response
|
|
@@ -406,6 +399,14 @@ const detect = ({ headers = {}, html = '', url = '', statusCode } = {}) => {
|
|
|
406
399
|
return byStatusCode('linkedin')
|
|
407
400
|
}
|
|
408
401
|
|
|
402
|
+
// Instagram: login page redirect indicates bot detection
|
|
403
|
+
if (
|
|
404
|
+
parseUrl(url).domain === 'instagram.com' &&
|
|
405
|
+
hasAnyHtml([/<title>\s*Login\s*[•·]\s*Instagram\s*<\/title>/i])
|
|
406
|
+
) {
|
|
407
|
+
return byHtml('instagram')
|
|
408
|
+
}
|
|
409
|
+
|
|
409
410
|
// YouTube: empty title pattern indicates a degraded response requiring BotGuard JS attestation
|
|
410
411
|
// Normal pages have `<title>Video Title - YouTube</title>`, bots get `<title> - YouTube</title>`
|
|
411
412
|
if (hasAnyHtml([/<title>\s*-\s*YouTube<\/title>/i])) {
|