mirror of
https://github.com/house-of-vanity/OutFleet.git
synced 2025-10-26 10:09:08 +00:00
Improve CI and lint code
This commit is contained in:
@@ -11,7 +11,6 @@ use crate::services::acme::{AcmeError, CloudflareClient};
|
||||
pub struct AcmeClient {
|
||||
cloudflare: CloudflareClient,
|
||||
account: Account,
|
||||
directory_url: String,
|
||||
}
|
||||
|
||||
impl AcmeClient {
|
||||
@@ -43,7 +42,6 @@ impl AcmeClient {
|
||||
Ok(Self {
|
||||
cloudflare,
|
||||
account,
|
||||
directory_url,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -85,7 +83,7 @@ impl AcmeClient {
|
||||
}
|
||||
|
||||
// Get challenge value and record ID first
|
||||
let (challenge_value, record_id) = {
|
||||
let (_challenge_value, record_id) = {
|
||||
// Find DNS challenge
|
||||
let mut challenge = authz
|
||||
.challenge(ChallengeType::Dns01)
|
||||
|
||||
@@ -6,7 +6,6 @@ pub mod telegram;
|
||||
pub mod uri_generator;
|
||||
pub mod xray;
|
||||
|
||||
pub use certificates::CertificateService;
|
||||
pub use tasks::TaskScheduler;
|
||||
pub use telegram::TelegramService;
|
||||
pub use uri_generator::UriGeneratorService;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::database::entities::inbound_users;
|
||||
use crate::database::repository::{
|
||||
CertificateRepository, InboundTemplateRepository, InboundUsersRepository,
|
||||
ServerInboundRepository, ServerRepository, UserRepository,
|
||||
@@ -8,7 +7,6 @@ use crate::services::events::SyncEvent;
|
||||
use crate::services::XrayService;
|
||||
use anyhow::Result;
|
||||
use chrono::{DateTime, Utc};
|
||||
use sea_orm::{ColumnTrait, EntityTrait, JoinType, QueryFilter, RelationTrait};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -10,7 +10,7 @@ pub async fn run_polling(
|
||||
bot: Bot,
|
||||
db: DatabaseManager,
|
||||
app_config: AppConfig,
|
||||
mut shutdown_rx: oneshot::Receiver<()>,
|
||||
shutdown_rx: oneshot::Receiver<()>,
|
||||
) {
|
||||
tracing::info!("Starting Telegram bot polling...");
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ pub async fn handle_approve_request(
|
||||
};
|
||||
|
||||
match user_repo.create(dto).await {
|
||||
Ok(new_user) => {
|
||||
Ok(_new_user) => {
|
||||
// Approve the request
|
||||
request_repo
|
||||
.approve(
|
||||
@@ -297,9 +297,9 @@ pub async fn handle_approve_request(
|
||||
}
|
||||
|
||||
// Send main menu to the user instead of just notification
|
||||
let user_lang = Language::from_telegram_code(Some(&request.get_language()));
|
||||
let _user_lang = Language::from_telegram_code(Some(&request.get_language()));
|
||||
let user_repo_for_user = UserRepository::new(db.connection());
|
||||
let is_admin = false; // New users are not admins by default
|
||||
let _is_admin = false; // New users are not admins by default
|
||||
|
||||
// Create a fake user object for language detection
|
||||
let fake_user = teloxide::types::User {
|
||||
@@ -633,7 +633,7 @@ pub async fn handle_select_server_access(
|
||||
short_request_id: &str,
|
||||
db: &DatabaseManager,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let lang = Language::English; // Default admin language
|
||||
let _lang = Language::English; // Default admin language
|
||||
let _l10n = LocalizationService::new();
|
||||
let chat_id = q
|
||||
.message
|
||||
@@ -815,7 +815,7 @@ pub async fn handle_apply_server_access(
|
||||
short_request_id: &str,
|
||||
db: &DatabaseManager,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let lang = Language::English; // Default admin language
|
||||
let _lang = Language::English; // Default admin language
|
||||
let _l10n = LocalizationService::new();
|
||||
let chat_id = q
|
||||
.message
|
||||
@@ -1177,7 +1177,7 @@ pub async fn handle_user_details(
|
||||
|
||||
// Build keyboard
|
||||
let short_user_id = generate_short_user_id(&user_id.to_string());
|
||||
let mut keyboard_buttons = vec![
|
||||
let keyboard_buttons = vec![
|
||||
vec![InlineKeyboardButton::callback(
|
||||
l10n.get(lang.clone(), "manage_access"),
|
||||
format!("user_manage:{}", short_user_id),
|
||||
|
||||
@@ -17,7 +17,7 @@ pub async fn handle_command(
|
||||
msg: Message,
|
||||
cmd: Command,
|
||||
db: DatabaseManager,
|
||||
app_config: AppConfig,
|
||||
_app_config: AppConfig,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let chat_id = msg.chat.id;
|
||||
let from = &msg.from.ok_or("No user info")?;
|
||||
|
||||
@@ -289,21 +289,3 @@ pub fn get_new_user_keyboard(lang: Language) -> InlineKeyboardMarkup {
|
||||
)]])
|
||||
}
|
||||
|
||||
/// Restore UUID from compact format (without dashes)
|
||||
fn restore_uuid(compact: &str) -> Option<String> {
|
||||
if compact.len() != 32 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Insert dashes at proper positions for UUID format
|
||||
let uuid_str = format!(
|
||||
"{}-{}-{}-{}-{}",
|
||||
&compact[0..8],
|
||||
&compact[8..12],
|
||||
&compact[12..16],
|
||||
&compact[16..20],
|
||||
&compact[20..32]
|
||||
);
|
||||
|
||||
Some(uuid_str)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use teloxide::{
|
||||
|
||||
use super::super::localization::{Language, LocalizationService};
|
||||
use super::types::{get_main_keyboard, get_new_user_keyboard, get_user_language};
|
||||
use crate::database::entities::user_request::{CreateUserRequestDto, RequestStatus};
|
||||
use crate::database::entities::user_request::CreateUserRequestDto;
|
||||
use crate::database::repository::{UserRepository, UserRequestRepository};
|
||||
use crate::database::DatabaseManager;
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ pub mod error;
|
||||
pub mod handlers;
|
||||
pub mod localization;
|
||||
|
||||
pub use error::TelegramError;
|
||||
|
||||
/// Main Telegram service that manages the bot lifecycle
|
||||
pub struct TelegramService {
|
||||
|
||||
@@ -38,7 +38,6 @@ pub trait UriBuilder {
|
||||
|
||||
/// Helper functions for URI building
|
||||
pub mod utils {
|
||||
use crate::services::uri_generator::error::UriGeneratorError;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use serde_json::Value;
|
||||
|
||||
use super::{utils, UriBuilder};
|
||||
use crate::services::uri_generator::{error::UriGeneratorError, ClientConfigData};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use serde_json::{json, Value};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::{utils, UriBuilder};
|
||||
use crate::services::uri_generator::{error::UriGeneratorError, ClientConfigData};
|
||||
@@ -144,97 +143,6 @@ impl VmessUriBuilder {
|
||||
Ok(format!("vmess://{}", encoded))
|
||||
}
|
||||
|
||||
/// Build VMess URI in query parameter format (alternative)
|
||||
fn build_query_param_uri(
|
||||
&self,
|
||||
config: &ClientConfigData,
|
||||
) -> Result<String, UriGeneratorError> {
|
||||
// Apply variable substitution to stream settings
|
||||
let stream_settings = if !config.variable_values.is_null() {
|
||||
apply_variables(&config.stream_settings, &config.variable_values)?
|
||||
} else {
|
||||
config.stream_settings.clone()
|
||||
};
|
||||
|
||||
let mut params = HashMap::new();
|
||||
|
||||
// VMess uses auto encryption
|
||||
params.insert("encryption".to_string(), "auto".to_string());
|
||||
|
||||
// Determine security layer
|
||||
let has_certificate = config.certificate_domain.is_some();
|
||||
let security = utils::extract_security_type(&stream_settings, has_certificate);
|
||||
if security != "none" {
|
||||
params.insert("security".to_string(), security.clone());
|
||||
}
|
||||
|
||||
// Transport type
|
||||
let transport_type = utils::extract_transport_type(&stream_settings);
|
||||
if transport_type != "tcp" {
|
||||
params.insert("type".to_string(), transport_type.clone());
|
||||
}
|
||||
|
||||
// Transport-specific parameters
|
||||
match transport_type.as_str() {
|
||||
"ws" => {
|
||||
if let Some(path) = utils::extract_ws_path(&stream_settings) {
|
||||
params.insert("path".to_string(), path);
|
||||
}
|
||||
if let Some(host) = utils::extract_ws_host(&stream_settings) {
|
||||
params.insert("host".to_string(), host);
|
||||
}
|
||||
}
|
||||
"grpc" => {
|
||||
if let Some(service_name) = utils::extract_grpc_service_name(&stream_settings) {
|
||||
params.insert("serviceName".to_string(), service_name);
|
||||
}
|
||||
params.insert("mode".to_string(), "gun".to_string());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// TLS specific parameters
|
||||
if security != "none" {
|
||||
if let Some(sni) =
|
||||
utils::extract_tls_sni(&stream_settings, config.certificate_domain.as_deref())
|
||||
{
|
||||
params.insert("sni".to_string(), sni);
|
||||
}
|
||||
|
||||
if let Some(fp) = stream_settings
|
||||
.get("tlsSettings")
|
||||
.and_then(|tls| tls.get("fingerprint"))
|
||||
.and_then(|fp| fp.as_str())
|
||||
{
|
||||
params.insert("fp".to_string(), fp.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// Build the URI
|
||||
let query_string = utils::build_query_string(¶ms);
|
||||
let alias = utils::generate_alias(&config.server_name, &config.template_name);
|
||||
|
||||
let uri = if query_string.is_empty() {
|
||||
format!(
|
||||
"vmess://{}@{}:{}#{}",
|
||||
config.xray_user_id,
|
||||
config.hostname,
|
||||
config.port,
|
||||
utils::url_encode(&alias)
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"vmess://{}@{}:{}?{}#{}",
|
||||
config.xray_user_id,
|
||||
config.hostname,
|
||||
config.port,
|
||||
query_string,
|
||||
utils::url_encode(&alias)
|
||||
)
|
||||
};
|
||||
|
||||
Ok(uri)
|
||||
}
|
||||
}
|
||||
|
||||
impl UriBuilder for VmessUriBuilder {
|
||||
|
||||
@@ -107,7 +107,8 @@ impl UriGeneratorService {
|
||||
})
|
||||
}
|
||||
|
||||
/// Apply variable substitution to JSON values
|
||||
/// Apply variable substitution to JSON values (for testing)
|
||||
#[cfg(test)]
|
||||
pub fn apply_variable_substitution(
|
||||
&self,
|
||||
template: &Value,
|
||||
@@ -132,6 +133,7 @@ impl UriGeneratorService {
|
||||
serde_json::from_str(&result)
|
||||
.map_err(|e| UriGeneratorError::VariableSubstitution(e.to_string()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Default for UriGeneratorService {
|
||||
|
||||
@@ -9,7 +9,6 @@ use xray_core::{
|
||||
common::protocol::User,
|
||||
common::serial::TypedMessage,
|
||||
core::InboundHandlerConfig,
|
||||
prost_types,
|
||||
proxy::shadowsocks::ServerConfig as ShadowsocksServerConfig,
|
||||
proxy::shadowsocks::{Account as ShadowsocksAccount, CipherType},
|
||||
proxy::trojan::Account as TrojanAccount,
|
||||
@@ -24,23 +23,6 @@ use xray_core::{
|
||||
Client,
|
||||
};
|
||||
|
||||
/// Convert PEM format to DER (x509) format
|
||||
fn pem_to_der(pem_data: &str) -> Result<Vec<u8>> {
|
||||
// Remove PEM headers and whitespace, then decode base64
|
||||
let base64_data: String = pem_data
|
||||
.lines()
|
||||
.filter(|line| !line.starts_with("-----") && !line.trim().is_empty())
|
||||
.map(|line| line.trim())
|
||||
.collect::<Vec<&str>>()
|
||||
.join("");
|
||||
|
||||
tracing::debug!("PEM to DER conversion: {} bytes", base64_data.len());
|
||||
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
general_purpose::STANDARD
|
||||
.decode(&base64_data)
|
||||
.map_err(|e| anyhow!("Failed to decode base64 PEM data: {}", e))
|
||||
}
|
||||
|
||||
pub struct InboundClient<'a> {
|
||||
endpoint: String,
|
||||
@@ -364,7 +346,7 @@ impl<'a> InboundClient<'a> {
|
||||
/// Restart Xray with new configuration
|
||||
pub async fn restart_with_config(
|
||||
&self,
|
||||
config: &crate::services::xray::XrayConfig,
|
||||
_config: &crate::services::xray::XrayConfig,
|
||||
) -> Result<()> {
|
||||
tracing::debug!(
|
||||
"Restarting Xray server at {} with new config",
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio::time::{timeout, Duration, Instant};
|
||||
use tracing::{error, warn};
|
||||
use tracing::warn;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub mod client;
|
||||
@@ -307,7 +307,7 @@ impl XrayService {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tokio::time::{sleep, Duration};
|
||||
use tokio::time::Duration;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tokio::test]
|
||||
@@ -378,7 +378,7 @@ mod tests {
|
||||
fn test_cached_connection_expiration() {
|
||||
// Create a mock client for testing purposes
|
||||
// In real tests, we would use a mock framework
|
||||
let now = Instant::now();
|
||||
let _now = Instant::now();
|
||||
|
||||
// Test the expiration logic directly without creating an actual client
|
||||
let short_ttl = Duration::from_nanos(1);
|
||||
|
||||
@@ -13,13 +13,12 @@ use xray_core::{
|
||||
};
|
||||
|
||||
pub struct UserClient<'a> {
|
||||
endpoint: String,
|
||||
client: &'a Client,
|
||||
}
|
||||
|
||||
impl<'a> UserClient<'a> {
|
||||
pub fn new(endpoint: String, client: &'a Client) -> Self {
|
||||
Self { endpoint, client }
|
||||
pub fn new(_endpoint: String, client: &'a Client) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
|
||||
/// Add user to inbound (simple version that works)
|
||||
|
||||
Reference in New Issue
Block a user