user-scanner 1.0.10.3__py3-none-any.whl → 1.1.0.1__py3-none-any.whl
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.
- user_scanner/__main__.py +241 -129
- user_scanner/core/email_orchestrator.py +78 -0
- user_scanner/core/formatter.py +27 -0
- user_scanner/core/helpers.py +194 -2
- user_scanner/core/orchestrator.py +24 -112
- user_scanner/core/result.py +51 -18
- user_scanner/email_scan/adult/pornhub.py +62 -0
- user_scanner/email_scan/adult/xnxx.py +46 -0
- user_scanner/email_scan/adult/xvideos.py +50 -0
- user_scanner/email_scan/community/stackoverflow.py +40 -0
- user_scanner/email_scan/creator/__init__.py +0 -0
- user_scanner/email_scan/creator/gumroad.py +82 -0
- user_scanner/email_scan/creator/patreon.py +58 -0
- user_scanner/email_scan/dev/__init__.py +0 -0
- user_scanner/email_scan/dev/bitbucket.py +33 -0
- user_scanner/email_scan/dev/github.py +72 -0
- user_scanner/email_scan/dev/huggingface.py +37 -0
- user_scanner/email_scan/gaming/__init__.py +0 -0
- user_scanner/email_scan/gaming/chess_com.py +47 -0
- user_scanner/email_scan/shopping/__init__.py +0 -0
- user_scanner/email_scan/shopping/flipkart.py +52 -0
- user_scanner/email_scan/social/__init__.py +0 -0
- user_scanner/email_scan/social/facebook.py +96 -0
- user_scanner/email_scan/social/instagram.py +48 -0
- user_scanner/email_scan/social/mastodon.py +57 -0
- user_scanner/email_scan/social/x.py +41 -0
- user_scanner/user_scan/community/lemmy.py +30 -0
- user_scanner/user_scan/creator/__init__.py +0 -0
- user_scanner/user_scan/creator/gumroad.py +22 -0
- user_scanner/user_scan/donation/__init__.py +0 -0
- user_scanner/user_scan/gaming/__init__.py +0 -0
- user_scanner/{gaming → user_scan/gaming}/roblox.py +15 -5
- user_scanner/version.json +1 -1
- user_scanner-1.1.0.1.dist-info/METADATA +239 -0
- user_scanner-1.1.0.1.dist-info/RECORD +98 -0
- user_scanner/cli/printer.py +0 -117
- user_scanner-1.0.10.3.dist-info/METADATA +0 -172
- user_scanner-1.0.10.3.dist-info/RECORD +0 -72
- /user_scanner/{creator → email_scan}/__init__.py +0 -0
- /user_scanner/{donation → email_scan/adult}/__init__.py +0 -0
- /user_scanner/{gaming → email_scan/community}/__init__.py +0 -0
- /user_scanner/{community → user_scan/community}/__init__.py +0 -0
- /user_scanner/{community → user_scan/community}/coderlegion.py +0 -0
- /user_scanner/{community → user_scan/community}/hackernews.py +0 -0
- /user_scanner/{community → user_scan/community}/stackoverflow.py +0 -0
- /user_scanner/{creator → user_scan/creator}/devto.py +0 -0
- /user_scanner/{creator → user_scan/creator}/hashnode.py +0 -0
- /user_scanner/{creator → user_scan/creator}/itch_io.py +0 -0
- /user_scanner/{creator → user_scan/creator}/kaggle.py +0 -0
- /user_scanner/{creator → user_scan/creator}/medium.py +0 -0
- /user_scanner/{creator → user_scan/creator}/patreon.py +0 -0
- /user_scanner/{creator → user_scan/creator}/producthunt.py +0 -0
- /user_scanner/{creator → user_scan/creator}/substack.py +0 -0
- /user_scanner/{creator → user_scan/creator}/twitch.py +0 -0
- /user_scanner/{dev → user_scan/dev}/__init__.py +0 -0
- /user_scanner/{dev → user_scan/dev}/bitbucket.py +0 -0
- /user_scanner/{dev → user_scan/dev}/codeberg.py +0 -0
- /user_scanner/{dev → user_scan/dev}/cratesio.py +0 -0
- /user_scanner/{dev → user_scan/dev}/dockerhub.py +0 -0
- /user_scanner/{dev → user_scan/dev}/github.py +0 -0
- /user_scanner/{dev → user_scan/dev}/gitlab.py +0 -0
- /user_scanner/{dev → user_scan/dev}/huggingface.py +0 -0
- /user_scanner/{dev → user_scan/dev}/launchpad.py +0 -0
- /user_scanner/{dev → user_scan/dev}/leetcode.py +0 -0
- /user_scanner/{dev → user_scan/dev}/npmjs.py +0 -0
- /user_scanner/{dev → user_scan/dev}/replit.py +0 -0
- /user_scanner/{dev → user_scan/dev}/sourceforge.py +0 -0
- /user_scanner/{donation → user_scan/donation}/buymeacoffee.py +0 -0
- /user_scanner/{donation → user_scan/donation}/liberapay.py +0 -0
- /user_scanner/{gaming → user_scan/gaming}/chess_com.py +0 -0
- /user_scanner/{gaming → user_scan/gaming}/lichess.py +0 -0
- /user_scanner/{gaming → user_scan/gaming}/minecraft.py +0 -0
- /user_scanner/{gaming → user_scan/gaming}/monkeytype.py +0 -0
- /user_scanner/{gaming → user_scan/gaming}/osu.py +0 -0
- /user_scanner/{gaming → user_scan/gaming}/steam.py +0 -0
- /user_scanner/{social → user_scan/social}/__init__.py +0 -0
- /user_scanner/{social → user_scan/social}/bluesky.py +0 -0
- /user_scanner/{social → user_scan/social}/discord.py +0 -0
- /user_scanner/{social → user_scan/social}/instagram.py +0 -0
- /user_scanner/{social → user_scan/social}/mastodon.py +0 -0
- /user_scanner/{social → user_scan/social}/pinterest.py +0 -0
- /user_scanner/{social → user_scan/social}/reddit.py +0 -0
- /user_scanner/{social → user_scan/social}/snapchat.py +0 -0
- /user_scanner/{social → user_scan/social}/soundcloud.py +0 -0
- /user_scanner/{social → user_scan/social}/telegram.py +0 -0
- /user_scanner/{social → user_scan/social}/threads.py +0 -0
- /user_scanner/{social → user_scan/social}/tiktok.py +0 -0
- /user_scanner/{social → user_scan/social}/x.py +0 -0
- /user_scanner/{social → user_scan/social}/youtube.py +0 -0
- {user_scanner-1.0.10.3.dist-info → user_scanner-1.1.0.1.dist-info}/WHEEL +0 -0
- {user_scanner-1.0.10.3.dist-info → user_scanner-1.1.0.1.dist-info}/entry_points.txt +0 -0
- {user_scanner-1.0.10.3.dist-info → user_scanner-1.1.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
url = "https://www.xvideos.com/account/checkemail"
|
|
7
|
+
params = {'email': email}
|
|
8
|
+
|
|
9
|
+
headers = {
|
|
10
|
+
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Mobile Safari/537.36",
|
|
11
|
+
'Accept': "application/json, text/javascript, */*; q=0.01",
|
|
12
|
+
'Accept-Encoding': "identity",
|
|
13
|
+
'X-Requested-With': "XMLHttpRequest",
|
|
14
|
+
'sec-ch-ua-platform': "\"Android\"",
|
|
15
|
+
'sec-ch-ua': "\"Google Chrome\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"",
|
|
16
|
+
'sec-ch-ua-mobile': "?1",
|
|
17
|
+
'Sec-Fetch-Site': "same-origin",
|
|
18
|
+
'Sec-Fetch-Mode': "cors",
|
|
19
|
+
'Sec-Fetch-Dest': "empty",
|
|
20
|
+
'Referer': "https://www.xvideos.com/",
|
|
21
|
+
'Accept-Language': "en-US,en;q=0.9"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async with httpx.AsyncClient(http2=True, timeout=3) as client:
|
|
25
|
+
try:
|
|
26
|
+
response = await client.get(url, params=params, headers=headers)
|
|
27
|
+
|
|
28
|
+
if response.status_code == 429:
|
|
29
|
+
return Result.error("Rate limited, wait for a few minutes")
|
|
30
|
+
|
|
31
|
+
if response.status_code != 200:
|
|
32
|
+
return Result.error(f"HTTP Error: {response.status_code}")
|
|
33
|
+
|
|
34
|
+
data = response.json()
|
|
35
|
+
|
|
36
|
+
exists_bool = data.get("result")
|
|
37
|
+
|
|
38
|
+
if exists_bool is True:
|
|
39
|
+
return Result.available()
|
|
40
|
+
elif exists_bool is False:
|
|
41
|
+
return Result.taken()
|
|
42
|
+
else:
|
|
43
|
+
return Result.error("Unexpected error, report it via GitHub issues")
|
|
44
|
+
|
|
45
|
+
except Exception as e:
|
|
46
|
+
return Result.error(e)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
async def validate_xvideos(email: str) -> Result:
|
|
50
|
+
return await _check(email)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
async def _check(email: str) -> Result:
|
|
5
|
+
async with httpx.AsyncClient(http2=False, follow_redirects=True) as client:
|
|
6
|
+
try:
|
|
7
|
+
url = "https://stackoverflow.com/users/login"
|
|
8
|
+
|
|
9
|
+
payload = {
|
|
10
|
+
'ssrc': "login",
|
|
11
|
+
'email': email,
|
|
12
|
+
'password': "Password109-grt",
|
|
13
|
+
'oauth_version': "",
|
|
14
|
+
'oauth_server': ""
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
headers = {
|
|
18
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
19
|
+
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
20
|
+
'Accept-Encoding': "identity",
|
|
21
|
+
'sec-ch-ua-platform': '"Linux"',
|
|
22
|
+
'origin': "https://stackoverflow.com",
|
|
23
|
+
'referer': "https://stackoverflow.com/users/login"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
response = await client.post(url, data=payload, headers=headers)
|
|
27
|
+
body = response.text
|
|
28
|
+
|
|
29
|
+
if "No user found with matching email" in body:
|
|
30
|
+
return Result.available()
|
|
31
|
+
elif "The email or password is incorrect" in body:
|
|
32
|
+
return Result.taken()
|
|
33
|
+
else:
|
|
34
|
+
return Result.error("Unexpected response body")
|
|
35
|
+
|
|
36
|
+
except Exception as e:
|
|
37
|
+
return Result.error(f"unexpected exception: {e}")
|
|
38
|
+
|
|
39
|
+
async def validate_stackoverflow(email: str) -> Result:
|
|
40
|
+
return await _check(email)
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import re
|
|
3
|
+
from user_scanner.core.result import Result
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async def _check(email: str) -> Result:
|
|
7
|
+
async with httpx.AsyncClient(http2=False, follow_redirects=True) as client:
|
|
8
|
+
try:
|
|
9
|
+
url1 = "https://gumroad.com/users/forgot_password/new"
|
|
10
|
+
headers1 = {
|
|
11
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
12
|
+
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
|
13
|
+
'Accept-Encoding': "gzip, deflate, br, zstd",
|
|
14
|
+
'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
|
|
15
|
+
'sec-ch-ua-mobile': "?0",
|
|
16
|
+
'sec-ch-ua-platform': '"Linux"',
|
|
17
|
+
'upgrade-insecure-requests': "1",
|
|
18
|
+
'referer': "https://www.google.com/",
|
|
19
|
+
'accept-language': "en-US,en;q=0.9"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
res1 = await client.get(url1, headers=headers1)
|
|
23
|
+
html = res1.text
|
|
24
|
+
|
|
25
|
+
csrf_match = re.search(
|
|
26
|
+
r'authenticity_token":"([^&]+)"', html)
|
|
27
|
+
if not csrf_match:
|
|
28
|
+
csrf_match = re.search(
|
|
29
|
+
r'name="csrf-token" content="([^"]+)"', html)
|
|
30
|
+
|
|
31
|
+
if not csrf_match:
|
|
32
|
+
return Result.error("Failed to extract CSRF token")
|
|
33
|
+
|
|
34
|
+
csrf_token = csrf_match.group(1)
|
|
35
|
+
|
|
36
|
+
url2 = "https://gumroad.com/users/forgot_password"
|
|
37
|
+
|
|
38
|
+
payload = {
|
|
39
|
+
"user": {
|
|
40
|
+
"email": email
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
headers2 = {
|
|
45
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
46
|
+
'Accept': "text/html, application/xhtml+xml",
|
|
47
|
+
'Accept-Encoding': "gzip, deflate, br, zstd",
|
|
48
|
+
'Content-Type': "application/json",
|
|
49
|
+
'sec-ch-ua-platform': '"Linux"',
|
|
50
|
+
'x-csrf-token': csrf_token,
|
|
51
|
+
'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
|
|
52
|
+
'x-inertia': "true",
|
|
53
|
+
'sec-ch-ua-mobile': "?0",
|
|
54
|
+
'x-requested-with': "XMLHttpRequest",
|
|
55
|
+
'origin': "https://gumroad.com",
|
|
56
|
+
'sec-fetch-site': "same-origin",
|
|
57
|
+
'sec-fetch-mode': "cors",
|
|
58
|
+
'sec-fetch-dest': "empty",
|
|
59
|
+
'referer': "https://gumroad.com/users/forgot_password/new",
|
|
60
|
+
'accept-language': "en-US,en;q=0.9",
|
|
61
|
+
'priority': "u=1, i"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
response = await client.post(url2, json=payload, headers=headers2)
|
|
65
|
+
|
|
66
|
+
data = response.json()
|
|
67
|
+
flash_msg = data.get("props", {}).get(
|
|
68
|
+
"flash", {}).get("message", "")
|
|
69
|
+
|
|
70
|
+
if "An account does not exist" in flash_msg:
|
|
71
|
+
return Result.available()
|
|
72
|
+
elif "An account does not exist" not in flash_msg:
|
|
73
|
+
return Result.taken()
|
|
74
|
+
else:
|
|
75
|
+
return Result.error(f"Unexpected status: {response.status_code}")
|
|
76
|
+
|
|
77
|
+
except Exception as e:
|
|
78
|
+
return Result.error(f"unexpected exception: {e}")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
async def validate_gumroad(email: str) -> Result:
|
|
82
|
+
return await _check(email)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
async with httpx.AsyncClient(http2=False) as client:
|
|
7
|
+
try:
|
|
8
|
+
url = "https://www.patreon.com/api/auth"
|
|
9
|
+
|
|
10
|
+
params = {
|
|
11
|
+
'include': "user.null",
|
|
12
|
+
'fields[user]': "[]",
|
|
13
|
+
'json-api-version': "1.0",
|
|
14
|
+
'json-api-use-default-includes': "false"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
payload = "{\"data\":{\"type\":\"genericPatreonApi\",\"attributes\":{\"patreon_auth\":{\"email\":\"" + email + \
|
|
18
|
+
"\",\"allow_account_creation\":false},\"auth_context\":\"auth\",\"ru\":\"https://www.patreon.com/home\"},\"relationships\":{}}}"
|
|
19
|
+
|
|
20
|
+
headers = {
|
|
21
|
+
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36",
|
|
22
|
+
'Accept-Encoding': "identity",
|
|
23
|
+
'content-type': "application/vnd.api+json",
|
|
24
|
+
'origin': "https://www.patreon.com"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
response = await client.post(
|
|
28
|
+
url,
|
|
29
|
+
params=params,
|
|
30
|
+
content=payload,
|
|
31
|
+
headers=headers
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
if response.status_code != 200:
|
|
35
|
+
return Result.error(f"Status {response.status_code}")
|
|
36
|
+
|
|
37
|
+
data = response.json()
|
|
38
|
+
next_step = data.get("data", {}).get(
|
|
39
|
+
"attributes", {}).get("next_auth_step")
|
|
40
|
+
|
|
41
|
+
if next_step == "password":
|
|
42
|
+
return Result.taken()
|
|
43
|
+
elif next_step == "signup":
|
|
44
|
+
return Result.available()
|
|
45
|
+
else:
|
|
46
|
+
return Result.error("Unexpected auth step")
|
|
47
|
+
|
|
48
|
+
except Exception as e:
|
|
49
|
+
return Result.error(f"unexpected exception: {e}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
async def validate_patreon(email: str) -> Result:
|
|
53
|
+
return await _check(email)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
async def _check(email: str) -> Result:
|
|
5
|
+
async with httpx.AsyncClient(http2=True) as client:
|
|
6
|
+
try:
|
|
7
|
+
url = "https://id.atlassian.com/rest/marketing-consent/config"
|
|
8
|
+
payload = {"email": email}
|
|
9
|
+
headers = {
|
|
10
|
+
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36",
|
|
11
|
+
'Content-Type': "application/json",
|
|
12
|
+
'Origin': "https://id.atlassian.com",
|
|
13
|
+
'Referer': f"https://id.atlassian.com/login?email={email}"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
response = await client.post(url, json=payload, headers=headers)
|
|
17
|
+
|
|
18
|
+
if response.status_code != 200:
|
|
19
|
+
return Result.error(f"Status {response.status_code}")
|
|
20
|
+
|
|
21
|
+
data = response.json()
|
|
22
|
+
is_reg = data.get("implicitConsent")
|
|
23
|
+
if is_reg is True:
|
|
24
|
+
return Result.available()
|
|
25
|
+
elif is_reg is False:
|
|
26
|
+
return Result.taken()
|
|
27
|
+
else:
|
|
28
|
+
return Result.error(f"Unexpected error occured [{response.status_code}]")
|
|
29
|
+
except Exception as e:
|
|
30
|
+
return Result.error(f"Unexpected exception:{e}")
|
|
31
|
+
|
|
32
|
+
async def validate_bitbucket(email: str) -> Result:
|
|
33
|
+
return await _check(email)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import re
|
|
3
|
+
from user_scanner.core.result import Result
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
async with httpx.AsyncClient(http2=True, follow_redirects=True) as client:
|
|
7
|
+
try:
|
|
8
|
+
url1 = "https://github.com/signup"
|
|
9
|
+
headers1 = {
|
|
10
|
+
'host': 'github.com',
|
|
11
|
+
'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
|
|
12
|
+
'sec-ch-ua-mobile': '?0',
|
|
13
|
+
'sec-ch-ua-platform': '"Linux"',
|
|
14
|
+
'upgrade-insecure-requests': '1',
|
|
15
|
+
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36',
|
|
16
|
+
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
|
17
|
+
'sec-fetch-site': 'cross-site',
|
|
18
|
+
'sec-fetch-mode': 'navigate',
|
|
19
|
+
'sec-fetch-user': '?1',
|
|
20
|
+
'sec-fetch-dest': 'document',
|
|
21
|
+
'referer': 'https://www.google.com/',
|
|
22
|
+
'accept-encoding': 'gzip, deflate, br, zstd',
|
|
23
|
+
'accept-language': 'en-US,en;q=0.9',
|
|
24
|
+
'priority': 'u=0, i'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
res1 = await client.get(url1, headers=headers1)
|
|
28
|
+
html = res1.text
|
|
29
|
+
|
|
30
|
+
csrf_match = re.search(r'data-csrf="true"\s+value="([^"]+)"', html)
|
|
31
|
+
|
|
32
|
+
if not csrf_match:
|
|
33
|
+
return Result.error("Failed to extract GitHub authenticity_token")
|
|
34
|
+
|
|
35
|
+
csrf_token = csrf_match.group(1)
|
|
36
|
+
|
|
37
|
+
url2 = "https://github.com/email_validity_checks"
|
|
38
|
+
payload = {
|
|
39
|
+
'authenticity_token': csrf_token,
|
|
40
|
+
'value': email
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
headers2 = {
|
|
44
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
45
|
+
'Accept-Encoding': "gzip, deflate, br, zstd",
|
|
46
|
+
'sec-ch-ua-platform': '"Linux"',
|
|
47
|
+
'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"',
|
|
48
|
+
'sec-ch-ua-mobile': "?0",
|
|
49
|
+
'origin': "https://github.com",
|
|
50
|
+
'sec-fetch-site': "same-origin",
|
|
51
|
+
'sec-fetch-mode': "cors",
|
|
52
|
+
'sec-fetch-dest': "empty",
|
|
53
|
+
'referer': "https://github.com/signup",
|
|
54
|
+
'accept-language': "en-US,en;q=0.9",
|
|
55
|
+
'priority': "u=1, i"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
response = await client.post(url2, data=payload, headers=headers2)
|
|
59
|
+
body = response.text
|
|
60
|
+
|
|
61
|
+
if "already associated with an account" in body:
|
|
62
|
+
return Result.taken()
|
|
63
|
+
elif response.status_code == 200 and "Email is available" in body:
|
|
64
|
+
return Result.available()
|
|
65
|
+
else:
|
|
66
|
+
return Result.error(f"Unexpected status code: {response.status_code}, report this via GitHub issues")
|
|
67
|
+
|
|
68
|
+
except Exception as e:
|
|
69
|
+
return Result.error(f"unexpected exception: {e}")
|
|
70
|
+
|
|
71
|
+
async def validate_github(email: str) -> Result:
|
|
72
|
+
return await _check(email)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
url = "https://huggingface.co/api/check-user-email"
|
|
7
|
+
params = {'email': email}
|
|
8
|
+
headers = {
|
|
9
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
|
|
10
|
+
'Accept-Encoding': "identity",
|
|
11
|
+
'referer': "https://huggingface.co/join",
|
|
12
|
+
'priority': "u=1, i"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async with httpx.AsyncClient(http2=True) as client:
|
|
16
|
+
try:
|
|
17
|
+
response = await client.get(url, params=params, headers=headers, timeout=5)
|
|
18
|
+
|
|
19
|
+
if response.status_code == 429:
|
|
20
|
+
return Result.error("Rate limited wait for few minutes")
|
|
21
|
+
|
|
22
|
+
if response.status_code == 400:
|
|
23
|
+
data = response.json()
|
|
24
|
+
if "already exists" in data.get("error", ""):
|
|
25
|
+
return Result.taken()
|
|
26
|
+
|
|
27
|
+
if response.status_code == 200:
|
|
28
|
+
return Result.available()
|
|
29
|
+
|
|
30
|
+
return Result.error(f"HTTP Error: {response.status_code}")
|
|
31
|
+
|
|
32
|
+
except Exception as e:
|
|
33
|
+
return Result.error(e)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def validate_huggingface(email: str) -> Result:
|
|
37
|
+
return await _check(email)
|
|
File without changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
async def _check(email: str) -> Result:
|
|
5
|
+
async with httpx.AsyncClient(http2=True) as client:
|
|
6
|
+
try:
|
|
7
|
+
url = "https://www.chess.com/rpc/chesscom.authentication.v1.EmailValidationService/Validate"
|
|
8
|
+
|
|
9
|
+
payload = {
|
|
10
|
+
"email": email
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
headers = {
|
|
14
|
+
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36",
|
|
15
|
+
'Accept': "application/json, text/plain, */*",
|
|
16
|
+
'Accept-Encoding': "identity",
|
|
17
|
+
'Content-Type': "application/json",
|
|
18
|
+
'sec-ch-ua-platform': '"Android"',
|
|
19
|
+
'accept-language': "en_US",
|
|
20
|
+
'connect-protocol-version': "1",
|
|
21
|
+
'origin': "https://www.chess.com",
|
|
22
|
+
'sec-fetch-site': "same-origin",
|
|
23
|
+
'sec-fetch-mode': "cors",
|
|
24
|
+
'referer': "https://www.chess.com/register",
|
|
25
|
+
'priority': "u=1, i"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
response = await client.post(url, json=payload, headers=headers)
|
|
29
|
+
|
|
30
|
+
if response.status_code != 200:
|
|
31
|
+
return Result.error(f"Status {response.status_code}, report is via GitHub issues")
|
|
32
|
+
|
|
33
|
+
data = response.json()
|
|
34
|
+
status = data.get("status")
|
|
35
|
+
|
|
36
|
+
if status == "EMAIL_STATUS_TAKEN":
|
|
37
|
+
return Result.taken()
|
|
38
|
+
elif status == "EMAIL_STATUS_AVAILABLE":
|
|
39
|
+
return Result.available()
|
|
40
|
+
else:
|
|
41
|
+
return Result.error(f"Unknown status: {status}, report is via GitHub issues")
|
|
42
|
+
|
|
43
|
+
except Exception as e:
|
|
44
|
+
return Result.error(f"unexpected exception: {e}")
|
|
45
|
+
|
|
46
|
+
async def validate_chess_com(email: str) -> Result:
|
|
47
|
+
return await _check(email)
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
async def _check(email: str) -> Result:
|
|
5
|
+
url = "https://1.rome.api.flipkart.com/1/action/view"
|
|
6
|
+
|
|
7
|
+
headers = {
|
|
8
|
+
'User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Mobile Safari/537.36",
|
|
9
|
+
'Content-Type': "application/json",
|
|
10
|
+
'X-User-Agent': "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Mobile Safari/537.36 FKUA/msite/0.0.3/msite/Mobile channelType/undefined",
|
|
11
|
+
'Origin': "https://www.flipkart.com",
|
|
12
|
+
'Referer': "https://www.flipkart.com/"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
payload = {
|
|
16
|
+
"actionRequestContext": {
|
|
17
|
+
"type": "LOGIN_IDENTITY_VERIFY",
|
|
18
|
+
"loginIdPrefix": "",
|
|
19
|
+
"loginId": email,
|
|
20
|
+
"clientQueryParamMap": {"ret": "/"},
|
|
21
|
+
"loginType": "EMAIL",
|
|
22
|
+
"verificationType": "PASSWORD",
|
|
23
|
+
"screenName": "LOGIN_V4_EMAIL",
|
|
24
|
+
"sourceContext": "DEFAULT"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async with httpx.AsyncClient(http2=True) as client:
|
|
29
|
+
try:
|
|
30
|
+
response = await client.post(url, json=payload, headers=headers)
|
|
31
|
+
|
|
32
|
+
if response.status_code == 429:
|
|
33
|
+
return Result.error("Rate limited wait for few minutes")
|
|
34
|
+
|
|
35
|
+
if response.status_code != 200:
|
|
36
|
+
return Result.error(f"HTTP Error: {response.status_code}")
|
|
37
|
+
|
|
38
|
+
response_text = response.text
|
|
39
|
+
|
|
40
|
+
if "Looks like you're new here!" in response_text:
|
|
41
|
+
return Result.available()
|
|
42
|
+
|
|
43
|
+
if "LOGIN_P_CHECK" in response_text or '"statusSuccess":true' in response_text:
|
|
44
|
+
return Result.taken()
|
|
45
|
+
|
|
46
|
+
return Result.taken()
|
|
47
|
+
|
|
48
|
+
except Exception as e:
|
|
49
|
+
return Result.error(e)
|
|
50
|
+
|
|
51
|
+
async def validate_flipkart(email: str) -> Result:
|
|
52
|
+
return await _check(email)
|
|
File without changes
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import re
|
|
3
|
+
from user_scanner.core.result import Result
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
async with httpx.AsyncClient(http2=True, follow_redirects=False) as client:
|
|
7
|
+
try:
|
|
8
|
+
url1 = "https://m.facebook.com/login/"
|
|
9
|
+
headers1 = {
|
|
10
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
|
|
11
|
+
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
12
|
+
'Accept-Encoding': "identity",
|
|
13
|
+
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
|
|
14
|
+
}
|
|
15
|
+
await client.get(url1, headers=headers1)
|
|
16
|
+
|
|
17
|
+
url2 = "https://www.facebook.com"
|
|
18
|
+
params2 = {'_rdr': ""}
|
|
19
|
+
headers2 = {
|
|
20
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
|
|
21
|
+
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
22
|
+
'Accept-Encoding': "identity",
|
|
23
|
+
'upgrade-insecure-requests': "1",
|
|
24
|
+
'sec-fetch-site': "cross-site",
|
|
25
|
+
'sec-fetch-mode': "navigate",
|
|
26
|
+
'sec-fetch-user': "?1",
|
|
27
|
+
'sec-fetch-dest': "document",
|
|
28
|
+
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
|
|
29
|
+
'sec-ch-ua-mobile': "?0",
|
|
30
|
+
'sec-ch-ua-platform': '"Linux"',
|
|
31
|
+
'referer': "https://www.google.com/",
|
|
32
|
+
'accept-language': "en-US,en;q=0.9",
|
|
33
|
+
'priority': "u=0, i"
|
|
34
|
+
}
|
|
35
|
+
res2 = await client.get(url2, params=params2, headers=headers2)
|
|
36
|
+
html = res2.text
|
|
37
|
+
|
|
38
|
+
j_match = re.search(r'name="jazoest" value="(\d+)"', html)
|
|
39
|
+
l_match = re.search(r'name="lsd" value="([^"]+)"', html)
|
|
40
|
+
|
|
41
|
+
if not j_match or not l_match:
|
|
42
|
+
return Result.error("Failed to extract tokens (LSD/Jazoest)")
|
|
43
|
+
|
|
44
|
+
jazoest = j_match.group(1)
|
|
45
|
+
lsd = l_match.group(1)
|
|
46
|
+
|
|
47
|
+
url3 = "https://www.facebook.com/ajax/login/help/identify.php"
|
|
48
|
+
params3 = {'ctx': "recover"}
|
|
49
|
+
|
|
50
|
+
payload3 = {
|
|
51
|
+
'jazoest': jazoest,
|
|
52
|
+
'lsd': lsd,
|
|
53
|
+
'email': email,
|
|
54
|
+
'did_submit': "1",
|
|
55
|
+
'__user': "0",
|
|
56
|
+
'__a': "1",
|
|
57
|
+
'__req': "7"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
headers3 = {
|
|
61
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
|
|
62
|
+
'Accept-Encoding': "identity",
|
|
63
|
+
'sec-ch-ua-full-version-list': '"Google Chrome";v="143.0.7499.192", "Chromium";v="143.0.7499.192", "Not A(Brand";v="24.0.0.0"',
|
|
64
|
+
'sec-ch-ua-platform': '"Linux"',
|
|
65
|
+
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
|
|
66
|
+
'sec-ch-ua-model': '""',
|
|
67
|
+
'sec-ch-ua-mobile': "?0",
|
|
68
|
+
'x-asbd-id': "359341",
|
|
69
|
+
'x-fb-lsd': lsd,
|
|
70
|
+
'sec-ch-prefers-color-scheme': "dark",
|
|
71
|
+
'sec-ch-ua-platform-version': '""',
|
|
72
|
+
'origin': "https://www.facebook.com",
|
|
73
|
+
'sec-fetch-site': "same-origin",
|
|
74
|
+
'sec-fetch-mode': "cors",
|
|
75
|
+
'sec-fetch-dest': "empty",
|
|
76
|
+
'referer': "https://www.facebook.com/login/identify/?ctx=recover&ars=facebook_login&from_login_screen=0",
|
|
77
|
+
'accept-language': "en-US,en;q=0.9",
|
|
78
|
+
'priority': "u=1, i"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
response = await client.post(url3, params=params3, data=payload3, headers=headers3)
|
|
82
|
+
body = response.text
|
|
83
|
+
|
|
84
|
+
if "redirectPageTo" in body and "ServerRedirect" in body:
|
|
85
|
+
return Result.taken()
|
|
86
|
+
elif "No search results" in body or "Your search did not return any results." in body:
|
|
87
|
+
return Result.available()
|
|
88
|
+
else:
|
|
89
|
+
return Result.error("Unexpected error, report it via GitHub issues")
|
|
90
|
+
|
|
91
|
+
except Exception as e:
|
|
92
|
+
return Result.error(f"Unexpected exception: {e}")
|
|
93
|
+
|
|
94
|
+
async def validate_facebook(email: str) -> Result:
|
|
95
|
+
return await _check(email)
|
|
96
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email):
|
|
6
|
+
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
|
|
7
|
+
async with httpx.AsyncClient(headers={"user-agent": USER_AGENT}, http2=True) as client:
|
|
8
|
+
await client.get("https://www.instagram.com/")
|
|
9
|
+
csrf = client.cookies.get("csrftoken")
|
|
10
|
+
|
|
11
|
+
headers = {
|
|
12
|
+
"x-csrftoken": csrf,
|
|
13
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
|
|
14
|
+
'Accept-Encoding': "identity",
|
|
15
|
+
'sec-ch-ua-full-version-list': "\"Google Chrome\";v=\"143.0.7499.146\", \"Chromium\";v=\"143.0.7499.146\", \"Not A(Brand\";v=\"24.0.0.0\"",
|
|
16
|
+
'sec-ch-ua-platform': "\"Linux\"",
|
|
17
|
+
'sec-ch-ua': "\"Google Chrome\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"",
|
|
18
|
+
'sec-ch-ua-model': "\"\"",
|
|
19
|
+
'sec-ch-ua-mobile': "?0",
|
|
20
|
+
'x-ig-app-id': "936619743392459",
|
|
21
|
+
'x-requested-with': "XMLHttpRequest",
|
|
22
|
+
'x-instagram-ajax': "1031566424",
|
|
23
|
+
'x-asbd-id': "359341",
|
|
24
|
+
'x-ig-www-claim': "0",
|
|
25
|
+
'sec-ch-ua-platform-version': "\"\"",
|
|
26
|
+
'origin': "https://www.instagram.com",
|
|
27
|
+
'referer': "https://www.instagram.com/accounts/password/reset/"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
response = await client.post(
|
|
31
|
+
"https://www.instagram.com/api/v1/web/accounts/account_recovery_send_ajax/",
|
|
32
|
+
data={"email_or_username": email},
|
|
33
|
+
headers=headers
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
data = response.json()
|
|
37
|
+
status_val = data.get("status")
|
|
38
|
+
if status_val == "ok":
|
|
39
|
+
return Result.taken()
|
|
40
|
+
elif status_val == "fail":
|
|
41
|
+
return Result.available()
|
|
42
|
+
else:
|
|
43
|
+
return Result.error("Unexpected response body, report it on github")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def validate_instagram(email: str) -> Result:
|
|
48
|
+
return await _check(email)
|