Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions user_scanner/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
"dragongroot",
"hoichoi",
"fantasia",
"couplejoy",
"asafeer",
],
}

Expand Down
52 changes: 52 additions & 0 deletions user_scanner/email_scan/learning/asafeer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import httpx
from user_scanner.core.result import Result


async def _check(email: str) -> Result:
url = "https://3asafeer.com/caller.php"
show_url = "https://3asafeer.com"

params = {
"page": "user",
"task": "forgotPass",
"eml": email,
"format": "json",
}

headers = {
"User-Agent": "okhttp/5.3.2",
"Accept-Encoding": "gzip",
}

async with httpx.AsyncClient(http2=True) as client:
try:
response = await client.get(url, params=params, headers=headers, timeout=6.0)

if response.status_code == 429:
return Result.error("Rate limited", url=show_url)

if response.status_code == 200:
data = response.json()
result_val = data.get("result")
if result_val == "success":
return Result.taken(url=show_url)
elif result_val == "failed":
return Result.available(url=show_url)

return Result.error("Unexpected response body, report it via GitHub issues", url=show_url)

return Result.error(
f"Unexpected response status: {response.status_code}, report it via GitHub issues",
url=show_url,
)

except Exception as e:
return Result.error(e, url=show_url)


async def validate_asafeer(email: str) -> Result:
"""
3Asafeer (مدرسة عصافير) email validator. Checks forgotPass endpoint.
Loud module because it sends a password reset email when account exists.
"""
return await _check(email)
66 changes: 66 additions & 0 deletions user_scanner/email_scan/shopping/tatacliq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import httpx
from user_scanner.core.result import Result


async def _check(email: str) -> Result:
url = "https://api.tatadigital.com/api/v2/sso/check-email"
show_url = "https://tatadigital.com"

payload = {
"email": email,
"sendOtp": False,
}

headers = {
"User-Agent": "okhttp/5.2.0",
"Accept-Encoding": "gzip",
"client_id": "TATACLIQ-ANDROID-APP",
"appversion": "103.22.0",
"appplatform": "android",
"content-type": "application/json; charset=UTF-8",
}

async with httpx.AsyncClient(http2=True) as client:
try:
response = await client.post(url, json=payload, headers=headers, timeout=6.0)

if response.status_code == 429:
return Result.error("Rate limited", url=show_url)

if response.status_code == 200:
data = response.json()
user_type = data.get("userType")
email_enrolled = data.get("emailEnrolled")

if user_type in ["existing", "migrated"] or email_enrolled is True:
extra = {}
if user_type:
extra["user_type"] = user_type
if email_enrolled is not None:
extra["email_enrolled"] = email_enrolled
if data.get("emailVerified") is not None:
extra["email_verified"] = data["emailVerified"]
if data.get("phoneMasked"):
extra["phone_masked"] = data["phoneMasked"]
return Result.taken(extra=extra, url=show_url)

if user_type == "new" or data.get("message") == "User is not found":
return Result.available(url=show_url)

return Result.error("Unexpected response body, report it via GitHub issues", url=show_url)

return Result.error(
f"Unexpected response status: {response.status_code}, report it via GitHub issues",
url=show_url,
)

except Exception as e:
return Result.error(e, url=show_url)


async def validate_tatacliq(email: str) -> Result:
"""
Tata CLiQ (Tata Neu / Tata Digital SSO) email validator.
Checks check-email endpoint without sending OTP (sendOtp=False).
"""
return await _check(email)
58 changes: 58 additions & 0 deletions user_scanner/email_scan/social/couplejoy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import httpx
from user_scanner.core.result import Result


async def _check(email: str) -> Result:
url = "https://api.couplejoyapp.com/v1/reset-password"
show_url = "https://couplejoyapp.com"

payload = {
"email": email
}

headers = {
"User-Agent": "okhttp/4.12.0",
"Accept": "application/json",
"Accept-Encoding": "gzip",
"Content-Type": "application/json",
"app-language": "en",
"app-timezone": "UTC",
"app-platform": "android",
"app-version": "4.28.0",
"app-locale": "en-US",
"app-os-version": "11",
"authorization": "Bearer null",
}

async with httpx.AsyncClient(http2=True) as client:
try:
response = await client.post(url, json=payload, headers=headers, timeout=6.0)

if response.status_code == 429:
return Result.error("Rate limited", url=show_url)

if response.status_code == 200:
data = response.json()
if data.get("success") is True:
return Result.taken(url=show_url)

if response.status_code == 400:
data = response.json()
if data.get("code") == "EMAIL_NOT_FOUND":
return Result.available(url=show_url)

return Result.error(
f"Unexpected response status: {response.status_code}, report it via GitHub issues",
url=show_url,
)

except Exception as e:
return Result.error(e, url=show_url)


async def validate_couplejoy(email: str) -> Result:
"""
Couplejoy email validator. Checks reset-password endpoint.
Loud module because it sends password reset email when account exists.
"""
return await _check(email)
52 changes: 52 additions & 0 deletions user_scanner/email_scan/social/lovenudge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import httpx
from user_scanner.core.result import Result


async def _check(email: str) -> Result:
url = "https://api.lovenudgeapp.com/api/register/check"
show_url = "https://lovenudgeapp.com"

params = {
"email": email,
"time_zone": "UTC",
"app_version": "5.2.10",
}

headers = {
"User-Agent": "okhttp/4.11.0",
"Accept": "application/json",
"Accept-Encoding": "gzip",
"Content-Type": "application/json",
}

async with httpx.AsyncClient(http2=True) as client:
try:
response = await client.get(url, params=params, headers=headers, timeout=6.0)

if response.status_code == 429:
return Result.error("Rate limited", url=show_url)

if response.status_code == 200:
data = response.json()
if "data" in data:
if data["data"] is True:
return Result.taken(url=show_url)
elif data["data"] is False:
return Result.available(url=show_url)

return Result.error("Unexpected response body, report it via GitHub issues", url=show_url)

return Result.error(
f"Unexpected response status: {response.status_code}, report it via GitHub issues",
url=show_url,
)

except Exception as e:
return Result.error(e, url=show_url)


async def validate_lovenudge(email: str) -> Result:
"""
Love Nudge email validator. Checks register/check endpoint.
"""
return await _check(email)
Loading