mirror of
https://github.com/house-of-vanity/khm.git
synced 2025-08-21 14:27:14 +00:00
Added auto deprecation feature
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -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",
|
||||||
|
@@ -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"
|
||||||
|
@@ -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",
|
||||||
|
@@ -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");
|
||||||
|
@@ -10,7 +10,10 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<header>
|
<header>
|
||||||
|
<div class="header-title">
|
||||||
<h1>SSH Key Manager</h1>
|
<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">
|
||||||
|
@@ -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();
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user