pinakes-server: wire backup, session refresh, webhooks, and rate limit config
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: If2855d44cc700c0f65a5f5ac850ee3866a6a6964
This commit is contained in:
parent
4e91cb6679
commit
52f0b5defc
8 changed files with 257 additions and 105 deletions
47
crates/pinakes-server/src/routes/backup.rs
Normal file
47
crates/pinakes-server/src/routes/backup.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use axum::{
|
||||
extract::State,
|
||||
http::header::{CONTENT_DISPOSITION, CONTENT_TYPE},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
|
||||
use crate::{error::ApiError, state::AppState};
|
||||
|
||||
/// Create a database backup and return it as a downloadable file.
|
||||
/// POST /api/v1/admin/backup
|
||||
///
|
||||
/// For `SQLite`: creates a backup via VACUUM INTO and returns the file.
|
||||
/// For `PostgreSQL`: returns unsupported error (use `pg_dump` instead).
|
||||
pub async fn create_backup(
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Response, ApiError> {
|
||||
// Use a unique temp directory to avoid predictable paths
|
||||
let backup_dir = std::env::temp_dir()
|
||||
.join(format!("pinakes-backup-{}", uuid::Uuid::now_v7()));
|
||||
tokio::fs::create_dir_all(&backup_dir)
|
||||
.await
|
||||
.map_err(|e| ApiError(pinakes_core::error::PinakesError::Io(e)))?;
|
||||
|
||||
let timestamp = chrono::Utc::now().format("%Y%m%d_%H%M%S");
|
||||
let filename = format!("pinakes_backup_{timestamp}.db");
|
||||
let backup_path = backup_dir.join(&filename);
|
||||
|
||||
state.storage.backup(&backup_path).await?;
|
||||
|
||||
// Read the backup into memory and clean up the temp file
|
||||
let bytes = tokio::fs::read(&backup_path)
|
||||
.await
|
||||
.map_err(|e| ApiError(pinakes_core::error::PinakesError::Io(e)))?;
|
||||
let _ = tokio::fs::remove_dir_all(&backup_dir).await;
|
||||
|
||||
let disposition = format!("attachment; filename=\"{filename}\"");
|
||||
Ok(
|
||||
(
|
||||
[
|
||||
(CONTENT_TYPE, "application/octet-stream".to_owned()),
|
||||
(CONTENT_DISPOSITION, disposition),
|
||||
],
|
||||
bytes,
|
||||
)
|
||||
.into_response(),
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue