tokenade 3.5.0__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.
- tokenade/__init__.py +84 -0
- tokenade/cli/__init__.py +306 -0
- tokenade/cli/__main__.py +5 -0
- tokenade/cli/advanced.py +458 -0
- tokenade/cli/completions.py +73 -0
- tokenade/cli/config.py +47 -0
- tokenade/cli/management.py +264 -0
- tokenade/cli/output.py +31 -0
- tokenade/cli/proxy.py +118 -0
- tokenade/cli/security.py +156 -0
- tokenade/cli/session.py +471 -0
- tokenade/core/__init__.py +0 -0
- tokenade/core/antidetection/__init__.py +4 -0
- tokenade/core/antidetection/behavioral.py +140 -0
- tokenade/core/antidetection/cdp_cleaner.py +60 -0
- tokenade/core/api/__init__.py +3 -0
- tokenade/core/api/server.py +251 -0
- tokenade/core/batch/__init__.py +23 -0
- tokenade/core/batch/operations.py +399 -0
- tokenade/core/browser/__init__.py +0 -0
- tokenade/core/browser/manager.py +311 -0
- tokenade/core/crypto/__init__.py +19 -0
- tokenade/core/crypto/cookie_crypto.py +506 -0
- tokenade/core/crypto/encryptor.py +299 -0
- tokenade/core/extractor/__init__.py +0 -0
- tokenade/core/fingerprint/__init__.py +0 -0
- tokenade/core/fingerprint/collectors/__init__.py +30 -0
- tokenade/core/fingerprint/collectors/audio.py +124 -0
- tokenade/core/fingerprint/collectors/base.py +69 -0
- tokenade/core/fingerprint/collectors/battery.py +59 -0
- tokenade/core/fingerprint/collectors/canvas.py +81 -0
- tokenade/core/fingerprint/collectors/fonts.py +52 -0
- tokenade/core/fingerprint/collectors/navigator.py +99 -0
- tokenade/core/fingerprint/collectors/plugins.py +92 -0
- tokenade/core/fingerprint/collectors/screen.py +81 -0
- tokenade/core/fingerprint/collectors/webgl.py +104 -0
- tokenade/core/fingerprint/collectors/webrtc.py +91 -0
- tokenade/core/fingerprint/injector.py +94 -0
- tokenade/core/fingerprint/manager.py +278 -0
- tokenade/core/fingerprint/stealth.py +357 -0
- tokenade/core/importer/__init__.py +23 -0
- tokenade/core/importer/adb_extractor.py +261 -0
- tokenade/core/importer/advanced_validator.py +666 -0
- tokenade/core/importer/browser_discovery.py +314 -0
- tokenade/core/importer/chromium_forks.py +175 -0
- tokenade/core/importer/cookie_extractor.py +517 -0
- tokenade/core/importer/db_utils.py +66 -0
- tokenade/core/importer/format_exporter.py +213 -0
- tokenade/core/importer/format_importer.py +278 -0
- tokenade/core/importer/local_storage_extractor.py +272 -0
- tokenade/core/importer/mobile_extractor.py +264 -0
- tokenade/core/importer/safari_extractor.py +318 -0
- tokenade/core/importer/session_comparator.py +124 -0
- tokenade/core/importer/session_loader.py +470 -0
- tokenade/core/importer/session_manager.py +295 -0
- tokenade/core/importer/session_packager.py +354 -0
- tokenade/core/importer/session_refresher.py +354 -0
- tokenade/core/importer/session_rotation.py +150 -0
- tokenade/core/importer/session_sharer.py +692 -0
- tokenade/core/importer/session_vault.py +282 -0
- tokenade/core/importer/tor_extractor.py +138 -0
- tokenade/core/importer/validator.py +498 -0
- tokenade/core/injector/__init__.py +15 -0
- tokenade/core/injector/profile_manager.py +375 -0
- tokenade/core/integration/__init__.py +8 -0
- tokenade/core/integration/docker_manager.py +349 -0
- tokenade/core/integration/kubernetes.py +395 -0
- tokenade/core/integration/plugin_registry.py +250 -0
- tokenade/core/integration/webhooks.py +219 -0
- tokenade/core/proxy/__init__.py +11 -0
- tokenade/core/proxy/cdp_proxy.py +1301 -0
- tokenade/core/proxy/extension_bridge.py +132 -0
- tokenade/core/proxy/forward_proxy.py +151 -0
- tokenade/core/proxy/multi_site_proxy.py +257 -0
- tokenade/core/proxy/server.py +1295 -0
- tokenade/core/refresh/__init__.py +19 -0
- tokenade/core/refresh/health_checker.py +356 -0
- tokenade/core/refresh/health_scorer.py +292 -0
- tokenade/core/runtime/__init__.py +30 -0
- tokenade/core/runtime/engine.py +786 -0
- tokenade/core/runtime/tls_matcher.py +251 -0
- tokenade/core/security/__init__.py +27 -0
- tokenade/core/security/audit.py +577 -0
- tokenade/core/security/credentials.py +418 -0
- tokenade/core/utils/__init__.py +0 -0
- tokenade/core/utils/performance.py +444 -0
- tokenade/handlers/__init__.py +0 -0
- tokenade/handlers/base.py +294 -0
- tokenade/handlers/generic_oauth.py +594 -0
- tokenade/handlers/github.py +349 -0
- tokenade/handlers/google.py +302 -0
- tokenade/sdk/__init__.py +257 -0
- tokenade/tests/__init__.py +0 -0
- tokenade/tests/portability.py +309 -0
- tokenade/tests/test_advanced_validator.py +237 -0
- tokenade/tests/test_antidetection.py +147 -0
- tokenade/tests/test_api_sdk.py +264 -0
- tokenade/tests/test_benchmarks.py +157 -0
- tokenade/tests/test_browser.py +351 -0
- tokenade/tests/test_browser_discovery.py +59 -0
- tokenade/tests/test_browser_improvements.py +276 -0
- tokenade/tests/test_browser_support.py +732 -0
- tokenade/tests/test_cli.py +204 -0
- tokenade/tests/test_cli_helpers.py +102 -0
- tokenade/tests/test_cli_refactor.py +458 -0
- tokenade/tests/test_collectors.py +286 -0
- tokenade/tests/test_comprehensive.py +314 -0
- tokenade/tests/test_cookie_extractor.py +156 -0
- tokenade/tests/test_crypto.py +189 -0
- tokenade/tests/test_db_utils.py +93 -0
- tokenade/tests/test_encryptor.py +126 -0
- tokenade/tests/test_encryptor_edge.py +66 -0
- tokenade/tests/test_enterprise.py +819 -0
- tokenade/tests/test_fingerprint.py +67 -0
- tokenade/tests/test_format_export.py +415 -0
- tokenade/tests/test_forward_proxy.py +52 -0
- tokenade/tests/test_handlers.py +523 -0
- tokenade/tests/test_health_scorer.py +538 -0
- tokenade/tests/test_importer_integration.py +273 -0
- tokenade/tests/test_integration.py +660 -0
- tokenade/tests/test_local_storage.py +57 -0
- tokenade/tests/test_local_storage_extractor.py +175 -0
- tokenade/tests/test_mac_crypto.py +74 -0
- tokenade/tests/test_multi_site_proxy.py +51 -0
- tokenade/tests/test_performance.py +302 -0
- tokenade/tests/test_property_based.py +215 -0
- tokenade/tests/test_proxy.py +645 -0
- tokenade/tests/test_proxy_config.py +86 -0
- tokenade/tests/test_proxy_gui.py +81 -0
- tokenade/tests/test_runtime.py +473 -0
- tokenade/tests/test_security.py +349 -0
- tokenade/tests/test_session_comparator.py +110 -0
- tokenade/tests/test_session_loader.py +53 -0
- tokenade/tests/test_session_manager.py +135 -0
- tokenade/tests/test_session_packager.py +104 -0
- tokenade/tests/test_session_refresher.py +558 -0
- tokenade/tests/test_session_rotation.py +408 -0
- tokenade/tests/test_session_sharer.py +588 -0
- tokenade/tests/test_session_vault.py +418 -0
- tokenade/tests/test_site_filter.py +66 -0
- tokenade/tests/test_ssrf.py +55 -0
- tokenade/tests/test_stealth.py +148 -0
- tokenade/tests/test_tls.py +40 -0
- tokenade/tests/test_tls_matcher.py +131 -0
- tokenade/utils/__init__.py +0 -0
- tokenade-3.5.0.dist-info/METADATA +567 -0
- tokenade-3.5.0.dist-info/RECORD +150 -0
- tokenade-3.5.0.dist-info/WHEEL +5 -0
- tokenade-3.5.0.dist-info/entry_points.txt +2 -0
- tokenade-3.5.0.dist-info/top_level.txt +1 -0
tokenade/__init__.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tokenade - Production-grade token shifting tool.
|
|
3
|
+
|
|
4
|
+
A secure, structured tool for extracting, transferring, and testing
|
|
5
|
+
browser sessions and authentication tokens across devices.
|
|
6
|
+
|
|
7
|
+
Modules:
|
|
8
|
+
core.browser: Browser automation abstractions
|
|
9
|
+
core.crypto: Cross-platform cookie encryption/decryption
|
|
10
|
+
core.fingerprint: Browser fingerprint collection and matching
|
|
11
|
+
core.extractor: Token extraction utilities
|
|
12
|
+
handlers: Site-specific handlers (Google, etc.)
|
|
13
|
+
tests: Portability testing framework
|
|
14
|
+
utils: Helper utilities
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
from tokenade.cli import main
|
|
18
|
+
main()
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
__version__ = "3.5.0"
|
|
22
|
+
__author__ = "Tokenade Team"
|
|
23
|
+
__license__ = "MIT"
|
|
24
|
+
|
|
25
|
+
from tokenade.core.browser.manager import BrowserManager, BrowserConfig, BrowserFactory
|
|
26
|
+
from tokenade.core.crypto.cookie_crypto import (
|
|
27
|
+
CookieCrypto, WindowsCookieCrypto, LinuxCookieCrypto, CookieCryptoFactory,
|
|
28
|
+
DecryptedCookie,
|
|
29
|
+
)
|
|
30
|
+
from tokenade.core.fingerprint.manager import (
|
|
31
|
+
BrowserFingerprint, FingerprintCollector, FingerprintManager,
|
|
32
|
+
)
|
|
33
|
+
from tokenade.core.security.credentials import (
|
|
34
|
+
AccountCredentials, CredentialManager, SecureSessionStorage,
|
|
35
|
+
)
|
|
36
|
+
from tokenade.core.runtime.engine import (
|
|
37
|
+
RuntimeConfig, RuntimeEngine, SessionValidator, create_engine_from_session,
|
|
38
|
+
)
|
|
39
|
+
from tokenade.handlers.base import (
|
|
40
|
+
SiteHandler, HandlerRegistry, SessionData, ExtractedToken,
|
|
41
|
+
AuthStatus, TokenType,
|
|
42
|
+
)
|
|
43
|
+
from tokenade.core.importer.browser_discovery import (
|
|
44
|
+
BrowserProfileDiscovery, BrowserProfile,
|
|
45
|
+
)
|
|
46
|
+
from tokenade.core.importer.cookie_extractor import (
|
|
47
|
+
CookieExtractor, SiteFilter, SITE_DETECTION,
|
|
48
|
+
)
|
|
49
|
+
from tokenade.core.importer.session_packager import SessionPackager
|
|
50
|
+
from tokenade.core.importer.session_loader import SessionLoader
|
|
51
|
+
|
|
52
|
+
__all__ = [
|
|
53
|
+
"BrowserManager",
|
|
54
|
+
"BrowserConfig",
|
|
55
|
+
"BrowserFactory",
|
|
56
|
+
"CookieCrypto",
|
|
57
|
+
"WindowsCookieCrypto",
|
|
58
|
+
"LinuxCookieCrypto",
|
|
59
|
+
"CookieCryptoFactory",
|
|
60
|
+
"DecryptedCookie",
|
|
61
|
+
"BrowserFingerprint",
|
|
62
|
+
"FingerprintCollector",
|
|
63
|
+
"FingerprintManager",
|
|
64
|
+
"AccountCredentials",
|
|
65
|
+
"CredentialManager",
|
|
66
|
+
"SecureSessionStorage",
|
|
67
|
+
"RuntimeConfig",
|
|
68
|
+
"RuntimeEngine",
|
|
69
|
+
"SessionValidator",
|
|
70
|
+
"create_engine_from_session",
|
|
71
|
+
"SiteHandler",
|
|
72
|
+
"HandlerRegistry",
|
|
73
|
+
"SessionData",
|
|
74
|
+
"ExtractedToken",
|
|
75
|
+
"AuthStatus",
|
|
76
|
+
"TokenType",
|
|
77
|
+
"BrowserProfileDiscovery",
|
|
78
|
+
"BrowserProfile",
|
|
79
|
+
"CookieExtractor",
|
|
80
|
+
"SiteFilter",
|
|
81
|
+
"SITE_DETECTION",
|
|
82
|
+
"SessionPackager",
|
|
83
|
+
"SessionLoader",
|
|
84
|
+
]
|
tokenade/cli/__init__.py
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"""Tokenade CLI - Main entry point and argument parser."""
|
|
2
|
+
import argparse
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from tokenade.cli.session import cmd_extract, cmd_export, cmd_load, cmd_transfer, cmd_inject_profile
|
|
7
|
+
from tokenade.cli.security import cmd_encrypt, cmd_decrypt, cmd_rekey
|
|
8
|
+
from tokenade.cli.proxy import cmd_proxy
|
|
9
|
+
from tokenade.cli.management import cmd_sessions, cmd_health, cmd_refresh, cmd_share, cmd_unshare
|
|
10
|
+
from tokenade.cli.advanced import (
|
|
11
|
+
cmd_batch_export, cmd_batch_load, cmd_validate, cmd_validate_rules,
|
|
12
|
+
cmd_diff, cmd_fingerprint, cmd_test, cmd_setup,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
logging.basicConfig(
|
|
16
|
+
level=logging.INFO,
|
|
17
|
+
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
18
|
+
)
|
|
19
|
+
logger = logging.getLogger("tokenade")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def setup_logging(verbose: bool = False):
|
|
23
|
+
"""Configure logging level."""
|
|
24
|
+
level = logging.DEBUG if verbose else logging.INFO
|
|
25
|
+
logging.getLogger("tokenade").setLevel(level)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def main():
|
|
29
|
+
"""Main CLI entry point."""
|
|
30
|
+
from tokenade import __version__
|
|
31
|
+
parser = argparse.ArgumentParser(
|
|
32
|
+
description="Tokenade - Browser session portability tool",
|
|
33
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
34
|
+
epilog="""
|
|
35
|
+
Quick Start:
|
|
36
|
+
1. Export: tokenade export --browser-name firefox --domains "google.com,accounts.google.com" -o my_session.tokenade
|
|
37
|
+
2. Proxy: tokenade proxy -s my_session.tokenade
|
|
38
|
+
3. Browse: Open http://127.0.0.1:9222 and enter the target URL
|
|
39
|
+
|
|
40
|
+
Commands:
|
|
41
|
+
export Extract cookies from browser to .tokenade file
|
|
42
|
+
proxy Start CDP proxy server with donor session
|
|
43
|
+
load Load .tokenade session into a browser
|
|
44
|
+
inject-profile Inject cookies directly into browser profile
|
|
45
|
+
encrypt Encrypt a .tokenade file
|
|
46
|
+
decrypt Decrypt a .tokenade file
|
|
47
|
+
health Check session health
|
|
48
|
+
batch-export Export multiple sites at once
|
|
49
|
+
""",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
|
53
|
+
parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose logging")
|
|
54
|
+
|
|
55
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
56
|
+
|
|
57
|
+
# Setup
|
|
58
|
+
setup_parser = subparsers.add_parser("setup", help="Setup accounts")
|
|
59
|
+
|
|
60
|
+
# Extract
|
|
61
|
+
extract_parser = subparsers.add_parser("extract", help="Extract tokens")
|
|
62
|
+
extract_parser.add_argument("--visible", action="store_true", help="Show browser window")
|
|
63
|
+
|
|
64
|
+
# Transfer
|
|
65
|
+
transfer_parser = subparsers.add_parser("transfer", help="Transfer session")
|
|
66
|
+
transfer_parser.add_argument("-s", "--session", required=True, help="Session file path")
|
|
67
|
+
transfer_parser.add_argument("-f", "--fingerprint", help="Target fingerprint name")
|
|
68
|
+
transfer_parser.add_argument("-p", "--profile-dir", default="browser_data/transfer", help="Profile directory")
|
|
69
|
+
transfer_parser.add_argument("--visible", action="store_true", help="Show browser window")
|
|
70
|
+
transfer_parser.add_argument("--stealth-level", choices=["basic", "advanced", "maximum"], default="maximum", help="Stealth injection level")
|
|
71
|
+
transfer_parser.add_argument("--validate-stealth", action="store_true", help="Validate stealth injection after launch")
|
|
72
|
+
|
|
73
|
+
# Test
|
|
74
|
+
test_parser = subparsers.add_parser("test", help="Test portability")
|
|
75
|
+
test_parser.add_argument("-s", "--session", required=True, help="Session file path")
|
|
76
|
+
test_parser.add_argument("--source-fp", default="default", help="Source fingerprint")
|
|
77
|
+
test_parser.add_argument("--target-fp", default="default", help="Target fingerprint")
|
|
78
|
+
test_parser.add_argument("--variations", action="store_true", help="Test fingerprint variations")
|
|
79
|
+
test_parser.add_argument("--test-api", action="store_true", help="Test API calls")
|
|
80
|
+
test_parser.add_argument("--stealth-level", choices=["basic", "advanced", "maximum"], default="maximum", help="Stealth injection level")
|
|
81
|
+
test_parser.add_argument("--validate-stealth", action="store_true", help="Validate stealth injection")
|
|
82
|
+
test_parser.add_argument("-o", "--output", help="Output report path")
|
|
83
|
+
|
|
84
|
+
# Fingerprint
|
|
85
|
+
fp_parser = subparsers.add_parser("fingerprint", help="Manage fingerprints")
|
|
86
|
+
fp_parser.add_argument("action", choices=["list", "collect", "show", "delete"], help="Action")
|
|
87
|
+
fp_parser.add_argument("-n", "--name", help="Fingerprint name")
|
|
88
|
+
fp_parser.add_argument("-p", "--profile-dir", help="Browser profile directory")
|
|
89
|
+
|
|
90
|
+
# Validate
|
|
91
|
+
validate_parser = subparsers.add_parser("validate", help="Validate sessions")
|
|
92
|
+
validate_parser.add_argument("-d", "--sessions-dir", default="sessions", help="Sessions directory")
|
|
93
|
+
|
|
94
|
+
# Export
|
|
95
|
+
export_parser = subparsers.add_parser("export", help="Export session from existing browser")
|
|
96
|
+
export_parser.add_argument("--browser-name", choices=["chrome", "firefox", "edge", "brave"], help="Browser name")
|
|
97
|
+
export_parser.add_argument("--browser-path", help="Custom path to browser profile")
|
|
98
|
+
export_parser.add_argument("--profile", help="Profile name within browser")
|
|
99
|
+
export_parser.add_argument("--site-config", help="Path to JSON site config file for filtering")
|
|
100
|
+
export_parser.add_argument("--domains", help="Comma-separated domains to filter (e.g. 'google.com,accounts.google.com')")
|
|
101
|
+
export_parser.add_argument("--file-path", help="Export from cookies file")
|
|
102
|
+
export_parser.add_argument("--format", choices=["netscape", "json", "curl"], default="netscape", help="File format")
|
|
103
|
+
export_parser.add_argument("--collect-fingerprint", action="store_true", help="Collect source browser fingerprint")
|
|
104
|
+
export_parser.add_argument("--output", "-o", help="Output file path (any extension)")
|
|
105
|
+
export_parser.add_argument("--list-profiles", action="store_true", help="List available profiles")
|
|
106
|
+
export_parser.add_argument("--decrypt", action="store_true", help="Decrypt cookies (auto-detected)")
|
|
107
|
+
export_parser.add_argument("--extract-local-storage", action="store_true", help="Also extract localStorage data")
|
|
108
|
+
export_parser.add_argument("--local-storage-origin", help="Origin to extract localStorage from")
|
|
109
|
+
|
|
110
|
+
# Load
|
|
111
|
+
load_parser = subparsers.add_parser("load", help="Load session file into browser")
|
|
112
|
+
load_parser.add_argument("--file", "-f", required=True, help="Path to session file")
|
|
113
|
+
load_parser.add_argument("--site-config", help="Path to JSON site config file for validation")
|
|
114
|
+
load_parser.add_argument("--fingerprint", help="Target fingerprint name")
|
|
115
|
+
load_parser.add_argument("--stealth-level", choices=["basic", "advanced", "maximum"], default="maximum", help="Stealth level")
|
|
116
|
+
load_parser.add_argument("--validate", action="store_true", help="Validate session after injection")
|
|
117
|
+
load_parser.add_argument("--runtime", action="store_true", help="Load into RuntimeEngine")
|
|
118
|
+
load_parser.add_argument("--test-api", action="store_true", help="Test API after loading")
|
|
119
|
+
load_parser.add_argument("--visible", action="store_true", help="Show browser window")
|
|
120
|
+
load_parser.add_argument("--profile-dir", help="Browser profile directory")
|
|
121
|
+
load_parser.add_argument("--no-local-storage", action="store_true", help="Skip localStorage injection if present")
|
|
122
|
+
|
|
123
|
+
# Inject Profile
|
|
124
|
+
inject_parser = subparsers.add_parser("inject-profile", help="Inject cookies directly into browser profile")
|
|
125
|
+
inject_parser.add_argument("--session", "-s", required=True, help="Path to session file")
|
|
126
|
+
inject_parser.add_argument("--profile", "-p", required=True, help="Browser profile path")
|
|
127
|
+
inject_parser.add_argument("--browser", "-b", choices=["chrome", "brave", "edge", "firefox", "opera", "vivaldi"],
|
|
128
|
+
default="chrome", help="Browser name")
|
|
129
|
+
inject_parser.add_argument("--no-backup", action="store_true", help="Skip backup creation")
|
|
130
|
+
inject_parser.add_argument("--dry-run", action="store_true", help="Show what would be injected without making changes")
|
|
131
|
+
|
|
132
|
+
# Encrypt
|
|
133
|
+
encrypt_parser = subparsers.add_parser("encrypt", help="Encrypt session file")
|
|
134
|
+
encrypt_parser.add_argument("--input", "-i", required=True, help="Input file path")
|
|
135
|
+
encrypt_parser.add_argument("--output", "-o", help="Output file path")
|
|
136
|
+
encrypt_parser.add_argument("--password", "-p", help="Encryption password")
|
|
137
|
+
encrypt_parser.add_argument("--key-file", "-k", help="Password file")
|
|
138
|
+
|
|
139
|
+
# Decrypt
|
|
140
|
+
decrypt_parser = subparsers.add_parser("decrypt", help="Decrypt session file")
|
|
141
|
+
decrypt_parser.add_argument("--input", "-i", required=True, help="Encrypted file path")
|
|
142
|
+
decrypt_parser.add_argument("--output", "-o", help="Output file path")
|
|
143
|
+
decrypt_parser.add_argument("--password", "-p", help="Decryption password")
|
|
144
|
+
decrypt_parser.add_argument("--key-file", "-k", help="Password file")
|
|
145
|
+
|
|
146
|
+
# Rekey
|
|
147
|
+
rekey_parser = subparsers.add_parser("rekey", help="Change encryption password")
|
|
148
|
+
rekey_parser.add_argument("--input", "-i", required=True, help="Encrypted file path")
|
|
149
|
+
rekey_parser.add_argument("--output", "-o", help="Output file path")
|
|
150
|
+
rekey_parser.add_argument("--old-password", help="Old password")
|
|
151
|
+
rekey_parser.add_argument("--new-password", help="New password")
|
|
152
|
+
rekey_parser.add_argument("--old-key-file", help="Old password file")
|
|
153
|
+
rekey_parser.add_argument("--new-key-file", help="New password file")
|
|
154
|
+
|
|
155
|
+
# Batch Export
|
|
156
|
+
batch_export_parser = subparsers.add_parser("batch-export", help="Batch export multiple sites")
|
|
157
|
+
batch_export_parser.add_argument("--site-config", "-s", required=True, help="Site config JSON file")
|
|
158
|
+
batch_export_parser.add_argument("--browser", "-b", choices=["chrome", "firefox", "edge", "brave"],
|
|
159
|
+
default="firefox", help="Browser name")
|
|
160
|
+
batch_export_parser.add_argument("--browser-path", help="Custom browser profile path")
|
|
161
|
+
batch_export_parser.add_argument("--profile", "-p", help="Profile name")
|
|
162
|
+
batch_export_parser.add_argument("--output", "-o", help="Output directory")
|
|
163
|
+
batch_export_parser.add_argument("--extract-local-storage", action="store_true", help="Extract localStorage")
|
|
164
|
+
|
|
165
|
+
# Batch Load
|
|
166
|
+
batch_load_parser = subparsers.add_parser("batch-load", help="Batch load multiple sessions")
|
|
167
|
+
batch_load_parser.add_argument("--sessions-dir", "-d", required=True, help="Sessions directory")
|
|
168
|
+
batch_load_parser.add_argument("--target-browser", "-t", choices=["chrome", "firefox", "edge", "brave"],
|
|
169
|
+
default="chrome", help="Target browser")
|
|
170
|
+
batch_load_parser.add_argument("--site-config", "-s", help="Site config JSON file for validation")
|
|
171
|
+
batch_load_parser.add_argument("--profile-dir", help="Target profile directory")
|
|
172
|
+
batch_load_parser.add_argument("--validate", action="store_true", help="Validate sessions")
|
|
173
|
+
batch_load_parser.add_argument("--visible", action="store_true", help="Show browser window")
|
|
174
|
+
|
|
175
|
+
# Health Check
|
|
176
|
+
health_parser = subparsers.add_parser("health", help="Check session health")
|
|
177
|
+
health_parser.add_argument("--session", "-s", help="Single session file to check")
|
|
178
|
+
health_parser.add_argument("--sessions-dir", "-d", help="Directory of sessions to check")
|
|
179
|
+
|
|
180
|
+
# Refresh
|
|
181
|
+
refresh_parser = subparsers.add_parser("refresh", help="Refresh session from source browser")
|
|
182
|
+
refresh_parser.add_argument("--session", "-s", required=True, help="Session file to refresh")
|
|
183
|
+
refresh_parser.add_argument("--source-browser", "-b", choices=["chrome", "firefox", "edge", "brave"],
|
|
184
|
+
required=True, help="Source browser name")
|
|
185
|
+
refresh_parser.add_argument("--source-browser-path", help="Custom source browser profile path")
|
|
186
|
+
refresh_parser.add_argument("--source-profile", help="Source profile name")
|
|
187
|
+
refresh_parser.add_argument("--site-config", help="Site config JSON file for filtering")
|
|
188
|
+
|
|
189
|
+
# Proxy
|
|
190
|
+
proxy_parser = subparsers.add_parser("proxy", help="Start fingerprint-matched proxy server")
|
|
191
|
+
proxy_parser.add_argument("--session", "-s", help="Path to .tokenade session file (single mode)")
|
|
192
|
+
proxy_parser.add_argument("--all", action="store_true", help="Serve all sessions (multi-site mode)")
|
|
193
|
+
proxy_parser.add_argument("--sessions-dir", "-d", help="Directory of .tokenade files (for --all)")
|
|
194
|
+
proxy_parser.add_argument("--mode", choices=["gui", "forward"], default="gui",
|
|
195
|
+
help="Proxy mode: gui (browser GUI) or forward (HTTP_PROXY)")
|
|
196
|
+
proxy_parser.add_argument("--port", "-p", type=int, default=9222, help="Port to listen on (default: 9222)")
|
|
197
|
+
proxy_parser.add_argument("--host", default="127.0.0.1", help="Host to bind to (default: 127.0.0.1)")
|
|
198
|
+
proxy_parser.add_argument("--legacy", action="store_true", help="Use legacy service-worker proxy (default: CDP)")
|
|
199
|
+
proxy_parser.add_argument("--visible", action="store_true", help="Show browser window (CDP mode only)")
|
|
200
|
+
proxy_parser.add_argument("--fingerprint", action="store_true", help="Enable TLS fingerprint matching via curl-cffi (breaks cf_clearance)")
|
|
201
|
+
proxy_parser.add_argument("--no-open-browser", action="store_true", help="Don't open browser automatically")
|
|
202
|
+
proxy_parser.add_argument("--no-gui", action="store_true", help="Disable GUI mode (legacy proxy only)")
|
|
203
|
+
proxy_parser.add_argument("--timeout", type=int, default=30, help="Request timeout in seconds (default: 30)")
|
|
204
|
+
proxy_parser.add_argument("--auto-refresh", action="store_true", help="Auto-refresh session from source browser when cookies expire")
|
|
205
|
+
proxy_parser.add_argument("--source-browser", help="Source browser for auto-refresh (e.g., firefox, chrome)")
|
|
206
|
+
proxy_parser.add_argument("--source-profile", help="Source profile for auto-refresh (e.g., default, Profile 1)")
|
|
207
|
+
|
|
208
|
+
# Sessions (subcommand group)
|
|
209
|
+
sessions_parser = subparsers.add_parser("sessions", help="Manage multiple sessions")
|
|
210
|
+
sessions_sub = sessions_parser.add_subparsers(dest="sessions_command", help="Session management commands")
|
|
211
|
+
|
|
212
|
+
# sessions list
|
|
213
|
+
sessions_list_parser = sessions_sub.add_parser("list", help="List all sessions")
|
|
214
|
+
sessions_list_parser.add_argument("--dir", "-d", default=".", help="Directory to search")
|
|
215
|
+
sessions_list_parser.add_argument("--pattern", "-p", default="*.tokenade", help="File pattern")
|
|
216
|
+
sessions_list_parser.add_argument("--recursive", "-r", action="store_true", help="Search subdirectories")
|
|
217
|
+
sessions_list_parser.add_argument("--site", "-s", help="Filter by site name")
|
|
218
|
+
sessions_list_parser.add_argument("--browser", "-b", help="Filter by source browser")
|
|
219
|
+
|
|
220
|
+
# sessions merge
|
|
221
|
+
sessions_merge_parser = sessions_sub.add_parser("merge", help="Merge multiple sessions")
|
|
222
|
+
sessions_merge_parser.add_argument("files", nargs="+", help="Session files to merge")
|
|
223
|
+
sessions_merge_parser.add_argument("--output", "-o", required=True, help="Output file path")
|
|
224
|
+
sessions_merge_parser.add_argument("--site-name", help="Site name for merged session")
|
|
225
|
+
|
|
226
|
+
# sessions rotate
|
|
227
|
+
sessions_rotate_parser = sessions_sub.add_parser("rotate", help="Select next session (rotation)")
|
|
228
|
+
sessions_rotate_parser.add_argument("files", nargs="+", help="Session files to rotate through")
|
|
229
|
+
sessions_rotate_parser.add_argument("--strategy", choices=["round-robin", "random"], default="round-robin",
|
|
230
|
+
help="Rotation strategy")
|
|
231
|
+
sessions_rotate_parser.add_argument("--state-file", help="State file for round-robin")
|
|
232
|
+
|
|
233
|
+
# sessions stats
|
|
234
|
+
sessions_stats_parser = sessions_sub.add_parser("stats", help="Show aggregate session statistics")
|
|
235
|
+
sessions_stats_parser.add_argument("files", nargs="+", help="Session files to analyze")
|
|
236
|
+
|
|
237
|
+
# Share
|
|
238
|
+
share_parser = subparsers.add_parser("share", help="Create shareable session link or QR code")
|
|
239
|
+
share_parser.add_argument("--session", "-s", required=True, help="Session file to share")
|
|
240
|
+
share_parser.add_argument("--output", "-o", help="Output file path (HTML or QR image)")
|
|
241
|
+
share_parser.add_argument("--format", choices=["url", "html", "qr"], default="url",
|
|
242
|
+
help="Output format: url (default), html, qr")
|
|
243
|
+
share_parser.add_argument("--expiry", type=int, default=24, help="Link expiry in hours (default: 24)")
|
|
244
|
+
share_parser.add_argument("--max-uses", type=int, default=0, help="Max uses (0 = unlimited)")
|
|
245
|
+
share_parser.add_argument("--password", "-p", help="Password protect the link")
|
|
246
|
+
|
|
247
|
+
# Unshare
|
|
248
|
+
unshare_parser = subparsers.add_parser("unshare", help="Revoke a shared session")
|
|
249
|
+
unshare_parser.add_argument("session_id", help="Session ID to revoke")
|
|
250
|
+
unshare_parser.add_argument("--list", action="store_true", help="List all active shares")
|
|
251
|
+
|
|
252
|
+
# Validate Rules
|
|
253
|
+
validate_rules_parser = subparsers.add_parser("validate-rules", help="Validate session with custom rules")
|
|
254
|
+
validate_rules_parser.add_argument("--session", "-s", required=True, help="Session file to validate")
|
|
255
|
+
validate_rules_parser.add_argument("--rules", "-r", required=True, help="Validation rules JSON file")
|
|
256
|
+
validate_rules_parser.add_argument("--url", "-u", help="Target site URL")
|
|
257
|
+
validate_rules_parser.add_argument("--update-baselines", action="store_true", help="Update screenshot baselines")
|
|
258
|
+
|
|
259
|
+
# Diff
|
|
260
|
+
diff_parser = subparsers.add_parser("diff", help="Compare two session files")
|
|
261
|
+
diff_parser.add_argument("session_a", help="First .tokenade file")
|
|
262
|
+
diff_parser.add_argument("session_b", help="Second .tokenade file")
|
|
263
|
+
diff_parser.add_argument("--verbose", "-v", action="store_true", help="Show detailed differences")
|
|
264
|
+
|
|
265
|
+
args = parser.parse_args()
|
|
266
|
+
|
|
267
|
+
if not args.command:
|
|
268
|
+
parser.print_help()
|
|
269
|
+
sys.exit(1)
|
|
270
|
+
|
|
271
|
+
setup_logging(args.verbose)
|
|
272
|
+
|
|
273
|
+
commands = {
|
|
274
|
+
"setup": cmd_setup,
|
|
275
|
+
"extract": cmd_extract,
|
|
276
|
+
"transfer": cmd_transfer,
|
|
277
|
+
"test": cmd_test,
|
|
278
|
+
"fingerprint": cmd_fingerprint,
|
|
279
|
+
"validate": cmd_validate,
|
|
280
|
+
"export": cmd_export,
|
|
281
|
+
"load": cmd_load,
|
|
282
|
+
"inject-profile": cmd_inject_profile,
|
|
283
|
+
"encrypt": cmd_encrypt,
|
|
284
|
+
"decrypt": cmd_decrypt,
|
|
285
|
+
"rekey": cmd_rekey,
|
|
286
|
+
"batch-export": cmd_batch_export,
|
|
287
|
+
"batch-load": cmd_batch_load,
|
|
288
|
+
"health": cmd_health,
|
|
289
|
+
"refresh": cmd_refresh,
|
|
290
|
+
"proxy": cmd_proxy,
|
|
291
|
+
"sessions": cmd_sessions,
|
|
292
|
+
"share": cmd_share,
|
|
293
|
+
"unshare": cmd_unshare,
|
|
294
|
+
"validate-rules": cmd_validate_rules,
|
|
295
|
+
"diff": cmd_diff,
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
try:
|
|
299
|
+
commands[args.command](args)
|
|
300
|
+
except KeyboardInterrupt:
|
|
301
|
+
print("\n\n⚠️ Interrupted by user")
|
|
302
|
+
sys.exit(130)
|
|
303
|
+
except Exception as e:
|
|
304
|
+
logger.exception("Command failed")
|
|
305
|
+
print(f"\n❌ Error: {e}")
|
|
306
|
+
sys.exit(1)
|