bgustscraper 0.2.0

Advanced semantic scraping engine with AI-driven compliance checks and legal terms validation
Documentation
use anyhow::{Result, anyhow};
use serde::{Deserialize, Serialize};
use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};
use chrono::{Utc, Duration};

const DEFAULT_SECRET: &str = "bgustscraper_super_secret_key_123_change_me!";

#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
    pub sub: String,      // Nombre de usuario
    pub exp: usize,       // Timestamp de expiración
}

pub fn generate_jwt(username: &str) -> Result<String> {
    let secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| DEFAULT_SECRET.to_string());
    
    // El token expira en 2 horas
    let expiration = Utc::now()
        .checked_add_signed(Duration::hours(2))
        .ok_or_else(|| anyhow!("Error al calcular la fecha de expiración del token"))?
        .timestamp();

    let claims = Claims {
        sub: username.to_string(),
        exp: expiration as usize,
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(secret.as_bytes()),
    )?;

    Ok(token)
}

pub fn validate_jwt(token: &str) -> Result<Claims> {
    let secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| DEFAULT_SECRET.to_string());
    
    let token_data = decode::<Claims>(
        token,
        &DecodingKey::from_secret(secret.as_bytes()),
        &Validation::default(),
    )?;

    Ok(token_data.claims)
}

pub fn verify_credentials(user: &str, pass: &str) -> bool {
    let env_user = std::env::var("API_USER").unwrap_or_else(|_| "admin".to_string());
    let env_pass = std::env::var("API_PASS").unwrap_or_else(|_| "bgust2026".to_string());
    
    user == env_user && pass == env_pass
}