user-scanner 1.1.0.4__tar.gz → 1.1.0.6__tar.gz
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-1.1.0.4 → user_scanner-1.1.0.6}/PKG-INFO +26 -62
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/README.md +25 -61
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/pyproject.toml +18 -2
- user_scanner-1.1.0.6/user_scanner/email_scan/dev/leetcode.py +64 -0
- user_scanner-1.1.0.6/user_scanner/email_scan/learning/duolingo.py +36 -0
- user_scanner-1.1.0.6/user_scanner/email_scan/other/eventbrite.py +51 -0
- user_scanner-1.1.0.6/user_scanner/email_scan/pipeline/axonaut.py +38 -0
- user_scanner-1.1.0.6/user_scanner/email_scan/pipeline/hubspot.py +52 -0
- user_scanner-1.1.0.6/user_scanner/email_scan/pipeline/insightly.py +43 -0
- user_scanner-1.1.0.6/user_scanner/email_scan/pipeline/zoho.py +63 -0
- user_scanner-1.1.0.6/user_scanner/user_scan/gaming/__init__.py +0 -0
- user_scanner-1.1.0.6/user_scanner/user_scan/shopping/__init__.py +0 -0
- user_scanner-1.1.0.6/user_scanner/utils/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/version.json +1 -1
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/.gitignore +0 -2
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/0.14.10/12603567674167520802 +0 -0
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/0.14.10/12688104075811904861 +0 -0
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/0.14.10/15694509833576274574 +0 -0
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/0.14.10/301008395129872757 +0 -0
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/0.14.10/4908403194175060721 +0 -0
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/0.14.10/572980360641624523 +0 -0
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/0.14.10/5935143038219898089 +0 -0
- user_scanner-1.1.0.4/user_scanner/.ruff_cache/CACHEDIR.TAG +0 -1
- user_scanner-1.1.0.4/user_scanner/email_scan/community/.ruff_cache/.gitignore +0 -2
- user_scanner-1.1.0.4/user_scanner/email_scan/community/.ruff_cache/0.14.10/3933329632096143294 +0 -0
- user_scanner-1.1.0.4/user_scanner/email_scan/community/.ruff_cache/CACHEDIR.TAG +0 -1
- user_scanner-1.1.0.4/user_scanner/email_scan/dev/.ruff_cache/.gitignore +0 -2
- user_scanner-1.1.0.4/user_scanner/email_scan/dev/.ruff_cache/0.14.10/10328336453267387919 +0 -0
- user_scanner-1.1.0.4/user_scanner/email_scan/dev/.ruff_cache/CACHEDIR.TAG +0 -1
- user_scanner-1.1.0.4/user_scanner/email_scan/hosting/.ruff_cache/.gitignore +0 -2
- user_scanner-1.1.0.4/user_scanner/email_scan/hosting/.ruff_cache/0.14.10/6358275293999347997 +0 -0
- user_scanner-1.1.0.4/user_scanner/email_scan/hosting/.ruff_cache/CACHEDIR.TAG +0 -1
- user_scanner-1.1.0.4/user_scanner/email_scan/music/.ruff_cache/.gitignore +0 -2
- user_scanner-1.1.0.4/user_scanner/email_scan/music/.ruff_cache/0.14.10/14677874048998292530 +0 -0
- user_scanner-1.1.0.4/user_scanner/email_scan/music/.ruff_cache/0.14.10/7544735312652879689 +0 -0
- user_scanner-1.1.0.4/user_scanner/email_scan/music/.ruff_cache/CACHEDIR.TAG +0 -1
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/LICENSE +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/__main__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/cli/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/cli/banner.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/config.json +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/core/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/core/email_orchestrator.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/core/formatter.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/core/helpers.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/core/orchestrator.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/core/result.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/core/version.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/adult/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/adult/pornhub.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/adult/sexvid.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/adult/xnxx.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/adult/xvideos.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/community/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/community/quora.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/community/stackoverflow.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/creator/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/creator/gumroad.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/creator/patreon.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/bitbucket.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/codecademy.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/codepen.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/devrant.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/github.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/huggingface.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/replit.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/dev/wordpress.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/gaming/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/gaming/chess_com.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/hosting/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/hosting/render.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/email_scan/music → user_scanner-1.1.0.6/user_scanner/email_scan/learning}/__init__.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/email_scan/shopping → user_scanner-1.1.0.6/user_scanner/email_scan/music}/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/music/lastfm.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/music/spotify.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/email_scan/social → user_scanner-1.1.0.6/user_scanner/email_scan/other}/__init__.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/user_scan/creator → user_scanner-1.1.0.6/user_scanner/email_scan/pipeline}/__init__.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/user_scan/donation → user_scanner-1.1.0.6/user_scanner/email_scan/shopping}/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/shopping/envato.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/shopping/flipkart.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/shopping/naturabuy.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/shopping/vivino.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/user_scan/gaming → user_scanner-1.1.0.6/user_scanner/email_scan/social}/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/social/facebook.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/social/instagram.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/social/mastodon.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/email_scan/social/x.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/community/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/community/coderlegion.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/community/hackernews.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/community/lemmy.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/community/stackoverflow.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/user_scan/shopping → user_scanner-1.1.0.6/user_scanner/user_scan/creator}/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/devto.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/gumroad.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/hashnode.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/itch_io.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/kaggle.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/medium.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/patreon.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/producthunt.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/substack.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/creator/twitch.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/bitbucket.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/codeberg.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/cratesio.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/dockerhub.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/github.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/gitlab.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/huggingface.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/launchpad.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/leetcode.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/npmjs.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/replit.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/dev/sourceforge.py +0 -0
- {user_scanner-1.1.0.4/user_scanner/utils → user_scanner-1.1.0.6/user_scanner/user_scan/donation}/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/donation/buymeacoffee.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/donation/liberapay.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/battlenet.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/chess_com.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/lichess.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/minecraft.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/monkeytype.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/osu.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/roblox.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/gaming/steam.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/shopping/vinted.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/__init__.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/bluesky.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/discord.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/instagram.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/mastodon.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/pinterest.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/reddit.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/snapchat.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/soundcloud.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/telegram.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/threads.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/tiktok.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/x.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/user_scan/social/youtube.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/utils/update.py +0 -0
- {user_scanner-1.1.0.4 → user_scanner-1.1.0.6}/user_scanner/utils/updater_logic.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: user-scanner
|
|
3
|
-
Version: 1.1.0.
|
|
3
|
+
Version: 1.1.0.6
|
|
4
4
|
Summary: Check username availability across multiple popular platforms
|
|
5
5
|
Keywords: username,checker,availability,social,tech,python,user-scanner
|
|
6
6
|
Author-email: Kaif <kafcodec@gmail.com>
|
|
@@ -16,7 +16,7 @@ Project-URL: Homepage, https://github.com/kaifcodec/user-scanner
|
|
|
16
16
|
|
|
17
17
|

|
|
18
18
|
<p align="center">
|
|
19
|
-
<img src="https://img.shields.io/badge/Version-1.1.0.
|
|
19
|
+
<img src="https://img.shields.io/badge/Version-1.1.0.6-blueviolet?style=for-the-badge&logo=github" />
|
|
20
20
|
<img src="https://img.shields.io/github/issues/kaifcodec/user-scanner?style=for-the-badge&logo=github" />
|
|
21
21
|
<img src="https://img.shields.io/badge/Tested%20on-Termux-black?style=for-the-badge&logo=termux" />
|
|
22
22
|
<img src="https://img.shields.io/badge/Tested%20on-Windows-cyan?style=for-the-badge&logo=Windows" />
|
|
@@ -34,23 +34,15 @@ Perfect for finding a **unique username** across GitHub, Twitter, Reddit, Instag
|
|
|
34
34
|
|
|
35
35
|
## Features
|
|
36
36
|
|
|
37
|
-
- ✅
|
|
38
|
-
- ✅
|
|
39
|
-
- ✅
|
|
40
|
-
- ✅
|
|
41
|
-
- ✅
|
|
42
|
-
- ✅
|
|
43
|
-
- ✅
|
|
44
|
-
- ✅
|
|
45
|
-
- ✅
|
|
46
|
-
- ✅ Save scanning and OSINT results in the preferred format and output file (ideal for power users).
|
|
47
|
-
- ✅ Command-line interface ready: works immediately after `pip install`.
|
|
48
|
-
- ✅ Lightweight with minimal dependencies; runs on any machine.
|
|
49
|
-
- ✅ **Proxy support** with round-robin rotation
|
|
50
|
-
- ✅ **Proxy validation** to test and filter working proxies before scanning
|
|
51
|
-
- ✅ **Bulk username scanning** from file support for checking multiple usernames at once
|
|
52
|
-
- ✅ **Bulk email scanning** from file support for checking multiple emails at once
|
|
53
|
-
---
|
|
37
|
+
- ✅ Email & username OSINT: check email registrations and username availability across social, developer, creator, and other platforms
|
|
38
|
+
- ✅ Dual-mode usage: works as an email scanner, username scanner, or username-only tool
|
|
39
|
+
- ✅ Clear results: `Registered` / `Not Registered` for emails and `Available` / `Taken` / `Error` for usernames with precise failure reasons
|
|
40
|
+
- ✅ Fully modular architecture for easy addition of new platform modules
|
|
41
|
+
- ✅ Bulk scanning support for usernames and emails via input files
|
|
42
|
+
- ✅ Wildcard-based username permutations with automatic variation generation
|
|
43
|
+
- ✅ Multiple output formats: console, **JSON**, and **CSV**, with file export support
|
|
44
|
+
- ✅ Proxy support with rotation and pre-scan proxy validation
|
|
45
|
+
- ✅ Smart auto-update system with interactive upgrade prompts via PyPI
|
|
54
46
|
|
|
55
47
|
## Virtual Environment (optional but recommended)
|
|
56
48
|
|
|
@@ -102,14 +94,11 @@ pip install user-scanner
|
|
|
102
94
|
|
|
103
95
|
### Basic username/email scan
|
|
104
96
|
|
|
105
|
-
Scan a single username across **all** available modules/platforms:
|
|
97
|
+
Scan a single email or username across **all** available modules/platforms:
|
|
106
98
|
|
|
107
99
|
```bash
|
|
108
|
-
user-scanner -e john_doe@gmail.com
|
|
109
|
-
user-scanner
|
|
110
|
-
|
|
111
|
-
user-scanner -u john_doe
|
|
112
|
-
user-scanner --username john_doe # long version
|
|
100
|
+
user-scanner -e john_doe@gmail.com # single email scanning
|
|
101
|
+
user-scanner -u john_doe # single username scanning
|
|
113
102
|
```
|
|
114
103
|
|
|
115
104
|
### Selective scanning
|
|
@@ -121,23 +110,14 @@ user-scanner -u john_doe -c dev # developer platforms only
|
|
|
121
110
|
user-scanner -u john_doe -m github # only GitHub
|
|
122
111
|
```
|
|
123
112
|
|
|
124
|
-
### Bulk username scanning
|
|
113
|
+
### Bulk email/username scanning
|
|
125
114
|
|
|
126
|
-
Scan multiple usernames from a file (one username per line):
|
|
127
|
-
- Can also be combined with categories or modules using `-c`
|
|
115
|
+
Scan multiple emails/usernames from a file (one email/username per line):
|
|
116
|
+
- Can also be combined with categories or modules using `-c` , `-m` and other flags
|
|
128
117
|
|
|
129
118
|
```bash
|
|
130
|
-
user-scanner -
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
### Bulk email scanning
|
|
135
|
-
|
|
136
|
-
Scan multiple emails from a file (one email per line):
|
|
137
|
-
- Can also be combined with categories or modules using `-c` and `-m` flags
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
user-scanner -ef emails.txt
|
|
119
|
+
user-scanner -ef emails.txt # bulk email scan
|
|
120
|
+
user-scanner -uf usernames.txt # bulk username scan
|
|
141
121
|
```
|
|
142
122
|
|
|
143
123
|
### Username/Email variations (suffix only)
|
|
@@ -163,37 +143,22 @@ user-scanner -u john_doe -P proxies.txt --validate-proxies # recommended
|
|
|
163
143
|
```
|
|
164
144
|
|
|
165
145
|
This will:
|
|
166
|
-
1.
|
|
167
|
-
2.
|
|
168
|
-
3.
|
|
169
|
-
4. Use only validated proxies for scanning
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
### Update
|
|
174
|
-
|
|
175
|
-
Update the tool to the latest PyPI version:
|
|
146
|
+
1. Filter out non-working proxies
|
|
147
|
+
2. Save working proxies to `validated_proxies.txt`
|
|
148
|
+
3. Use only validated proxies for scanning
|
|
176
149
|
|
|
177
|
-
```bash
|
|
178
|
-
user-scanner -U
|
|
179
|
-
```
|
|
180
150
|
---
|
|
181
151
|
|
|
182
|
-
##
|
|
152
|
+
## Screenshots:
|
|
183
153
|
|
|
184
|
-
- Note*: New modules are constantly getting added so
|
|
154
|
+
- Note*: New modules are constantly getting added so screenshots might show only limited, outdated output:
|
|
185
155
|
|
|
186
|
-
<img width="1080" height="
|
|
156
|
+
<img width="1080" height="800" alt="1000146237" src="https://github.com/user-attachments/assets/1bb7d7cb-9b78-495a-ae95-01a9ef48d9a2" />
|
|
187
157
|
|
|
188
158
|
---
|
|
189
159
|
|
|
190
160
|
<img width="1072" height="848" alt="user-scanner's main usage screenshot" src="https://github.com/user-attachments/assets/34e44ca6-e314-419e-9035-d951b493b47f" />
|
|
191
161
|
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
<img width="1080" height="352" alt="user-scanner's wildcard username feature" src="https://github.com/user-attachments/assets/578b248c-2a05-4917-aab3-6372a7c28045" />
|
|
195
|
-
|
|
196
|
-
|
|
197
162
|
---
|
|
198
163
|
|
|
199
164
|
## Contributing
|
|
@@ -212,8 +177,7 @@ user_scanner/
|
|
|
212
177
|
│ ├── creator/ # Creator platforms (Hashnode, Dev.to, Medium, Patreon, etc.)
|
|
213
178
|
│ ├── community/ # Community platforms (forums, StackOverflow, HackerNews, etc.)
|
|
214
179
|
│ ├── gaming/ # Gaming sites (chess.com, Lichess, Roblox, Minecraft, etc.)
|
|
215
|
-
|
|
216
|
-
|...
|
|
180
|
+
...
|
|
217
181
|
```
|
|
218
182
|
|
|
219
183
|
**Module guidelines:**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
<p align="center">
|
|
5
|
-
<img src="https://img.shields.io/badge/Version-1.1.0.
|
|
5
|
+
<img src="https://img.shields.io/badge/Version-1.1.0.6-blueviolet?style=for-the-badge&logo=github" />
|
|
6
6
|
<img src="https://img.shields.io/github/issues/kaifcodec/user-scanner?style=for-the-badge&logo=github" />
|
|
7
7
|
<img src="https://img.shields.io/badge/Tested%20on-Termux-black?style=for-the-badge&logo=termux" />
|
|
8
8
|
<img src="https://img.shields.io/badge/Tested%20on-Windows-cyan?style=for-the-badge&logo=Windows" />
|
|
@@ -20,23 +20,15 @@ Perfect for finding a **unique username** across GitHub, Twitter, Reddit, Instag
|
|
|
20
20
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
23
|
-
- ✅
|
|
24
|
-
- ✅
|
|
25
|
-
- ✅
|
|
26
|
-
- ✅
|
|
27
|
-
- ✅
|
|
28
|
-
- ✅
|
|
29
|
-
- ✅
|
|
30
|
-
- ✅
|
|
31
|
-
- ✅
|
|
32
|
-
- ✅ Save scanning and OSINT results in the preferred format and output file (ideal for power users).
|
|
33
|
-
- ✅ Command-line interface ready: works immediately after `pip install`.
|
|
34
|
-
- ✅ Lightweight with minimal dependencies; runs on any machine.
|
|
35
|
-
- ✅ **Proxy support** with round-robin rotation
|
|
36
|
-
- ✅ **Proxy validation** to test and filter working proxies before scanning
|
|
37
|
-
- ✅ **Bulk username scanning** from file support for checking multiple usernames at once
|
|
38
|
-
- ✅ **Bulk email scanning** from file support for checking multiple emails at once
|
|
39
|
-
---
|
|
23
|
+
- ✅ Email & username OSINT: check email registrations and username availability across social, developer, creator, and other platforms
|
|
24
|
+
- ✅ Dual-mode usage: works as an email scanner, username scanner, or username-only tool
|
|
25
|
+
- ✅ Clear results: `Registered` / `Not Registered` for emails and `Available` / `Taken` / `Error` for usernames with precise failure reasons
|
|
26
|
+
- ✅ Fully modular architecture for easy addition of new platform modules
|
|
27
|
+
- ✅ Bulk scanning support for usernames and emails via input files
|
|
28
|
+
- ✅ Wildcard-based username permutations with automatic variation generation
|
|
29
|
+
- ✅ Multiple output formats: console, **JSON**, and **CSV**, with file export support
|
|
30
|
+
- ✅ Proxy support with rotation and pre-scan proxy validation
|
|
31
|
+
- ✅ Smart auto-update system with interactive upgrade prompts via PyPI
|
|
40
32
|
|
|
41
33
|
## Virtual Environment (optional but recommended)
|
|
42
34
|
|
|
@@ -88,14 +80,11 @@ pip install user-scanner
|
|
|
88
80
|
|
|
89
81
|
### Basic username/email scan
|
|
90
82
|
|
|
91
|
-
Scan a single username across **all** available modules/platforms:
|
|
83
|
+
Scan a single email or username across **all** available modules/platforms:
|
|
92
84
|
|
|
93
85
|
```bash
|
|
94
|
-
user-scanner -e john_doe@gmail.com
|
|
95
|
-
user-scanner
|
|
96
|
-
|
|
97
|
-
user-scanner -u john_doe
|
|
98
|
-
user-scanner --username john_doe # long version
|
|
86
|
+
user-scanner -e john_doe@gmail.com # single email scanning
|
|
87
|
+
user-scanner -u john_doe # single username scanning
|
|
99
88
|
```
|
|
100
89
|
|
|
101
90
|
### Selective scanning
|
|
@@ -107,23 +96,14 @@ user-scanner -u john_doe -c dev # developer platforms only
|
|
|
107
96
|
user-scanner -u john_doe -m github # only GitHub
|
|
108
97
|
```
|
|
109
98
|
|
|
110
|
-
### Bulk username scanning
|
|
99
|
+
### Bulk email/username scanning
|
|
111
100
|
|
|
112
|
-
Scan multiple usernames from a file (one username per line):
|
|
113
|
-
- Can also be combined with categories or modules using `-c`
|
|
101
|
+
Scan multiple emails/usernames from a file (one email/username per line):
|
|
102
|
+
- Can also be combined with categories or modules using `-c` , `-m` and other flags
|
|
114
103
|
|
|
115
104
|
```bash
|
|
116
|
-
user-scanner -
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
### Bulk email scanning
|
|
121
|
-
|
|
122
|
-
Scan multiple emails from a file (one email per line):
|
|
123
|
-
- Can also be combined with categories or modules using `-c` and `-m` flags
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
user-scanner -ef emails.txt
|
|
105
|
+
user-scanner -ef emails.txt # bulk email scan
|
|
106
|
+
user-scanner -uf usernames.txt # bulk username scan
|
|
127
107
|
```
|
|
128
108
|
|
|
129
109
|
### Username/Email variations (suffix only)
|
|
@@ -149,37 +129,22 @@ user-scanner -u john_doe -P proxies.txt --validate-proxies # recommended
|
|
|
149
129
|
```
|
|
150
130
|
|
|
151
131
|
This will:
|
|
152
|
-
1.
|
|
153
|
-
2.
|
|
154
|
-
3.
|
|
155
|
-
4. Use only validated proxies for scanning
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
### Update
|
|
160
|
-
|
|
161
|
-
Update the tool to the latest PyPI version:
|
|
132
|
+
1. Filter out non-working proxies
|
|
133
|
+
2. Save working proxies to `validated_proxies.txt`
|
|
134
|
+
3. Use only validated proxies for scanning
|
|
162
135
|
|
|
163
|
-
```bash
|
|
164
|
-
user-scanner -U
|
|
165
|
-
```
|
|
166
136
|
---
|
|
167
137
|
|
|
168
|
-
##
|
|
138
|
+
## Screenshots:
|
|
169
139
|
|
|
170
|
-
- Note*: New modules are constantly getting added so
|
|
140
|
+
- Note*: New modules are constantly getting added so screenshots might show only limited, outdated output:
|
|
171
141
|
|
|
172
|
-
<img width="1080" height="
|
|
142
|
+
<img width="1080" height="800" alt="1000146237" src="https://github.com/user-attachments/assets/1bb7d7cb-9b78-495a-ae95-01a9ef48d9a2" />
|
|
173
143
|
|
|
174
144
|
---
|
|
175
145
|
|
|
176
146
|
<img width="1072" height="848" alt="user-scanner's main usage screenshot" src="https://github.com/user-attachments/assets/34e44ca6-e314-419e-9035-d951b493b47f" />
|
|
177
147
|
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
<img width="1080" height="352" alt="user-scanner's wildcard username feature" src="https://github.com/user-attachments/assets/578b248c-2a05-4917-aab3-6372a7c28045" />
|
|
181
|
-
|
|
182
|
-
|
|
183
148
|
---
|
|
184
149
|
|
|
185
150
|
## Contributing
|
|
@@ -198,8 +163,7 @@ user_scanner/
|
|
|
198
163
|
│ ├── creator/ # Creator platforms (Hashnode, Dev.to, Medium, Patreon, etc.)
|
|
199
164
|
│ ├── community/ # Community platforms (forums, StackOverflow, HackerNews, etc.)
|
|
200
165
|
│ ├── gaming/ # Gaming sites (chess.com, Lichess, Roblox, Minecraft, etc.)
|
|
201
|
-
|
|
202
|
-
|...
|
|
166
|
+
...
|
|
203
167
|
```
|
|
204
168
|
|
|
205
169
|
**Module guidelines:**
|
|
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "user-scanner"
|
|
7
|
-
version = "1.1.0.
|
|
7
|
+
version = "1.1.0.6"
|
|
8
8
|
description = "Check username availability across multiple popular platforms"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {file = "LICENSE"}
|
|
@@ -27,8 +27,24 @@ Homepage = "https://github.com/kaifcodec/user-scanner"
|
|
|
27
27
|
[project.scripts]
|
|
28
28
|
user-scanner = "user_scanner.__main__:main"
|
|
29
29
|
|
|
30
|
+
[tool.flit.module]
|
|
31
|
+
name = "user_scanner"
|
|
32
|
+
|
|
30
33
|
[tool.flit.sdist]
|
|
31
|
-
exclude = [
|
|
34
|
+
exclude = [
|
|
35
|
+
"tests/",
|
|
36
|
+
"docs/",
|
|
37
|
+
".github/",
|
|
38
|
+
".git",
|
|
39
|
+
".gitignore",
|
|
40
|
+
".ruff_cache/",
|
|
41
|
+
"**/.ruff_cache/**",
|
|
42
|
+
"__pycache__/",
|
|
43
|
+
"**/__pycache__/**",
|
|
44
|
+
"*.pyc",
|
|
45
|
+
"rm_pycache.py",
|
|
46
|
+
"che.py"
|
|
47
|
+
]
|
|
32
48
|
|
|
33
49
|
[tool.pytest.ini_options]
|
|
34
50
|
pythonpath = "."
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
headers = {
|
|
7
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
8
|
+
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
|
9
|
+
'Accept-Language': "en-US,en;q=0.9",
|
|
10
|
+
'Referer': "https://leetcode.com/accounts/login/",
|
|
11
|
+
'Origin': "https://leetcode.com",
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
async with httpx.AsyncClient(timeout=5.0, follow_redirects=True) as client:
|
|
16
|
+
await client.get("https://leetcode.com/accounts/login/", headers=headers)
|
|
17
|
+
csrf_token = client.cookies.get("csrftoken")
|
|
18
|
+
|
|
19
|
+
if not csrf_token:
|
|
20
|
+
return Result.error("CSRF token not found, possible rate-limit")
|
|
21
|
+
|
|
22
|
+
headers.update({
|
|
23
|
+
'x-requested-with': "XMLHttpRequest",
|
|
24
|
+
'referer': "https://leetcode.com/accounts/password/reset/",
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
payload = {
|
|
28
|
+
'next': 'undefined',
|
|
29
|
+
'userName': '',
|
|
30
|
+
'email': email,
|
|
31
|
+
'csrfmiddlewaretoken': csrf_token
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
response = await client.post(
|
|
35
|
+
"https://leetcode.com/accounts/password/reset/",
|
|
36
|
+
headers=headers,
|
|
37
|
+
data=payload
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if response.status_code in [200, 400]:
|
|
41
|
+
data = response.json()
|
|
42
|
+
|
|
43
|
+
if data.get("location") == "/accounts/password/reset/done/":
|
|
44
|
+
return Result.taken()
|
|
45
|
+
|
|
46
|
+
email_field = data.get("form", {}).get(
|
|
47
|
+
"fields", {}).get("email", {})
|
|
48
|
+
errors = email_field.get("errors", [])
|
|
49
|
+
|
|
50
|
+
if any("not assigned to any user account" in err for err in errors):
|
|
51
|
+
return Result.available()
|
|
52
|
+
|
|
53
|
+
return Result.error("Unexpected response data")
|
|
54
|
+
|
|
55
|
+
return Result.error(f"HTTP {response.status_code}")
|
|
56
|
+
|
|
57
|
+
except httpx.TimeoutException:
|
|
58
|
+
return Result.error("Connection timed out")
|
|
59
|
+
except Exception as e:
|
|
60
|
+
return Result.error(e)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
async def validate_leetcode(email: str) -> Result:
|
|
64
|
+
return await _check(email)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
async def _check(email: str) -> Result:
|
|
5
|
+
headers = {
|
|
6
|
+
'authority': 'www.duolingo.com',
|
|
7
|
+
'Accept': 'application/json, text/plain, */*',
|
|
8
|
+
'Accept-Language': 'en-US,en;q=0.9',
|
|
9
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0",
|
|
10
|
+
'Referer': 'https://www.duolingo.com/',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
async with httpx.AsyncClient(timeout=5.0, follow_redirects=True) as client:
|
|
15
|
+
response = await client.get(
|
|
16
|
+
f"https://www.duolingo.com/2017-06-30/users?email={email}",
|
|
17
|
+
headers=headers
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if response.status_code == 200:
|
|
21
|
+
data = response.json()
|
|
22
|
+
# Duolingo returns a list of users matching the email
|
|
23
|
+
if data.get("users") and len(data["users"]) > 0:
|
|
24
|
+
return Result.taken()
|
|
25
|
+
else:
|
|
26
|
+
return Result.available()
|
|
27
|
+
|
|
28
|
+
return Result.error(f"HTTP {response.status_code}")
|
|
29
|
+
|
|
30
|
+
except httpx.TimeoutException:
|
|
31
|
+
return Result.error("Connection timed out")
|
|
32
|
+
except Exception as e:
|
|
33
|
+
return Result.error(e)
|
|
34
|
+
|
|
35
|
+
async def validate_duolingo(email: str) -> Result:
|
|
36
|
+
return await _check(email)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
headers = {
|
|
7
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
8
|
+
'Accept': '*/*',
|
|
9
|
+
'Accept-Language': 'en,en-US;q=0.9',
|
|
10
|
+
'Referer': 'https://www.eventbrite.com/signin/',
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
13
|
+
'Origin': 'https://www.eventbrite.com',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
async with httpx.AsyncClient(timeout=5.0, follow_redirects=True) as client:
|
|
18
|
+
await client.get("https://www.eventbrite.com/signin/", headers=headers)
|
|
19
|
+
|
|
20
|
+
csrf_token = client.cookies.get("csrftoken")
|
|
21
|
+
if not csrf_token:
|
|
22
|
+
return Result.error("CSRF token not found")
|
|
23
|
+
|
|
24
|
+
headers["X-CSRFToken"] = csrf_token
|
|
25
|
+
payload = {"email": email}
|
|
26
|
+
|
|
27
|
+
response = await client.post(
|
|
28
|
+
'https://www.eventbrite.com/api/v3/users/lookup/',
|
|
29
|
+
headers=headers,
|
|
30
|
+
json=payload
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if response.status_code == 200:
|
|
34
|
+
data = response.json()
|
|
35
|
+
if data.get("exists") is True:
|
|
36
|
+
return Result.taken()
|
|
37
|
+
elif data.get("exists") is False:
|
|
38
|
+
return Result.available()
|
|
39
|
+
else:
|
|
40
|
+
return Result.error(data)
|
|
41
|
+
|
|
42
|
+
return Result.error(f"HTTP {response.status_code}")
|
|
43
|
+
|
|
44
|
+
except httpx.TimeoutException:
|
|
45
|
+
return Result.error("Connection timed out")
|
|
46
|
+
except Exception as e:
|
|
47
|
+
return Result.error(e)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def validate_eventbrite(email: str) -> Result:
|
|
51
|
+
return await _check(email)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
headers = {
|
|
7
|
+
'authority': 'axonaut.com',
|
|
8
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
9
|
+
'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.9',
|
|
10
|
+
'referer': 'https://axonaut.com/en',
|
|
11
|
+
'accept-language': 'en-US,en;q=0.9',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
async with httpx.AsyncClient(timeout=5.0, follow_redirects=False) as client:
|
|
16
|
+
response = await client.get(
|
|
17
|
+
f'https://axonaut.com/onboarding/?email={email}',
|
|
18
|
+
headers=headers
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
if response.status_code == 302 and "/login?email" in response.headers.get('Location', ''):
|
|
22
|
+
|
|
23
|
+
return Result.taken()
|
|
24
|
+
|
|
25
|
+
elif response.status_code == 200:
|
|
26
|
+
return Result.available()
|
|
27
|
+
|
|
28
|
+
else:
|
|
29
|
+
return Result.error(f"HTTP {response.status_code}")
|
|
30
|
+
|
|
31
|
+
except httpx.TimeoutException:
|
|
32
|
+
return Result.error("Connection timed out")
|
|
33
|
+
except Exception as e:
|
|
34
|
+
return Result.error(str(e))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async def validate_axonaut(email: str) -> Result:
|
|
38
|
+
return await _check(email)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
headers = {
|
|
7
|
+
'authority': 'api.hubspot.com',
|
|
8
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
9
|
+
'content-type': 'application/json',
|
|
10
|
+
'origin': 'https://app.hubspot.com',
|
|
11
|
+
'referer': 'https://app.hubspot.com/',
|
|
12
|
+
'accept-language': 'en-US,en;q=0.9',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
async with httpx.AsyncClient(timeout=5.0, follow_redirects=True) as client:
|
|
17
|
+
payload = {
|
|
18
|
+
"email": email,
|
|
19
|
+
"password": "",
|
|
20
|
+
"rememberLogin": False
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
response = await client.post(
|
|
24
|
+
'https://api.hubspot.com/login-api/v1/login',
|
|
25
|
+
headers=headers,
|
|
26
|
+
json=payload
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# HubSpot returns 400 for both "wrong password" and "user not found"
|
|
30
|
+
if response.status_code == 400:
|
|
31
|
+
data = response.json()
|
|
32
|
+
status = data.get("status")
|
|
33
|
+
|
|
34
|
+
if status == "INVALID_PASSWORD":
|
|
35
|
+
return Result.taken()
|
|
36
|
+
|
|
37
|
+
elif status == "INVALID_USER":
|
|
38
|
+
return Result.available()
|
|
39
|
+
|
|
40
|
+
else:
|
|
41
|
+
return Result.error(data)
|
|
42
|
+
|
|
43
|
+
return Result.error(f"HTTP {response.status_code}")
|
|
44
|
+
|
|
45
|
+
except httpx.TimeoutException:
|
|
46
|
+
return Result.error("Connection timed out")
|
|
47
|
+
except Exception as e:
|
|
48
|
+
return Result.error(str(e))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
async def validate_hubspot(email: str) -> Result:
|
|
52
|
+
return await _check(email)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from user_scanner.core.result import Result
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
async def _check(email: str) -> Result:
|
|
6
|
+
headers = {
|
|
7
|
+
'authority': 'accounts.insightly.com',
|
|
8
|
+
'accept': 'application/json, text/javascript, */*; q=0.01',
|
|
9
|
+
'x-requested-with': 'XMLHttpRequest',
|
|
10
|
+
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
|
|
11
|
+
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
12
|
+
'origin': 'https://accounts.insightly.com',
|
|
13
|
+
'referer': 'https://accounts.insightly.com/?plan=trial',
|
|
14
|
+
'accept-language': 'en-US,en;q=0.9',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
async with httpx.AsyncClient(timeout=5.0, follow_redirects=True) as client:
|
|
19
|
+
payload = {'emailaddress': email}
|
|
20
|
+
|
|
21
|
+
response = await client.post(
|
|
22
|
+
'https://accounts.insightly.com/signup/isemailvalid',
|
|
23
|
+
headers=headers,
|
|
24
|
+
data=payload
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if "An account exists for this address." in response.text:
|
|
28
|
+
return Result.taken()
|
|
29
|
+
|
|
30
|
+
elif response.text.strip() == "true":
|
|
31
|
+
return Result.available()
|
|
32
|
+
|
|
33
|
+
else:
|
|
34
|
+
return Result.error(f"Unexpected response: {response.status_code}")
|
|
35
|
+
|
|
36
|
+
except httpx.TimeoutException:
|
|
37
|
+
return Result.error("Connection timed out")
|
|
38
|
+
except Exception as e:
|
|
39
|
+
return Result.error(str(e))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
async def validate_insightly(email: str) -> Result:
|
|
43
|
+
return await _check(email)
|