Added auto deprecation feature

This commit is contained in:
Ultradesu
2025-07-20 17:37:46 +03:00
parent 9c5518b39e
commit af6c4d7e61
7 changed files with 58 additions and 3 deletions

2
Cargo.lock generated
View File

@@ -1139,7 +1139,7 @@ dependencies = [
[[package]] [[package]]
name = "khm" name = "khm"
version = "0.6.2" version = "0.6.3"
dependencies = [ dependencies = [
"actix-web", "actix-web",
"base64 0.21.7", "base64 0.21.7",

View File

@@ -12,11 +12,13 @@ env_logger = "0.11.3"
log = "0.4" log = "0.4"
regex = "1.10.5" regex = "1.10.5"
base64 = "0.21" base64 = "0.21"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full", "sync"] }
tokio-postgres = { version = "0.7", features = ["with-chrono-0_4"] } tokio-postgres = { version = "0.7", features = ["with-chrono-0_4"] }
tokio-util = { version = "0.7", features = ["codec"] } tokio-util = { version = "0.7", features = ["codec"] }
clap = { version = "4", features = ["derive"] } clap = { version = "4", features = ["derive"] }
chrono = "0.4.38" chrono = "0.4.38"
reqwest = { version = "0.12", features = ["json"] } reqwest = { version = "0.12", features = ["json"] }
trust-dns-resolver = "0.23"
futures = "0.3"
hostname = "0.3" hostname = "0.3"
rust-embed = "8.0" rust-embed = "8.0"

View File

@@ -305,6 +305,7 @@ pub async fn run_server(args: crate::Args) -> std::io::Result<()> {
.app_data(web::Data::new(db_client.clone())) .app_data(web::Data::new(db_client.clone()))
.app_data(allowed_flows.clone()) .app_data(allowed_flows.clone())
// API routes // API routes
.route("/api/version", web::get().to(crate::web::get_version_api))
.route("/api/flows", web::get().to(crate::web::get_flows_api)) .route("/api/flows", web::get().to(crate::web::get_flows_api))
.route( .route(
"/{flow_id}/scan-dns", "/{flow_id}/scan-dns",

View File

@@ -67,6 +67,13 @@ async fn check_dns_resolution(hostname: String, semaphore: Arc<Semaphore>) -> Dn
} }
} }
// API endpoint to get application version
pub async fn get_version_api() -> Result<HttpResponse> {
Ok(HttpResponse::Ok().json(json!({
"version": env!("CARGO_PKG_VERSION")
})))
}
// API endpoint to get list of available flows // API endpoint to get list of available flows
pub async fn get_flows_api(allowed_flows: web::Data<Vec<String>>) -> Result<HttpResponse> { pub async fn get_flows_api(allowed_flows: web::Data<Vec<String>>) -> Result<HttpResponse> {
info!("API request for available flows"); info!("API request for available flows");

View File

@@ -10,7 +10,10 @@
<body> <body>
<div class="container"> <div class="container">
<header> <header>
<h1>SSH Key Manager</h1> <div class="header-title">
<h1>SSH Key Manager</h1>
<span class="version" id="appVersion">Loading...</span>
</div>
<div class="flow-selector"> <div class="flow-selector">
<label for="flowSelect">Flow:</label> <label for="flowSelect">Flow:</label>
<select id="flowSelect"> <select id="flowSelect">

View File

@@ -12,6 +12,7 @@ class SSHKeyManager {
this.showDeprecatedOnly = false; this.showDeprecatedOnly = false;
this.initializeEventListeners(); this.initializeEventListeners();
this.loadVersion();
this.loadFlows(); this.loadFlows();
} }
@@ -149,6 +150,20 @@ class SSHKeyManager {
}); });
} }
async loadVersion() {
try {
const response = await fetch('/api/version');
if (response.ok) {
const data = await response.json();
document.getElementById('appVersion').textContent = `v${data.version}`;
} else {
document.getElementById('appVersion').textContent = 'Unknown';
}
} catch (error) {
document.getElementById('appVersion').textContent = 'Error';
}
}
async loadFlows() { async loadFlows() {
try { try {
this.showLoading(); this.showLoading();

View File

@@ -50,6 +50,23 @@ header h1 {
font-size: 2.5rem; font-size: 2.5rem;
font-weight: 600; font-weight: 600;
color: var(--text-primary); color: var(--text-primary);
margin: 0;
}
.header-title {
display: flex;
align-items: baseline;
gap: 1rem;
}
.version {
font-size: 0.875rem;
color: var(--text-secondary);
background: var(--background);
padding: 0.25rem 0.5rem;
border-radius: var(--border-radius);
font-weight: 500;
border: 1px solid var(--border);
} }
.flow-selector { .flow-selector {
@@ -594,6 +611,16 @@ header h1 {
align-items: stretch; align-items: stretch;
} }
.header-title {
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
}
.header-title h1 {
font-size: 2rem;
}
.actions-panel { .actions-panel {
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;