From f38aa3b6f16a4e54ff5b8ed24cf3d4ffeea5d6b4 Mon Sep 17 00:00:00 2001 From: zenaku Date: Tue, 26 May 2026 18:29:24 -0500 Subject: [PATCH] 26-05-16-6:29 --- {core => app}/Constants.py | 0 {core => app}/Errors.py | 0 {core => app}/Helpers.py | 0 {core => app}/__init__.py | 0 .../controllers/ApplicationController.py | 0 .../ApplicationVersionController.py | 0 {core => app}/controllers/ClientController.py | 0 .../controllers/ClientVersionController.py | 0 .../controllers/ConfigurationController.py | 0 .../controllers/ConnectionController.py | 0 .../controllers/InvoiceController.py | 0 .../controllers/LocationController.py | 0 .../controllers/OperatorController.py | 0 {core => app}/controllers/PolicyController.py | 0 .../controllers/ProfileController.py | 0 .../controllers/SessionStateController.py | 0 .../controllers/SubscriptionController.py | 0 .../controllers/SubscriptionPlanController.py | 0 .../controllers/SystemStateController.py | 0 .../encrypted_proxy/DisableController.py | 0 .../encrypted_proxy/HysteriaController.py | 0 .../encrypted_proxy/VlessController.py | 0 .../controllers/encrypted_proxy/__init__.py | 0 .../tickets/FailedVerificationController.py | 0 .../tickets/TicketPayController.py | 0 .../tickets/TicketPrepController.py | 0 .../tickets/TicketSyncController.py | 0 .../tickets/UseTicketController.py | 0 {core => app}/errors/exceptions.py | 0 {core => app}/errors/get_error_msg.py | 0 {core => app}/errors/logger.py | 0 {core => app}/models/BaseConnection.py | 0 {core => app}/models/BasePolicy.py | 0 {core => app}/models/BaseProfile.py | 0 {core => app}/models/ClientVersion.py | 0 {core => app}/models/Configuration.py | 0 {core => app}/models/Event.py | 0 {core => app}/models/Location.py | 0 {core => app}/models/Model.py | 0 {core => app}/models/Operator.py | 0 {core => app}/models/OperatorProxySession.py | 0 {core => app}/models/Subscription.py | 0 {core => app}/models/SubscriptionPlan.py | 0 {core => app}/models/invoice/Invoice.py | 0 {core => app}/models/invoice/PaymentMethod.py | 0 {core => app}/models/invoice/TicketInvoice.py | 0 .../models/policy/CapabilityPolicy.py | 0 .../models/policy/PrivilegePolicy.py | 0 {core => app}/models/session/Application.py | 0 .../models/session/ApplicationVersion.py | 0 .../models/session/NetworkPortNumbers.py | 0 .../models/session/ProxyConfiguration.py | 0 .../models/session/SessionConnection.py | 0 .../models/session/SessionProfile.py | 0 {core => app}/models/session/SessionState.py | 0 .../models/system/SystemConnection.py | 0 {core => app}/models/system/SystemProfile.py | 0 {core => app}/models/system/SystemState.py | 0 .../observers/ApplicationVersionObserver.py | 0 {core => app}/observers/BaseObserver.py | 0 {core => app}/observers/ClientObserver.py | 0 {core => app}/observers/ConnectionObserver.py | 0 .../observers/EncryptedProxyObserver.py | 0 {core => app}/observers/InvoiceObserver.py | 0 {core => app}/observers/ProfileObserver.py | 0 {core => app}/observers/TicketObserver.py | 0 .../services/WebServiceApiService.py | 0 .../services/crypto/TicketCustomer.py | 0 .../services/crypto/make_commitments.py | 0 .../services/encrypted_proxy/__init__.py | 0 .../encrypted_proxy/disable_service.py | 0 .../encrypted_proxy/hysteria_service.py | 4 +- .../services/encrypted_proxy/vless_service.py | 4 +- .../is_the_key_to_blame.py | 0 .../prep_with_previously_saved_blind_sigs.py | 0 .../test_if_new_key_works.py | 0 .../helpers/does_ticket_file_exist.py | 0 .../get_how_many_profiles_were_ordered.py | 0 .../services/helpers/get_plan_data.py | 0 .../services/helpers/get_value_from_config.py | 0 .../services/helpers/get_which_billing_key.py | 0 .../services/helpers/save_sync_results.py | 0 .../helpers/valid_profile_quantity.py | 0 .../helpers/validate_number_format.py | 0 .../networking/evaluate_networking_problem.py | 0 .../services/networking/extract_domain.py | 0 .../networking/get_connection_type.py | 0 .../networking/get_data_from_server.py | 0 .../services/networking/internet_test.py | 0 .../services/networking/is_dns_problem.py | 0 .../services/networking/is_tor_working.py | 0 {core => app}/services/networking/make_url.py | 0 .../networking/regular_get_request.py | 0 .../networking/regular_post_request.py | 0 .../networking/send_data_to_server.py | 0 {core => app}/services/networking/use_tor.py | 0 .../services/payment_phase/check_if_paid.py | 0 .../payment_phase/extract_payment_details.py | 0 .../save_and_send_intitial_billing.py | 0 .../payment_phase/save_billing_choices.py | 0 .../services/prepare_tickets/get_pub_key.py | 0 .../get_public_key_by_config.py | 0 .../make_sure_pub_key_exists.py | 0 .../prepare_tickets/save_ALL_blind_sigs.py | 0 .../prepare_tickets/send_blind_commitments.py | 0 .../prepare_tickets/setup_ticket_tracker.py | 0 .../ticket_prep_orchestrator.py | 0 .../prepare_tickets/ticket_tracker.py | 0 .../prepare_tickets/unblind_all_tickets.py | 0 .../validate_blind_signatures.py | 0 .../services/using_tickets/send_unblinded.py | 0 .../using_tickets/use_ticket_orchestrator.py | 0 .../utils/basic_operations/does_file_exist.py | 0 .../utils/basic_operations/filter_data.py | 0 .../utils/basic_operations/get_json_keys.py | 0 .../write_or_read_from_json.py | 0 .../write_string_to_text_file.py | 0 .../utils/confirm_its_a_valid_key_choice.py | 0 {core => app}/utils/convert_time.py | 0 .../utils/encrypted_proxy/__init__.py | 0 {core => app}/utils/encrypted_proxy/net.py | 0 .../utils/encrypted_proxy/singbox.py | 84 ++++-- {core => app}/utils/get_data.py | 0 {core => app}/utils/get_raw_string.py | 0 {core => app}/utils/save_data.py | 0 lib/steps.sh | 57 +++- uninstall.sh | 265 ++++++++++++++++++ 127 files changed, 383 insertions(+), 31 deletions(-) rename {core => app}/Constants.py (100%) rename {core => app}/Errors.py (100%) rename {core => app}/Helpers.py (100%) rename {core => app}/__init__.py (100%) rename {core => app}/controllers/ApplicationController.py (100%) rename {core => app}/controllers/ApplicationVersionController.py (100%) rename {core => app}/controllers/ClientController.py (100%) rename {core => app}/controllers/ClientVersionController.py (100%) rename {core => app}/controllers/ConfigurationController.py (100%) rename {core => app}/controllers/ConnectionController.py (100%) rename {core => app}/controllers/InvoiceController.py (100%) rename {core => app}/controllers/LocationController.py (100%) rename {core => app}/controllers/OperatorController.py (100%) rename {core => app}/controllers/PolicyController.py (100%) rename {core => app}/controllers/ProfileController.py (100%) rename {core => app}/controllers/SessionStateController.py (100%) rename {core => app}/controllers/SubscriptionController.py (100%) rename {core => app}/controllers/SubscriptionPlanController.py (100%) rename {core => app}/controllers/SystemStateController.py (100%) rename {core => app}/controllers/encrypted_proxy/DisableController.py (100%) rename {core => app}/controllers/encrypted_proxy/HysteriaController.py (100%) rename {core => app}/controllers/encrypted_proxy/VlessController.py (100%) rename {core => app}/controllers/encrypted_proxy/__init__.py (100%) rename {core => app}/controllers/tickets/FailedVerificationController.py (100%) rename {core => app}/controllers/tickets/TicketPayController.py (100%) rename {core => app}/controllers/tickets/TicketPrepController.py (100%) rename {core => app}/controllers/tickets/TicketSyncController.py (100%) rename {core => app}/controllers/tickets/UseTicketController.py (100%) rename {core => app}/errors/exceptions.py (100%) rename {core => app}/errors/get_error_msg.py (100%) rename {core => app}/errors/logger.py (100%) rename {core => app}/models/BaseConnection.py (100%) rename {core => app}/models/BasePolicy.py (100%) rename {core => app}/models/BaseProfile.py (100%) rename {core => app}/models/ClientVersion.py (100%) rename {core => app}/models/Configuration.py (100%) rename {core => app}/models/Event.py (100%) rename {core => app}/models/Location.py (100%) rename {core => app}/models/Model.py (100%) rename {core => app}/models/Operator.py (100%) rename {core => app}/models/OperatorProxySession.py (100%) rename {core => app}/models/Subscription.py (100%) rename {core => app}/models/SubscriptionPlan.py (100%) rename {core => app}/models/invoice/Invoice.py (100%) rename {core => app}/models/invoice/PaymentMethod.py (100%) rename {core => app}/models/invoice/TicketInvoice.py (100%) rename {core => app}/models/policy/CapabilityPolicy.py (100%) rename {core => app}/models/policy/PrivilegePolicy.py (100%) rename {core => app}/models/session/Application.py (100%) rename {core => app}/models/session/ApplicationVersion.py (100%) rename {core => app}/models/session/NetworkPortNumbers.py (100%) rename {core => app}/models/session/ProxyConfiguration.py (100%) rename {core => app}/models/session/SessionConnection.py (100%) rename {core => app}/models/session/SessionProfile.py (100%) rename {core => app}/models/session/SessionState.py (100%) rename {core => app}/models/system/SystemConnection.py (100%) rename {core => app}/models/system/SystemProfile.py (100%) rename {core => app}/models/system/SystemState.py (100%) rename {core => app}/observers/ApplicationVersionObserver.py (100%) rename {core => app}/observers/BaseObserver.py (100%) rename {core => app}/observers/ClientObserver.py (100%) rename {core => app}/observers/ConnectionObserver.py (100%) rename {core => app}/observers/EncryptedProxyObserver.py (100%) rename {core => app}/observers/InvoiceObserver.py (100%) rename {core => app}/observers/ProfileObserver.py (100%) rename {core => app}/observers/TicketObserver.py (100%) rename {core => app}/services/WebServiceApiService.py (100%) rename {core => app}/services/crypto/TicketCustomer.py (100%) rename {core => app}/services/crypto/make_commitments.py (100%) rename {core => app}/services/encrypted_proxy/__init__.py (100%) rename {core => app}/services/encrypted_proxy/disable_service.py (100%) rename {core => app}/services/encrypted_proxy/hysteria_service.py (97%) rename {core => app}/services/encrypted_proxy/vless_service.py (97%) rename {core => app}/services/failed_verification/is_the_key_to_blame.py (100%) rename {core => app}/services/failed_verification/prep_with_previously_saved_blind_sigs.py (100%) rename {core => app}/services/failed_verification/test_if_new_key_works.py (100%) rename {core => app}/services/helpers/does_ticket_file_exist.py (100%) rename {core => app}/services/helpers/get_how_many_profiles_were_ordered.py (100%) rename {core => app}/services/helpers/get_plan_data.py (100%) rename {core => app}/services/helpers/get_value_from_config.py (100%) rename {core => app}/services/helpers/get_which_billing_key.py (100%) rename {core => app}/services/helpers/save_sync_results.py (100%) rename {core => app}/services/helpers/valid_profile_quantity.py (100%) rename {core => app}/services/helpers/validate_number_format.py (100%) rename {core => app}/services/networking/evaluate_networking_problem.py (100%) rename {core => app}/services/networking/extract_domain.py (100%) rename {core => app}/services/networking/get_connection_type.py (100%) rename {core => app}/services/networking/get_data_from_server.py (100%) rename {core => app}/services/networking/internet_test.py (100%) rename {core => app}/services/networking/is_dns_problem.py (100%) rename {core => app}/services/networking/is_tor_working.py (100%) rename {core => app}/services/networking/make_url.py (100%) rename {core => app}/services/networking/regular_get_request.py (100%) rename {core => app}/services/networking/regular_post_request.py (100%) rename {core => app}/services/networking/send_data_to_server.py (100%) rename {core => app}/services/networking/use_tor.py (100%) rename {core => app}/services/payment_phase/check_if_paid.py (100%) rename {core => app}/services/payment_phase/extract_payment_details.py (100%) rename {core => app}/services/payment_phase/save_and_send_intitial_billing.py (100%) rename {core => app}/services/payment_phase/save_billing_choices.py (100%) rename {core => app}/services/prepare_tickets/get_pub_key.py (100%) rename {core => app}/services/prepare_tickets/get_public_key_by_config.py (100%) rename {core => app}/services/prepare_tickets/make_sure_pub_key_exists.py (100%) rename {core => app}/services/prepare_tickets/save_ALL_blind_sigs.py (100%) rename {core => app}/services/prepare_tickets/send_blind_commitments.py (100%) rename {core => app}/services/prepare_tickets/setup_ticket_tracker.py (100%) rename {core => app}/services/prepare_tickets/ticket_prep_orchestrator.py (100%) rename {core => app}/services/prepare_tickets/ticket_tracker.py (100%) rename {core => app}/services/prepare_tickets/unblind_all_tickets.py (100%) rename {core => app}/services/prepare_tickets/validate_blind_signatures.py (100%) rename {core => app}/services/using_tickets/send_unblinded.py (100%) rename {core => app}/services/using_tickets/use_ticket_orchestrator.py (100%) rename {core => app}/utils/basic_operations/does_file_exist.py (100%) rename {core => app}/utils/basic_operations/filter_data.py (100%) rename {core => app}/utils/basic_operations/get_json_keys.py (100%) rename {core => app}/utils/basic_operations/write_or_read_from_json.py (100%) rename {core => app}/utils/basic_operations/write_string_to_text_file.py (100%) rename {core => app}/utils/confirm_its_a_valid_key_choice.py (100%) rename {core => app}/utils/convert_time.py (100%) rename {core => app}/utils/encrypted_proxy/__init__.py (100%) rename {core => app}/utils/encrypted_proxy/net.py (100%) rename {core => app}/utils/encrypted_proxy/singbox.py (61%) rename {core => app}/utils/get_data.py (100%) rename {core => app}/utils/get_raw_string.py (100%) rename {core => app}/utils/save_data.py (100%) create mode 100755 uninstall.sh diff --git a/core/Constants.py b/app/Constants.py similarity index 100% rename from core/Constants.py rename to app/Constants.py diff --git a/core/Errors.py b/app/Errors.py similarity index 100% rename from core/Errors.py rename to app/Errors.py diff --git a/core/Helpers.py b/app/Helpers.py similarity index 100% rename from core/Helpers.py rename to app/Helpers.py diff --git a/core/__init__.py b/app/__init__.py similarity index 100% rename from core/__init__.py rename to app/__init__.py diff --git a/core/controllers/ApplicationController.py b/app/controllers/ApplicationController.py similarity index 100% rename from core/controllers/ApplicationController.py rename to app/controllers/ApplicationController.py diff --git a/core/controllers/ApplicationVersionController.py b/app/controllers/ApplicationVersionController.py similarity index 100% rename from core/controllers/ApplicationVersionController.py rename to app/controllers/ApplicationVersionController.py diff --git a/core/controllers/ClientController.py b/app/controllers/ClientController.py similarity index 100% rename from core/controllers/ClientController.py rename to app/controllers/ClientController.py diff --git a/core/controllers/ClientVersionController.py b/app/controllers/ClientVersionController.py similarity index 100% rename from core/controllers/ClientVersionController.py rename to app/controllers/ClientVersionController.py diff --git a/core/controllers/ConfigurationController.py b/app/controllers/ConfigurationController.py similarity index 100% rename from core/controllers/ConfigurationController.py rename to app/controllers/ConfigurationController.py diff --git a/core/controllers/ConnectionController.py b/app/controllers/ConnectionController.py similarity index 100% rename from core/controllers/ConnectionController.py rename to app/controllers/ConnectionController.py diff --git a/core/controllers/InvoiceController.py b/app/controllers/InvoiceController.py similarity index 100% rename from core/controllers/InvoiceController.py rename to app/controllers/InvoiceController.py diff --git a/core/controllers/LocationController.py b/app/controllers/LocationController.py similarity index 100% rename from core/controllers/LocationController.py rename to app/controllers/LocationController.py diff --git a/core/controllers/OperatorController.py b/app/controllers/OperatorController.py similarity index 100% rename from core/controllers/OperatorController.py rename to app/controllers/OperatorController.py diff --git a/core/controllers/PolicyController.py b/app/controllers/PolicyController.py similarity index 100% rename from core/controllers/PolicyController.py rename to app/controllers/PolicyController.py diff --git a/core/controllers/ProfileController.py b/app/controllers/ProfileController.py similarity index 100% rename from core/controllers/ProfileController.py rename to app/controllers/ProfileController.py diff --git a/core/controllers/SessionStateController.py b/app/controllers/SessionStateController.py similarity index 100% rename from core/controllers/SessionStateController.py rename to app/controllers/SessionStateController.py diff --git a/core/controllers/SubscriptionController.py b/app/controllers/SubscriptionController.py similarity index 100% rename from core/controllers/SubscriptionController.py rename to app/controllers/SubscriptionController.py diff --git a/core/controllers/SubscriptionPlanController.py b/app/controllers/SubscriptionPlanController.py similarity index 100% rename from core/controllers/SubscriptionPlanController.py rename to app/controllers/SubscriptionPlanController.py diff --git a/core/controllers/SystemStateController.py b/app/controllers/SystemStateController.py similarity index 100% rename from core/controllers/SystemStateController.py rename to app/controllers/SystemStateController.py diff --git a/core/controllers/encrypted_proxy/DisableController.py b/app/controllers/encrypted_proxy/DisableController.py similarity index 100% rename from core/controllers/encrypted_proxy/DisableController.py rename to app/controllers/encrypted_proxy/DisableController.py diff --git a/core/controllers/encrypted_proxy/HysteriaController.py b/app/controllers/encrypted_proxy/HysteriaController.py similarity index 100% rename from core/controllers/encrypted_proxy/HysteriaController.py rename to app/controllers/encrypted_proxy/HysteriaController.py diff --git a/core/controllers/encrypted_proxy/VlessController.py b/app/controllers/encrypted_proxy/VlessController.py similarity index 100% rename from core/controllers/encrypted_proxy/VlessController.py rename to app/controllers/encrypted_proxy/VlessController.py diff --git a/core/controllers/encrypted_proxy/__init__.py b/app/controllers/encrypted_proxy/__init__.py similarity index 100% rename from core/controllers/encrypted_proxy/__init__.py rename to app/controllers/encrypted_proxy/__init__.py diff --git a/core/controllers/tickets/FailedVerificationController.py b/app/controllers/tickets/FailedVerificationController.py similarity index 100% rename from core/controllers/tickets/FailedVerificationController.py rename to app/controllers/tickets/FailedVerificationController.py diff --git a/core/controllers/tickets/TicketPayController.py b/app/controllers/tickets/TicketPayController.py similarity index 100% rename from core/controllers/tickets/TicketPayController.py rename to app/controllers/tickets/TicketPayController.py diff --git a/core/controllers/tickets/TicketPrepController.py b/app/controllers/tickets/TicketPrepController.py similarity index 100% rename from core/controllers/tickets/TicketPrepController.py rename to app/controllers/tickets/TicketPrepController.py diff --git a/core/controllers/tickets/TicketSyncController.py b/app/controllers/tickets/TicketSyncController.py similarity index 100% rename from core/controllers/tickets/TicketSyncController.py rename to app/controllers/tickets/TicketSyncController.py diff --git a/core/controllers/tickets/UseTicketController.py b/app/controllers/tickets/UseTicketController.py similarity index 100% rename from core/controllers/tickets/UseTicketController.py rename to app/controllers/tickets/UseTicketController.py diff --git a/core/errors/exceptions.py b/app/errors/exceptions.py similarity index 100% rename from core/errors/exceptions.py rename to app/errors/exceptions.py diff --git a/core/errors/get_error_msg.py b/app/errors/get_error_msg.py similarity index 100% rename from core/errors/get_error_msg.py rename to app/errors/get_error_msg.py diff --git a/core/errors/logger.py b/app/errors/logger.py similarity index 100% rename from core/errors/logger.py rename to app/errors/logger.py diff --git a/core/models/BaseConnection.py b/app/models/BaseConnection.py similarity index 100% rename from core/models/BaseConnection.py rename to app/models/BaseConnection.py diff --git a/core/models/BasePolicy.py b/app/models/BasePolicy.py similarity index 100% rename from core/models/BasePolicy.py rename to app/models/BasePolicy.py diff --git a/core/models/BaseProfile.py b/app/models/BaseProfile.py similarity index 100% rename from core/models/BaseProfile.py rename to app/models/BaseProfile.py diff --git a/core/models/ClientVersion.py b/app/models/ClientVersion.py similarity index 100% rename from core/models/ClientVersion.py rename to app/models/ClientVersion.py diff --git a/core/models/Configuration.py b/app/models/Configuration.py similarity index 100% rename from core/models/Configuration.py rename to app/models/Configuration.py diff --git a/core/models/Event.py b/app/models/Event.py similarity index 100% rename from core/models/Event.py rename to app/models/Event.py diff --git a/core/models/Location.py b/app/models/Location.py similarity index 100% rename from core/models/Location.py rename to app/models/Location.py diff --git a/core/models/Model.py b/app/models/Model.py similarity index 100% rename from core/models/Model.py rename to app/models/Model.py diff --git a/core/models/Operator.py b/app/models/Operator.py similarity index 100% rename from core/models/Operator.py rename to app/models/Operator.py diff --git a/core/models/OperatorProxySession.py b/app/models/OperatorProxySession.py similarity index 100% rename from core/models/OperatorProxySession.py rename to app/models/OperatorProxySession.py diff --git a/core/models/Subscription.py b/app/models/Subscription.py similarity index 100% rename from core/models/Subscription.py rename to app/models/Subscription.py diff --git a/core/models/SubscriptionPlan.py b/app/models/SubscriptionPlan.py similarity index 100% rename from core/models/SubscriptionPlan.py rename to app/models/SubscriptionPlan.py diff --git a/core/models/invoice/Invoice.py b/app/models/invoice/Invoice.py similarity index 100% rename from core/models/invoice/Invoice.py rename to app/models/invoice/Invoice.py diff --git a/core/models/invoice/PaymentMethod.py b/app/models/invoice/PaymentMethod.py similarity index 100% rename from core/models/invoice/PaymentMethod.py rename to app/models/invoice/PaymentMethod.py diff --git a/core/models/invoice/TicketInvoice.py b/app/models/invoice/TicketInvoice.py similarity index 100% rename from core/models/invoice/TicketInvoice.py rename to app/models/invoice/TicketInvoice.py diff --git a/core/models/policy/CapabilityPolicy.py b/app/models/policy/CapabilityPolicy.py similarity index 100% rename from core/models/policy/CapabilityPolicy.py rename to app/models/policy/CapabilityPolicy.py diff --git a/core/models/policy/PrivilegePolicy.py b/app/models/policy/PrivilegePolicy.py similarity index 100% rename from core/models/policy/PrivilegePolicy.py rename to app/models/policy/PrivilegePolicy.py diff --git a/core/models/session/Application.py b/app/models/session/Application.py similarity index 100% rename from core/models/session/Application.py rename to app/models/session/Application.py diff --git a/core/models/session/ApplicationVersion.py b/app/models/session/ApplicationVersion.py similarity index 100% rename from core/models/session/ApplicationVersion.py rename to app/models/session/ApplicationVersion.py diff --git a/core/models/session/NetworkPortNumbers.py b/app/models/session/NetworkPortNumbers.py similarity index 100% rename from core/models/session/NetworkPortNumbers.py rename to app/models/session/NetworkPortNumbers.py diff --git a/core/models/session/ProxyConfiguration.py b/app/models/session/ProxyConfiguration.py similarity index 100% rename from core/models/session/ProxyConfiguration.py rename to app/models/session/ProxyConfiguration.py diff --git a/core/models/session/SessionConnection.py b/app/models/session/SessionConnection.py similarity index 100% rename from core/models/session/SessionConnection.py rename to app/models/session/SessionConnection.py diff --git a/core/models/session/SessionProfile.py b/app/models/session/SessionProfile.py similarity index 100% rename from core/models/session/SessionProfile.py rename to app/models/session/SessionProfile.py diff --git a/core/models/session/SessionState.py b/app/models/session/SessionState.py similarity index 100% rename from core/models/session/SessionState.py rename to app/models/session/SessionState.py diff --git a/core/models/system/SystemConnection.py b/app/models/system/SystemConnection.py similarity index 100% rename from core/models/system/SystemConnection.py rename to app/models/system/SystemConnection.py diff --git a/core/models/system/SystemProfile.py b/app/models/system/SystemProfile.py similarity index 100% rename from core/models/system/SystemProfile.py rename to app/models/system/SystemProfile.py diff --git a/core/models/system/SystemState.py b/app/models/system/SystemState.py similarity index 100% rename from core/models/system/SystemState.py rename to app/models/system/SystemState.py diff --git a/core/observers/ApplicationVersionObserver.py b/app/observers/ApplicationVersionObserver.py similarity index 100% rename from core/observers/ApplicationVersionObserver.py rename to app/observers/ApplicationVersionObserver.py diff --git a/core/observers/BaseObserver.py b/app/observers/BaseObserver.py similarity index 100% rename from core/observers/BaseObserver.py rename to app/observers/BaseObserver.py diff --git a/core/observers/ClientObserver.py b/app/observers/ClientObserver.py similarity index 100% rename from core/observers/ClientObserver.py rename to app/observers/ClientObserver.py diff --git a/core/observers/ConnectionObserver.py b/app/observers/ConnectionObserver.py similarity index 100% rename from core/observers/ConnectionObserver.py rename to app/observers/ConnectionObserver.py diff --git a/core/observers/EncryptedProxyObserver.py b/app/observers/EncryptedProxyObserver.py similarity index 100% rename from core/observers/EncryptedProxyObserver.py rename to app/observers/EncryptedProxyObserver.py diff --git a/core/observers/InvoiceObserver.py b/app/observers/InvoiceObserver.py similarity index 100% rename from core/observers/InvoiceObserver.py rename to app/observers/InvoiceObserver.py diff --git a/core/observers/ProfileObserver.py b/app/observers/ProfileObserver.py similarity index 100% rename from core/observers/ProfileObserver.py rename to app/observers/ProfileObserver.py diff --git a/core/observers/TicketObserver.py b/app/observers/TicketObserver.py similarity index 100% rename from core/observers/TicketObserver.py rename to app/observers/TicketObserver.py diff --git a/core/services/WebServiceApiService.py b/app/services/WebServiceApiService.py similarity index 100% rename from core/services/WebServiceApiService.py rename to app/services/WebServiceApiService.py diff --git a/core/services/crypto/TicketCustomer.py b/app/services/crypto/TicketCustomer.py similarity index 100% rename from core/services/crypto/TicketCustomer.py rename to app/services/crypto/TicketCustomer.py diff --git a/core/services/crypto/make_commitments.py b/app/services/crypto/make_commitments.py similarity index 100% rename from core/services/crypto/make_commitments.py rename to app/services/crypto/make_commitments.py diff --git a/core/services/encrypted_proxy/__init__.py b/app/services/encrypted_proxy/__init__.py similarity index 100% rename from core/services/encrypted_proxy/__init__.py rename to app/services/encrypted_proxy/__init__.py diff --git a/core/services/encrypted_proxy/disable_service.py b/app/services/encrypted_proxy/disable_service.py similarity index 100% rename from core/services/encrypted_proxy/disable_service.py rename to app/services/encrypted_proxy/disable_service.py diff --git a/core/services/encrypted_proxy/hysteria_service.py b/app/services/encrypted_proxy/hysteria_service.py similarity index 97% rename from core/services/encrypted_proxy/hysteria_service.py rename to app/services/encrypted_proxy/hysteria_service.py index 193e7c7..7695070 100644 --- a/core/services/encrypted_proxy/hysteria_service.py +++ b/app/services/encrypted_proxy/hysteria_service.py @@ -72,7 +72,7 @@ def enable_hysteria(username: str, password: str, server_host: str, real_ip = get_real_ip() runner = SingboxRunner() runner.stop() - config_path = Path(Constants.HV_DATA_HOME) / f"{username}-sing-box.json" + config_path = Path(Constants.SINGBOX_CONFIG_DIR) / f"{username}-sing-box.json" config = build_hysteria_config(username, password, server_host, socks5_port) try: runner.write_config(config_path, config) @@ -99,4 +99,4 @@ def disable_hysteria(observer=None) -> bool: SingboxRunner().stop() if observer: observer.notify("disconnected", {}) - return True \ No newline at end of file + return True diff --git a/core/services/encrypted_proxy/vless_service.py b/app/services/encrypted_proxy/vless_service.py similarity index 97% rename from core/services/encrypted_proxy/vless_service.py rename to app/services/encrypted_proxy/vless_service.py index 03cbc40..da45a73 100644 --- a/core/services/encrypted_proxy/vless_service.py +++ b/app/services/encrypted_proxy/vless_service.py @@ -100,7 +100,7 @@ def enable_vless(vless_link: str, username: str, real_ip = get_real_ip() runner = SingboxRunner() runner.stop() - config_path = Path(Constants.HV_DATA_HOME) / f"{username}-sing-box.json" + config_path = Path(Constants.SINGBOX_CONFIG_DIR) / f"{username}-sing-box.json" config = build_vless_config(vless, socks5_port) try: runner.write_config(config_path, config) @@ -127,4 +127,4 @@ def disable_vless(observer=None) -> bool: SingboxRunner().stop() if observer: observer.notify("disconnected", {}) - return True \ No newline at end of file + return True diff --git a/core/services/failed_verification/is_the_key_to_blame.py b/app/services/failed_verification/is_the_key_to_blame.py similarity index 100% rename from core/services/failed_verification/is_the_key_to_blame.py rename to app/services/failed_verification/is_the_key_to_blame.py diff --git a/core/services/failed_verification/prep_with_previously_saved_blind_sigs.py b/app/services/failed_verification/prep_with_previously_saved_blind_sigs.py similarity index 100% rename from core/services/failed_verification/prep_with_previously_saved_blind_sigs.py rename to app/services/failed_verification/prep_with_previously_saved_blind_sigs.py diff --git a/core/services/failed_verification/test_if_new_key_works.py b/app/services/failed_verification/test_if_new_key_works.py similarity index 100% rename from core/services/failed_verification/test_if_new_key_works.py rename to app/services/failed_verification/test_if_new_key_works.py diff --git a/core/services/helpers/does_ticket_file_exist.py b/app/services/helpers/does_ticket_file_exist.py similarity index 100% rename from core/services/helpers/does_ticket_file_exist.py rename to app/services/helpers/does_ticket_file_exist.py diff --git a/core/services/helpers/get_how_many_profiles_were_ordered.py b/app/services/helpers/get_how_many_profiles_were_ordered.py similarity index 100% rename from core/services/helpers/get_how_many_profiles_were_ordered.py rename to app/services/helpers/get_how_many_profiles_were_ordered.py diff --git a/core/services/helpers/get_plan_data.py b/app/services/helpers/get_plan_data.py similarity index 100% rename from core/services/helpers/get_plan_data.py rename to app/services/helpers/get_plan_data.py diff --git a/core/services/helpers/get_value_from_config.py b/app/services/helpers/get_value_from_config.py similarity index 100% rename from core/services/helpers/get_value_from_config.py rename to app/services/helpers/get_value_from_config.py diff --git a/core/services/helpers/get_which_billing_key.py b/app/services/helpers/get_which_billing_key.py similarity index 100% rename from core/services/helpers/get_which_billing_key.py rename to app/services/helpers/get_which_billing_key.py diff --git a/core/services/helpers/save_sync_results.py b/app/services/helpers/save_sync_results.py similarity index 100% rename from core/services/helpers/save_sync_results.py rename to app/services/helpers/save_sync_results.py diff --git a/core/services/helpers/valid_profile_quantity.py b/app/services/helpers/valid_profile_quantity.py similarity index 100% rename from core/services/helpers/valid_profile_quantity.py rename to app/services/helpers/valid_profile_quantity.py diff --git a/core/services/helpers/validate_number_format.py b/app/services/helpers/validate_number_format.py similarity index 100% rename from core/services/helpers/validate_number_format.py rename to app/services/helpers/validate_number_format.py diff --git a/core/services/networking/evaluate_networking_problem.py b/app/services/networking/evaluate_networking_problem.py similarity index 100% rename from core/services/networking/evaluate_networking_problem.py rename to app/services/networking/evaluate_networking_problem.py diff --git a/core/services/networking/extract_domain.py b/app/services/networking/extract_domain.py similarity index 100% rename from core/services/networking/extract_domain.py rename to app/services/networking/extract_domain.py diff --git a/core/services/networking/get_connection_type.py b/app/services/networking/get_connection_type.py similarity index 100% rename from core/services/networking/get_connection_type.py rename to app/services/networking/get_connection_type.py diff --git a/core/services/networking/get_data_from_server.py b/app/services/networking/get_data_from_server.py similarity index 100% rename from core/services/networking/get_data_from_server.py rename to app/services/networking/get_data_from_server.py diff --git a/core/services/networking/internet_test.py b/app/services/networking/internet_test.py similarity index 100% rename from core/services/networking/internet_test.py rename to app/services/networking/internet_test.py diff --git a/core/services/networking/is_dns_problem.py b/app/services/networking/is_dns_problem.py similarity index 100% rename from core/services/networking/is_dns_problem.py rename to app/services/networking/is_dns_problem.py diff --git a/core/services/networking/is_tor_working.py b/app/services/networking/is_tor_working.py similarity index 100% rename from core/services/networking/is_tor_working.py rename to app/services/networking/is_tor_working.py diff --git a/core/services/networking/make_url.py b/app/services/networking/make_url.py similarity index 100% rename from core/services/networking/make_url.py rename to app/services/networking/make_url.py diff --git a/core/services/networking/regular_get_request.py b/app/services/networking/regular_get_request.py similarity index 100% rename from core/services/networking/regular_get_request.py rename to app/services/networking/regular_get_request.py diff --git a/core/services/networking/regular_post_request.py b/app/services/networking/regular_post_request.py similarity index 100% rename from core/services/networking/regular_post_request.py rename to app/services/networking/regular_post_request.py diff --git a/core/services/networking/send_data_to_server.py b/app/services/networking/send_data_to_server.py similarity index 100% rename from core/services/networking/send_data_to_server.py rename to app/services/networking/send_data_to_server.py diff --git a/core/services/networking/use_tor.py b/app/services/networking/use_tor.py similarity index 100% rename from core/services/networking/use_tor.py rename to app/services/networking/use_tor.py diff --git a/core/services/payment_phase/check_if_paid.py b/app/services/payment_phase/check_if_paid.py similarity index 100% rename from core/services/payment_phase/check_if_paid.py rename to app/services/payment_phase/check_if_paid.py diff --git a/core/services/payment_phase/extract_payment_details.py b/app/services/payment_phase/extract_payment_details.py similarity index 100% rename from core/services/payment_phase/extract_payment_details.py rename to app/services/payment_phase/extract_payment_details.py diff --git a/core/services/payment_phase/save_and_send_intitial_billing.py b/app/services/payment_phase/save_and_send_intitial_billing.py similarity index 100% rename from core/services/payment_phase/save_and_send_intitial_billing.py rename to app/services/payment_phase/save_and_send_intitial_billing.py diff --git a/core/services/payment_phase/save_billing_choices.py b/app/services/payment_phase/save_billing_choices.py similarity index 100% rename from core/services/payment_phase/save_billing_choices.py rename to app/services/payment_phase/save_billing_choices.py diff --git a/core/services/prepare_tickets/get_pub_key.py b/app/services/prepare_tickets/get_pub_key.py similarity index 100% rename from core/services/prepare_tickets/get_pub_key.py rename to app/services/prepare_tickets/get_pub_key.py diff --git a/core/services/prepare_tickets/get_public_key_by_config.py b/app/services/prepare_tickets/get_public_key_by_config.py similarity index 100% rename from core/services/prepare_tickets/get_public_key_by_config.py rename to app/services/prepare_tickets/get_public_key_by_config.py diff --git a/core/services/prepare_tickets/make_sure_pub_key_exists.py b/app/services/prepare_tickets/make_sure_pub_key_exists.py similarity index 100% rename from core/services/prepare_tickets/make_sure_pub_key_exists.py rename to app/services/prepare_tickets/make_sure_pub_key_exists.py diff --git a/core/services/prepare_tickets/save_ALL_blind_sigs.py b/app/services/prepare_tickets/save_ALL_blind_sigs.py similarity index 100% rename from core/services/prepare_tickets/save_ALL_blind_sigs.py rename to app/services/prepare_tickets/save_ALL_blind_sigs.py diff --git a/core/services/prepare_tickets/send_blind_commitments.py b/app/services/prepare_tickets/send_blind_commitments.py similarity index 100% rename from core/services/prepare_tickets/send_blind_commitments.py rename to app/services/prepare_tickets/send_blind_commitments.py diff --git a/core/services/prepare_tickets/setup_ticket_tracker.py b/app/services/prepare_tickets/setup_ticket_tracker.py similarity index 100% rename from core/services/prepare_tickets/setup_ticket_tracker.py rename to app/services/prepare_tickets/setup_ticket_tracker.py diff --git a/core/services/prepare_tickets/ticket_prep_orchestrator.py b/app/services/prepare_tickets/ticket_prep_orchestrator.py similarity index 100% rename from core/services/prepare_tickets/ticket_prep_orchestrator.py rename to app/services/prepare_tickets/ticket_prep_orchestrator.py diff --git a/core/services/prepare_tickets/ticket_tracker.py b/app/services/prepare_tickets/ticket_tracker.py similarity index 100% rename from core/services/prepare_tickets/ticket_tracker.py rename to app/services/prepare_tickets/ticket_tracker.py diff --git a/core/services/prepare_tickets/unblind_all_tickets.py b/app/services/prepare_tickets/unblind_all_tickets.py similarity index 100% rename from core/services/prepare_tickets/unblind_all_tickets.py rename to app/services/prepare_tickets/unblind_all_tickets.py diff --git a/core/services/prepare_tickets/validate_blind_signatures.py b/app/services/prepare_tickets/validate_blind_signatures.py similarity index 100% rename from core/services/prepare_tickets/validate_blind_signatures.py rename to app/services/prepare_tickets/validate_blind_signatures.py diff --git a/core/services/using_tickets/send_unblinded.py b/app/services/using_tickets/send_unblinded.py similarity index 100% rename from core/services/using_tickets/send_unblinded.py rename to app/services/using_tickets/send_unblinded.py diff --git a/core/services/using_tickets/use_ticket_orchestrator.py b/app/services/using_tickets/use_ticket_orchestrator.py similarity index 100% rename from core/services/using_tickets/use_ticket_orchestrator.py rename to app/services/using_tickets/use_ticket_orchestrator.py diff --git a/core/utils/basic_operations/does_file_exist.py b/app/utils/basic_operations/does_file_exist.py similarity index 100% rename from core/utils/basic_operations/does_file_exist.py rename to app/utils/basic_operations/does_file_exist.py diff --git a/core/utils/basic_operations/filter_data.py b/app/utils/basic_operations/filter_data.py similarity index 100% rename from core/utils/basic_operations/filter_data.py rename to app/utils/basic_operations/filter_data.py diff --git a/core/utils/basic_operations/get_json_keys.py b/app/utils/basic_operations/get_json_keys.py similarity index 100% rename from core/utils/basic_operations/get_json_keys.py rename to app/utils/basic_operations/get_json_keys.py diff --git a/core/utils/basic_operations/write_or_read_from_json.py b/app/utils/basic_operations/write_or_read_from_json.py similarity index 100% rename from core/utils/basic_operations/write_or_read_from_json.py rename to app/utils/basic_operations/write_or_read_from_json.py diff --git a/core/utils/basic_operations/write_string_to_text_file.py b/app/utils/basic_operations/write_string_to_text_file.py similarity index 100% rename from core/utils/basic_operations/write_string_to_text_file.py rename to app/utils/basic_operations/write_string_to_text_file.py diff --git a/core/utils/confirm_its_a_valid_key_choice.py b/app/utils/confirm_its_a_valid_key_choice.py similarity index 100% rename from core/utils/confirm_its_a_valid_key_choice.py rename to app/utils/confirm_its_a_valid_key_choice.py diff --git a/core/utils/convert_time.py b/app/utils/convert_time.py similarity index 100% rename from core/utils/convert_time.py rename to app/utils/convert_time.py diff --git a/core/utils/encrypted_proxy/__init__.py b/app/utils/encrypted_proxy/__init__.py similarity index 100% rename from core/utils/encrypted_proxy/__init__.py rename to app/utils/encrypted_proxy/__init__.py diff --git a/core/utils/encrypted_proxy/net.py b/app/utils/encrypted_proxy/net.py similarity index 100% rename from core/utils/encrypted_proxy/net.py rename to app/utils/encrypted_proxy/net.py diff --git a/core/utils/encrypted_proxy/singbox.py b/app/utils/encrypted_proxy/singbox.py similarity index 61% rename from core/utils/encrypted_proxy/singbox.py rename to app/utils/encrypted_proxy/singbox.py index 1969c17..e315ac3 100644 --- a/core/utils/encrypted_proxy/singbox.py +++ b/app/utils/encrypted_proxy/singbox.py @@ -23,9 +23,10 @@ class SingboxRunner: _LOG_FILE = Path(Constants.SINGBOX_LOG_FILE) _CONFIG_DIR = Path(Constants.SINGBOX_CONFIG_DIR) - _START_TIMEOUT_S = 10.0 - _START_POLL_S = 0.5 + _START_TIMEOUT_S = 10.0 + _START_POLL_S = 0.5 + # ── Público ─────────────────────────────────────────────────────────────── def start(self, config_path: Path) -> bool: """ @@ -33,16 +34,14 @@ class SingboxRunner: Retorna True solo cuando el proceso está confirmado vivo. """ self.stop() - self._assert_config_safe(config_path) - - self._LOG_FILE.parent.mkdir(parents=True, exist_ok=True) + self._ensure_log_file() try: subprocess.Popen( ['sudo', self._WRAPPER, str(config_path), 'start'], stdout=subprocess.DEVNULL, - stderr=open(self._LOG_FILE, 'a'), + stderr=subprocess.DEVNULL, # el wrapper escribe el log como root stdin=subprocess.DEVNULL, env={**os.environ, 'SUDO_ASKPASS': '/bin/false'}, ) @@ -52,20 +51,23 @@ class SingboxRunner: 'Ejecutá el installer primero.' ) + # Esperar confirmación por PID file, no por tiempo fijo deadline = time.monotonic() + self._START_TIMEOUT_S while time.monotonic() < deadline: time.sleep(self._START_POLL_S) if self.is_running(): return True - error = self.get_last_error() raise RuntimeError( f'sing-box no levantó en {self._START_TIMEOUT_S}s.\n' - f'Último error:\n{error}' + f'Último error:\n{self.get_last_error()}' ) def stop(self) -> None: - + """ + Para sing-box limpiamente via wrapper. + Nunca lanza excepción — stop debe ser siempre seguro de llamar. + """ try: subprocess.run( ['sudo', self._WRAPPER, '', 'stop'], @@ -73,13 +75,17 @@ class SingboxRunner: stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL, env={**os.environ, 'SUDO_ASKPASS': '/bin/false'}, - timeout=15, + timeout=15, ) except (subprocess.TimeoutExpired, FileNotFoundError, OSError): + # Wrapper no responde — kill directo por PID file como último recurso self._emergency_kill() def is_running(self) -> bool: - + """ + Verifica por PID file + señal 0. + PermissionError significa que el proceso VIVE (corre como root). + """ if not self._PID_FILE.exists(): return False try: @@ -89,26 +95,45 @@ class SingboxRunner: os.kill(pid, 0) return True except (ValueError, ProcessLookupError): + # PID corrupto o proceso muerto — limpiar self._PID_FILE.unlink(missing_ok=True) return False except PermissionError: - + # Proceso vivo pero de root — PermissionError es señal de vida return True def get_last_error(self) -> str: + """ + Lee las últimas 80 líneas del log via sudo para evitar + problemas de permisos (el log lo escribe root via wrapper). + """ try: - lines = self._LOG_FILE.read_text(errors='replace').splitlines() - return '\n'.join(lines[-80:]) - except OSError: - return '' + result = subprocess.run( + ['sudo', self._WRAPPER, '', 'log'], + capture_output=True, + text=True, + timeout=5, + stdin=subprocess.DEVNULL, + env={**os.environ, 'SUDO_ASKPASS': '/bin/false'}, + ) + return result.stdout.strip() + except Exception: + # Fallback: leer directo si tenemos permisos + try: + lines = self._LOG_FILE.read_text(errors='replace').splitlines() + return '\n'.join(lines[-80:]) + except OSError: + return '' def write_config(self, config_path: Path, config: dict) -> None: - + """ + Escribe el JSON de forma atómica con permisos 0o600. + Write en .tmp + rename — nunca deja un config a medias. + """ self._assert_config_safe(config_path) - config_path.parent.mkdir(parents=True, exist_ok=True, mode=0o700) - tmp = config_path.with_suffix('.tmp') + tmp = config_path.with_suffix('.tmp') try: with open(tmp, 'w') as f: json.dump(config, f, indent=2) @@ -120,8 +145,20 @@ class SingboxRunner: # ── Privado ─────────────────────────────────────────────────────────────── - def _assert_config_safe(self, config_path: Path) -> None: + def _ensure_log_file(self) -> None: + """ + Crea el log file con permisos del usuario actual si no existe. + Debe llamarse ANTES de que el wrapper lo tome como root. + """ + self._LOG_FILE.parent.mkdir(parents=True, exist_ok=True) + if not self._LOG_FILE.exists(): + self._LOG_FILE.touch(mode=0o600) + def _assert_config_safe(self, config_path: Path) -> None: + """ + Verifica que el config está dentro del directorio permitido. + Lanza ValueError si no — nunca continúa con path inseguro. + """ try: config_path.resolve().relative_to(self._CONFIG_DIR.resolve()) except ValueError: @@ -132,7 +169,10 @@ class SingboxRunner: ) def _emergency_kill(self) -> None: - + """ + Kill directo por PID file cuando el wrapper no responde. + Último recurso — no usa sudo. + """ if not self._PID_FILE.exists(): return try: @@ -142,4 +182,4 @@ class SingboxRunner: except (ValueError, ProcessLookupError, PermissionError, OSError): pass finally: - self._PID_FILE.unlink(missing_ok=True) \ No newline at end of file + self._PID_FILE.unlink(missing_ok=True) diff --git a/core/utils/get_data.py b/app/utils/get_data.py similarity index 100% rename from core/utils/get_data.py rename to app/utils/get_data.py diff --git a/core/utils/get_raw_string.py b/app/utils/get_raw_string.py similarity index 100% rename from core/utils/get_raw_string.py rename to app/utils/get_raw_string.py diff --git a/core/utils/save_data.py b/app/utils/save_data.py similarity index 100% rename from core/utils/save_data.py rename to app/utils/save_data.py diff --git a/lib/steps.sh b/lib/steps.sh index 0d91ce2..fb93727 100755 --- a/lib/steps.sh +++ b/lib/steps.sh @@ -6,7 +6,7 @@ HV_CORE_HOME="$HOME/.local/share/hydra-veil/core" # Subdirectorios -HV_REPO_DIR="$HV_CORE_HOME/repo" +HV_REPO_DIR="$HV_CORE_HOME" HV_VENV_DIR="$HV_CORE_HOME/.venv" HV_DATA_DIR="$HV_CORE_HOME/data/hydra-veil" HV_LOG_DIR="$HV_CORE_HOME/logs/hydra-veil" @@ -28,6 +28,38 @@ BRANCH="core-laravel-proxyTEST" TOTAL_STEPS=6 +# ─── Helper: crear log file con permisos del usuario ───────────────────────── +# El wrapper corre como root y appendea con >>. Si root crea el archivo primero, +# Python (que corre como usuario) no puede leerlo. Esta función lo crea con +# permisos del usuario ANTES de que el wrapper lo toque por primera vez. +_ensure_log_file() { + local log_file="$1" + local log_dir + log_dir="$(dirname "$log_file")" + + # Crear directorio si no existe (permisos de usuario) + if [ ! -d "$log_dir" ]; then + mkdir -p "$log_dir" + chmod 700 "$log_dir" + fi + + # Crear el archivo solo si no existe — nunca sobreescribir + if [ ! -f "$log_file" ]; then + touch "$log_file" + chmod 600 "$log_file" + fi + + # Verificar que el usuario actual puede leerlo + if [ ! -r "$log_file" ]; then + log_warn "Log file existe pero no es legible por el usuario actual: $log_file" + log_warn "Intentando corregir permisos..." + chmod 600 "$log_file" 2>/dev/null || { + log_error "No se pudieron corregir los permisos de: $log_file" + return 1 + } + fi +} + # ─── Step 1: Repo ───────────────────────────────────────────────────────────── step_clone_repo() { print_section "Repository" @@ -306,6 +338,7 @@ step_wrapper() { # Uso: # sudo hydraveil-singbox start # sudo hydraveil-singbox "" stop +# sudo hydraveil-singbox "" log set -euo pipefail CONFIG="\${1:-}" @@ -319,8 +352,8 @@ CONFIG_DIR="${HV_CONFIG_DIR}" STOP_TIMEOUT=8 # ── Validar acción ──────────────────────────────────────────────────────────── -if [[ "\$ACTION" != "start" && "\$ACTION" != "stop" ]]; then - echo "Error: acción inválida '\$ACTION'. Uso: start|stop" >&2 +if [[ "\$ACTION" != "start" && "\$ACTION" != "stop" && "\$ACTION" != "log" ]]; then + echo "Error: acción inválida '\$ACTION'. Uso: start|stop|log" >&2 exit 1 fi @@ -367,6 +400,12 @@ _kill_by_pidfile() { rm -f "\$PID_FILE" } +# ── log ─────────────────────────────────────────────────────────────────────── +if [[ "\$ACTION" == "log" ]]; then + [ -f "\$LOG_FILE" ] && tail -80 "\$LOG_FILE" || echo "Sin logs disponibles" + exit 0 +fi + # ── stop ────────────────────────────────────────────────────────────────────── if [[ "\$ACTION" == "stop" ]]; then _kill_by_pidfile @@ -419,9 +458,11 @@ fi _kill_by_pidfile _delete_tun -# 7. Directorios +# 7. Directorios — solo mkdir/chmod, nunca tocar el log file existente mkdir -p "\$(dirname "\$PID_FILE")" && chmod 700 "\$(dirname "\$PID_FILE")" mkdir -p "\$(dirname "\$LOG_FILE")" && chmod 700 "\$(dirname "\$LOG_FILE")" +# NOTA: el log file fue creado por el installer con permisos del usuario. +# El wrapper solo appendea (>>) — nunca lo recrea ni cambia sus permisos. # 8. Lanzar sing-box "\$SINGBOX_BIN" run -c "\$CONFIG" >> "\$LOG_FILE" 2>&1 & @@ -486,4 +527,10 @@ EOF chmod 700 "$_dir" log_ok "Directorio → ${_dir}" done -} \ No newline at end of file + + # ── Crear log file con permisos del usuario ANTES de que root lo toque ──── + # Crítico: si root crea el archivo primero (via wrapper), Python no puede + # leerlo. _ensure_log_file() lo crea como usuario con chmod 600 ahora. + _ensure_log_file "$SINGBOX_LOG_FILE" + log_ok "Log file preparado con permisos de usuario → ${SINGBOX_LOG_FILE}" +} diff --git a/uninstall.sh b/uninstall.sh new file mode 100755 index 0000000..c5a9c43 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,265 @@ +#!/bin/bash +# hv-clean.sh — Limpieza completa de hydra-veil para reinstalación limpia +# Elimina: wrapper, sudoers, dirs de runtime (logs/run/pid) +# Conserva: repo, venv, configs (a menos que se pase --full) + +set -euo pipefail + +# ─── Colores ────────────────────────────────────────────────────────────────── +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +DIM='\033[2m' +BOLD='\033[1m' +RESET='\033[0m' + +ok() { printf " ${GREEN}✔${RESET} %s\n" "$*"; } +warn() { printf " ${YELLOW}⚠${RESET} %s\n" "$*"; } +info() { printf " ${CYAN}→${RESET} %s\n" "$*"; } +err() { printf " ${RED}✖${RESET} %s\n" "$*" >&2; } +hdr() { echo ""; printf "${BOLD}${CYAN}── %s ${RESET}\n" "$*"; echo ""; } + +# ─── Paths (deben coincidir con steps.sh) ──────────────────────────────────── +HV_CORE_HOME="$HOME/.local/share/hydra-veil/core" +HV_LOG_DIR="$HV_CORE_HOME/logs/hydra-veil" +HV_RUN_DIR="$HV_CORE_HOME/run" +HV_DATA_DIR="$HV_CORE_HOME/data/hydra-veil" +HV_CONFIG_DIR="$HV_DATA_DIR/configs" +HV_VENV_DIR="$HV_CORE_HOME/.venv" + +SINGBOX_BIN="/usr/bin/sing-box" +SINGBOX_PID_FILE="$HV_RUN_DIR/singbox.pid" +SINGBOX_LOG_FILE="$HV_LOG_DIR/singbox.log" + +WRAPPER_PATH="/usr/local/bin/hydraveil-singbox" +SUDOERS_PATH="/etc/sudoers.d/hydraveil" + +# ─── Flags ──────────────────────────────────────────────────────────────────── +FULL=false +YES=false + +for arg in "$@"; do + case "$arg" in + --full|-f) FULL=true ;; + --yes|-y) YES=true ;; + --help|-h) + echo "" + echo " Uso: $0 [opciones]" + echo "" + echo " Sin flags — elimina wrapper, sudoers, logs, pid, run" + echo " conserva repo, venv y configs" + echo "" + echo " --full — todo lo anterior + repo completo, venv y configs" + echo " --yes — no pide confirmación" + echo "" + exit 0 + ;; + *) + err "Flag desconocido: $arg" + exit 1 + ;; + esac +done + +# ─── Banner ─────────────────────────────────────────────────────────────────── +echo "" +printf "${BOLD}${RED} hydra-veil — limpieza para reinstalación${RESET}\n" +echo "" + +if $FULL; then + warn "Modo --full: se eliminará TODO incluyendo repo, venv y configs" +else + info "Modo normal: conserva repo, venv y configs" +fi + +echo "" + +# ─── Confirmación ───────────────────────────────────────────────────────────── +if ! $YES; then + printf " ${YELLOW}¿Continuar?${RESET} ${DIM}[s/N]:${RESET} " + read -r _confirm < /dev/tty + case "$_confirm" in + s|S|y|Y) : ;; + *) + echo "" + info "Cancelado." + exit 0 + ;; + esac + echo "" +fi + +# ─── 1. Detener sing-box si está corriendo ──────────────────────────────────── +hdr "1. Proceso sing-box" + +_stop_singbox() { + local pid="" + + # Intentar via pidfile primero + if [ -f "$SINGBOX_PID_FILE" ]; then + pid=$(cat "$SINGBOX_PID_FILE" 2>/dev/null || echo "") + fi + + # Si no hay pidfile, buscar por nombre + if [[ -z "$pid" || ! "$pid" =~ ^[0-9]+$ ]]; then + pid=$(pgrep -x sing-box 2>/dev/null | head -1 || echo "") + fi + + if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null; then + info "Deteniendo sing-box PID $pid..." + kill -TERM "$pid" 2>/dev/null || true + local elapsed=0 + while kill -0 "$pid" 2>/dev/null && (( elapsed < 16 )); do + sleep 0.5 + (( elapsed++ )) || true + done + if kill -0 "$pid" 2>/dev/null; then + kill -KILL "$pid" 2>/dev/null || true + sleep 0.3 + ok "sing-box eliminado (SIGKILL)" + else + ok "sing-box detenido (SIGTERM)" + fi + else + info "sing-box no está corriendo" + fi +} + +# Intentar via wrapper si existe, sino directo +if [ -x "$WRAPPER_PATH" ]; then + sudo "$WRAPPER_PATH" "" stop 2>/dev/null && ok "Detenido via wrapper" || _stop_singbox +else + _stop_singbox +fi + +# Eliminar interfaz tun0 si existe +if ip link show tun0 &>/dev/null 2>&1; then + sudo ip link delete tun0 2>/dev/null && ok "tun0 eliminada" || warn "No se pudo eliminar tun0" +else + info "tun0 no existe" +fi + +# ─── 2. Wrapper ─────────────────────────────────────────────────────────────── +hdr "2. Wrapper" + +if [ -f "$WRAPPER_PATH" ]; then + sudo rm -f "$WRAPPER_PATH" + ok "Eliminado: $WRAPPER_PATH" +else + info "No existe: $WRAPPER_PATH" +fi + +# ─── 3. Sudoers ─────────────────────────────────────────────────────────────── +hdr "3. Sudoers" + +if [ -f "$SUDOERS_PATH" ]; then + sudo rm -f "$SUDOERS_PATH" + ok "Eliminado: $SUDOERS_PATH" +else + info "No existe: $SUDOERS_PATH" +fi + +# Verificar que no haya entradas huérfanas en sudoers.d +_orphans=$(sudo grep -rl "hydraveil" /etc/sudoers.d/ 2>/dev/null || true) +if [ -n "$_orphans" ]; then + warn "Entradas huérfanas de hydraveil encontradas:" + echo "$_orphans" | while read -r f; do + warn " $f" + sudo rm -f "$f" && ok " Eliminado: $f" + done +else + info "Sin entradas huérfanas en sudoers.d" +fi + +# ─── 4. PID file y runtime ──────────────────────────────────────────────────── +hdr "4. Runtime (pid / run)" + +if [ -f "$SINGBOX_PID_FILE" ]; then + rm -f "$SINGBOX_PID_FILE" + ok "Eliminado PID file: $SINGBOX_PID_FILE" +else + info "Sin PID file" +fi + +if [ -d "$HV_RUN_DIR" ]; then + rm -rf "$HV_RUN_DIR" + ok "Eliminado: $HV_RUN_DIR" +else + info "No existe: $HV_RUN_DIR" +fi + +# ─── 5. Logs ────────────────────────────────────────────────────────────────── +hdr "5. Logs" + +if [ -d "$HV_LOG_DIR" ]; then + rm -rf "$HV_LOG_DIR" + ok "Eliminado: $HV_LOG_DIR" +else + info "No existe: $HV_LOG_DIR" +fi + +# ─── 6. Limpieza completa (--full) ──────────────────────────────────────────── +if $FULL; then + hdr "6. Limpieza completa (--full)" + + # Configs + if [ -d "$HV_CONFIG_DIR" ]; then + rm -rf "$HV_CONFIG_DIR" + ok "Eliminado: $HV_CONFIG_DIR" + else + info "No existe: $HV_CONFIG_DIR" + fi + + # Data dir completo + if [ -d "$HV_DATA_DIR" ]; then + rm -rf "$HV_DATA_DIR" + ok "Eliminado: $HV_DATA_DIR" + else + info "No existe: $HV_DATA_DIR" + fi + + # Venv + if [ -d "$HV_VENV_DIR" ]; then + rm -rf "$HV_VENV_DIR" + ok "Eliminado venv: $HV_VENV_DIR" + else + info "No existe: $HV_VENV_DIR" + fi + + # Repo completo + if [ -d "$HV_CORE_HOME/.git" ]; then + rm -rf "$HV_CORE_HOME" + ok "Eliminado repo: $HV_CORE_HOME" + elif [ -d "$HV_CORE_HOME" ]; then + rm -rf "$HV_CORE_HOME" + ok "Eliminado directorio: $HV_CORE_HOME" + else + info "No existe: $HV_CORE_HOME" + fi + + # sing-box binary (solo si se instaló por el installer, no si era preexistente) + if [ -L "$SINGBOX_BIN" ]; then + sudo rm -f "$SINGBOX_BIN" + ok "Eliminado symlink sing-box: $SINGBOX_BIN" + else + info "sing-box no es symlink — conservado: $SINGBOX_BIN" + fi +fi + +# ─── Resumen ────────────────────────────────────────────────────────────────── +echo "" +printf "${BOLD}${GREEN} ✔ Limpieza completa.${RESET}" + +if $FULL; then + printf " ${DIM}(modo --full)${RESET}\n" +else + printf "\n" + echo "" + printf " ${DIM}Conservados: repo, venv, configs${RESET}\n" + printf " ${DIM}Para eliminar todo: %s --full${RESET}\n" "$0" +fi + +echo "" +info "Podés correr el installer nuevamente sin conflictos." +echo ""