pinakes-server: validate GPS coordinate bounds; validate saved search fields and sort_order

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Idca86117aeeff4afd489ee00bb5c70a36a6a6964
This commit is contained in:
raf 2026-03-12 20:47:44 +03:00
commit 61eb2335d3
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
4 changed files with 51 additions and 0 deletions

View file

@ -22,10 +22,43 @@ pub struct SavedSearchResponse {
pub created_at: chrono::DateTime<chrono::Utc>,
}
const VALID_SORT_ORDERS: &[&str] = &[
"date_asc",
"date_desc",
"name_asc",
"name_desc",
"size_asc",
"size_desc",
];
pub async fn create_saved_search(
State(state): State<AppState>,
Json(req): Json<CreateSavedSearchRequest>,
) -> Result<Json<SavedSearchResponse>, ApiError> {
let name_len = req.name.chars().count();
if name_len == 0 || name_len > 255 {
return Err(ApiError(
pinakes_core::error::PinakesError::InvalidOperation(
"name must be 1-255 characters".into(),
),
));
}
if req.query.is_empty() || req.query.len() > 2048 {
return Err(ApiError(
pinakes_core::error::PinakesError::InvalidOperation(
"query must be 1-2048 bytes".into(),
),
));
}
if let Some(ref sort) = req.sort_order
&& !VALID_SORT_ORDERS.contains(&sort.as_str()) {
return Err(ApiError(
pinakes_core::error::PinakesError::InvalidOperation(format!(
"sort_order must be one of: {}",
VALID_SORT_ORDERS.join(", ")
)),
));
}
let id = uuid::Uuid::now_v7();
state
.storage