210 lines
6.5 KiB
Python
Executable File
210 lines
6.5 KiB
Python
Executable File
# discord_tools/scripts/token_validator.py
|
|
import os
|
|
import sys
|
|
import requests
|
|
from datetime import datetime
|
|
|
|
# Add the parent directory to the Python path
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
project_root = os.path.dirname(os.path.dirname(script_dir))
|
|
sys.path.insert(0, project_root)
|
|
|
|
from discord_tools.config.settings import DISCORD_API_BASE_URL
|
|
|
|
def validate_token(token):
|
|
# Check if a Discord token is valid
|
|
url = f"{DISCORD_API_BASE_URL}/users/@me"
|
|
headers = {
|
|
"Authorization": token,
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
try:
|
|
response = requests.get(url, headers=headers)
|
|
|
|
if response.status_code == 200:
|
|
user_data = response.json()
|
|
return {
|
|
'valid': True,
|
|
'user_id': user_data['id'],
|
|
'username': user_data['username'],
|
|
'discriminator': user_data.get('discriminator', '0'),
|
|
'email': user_data.get('email', 'N/A'),
|
|
'verified': user_data.get('verified', False),
|
|
'mfa_enabled': user_data.get('mfa_enabled', False),
|
|
'flags': user_data.get('flags', 0),
|
|
'premium_type': user_data.get('premium_type', 0),
|
|
'phone': user_data.get('phone', 'N/A')
|
|
}
|
|
elif response.status_code == 401:
|
|
return {'valid': False, 'error': 'Invalid token'}
|
|
elif response.status_code == 403:
|
|
return {'valid': False, 'error': 'Token is valid but locked/disabled'}
|
|
else:
|
|
return {'valid': False, 'error': f'HTTP {response.status_code}'}
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
return {'valid': False, 'error': f'Request failed: {str(e)}'}
|
|
|
|
def get_token_type(token):
|
|
# Determine what kind of token it is
|
|
if token.startswith('mfa.'):
|
|
return 'MFA Token'
|
|
elif token.startswith('Bot '):
|
|
return 'Bot Token'
|
|
elif '.' in token:
|
|
# User tokens typically have format: base64.base64.base64
|
|
parts = token.split('.')
|
|
if len(parts) == 3:
|
|
return 'User Token'
|
|
return 'Unknown'
|
|
|
|
def print_token_info(result, token):
|
|
# Print info about a token
|
|
print("\n" + "=" * 60)
|
|
|
|
if result['valid']:
|
|
print("✓ TOKEN IS VALID")
|
|
print("=" * 60)
|
|
print(f"Type: {get_token_type(token)}")
|
|
print(f"User ID: {result['user_id']}")
|
|
print(f"Username: {result['username']}#{result['discriminator']}")
|
|
print(f"Email: {result['email']}")
|
|
print(f"Verified: {result['verified']}")
|
|
print(f"MFA Enabled: {result['mfa_enabled']}")
|
|
print(f"Phone: {result['phone']}")
|
|
|
|
# Decode premium type
|
|
premium_types = {
|
|
0: 'None',
|
|
1: 'Nitro Classic',
|
|
2: 'Nitro',
|
|
3: 'Nitro Basic'
|
|
}
|
|
print(f"Premium: {premium_types.get(result['premium_type'], 'Unknown')}")
|
|
else:
|
|
print("✗ TOKEN IS INVALID")
|
|
print("=" * 60)
|
|
print(f"Type: {get_token_type(token)}")
|
|
print(f"Error: {result['error']}")
|
|
|
|
print("=" * 60)
|
|
|
|
def validate_tokens_from_file(filepath):
|
|
# Validate multiple tokens from a file
|
|
if not os.path.exists(filepath):
|
|
print(f"File not found: {filepath}")
|
|
return
|
|
|
|
with open(filepath, 'r') as f:
|
|
tokens = [line.strip() for line in f if line.strip()]
|
|
|
|
print(f"Validating {len(tokens)} tokens from {filepath}...")
|
|
|
|
valid_count = 0
|
|
invalid_count = 0
|
|
|
|
results = []
|
|
|
|
for i, token in enumerate(tokens, 1):
|
|
print(f"\n[{i}/{len(tokens)}] Checking token...")
|
|
result = validate_token(token)
|
|
|
|
if result['valid']:
|
|
valid_count += 1
|
|
status = "VALID"
|
|
else:
|
|
invalid_count += 1
|
|
status = "INVALID"
|
|
|
|
results.append({
|
|
'token': token,
|
|
'status': status,
|
|
'result': result
|
|
})
|
|
|
|
print_token_info(result, token)
|
|
|
|
# Summary
|
|
print("\n" + "=" * 60)
|
|
print("SUMMARY")
|
|
print("=" * 60)
|
|
print(f"Total Tokens: {len(tokens)}")
|
|
print(f"Valid: {valid_count}")
|
|
print(f"Invalid: {invalid_count}")
|
|
print("=" * 60)
|
|
|
|
# Save results
|
|
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
|
output_file = f"token_validation_{timestamp}.txt"
|
|
|
|
with open(output_file, 'w') as f:
|
|
f.write(f"Token Validation Results\n")
|
|
f.write(f"Validated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
|
f.write(f"Total: {len(tokens)} | Valid: {valid_count} | Invalid: {invalid_count}\n")
|
|
f.write("=" * 80 + "\n\n")
|
|
|
|
for i, item in enumerate(results, 1):
|
|
f.write(f"[{i}] {item['status']}\n")
|
|
f.write(f"Token: {item['token'][:20]}...{item['token'][-10:]}\n")
|
|
|
|
if item['result']['valid']:
|
|
f.write(f"User: {item['result']['username']}#{item['result']['discriminator']}\n")
|
|
f.write(f"ID: {item['result']['user_id']}\n")
|
|
else:
|
|
f.write(f"Error: {item['result']['error']}\n")
|
|
|
|
f.write("\n")
|
|
|
|
print(f"\nResults saved to: {output_file}")
|
|
|
|
def validate_env_token():
|
|
# Check the token from the .env file
|
|
try:
|
|
from discord_tools.config.settings import DISCORD_TOKEN
|
|
|
|
if not DISCORD_TOKEN:
|
|
print("No token found in .env file")
|
|
return
|
|
|
|
print("\nValidating token from .env file...")
|
|
result = validate_token(DISCORD_TOKEN)
|
|
print_token_info(result, DISCORD_TOKEN)
|
|
|
|
except Exception as e:
|
|
print(f"Failed to load token from .env: {e}")
|
|
|
|
def main():
|
|
print("Discord Token Validator")
|
|
print("=" * 60)
|
|
print("1. Validate single token")
|
|
print("2. Validate tokens from file")
|
|
print("3. Validate token from .env")
|
|
print("=" * 60)
|
|
|
|
choice = input("Choice: ").strip()
|
|
|
|
if choice == '1':
|
|
token = input("\nEnter Discord token: ").strip()
|
|
|
|
if not token:
|
|
print("No token provided")
|
|
return
|
|
|
|
print("\nValidating token...")
|
|
result = validate_token(token)
|
|
print_token_info(result, token)
|
|
|
|
elif choice == '2':
|
|
filepath = input("\nEnter path to tokens file (one token per line): ").strip()
|
|
validate_tokens_from_file(filepath)
|
|
|
|
elif choice == '3':
|
|
validate_env_token()
|
|
|
|
else:
|
|
print("Invalid choice")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|