mirror of
https://github.com/v0l/route96.git
synced 2025-06-19 07:04:58 +00:00
Implement payments system with default free allowance and quota enforcement (#17)
* Initial plan for issue * Implement complete payments system with quota enforcement - Add default free allowance configuration (100MB) - Implement quota checking before uploads in both blossom and nip96 routes - Add comprehensive quota checking functions in database module - Enhance admin API to show quota information - Add payment processing infrastructure - Include all necessary database migrations Users now get 100MB free storage + any valid paid storage. Uploads are rejected when quota would be exceeded. * Move free_quota_bytes to PaymentConfig and restore mime_type parameter Co-authored-by: v0l <1172179+v0l@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: v0l <1172179+v0l@users.noreply.github.com>
This commit is contained in:
@ -25,7 +25,7 @@ pub struct BlobDescriptor {
|
||||
pub size: u64,
|
||||
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
|
||||
pub mime_type: Option<String>,
|
||||
pub uploaded: u64,
|
||||
pub created: u64,
|
||||
#[serde(rename = "nip94", skip_serializing_if = "Option::is_none")]
|
||||
pub nip94: Option<HashMap<String, String>>,
|
||||
}
|
||||
@ -45,7 +45,7 @@ impl BlobDescriptor {
|
||||
sha256: id_hex,
|
||||
size: value.size,
|
||||
mime_type: Some(value.mime_type.clone()),
|
||||
uploaded: value.created.timestamp() as u64,
|
||||
created: value.created.timestamp() as u64,
|
||||
nip94: Some(
|
||||
Nip94Event::from_upload(settings, value)
|
||||
.tags
|
||||
@ -362,6 +362,21 @@ async fn process_upload(
|
||||
return e;
|
||||
}
|
||||
|
||||
// check quota
|
||||
#[cfg(feature = "payments")]
|
||||
if let Some(upload_size) = size {
|
||||
let free_quota = settings.payments.as_ref()
|
||||
.and_then(|p| p.free_quota_bytes)
|
||||
.unwrap_or(104857600); // Default to 100MB
|
||||
let pubkey_vec = auth.event.pubkey.to_bytes().to_vec();
|
||||
|
||||
match db.check_user_quota(&pubkey_vec, upload_size, free_quota).await {
|
||||
Ok(false) => return BlossomResponse::error("Upload would exceed quota"),
|
||||
Err(_) => return BlossomResponse::error("Failed to check quota"),
|
||||
Ok(true) => {} // Quota check passed
|
||||
}
|
||||
}
|
||||
|
||||
process_stream(
|
||||
data.open(ByteUnit::Byte(settings.max_upload_bytes)),
|
||||
&auth
|
||||
@ -415,7 +430,7 @@ where
|
||||
return BlossomResponse::error(format!("Failed to save file (db): {}", e));
|
||||
}
|
||||
};
|
||||
if let Err(e) = db.add_file(&upload, Some(user_id)).await {
|
||||
if let Err(e) = db.add_file(&upload, user_id).await {
|
||||
error!("{}", e.to_string());
|
||||
BlossomResponse::error(format!("Error saving file (db): {}", e))
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user