tokenade 5.1.2__tar.gz → 5.1.4__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.
- {tokenade-5.1.2 → tokenade-5.1.4}/PKG-INFO +1 -1
- {tokenade-5.1.2 → tokenade-5.1.4}/pyproject.toml +1 -1
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/management.py +27 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/session.py +174 -12
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_packager.py +6 -1
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade.egg-info/PKG-INFO +1 -1
- {tokenade-5.1.2 → tokenade-5.1.4}/README.md +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/setup.cfg +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/__main__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/__main__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/advanced.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/completions.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/config.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/output.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/cli/security.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/antidetection/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/antidetection/behavioral.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/antidetection/cdp_cleaner.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/api/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/api/server.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/batch/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/batch/operations.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/browser/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/browser/cdp_connection.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/browser/manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/browser/undetectable.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/cicd/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/cicd/workflow_generator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/config.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/crypto/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/crypto/cookie_crypto.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/crypto/encryptor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/errors.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/extractor/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/audio.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/base.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/battery.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/canvas.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/fonts.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/navigator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/plugins.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/screen.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/webgl.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/collectors/webrtc.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/injector.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/fingerprint/stealth.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/adb_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/advanced_validator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/browser_discovery.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/chromium_forks.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/cookie_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/db_utils.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/format_exporter.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/format_importer.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/local_storage_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/mobile_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/safari_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_comparator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_loader.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_refresher.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_rotation.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_rotator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_sharer.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_sync.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/session_vault.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/site_configs.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/tor_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/importer/validator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/injector/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/injector/profile_manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/integration/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/integration/docker_manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/integration/kubernetes.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/integration/plugin_loader.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/integration/plugin_registry.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/integration/webhooks.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/monitoring/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/monitoring/analytics.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/monitoring/session_monitor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/cdp_api.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/cdp_gui.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/cdp_injection.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/cdp_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/cdp_routing.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/cdp_stealth.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/extension_bridge.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/forward_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/multi_site_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/server.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/server_gui.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/server_routing.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/proxy/server_utils.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/refresh/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/refresh/batch_refresh.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/refresh/encrypted_refresh.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/refresh/health_checker.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/refresh/health_scorer.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/refresh/oauth_refresh.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/refresh/session_validator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/runtime/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/runtime/engine.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/runtime/tls_matcher.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/security/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/security/audit.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/security/credentials.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/utils/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/core/utils/performance.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/handlers/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/handlers/base.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/handlers/generic_oauth.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/handlers/github.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/handlers/google.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/sdk/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/portability.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_advanced_validator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_advanced_validator_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_analytics.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_antidetection.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_api_monitor_endpoints.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_api_monitoring.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_api_sdk.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_api_server_comprehensive.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_api_server_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_audit_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_base_handler_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_batch_operations.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_batch_operations_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_batch_refresh.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_benchmarks.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_browser.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_browser_discovery.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_browser_discovery_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_browser_improvements.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_browser_manager_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_browser_support.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_gui_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_injection_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_injection_coverage2.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_injection_coverage3.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_injection_coverage4.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_proxy_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_proxy_coverage3.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_proxy_start_errors.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_routing_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cdp_stealth_coverage2.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_chromium_forks_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cicd.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_advanced.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_helpers.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_init_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_integration.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_main_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_management.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_management_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_monitor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_output.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_refactor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_security_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_security_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cli_session.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_collectors.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_comprehensive.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_config_and_cdp_modules.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cookie_crypto.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_cookie_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_coverage_boost.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_credentials_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_crypto.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_custom_errors.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_db_utils.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_db_utils_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_docker_manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_encrypted_refresh.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_encryptor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_encryptor_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_encryptor_edge.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_engine_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_enterprise.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_extension_bridge_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_extension_bridge_coverage2.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_fingerprint.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_fingerprint_collectors.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_fingerprint_collectors_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_fingerprint_injector.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_fingerprint_manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_format_export.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_forward_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_forward_proxy_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_generic_oauth_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_github_handler_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_google_handler_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_handlers.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_health_checker_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_health_scorer.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_importer_integration.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_integration.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_kubernetes.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_local_storage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_local_storage_extractor.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_local_storage_extractor_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_local_storage_extractor_coverage2.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_mac_crypto.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_mobile_extractor_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_monitoring.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_multi_site_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_multi_site_proxy_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_oauth_refresh.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_performance.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_performance_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_playwright_e2e.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_plugin_loader.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_plugin_loader_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_plugin_registry.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_profile_manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_profile_manager_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_profile_manager_coverage2.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_property_based.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_proxy.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_proxy_config.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_proxy_gui.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_proxy_modules.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_runtime.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_safari_extractor_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_sdk_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_security.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_server_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_server_gui_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_server_routing_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_server_utils_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_server_utils_coverage2.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_comparator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_loader.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_loader_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_manager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_monitor_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_monitor_enhanced.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_packager.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_packager_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_refresher.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_rotation.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_rotator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_sharer.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_sharer_coverage2.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_sync.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_sync_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_validator.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_session_vault.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_site_configs_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_site_filter.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_ssrf.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_stealth.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_tls.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_tls_matcher.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_tls_matcher_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_tor_extractor_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_undetectable.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_validator_coverage.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/tests/test_webhooks.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade/utils/__init__.py +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade.egg-info/SOURCES.txt +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade.egg-info/dependency_links.txt +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade.egg-info/entry_points.txt +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade.egg-info/requires.txt +0 -0
- {tokenade-5.1.2 → tokenade-5.1.4}/tokenade.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Session management CLI commands."""
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
|
+
import platform
|
|
4
5
|
import signal
|
|
5
6
|
import time
|
|
6
7
|
from pathlib import Path
|
|
@@ -827,6 +828,32 @@ def cmd_launch(args):
|
|
|
827
828
|
# Wait for page load
|
|
828
829
|
await asyncio.sleep(4)
|
|
829
830
|
|
|
831
|
+
# Step 6: Inject localStorage + sessionStorage (after navigation, on correct origin)
|
|
832
|
+
session_data = session.get("session_storage", {})
|
|
833
|
+
local_data = session.get("local_storage", {})
|
|
834
|
+
|
|
835
|
+
if local_data:
|
|
836
|
+
print(f" Injecting {len(local_data)} localStorage entries...", flush=True)
|
|
837
|
+
ls_json = json.dumps(local_data)
|
|
838
|
+
await cdp_cmd(tab_ws, "Runtime.evaluate", {
|
|
839
|
+
"expression": f"(function(d){{Object.entries(d).forEach(function(e){{localStorage.setItem(e[0],e[1])}})}})({ls_json})",
|
|
840
|
+
"returnByValue": True,
|
|
841
|
+
})
|
|
842
|
+
|
|
843
|
+
if session_data:
|
|
844
|
+
print(f" Injecting {len(session_data)} sessionStorage entries...", flush=True)
|
|
845
|
+
ss_json = json.dumps(session_data)
|
|
846
|
+
await cdp_cmd(tab_ws, "Runtime.evaluate", {
|
|
847
|
+
"expression": f"(function(d){{Object.entries(d).forEach(function(e){{sessionStorage.setItem(e[0],e[1])}})}})({ss_json})",
|
|
848
|
+
"returnByValue": True,
|
|
849
|
+
})
|
|
850
|
+
|
|
851
|
+
# Step 7: Re-navigate with full session state
|
|
852
|
+
if local_data or session_data:
|
|
853
|
+
print(f" Re-navigating with full session state...", flush=True)
|
|
854
|
+
await cdp_cmd(tab_ws, "Page.navigate", {"url": args.url})
|
|
855
|
+
await asyncio.sleep(4)
|
|
856
|
+
|
|
830
857
|
# Get page info
|
|
831
858
|
title_result = await cdp_cmd(
|
|
832
859
|
tab_ws, "Runtime.evaluate",
|
|
@@ -16,8 +16,36 @@ from tokenade.handlers.google import GoogleHandler
|
|
|
16
16
|
logger = logging.getLogger("tokenade")
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def
|
|
20
|
-
"""
|
|
19
|
+
async def _eval_with_session(ws, msg_id, session_id, expression):
|
|
20
|
+
"""Evaluate JS in a tab via CDP session (async)."""
|
|
21
|
+
import asyncio
|
|
22
|
+
import time as _time
|
|
23
|
+
|
|
24
|
+
msg_id[0] += 1
|
|
25
|
+
mid = msg_id[0]
|
|
26
|
+
m = {
|
|
27
|
+
"id": mid,
|
|
28
|
+
"method": "Runtime.evaluate",
|
|
29
|
+
"params": {"expression": expression, "returnByValue": True},
|
|
30
|
+
"sessionId": session_id,
|
|
31
|
+
}
|
|
32
|
+
await ws.send(json.dumps(m))
|
|
33
|
+
|
|
34
|
+
deadline = _time.time() + 10
|
|
35
|
+
while _time.time() < deadline:
|
|
36
|
+
try:
|
|
37
|
+
raw = await asyncio.wait_for(ws.recv(), timeout=min(2, deadline - _time.time()))
|
|
38
|
+
except asyncio.TimeoutError:
|
|
39
|
+
continue
|
|
40
|
+
d = json.loads(raw)
|
|
41
|
+
if d.get("id") == mid:
|
|
42
|
+
result = d.get("result", {}).get("result", {})
|
|
43
|
+
return result.get("value")
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _extract_via_cdp(port: int, domain_filter: str = None) -> dict:
|
|
48
|
+
"""Extract cookies + localStorage + sessionStorage from running browser via CDP."""
|
|
21
49
|
import urllib.request as _urllib_req
|
|
22
50
|
|
|
23
51
|
try:
|
|
@@ -26,14 +54,14 @@ def _extract_via_cdp(port: int, domain_filter: str = None) -> list:
|
|
|
26
54
|
browser_ws = version.get("webSocketDebuggerUrl")
|
|
27
55
|
except Exception as e:
|
|
28
56
|
print(f"❌ Cannot connect to CDP on port {port}: {e}")
|
|
29
|
-
return []
|
|
57
|
+
return {"cookies": [], "local_storage": {}, "session_storage": {}}
|
|
30
58
|
|
|
31
59
|
import asyncio
|
|
32
60
|
import websockets
|
|
33
61
|
|
|
34
|
-
async def
|
|
62
|
+
async def _get_session_state():
|
|
35
63
|
ws = await websockets.connect(
|
|
36
|
-
browser_ws, max_size=
|
|
64
|
+
browser_ws, max_size=50 * 1024 * 1024,
|
|
37
65
|
ping_interval=30, ping_timeout=10,
|
|
38
66
|
)
|
|
39
67
|
msg_id = [0]
|
|
@@ -57,20 +85,139 @@ def _extract_via_cdp(port: int, domain_filter: str = None) -> list:
|
|
|
57
85
|
return d.get("result", {})
|
|
58
86
|
return {}
|
|
59
87
|
|
|
88
|
+
# 1. Get all cookies
|
|
60
89
|
result = await cmd("Storage.getCookies")
|
|
61
90
|
cdp_cookies = result.get("cookies", [])
|
|
91
|
+
|
|
92
|
+
# 2. Find a tab on the target domain for localStorage/sessionStorage
|
|
93
|
+
local_storage = {}
|
|
94
|
+
session_storage = {}
|
|
95
|
+
|
|
96
|
+
targets_result = await cmd("Target.getTargets")
|
|
97
|
+
targets = targets_result.get("targetInfos", [])
|
|
98
|
+
|
|
99
|
+
# Find a tab matching domain filter
|
|
100
|
+
target_page = None
|
|
101
|
+
domains_needed = []
|
|
102
|
+
if domain_filter:
|
|
103
|
+
domains_needed = [d.strip().lstrip(".") for d in domain_filter.split(",") if d.strip()]
|
|
104
|
+
|
|
105
|
+
for t in targets:
|
|
106
|
+
if t.get("type") == "page" and t.get("url"):
|
|
107
|
+
url = t["url"]
|
|
108
|
+
for d in domains_needed:
|
|
109
|
+
if d in url:
|
|
110
|
+
target_page = t
|
|
111
|
+
break
|
|
112
|
+
if target_page:
|
|
113
|
+
break
|
|
114
|
+
|
|
115
|
+
# If no matching tab, open a new one on the first domain
|
|
116
|
+
if not target_page and domains_needed:
|
|
117
|
+
first_domain = domains_needed[0]
|
|
118
|
+
proto = "https" if first_domain not in ("localhost", "127.0.0.1") else "http"
|
|
119
|
+
create_result = await cmd("Target.createTarget", {
|
|
120
|
+
"url": f"{proto}://{first_domain}"
|
|
121
|
+
})
|
|
122
|
+
target_id = create_result.get("targetId")
|
|
123
|
+
if target_id:
|
|
124
|
+
# Attach to the new tab
|
|
125
|
+
attach_result = await cmd("Target.attachToTarget", {
|
|
126
|
+
"targetId": target_id,
|
|
127
|
+
"flatten": True,
|
|
128
|
+
})
|
|
129
|
+
session_id = attach_result.get("sessionId")
|
|
130
|
+
if session_id:
|
|
131
|
+
# Wait for page load
|
|
132
|
+
import time as _time
|
|
133
|
+
_time.sleep(3)
|
|
134
|
+
|
|
135
|
+
# Get localStorage
|
|
136
|
+
for d in domains_needed:
|
|
137
|
+
proto = "https" if d not in ("localhost", "127.0.0.1") else "http"
|
|
138
|
+
nav_cmd = {
|
|
139
|
+
"id": msg_id[0] + 1000,
|
|
140
|
+
"method": "Page.navigate",
|
|
141
|
+
"params": {"url": f"{proto}://{d}"},
|
|
142
|
+
"sessionId": session_id,
|
|
143
|
+
}
|
|
144
|
+
msg_id[0] += 1
|
|
145
|
+
await ws.send(json.dumps(nav_cmd))
|
|
146
|
+
_time.sleep(2)
|
|
147
|
+
|
|
148
|
+
# Collect localStorage
|
|
149
|
+
ls_result = await _eval_with_session(ws, msg_id, session_id,
|
|
150
|
+
"JSON.stringify(Object.entries(localStorage))")
|
|
151
|
+
if ls_result:
|
|
152
|
+
try:
|
|
153
|
+
entries = json.loads(ls_result)
|
|
154
|
+
for key, val in entries:
|
|
155
|
+
local_storage[key] = val
|
|
156
|
+
except (json.JSONDecodeError, TypeError):
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
# Collect sessionStorage
|
|
160
|
+
ss_result = await _eval_with_session(ws, msg_id, session_id,
|
|
161
|
+
"JSON.stringify(Object.entries(sessionStorage))")
|
|
162
|
+
if ss_result:
|
|
163
|
+
try:
|
|
164
|
+
entries = json.loads(ss_result)
|
|
165
|
+
for key, val in entries:
|
|
166
|
+
session_storage[key] = val
|
|
167
|
+
except (json.JSONDecodeError, TypeError):
|
|
168
|
+
pass
|
|
169
|
+
|
|
170
|
+
# Close the tab we created
|
|
171
|
+
await cmd("Target.closeTarget", {"targetId": target_id})
|
|
172
|
+
|
|
173
|
+
# 3. If we found an existing tab, try to get its storage via the main browser ws
|
|
174
|
+
elif target_page:
|
|
175
|
+
target_id = target_page.get("targetId")
|
|
176
|
+
attach_result = await cmd("Target.attachToTarget", {
|
|
177
|
+
"targetId": target_id,
|
|
178
|
+
"flatten": True,
|
|
179
|
+
})
|
|
180
|
+
session_id = attach_result.get("sessionId")
|
|
181
|
+
if session_id:
|
|
182
|
+
for d in domains_needed:
|
|
183
|
+
# Collect localStorage
|
|
184
|
+
ls_result = await _eval_with_session(ws, msg_id, session_id,
|
|
185
|
+
"JSON.stringify(Object.entries(localStorage))")
|
|
186
|
+
if ls_result:
|
|
187
|
+
try:
|
|
188
|
+
entries = json.loads(ls_result)
|
|
189
|
+
for key, val in entries:
|
|
190
|
+
local_storage[key] = val
|
|
191
|
+
except (json.JSONDecodeError, TypeError):
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
# Collect sessionStorage
|
|
195
|
+
ss_result = await _eval_with_session(ws, msg_id, session_id,
|
|
196
|
+
"JSON.stringify(Object.entries(sessionStorage))")
|
|
197
|
+
if ss_result:
|
|
198
|
+
try:
|
|
199
|
+
entries = json.loads(ss_result)
|
|
200
|
+
for key, val in entries:
|
|
201
|
+
session_storage[key] = val
|
|
202
|
+
except (json.JSONDecodeError, TypeError):
|
|
203
|
+
pass
|
|
204
|
+
|
|
62
205
|
await ws.close()
|
|
63
|
-
return
|
|
206
|
+
return {
|
|
207
|
+
"cookies": cdp_cookies,
|
|
208
|
+
"local_storage": local_storage,
|
|
209
|
+
"session_storage": session_storage,
|
|
210
|
+
}
|
|
64
211
|
|
|
65
212
|
try:
|
|
66
|
-
|
|
213
|
+
session_state = asyncio.run(_get_session_state())
|
|
67
214
|
except Exception as e:
|
|
68
215
|
print(f"❌ CDP extraction failed: {e}")
|
|
69
|
-
return []
|
|
216
|
+
return {"cookies": [], "local_storage": {}, "session_storage": {}}
|
|
70
217
|
|
|
71
218
|
# Convert CDP format to tokenade format
|
|
72
219
|
cookies = []
|
|
73
|
-
for c in
|
|
220
|
+
for c in session_state["cookies"]:
|
|
74
221
|
cookie = {
|
|
75
222
|
"name": c.get("name", ""),
|
|
76
223
|
"value": c.get("value", ""),
|
|
@@ -104,7 +251,11 @@ def _extract_via_cdp(port: int, domain_filter: str = None) -> list:
|
|
|
104
251
|
break
|
|
105
252
|
cookies = filtered
|
|
106
253
|
|
|
107
|
-
return
|
|
254
|
+
return {
|
|
255
|
+
"cookies": cookies,
|
|
256
|
+
"local_storage": session_state["local_storage"],
|
|
257
|
+
"session_storage": session_state["session_storage"],
|
|
258
|
+
}
|
|
108
259
|
|
|
109
260
|
|
|
110
261
|
def cmd_extract(args):
|
|
@@ -304,7 +455,10 @@ def cmd_export(args):
|
|
|
304
455
|
print(f"❌ Failed to launch browser: {e}")
|
|
305
456
|
return
|
|
306
457
|
|
|
307
|
-
|
|
458
|
+
session_state = _extract_via_cdp(cdp_port, domain_filter=getattr(args, 'domains', None))
|
|
459
|
+
cookies = session_state["cookies"]
|
|
460
|
+
local_storage = session_state.get("local_storage", {})
|
|
461
|
+
session_storage = session_state.get("session_storage", {})
|
|
308
462
|
|
|
309
463
|
if launched_browser:
|
|
310
464
|
try:
|
|
@@ -316,6 +470,10 @@ def cmd_export(args):
|
|
|
316
470
|
print("❌ No cookies extracted via CDP")
|
|
317
471
|
return
|
|
318
472
|
print(f" ✅ Extracted {len(cookies)} cookies via CDP")
|
|
473
|
+
if local_storage:
|
|
474
|
+
print(f" ✅ Extracted {len(local_storage)} localStorage entries")
|
|
475
|
+
if session_storage:
|
|
476
|
+
print(f" ✅ Extracted {len(session_storage)} sessionStorage entries")
|
|
319
477
|
else:
|
|
320
478
|
print(f"\n🍪 Extracting cookies from: {browser_path}")
|
|
321
479
|
extractor = CookieExtractor(browser_path, browser=browser_name)
|
|
@@ -391,6 +549,7 @@ def cmd_export(args):
|
|
|
391
549
|
print(f" 🎯 Filtered to {len(cookies)} cookies for domains: {', '.join(domains)}")
|
|
392
550
|
|
|
393
551
|
local_storage = {}
|
|
552
|
+
session_storage = {}
|
|
394
553
|
if args.extract_local_storage:
|
|
395
554
|
print(f"\n💾 Extracting localStorage from: {browser_path}")
|
|
396
555
|
ls_extractor = LocalStorageExtractor(browser_path, browser=browser_name)
|
|
@@ -429,7 +588,7 @@ def cmd_export(args):
|
|
|
429
588
|
except Exception:
|
|
430
589
|
pass
|
|
431
590
|
|
|
432
|
-
if not cookies and not local_storage:
|
|
591
|
+
if not cookies and not local_storage and not session_storage:
|
|
433
592
|
print("❌ No cookies or localStorage to export")
|
|
434
593
|
return
|
|
435
594
|
|
|
@@ -439,6 +598,7 @@ def cmd_export(args):
|
|
|
439
598
|
browser=browser_name,
|
|
440
599
|
profile=args.profile or "unknown",
|
|
441
600
|
local_storage=local_storage if local_storage else None,
|
|
601
|
+
session_storage=session_storage if session_storage else None,
|
|
442
602
|
)
|
|
443
603
|
|
|
444
604
|
site_name = package.get("site_name", "session")
|
|
@@ -452,6 +612,8 @@ def cmd_export(args):
|
|
|
452
612
|
print(f" Critical: {package['metadata']['critical_cookie_count']}")
|
|
453
613
|
if package['metadata'].get('local_storage_count', 0) > 0:
|
|
454
614
|
print(f" localStorage: {package['metadata']['local_storage_count']} entries")
|
|
615
|
+
if package['metadata'].get('session_storage_count', 0) > 0:
|
|
616
|
+
print(f" sessionStorage: {package['metadata']['session_storage_count']} entries")
|
|
455
617
|
|
|
456
618
|
print("\n" + packager.get_summary(package))
|
|
457
619
|
|
|
@@ -130,6 +130,7 @@ class SessionPackager:
|
|
|
130
130
|
fingerprint: Optional[Dict] = None,
|
|
131
131
|
tokens: Optional[List[Dict]] = None,
|
|
132
132
|
local_storage: Optional[Dict[str, str]] = None,
|
|
133
|
+
session_storage: Optional[Dict[str, str]] = None,
|
|
133
134
|
source_browser_manager=None,
|
|
134
135
|
tls_profile: Optional[Dict] = None,
|
|
135
136
|
oauth_config: Optional[Dict] = None) -> Dict:
|
|
@@ -143,6 +144,7 @@ class SessionPackager:
|
|
|
143
144
|
fingerprint: Optional fingerprint dict
|
|
144
145
|
tokens: Optional list of tokens
|
|
145
146
|
local_storage: Optional localStorage key-value dict
|
|
147
|
+
session_storage: Optional sessionStorage key-value dict
|
|
146
148
|
source_browser_manager: Optional browser manager for fingerprint collection
|
|
147
149
|
tls_profile: Optional TLS profile for proxy mode
|
|
148
150
|
oauth_config: Optional OAuth 2.0 configuration dict
|
|
@@ -183,6 +185,7 @@ class SessionPackager:
|
|
|
183
185
|
"cookies": cookies,
|
|
184
186
|
"tokens": tokens or [],
|
|
185
187
|
"local_storage": local_storage or {},
|
|
188
|
+
"session_storage": session_storage or {},
|
|
186
189
|
"fingerprint": fingerprint,
|
|
187
190
|
"tls_profile": tls_profile,
|
|
188
191
|
"oauth_config": oauth_config,
|
|
@@ -191,11 +194,13 @@ class SessionPackager:
|
|
|
191
194
|
"cookie_count": len(cookies),
|
|
192
195
|
"critical_cookie_count": critical_count,
|
|
193
196
|
"local_storage_count": len(local_storage) if local_storage else 0,
|
|
197
|
+
"session_storage_count": len(session_storage) if session_storage else 0,
|
|
194
198
|
},
|
|
195
199
|
}
|
|
196
200
|
|
|
197
201
|
ls_info = f", {len(local_storage)} localStorage" if local_storage else ""
|
|
198
|
-
|
|
202
|
+
ss_info = f", {len(session_storage)} sessionStorage" if session_storage else ""
|
|
203
|
+
logger.info(f"Packaged session: {site_name} ({len(cookies)} cookies, {critical_count} critical{ls_info}{ss_info})")
|
|
199
204
|
return package
|
|
200
205
|
|
|
201
206
|
def _detect_tls_profile(self, browser: str, fingerprint: Optional[Dict] = None) -> Dict:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|