pinakes-server: TLS support; session persistence and security polish

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: If2c9c3e3af62bbf9f33a97be89ac40bc6a6a6964
This commit is contained in:
raf 2026-01-31 15:20:27 +03:00
commit 87a4482576
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
19 changed files with 1835 additions and 111 deletions

View file

@ -98,6 +98,24 @@ async fn main() -> Result<()> {
.validate()
.map_err(|e| anyhow::anyhow!("invalid configuration: {e}"))?;
// Warn about authentication configuration
if config.server.authentication_disabled {
tracing::warn!(
"⚠️ AUTHENTICATION IS DISABLED - All requests will be allowed without authentication!"
);
tracing::warn!("⚠️ This is INSECURE and should only be used for development.");
} else {
let has_api_key = config
.server
.api_key
.as_ref()
.map_or(false, |k| !k.is_empty());
let has_accounts = !config.accounts.users.is_empty();
if !has_api_key && !has_accounts {
tracing::error!("⚠️ No authentication method configured!");
}
}
// Apply CLI overrides
if let Some(host) = cli.host {
config.server.host = host;
@ -466,7 +484,6 @@ async fn main() -> Result<()> {
config: config_arc.clone(),
config_path: Some(config_path),
scan_progress: pinakes_core::scan::ScanProgress::new(),
sessions: Arc::new(RwLock::new(std::collections::HashMap::new())),
job_queue,
cache,
scheduler,
@ -476,14 +493,22 @@ async fn main() -> Result<()> {
// Periodic session cleanup (every 15 minutes)
{
let sessions = state.sessions.clone();
let storage_clone = storage.clone();
let cancel = shutdown_token.clone();
tokio::spawn(async move {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(15 * 60));
loop {
tokio::select! {
_ = interval.tick() => {
pinakes_server::state::cleanup_expired_sessions(&sessions).await;
match storage_clone.delete_expired_sessions().await {
Ok(count) if count > 0 => {
tracing::info!(count = count, "cleaned up expired sessions");
}
Ok(_) => {} // No sessions to clean up
Err(e) => {
tracing::error!(error = %e, "failed to cleanup expired sessions");
}
}
}
_ = cancel.cancelled() => {
break;