some changes
This commit is contained in:
+88
-9
@@ -99,7 +99,11 @@ pub async fn upload_pad_file(
|
||||
stored = format!("{stem}-{}{}", db::random_suffix(6), ext);
|
||||
key = crate::storage::object_key("pads", pad.id, &file_token, &stored);
|
||||
}
|
||||
let url = format!("/f/{}/{}", file_token, stored);
|
||||
let stored_url = crate::file_urls::stored_file_path(&file_token, &stored);
|
||||
let public_url = crate::file_urls::public_file_url(
|
||||
state.files_public_url.as_deref(),
|
||||
&stored_url,
|
||||
);
|
||||
let mime = mime_guess::from_path(&stored)
|
||||
.first_or_octet_stream()
|
||||
.to_string();
|
||||
@@ -109,8 +113,16 @@ pub async fn upload_pad_file(
|
||||
.put(&key, bytes.clone().into(), &mime, &cache_control)
|
||||
.await
|
||||
.map_err(|_| ApiError::internal("Failed to save the file"))?;
|
||||
db::register_pad_file(&state.db, pad.id, &stored, &url, &mime, bytes.len() as i64).await?;
|
||||
Ok(Json(serde_json::json!({"name": stored, "url": url, "mime_type": mime})))
|
||||
db::register_pad_file(
|
||||
&state.db,
|
||||
pad.id,
|
||||
&stored,
|
||||
&stored_url,
|
||||
&mime,
|
||||
bytes.len() as i64,
|
||||
)
|
||||
.await?;
|
||||
Ok(Json(serde_json::json!({"name": stored, "url": public_url, "mime_type": mime})))
|
||||
}
|
||||
|
||||
pub(super) fn content_references_file(content: &str, filename: &str, url: &str) -> bool {
|
||||
@@ -136,6 +148,26 @@ pub(super) fn content_references_file(content: &str, filename: &str, url: &str)
|
||||
false
|
||||
}
|
||||
|
||||
pub(super) fn content_references_stored_file(
|
||||
content: &str,
|
||||
filename: &str,
|
||||
stored_url: &str,
|
||||
public_base: Option<&str>,
|
||||
) -> bool {
|
||||
if content_references_file(content, filename, stored_url) {
|
||||
return true;
|
||||
}
|
||||
let canonical = crate::file_urls::canonical_file_path(stored_url);
|
||||
if canonical
|
||||
.as_deref()
|
||||
.is_some_and(|url| url != stored_url && content.contains(url))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
let public_url = crate::file_urls::public_file_url(public_base, stored_url);
|
||||
public_url != stored_url && content.contains(&public_url)
|
||||
}
|
||||
|
||||
pub async fn pad_files(
|
||||
State(state): State<SharedState>,
|
||||
headers: HeaderMap,
|
||||
@@ -153,7 +185,12 @@ pub async fn pad_files(
|
||||
.await?;
|
||||
let mut files = db::list_pad_files(&state.db, pad.id).await?;
|
||||
for file in &mut files {
|
||||
let attached = content_references_file(&pad.content, &file.filename, &file.url);
|
||||
let attached = content_references_stored_file(
|
||||
&pad.content,
|
||||
&file.filename,
|
||||
&file.url,
|
||||
state.files_public_url.as_deref(),
|
||||
);
|
||||
if attached != file.is_attached {
|
||||
db::set_pad_file_attached(&state.db, file.id, attached).await?;
|
||||
file.is_attached = attached;
|
||||
@@ -164,6 +201,10 @@ pub async fn pad_files(
|
||||
};
|
||||
}
|
||||
file.created_at = db::normalize_timestamp(&file.created_at);
|
||||
file.url = crate::file_urls::public_file_url(
|
||||
state.files_public_url.as_deref(),
|
||||
&file.url,
|
||||
);
|
||||
}
|
||||
Ok(Json(files))
|
||||
}
|
||||
@@ -298,7 +339,11 @@ pub async fn upload_note_file(
|
||||
stored = format!("{stem}-{}{}", db::random_suffix(6), ext);
|
||||
key = crate::storage::object_key("notes", note.id, &file_token, &stored);
|
||||
}
|
||||
let url = format!("/f/{}/{}", file_token, stored);
|
||||
let stored_url = crate::file_urls::stored_file_path(&file_token, &stored);
|
||||
let public_url = crate::file_urls::public_file_url(
|
||||
state.files_public_url.as_deref(),
|
||||
&stored_url,
|
||||
);
|
||||
let mime = mime_guess::from_path(&stored)
|
||||
.first_or_octet_stream()
|
||||
.to_string();
|
||||
@@ -308,8 +353,16 @@ pub async fn upload_note_file(
|
||||
.put(&key, bytes.clone().into(), &mime, &cache_control)
|
||||
.await
|
||||
.map_err(|_| ApiError::internal("Failed to save the file"))?;
|
||||
db::register_note_file(&state.db, note.id, &stored, &url, &mime, bytes.len() as i64).await?;
|
||||
Ok(Json(serde_json::json!({"name": stored, "url": url, "mime_type": mime})))
|
||||
db::register_note_file(
|
||||
&state.db,
|
||||
note.id,
|
||||
&stored,
|
||||
&stored_url,
|
||||
&mime,
|
||||
bytes.len() as i64,
|
||||
)
|
||||
.await?;
|
||||
Ok(Json(serde_json::json!({"name": stored, "url": public_url, "mime_type": mime})))
|
||||
}
|
||||
|
||||
pub async fn delete_note(
|
||||
@@ -382,7 +435,12 @@ pub async fn note_files(
|
||||
.await?;
|
||||
let mut files = db::list_note_files(&state.db, note.id).await?;
|
||||
for file in &mut files {
|
||||
let attached = content_references_file(¬e.content, &file.filename, &file.url);
|
||||
let attached = content_references_stored_file(
|
||||
¬e.content,
|
||||
&file.filename,
|
||||
&file.url,
|
||||
state.files_public_url.as_deref(),
|
||||
);
|
||||
if attached != file.is_attached {
|
||||
db::set_note_file_attached(&state.db, file.id, attached).await?;
|
||||
file.is_attached = attached;
|
||||
@@ -393,6 +451,10 @@ pub async fn note_files(
|
||||
};
|
||||
}
|
||||
file.created_at = db::normalize_timestamp(&file.created_at);
|
||||
file.url = crate::file_urls::public_file_url(
|
||||
state.files_public_url.as_deref(),
|
||||
&file.url,
|
||||
);
|
||||
}
|
||||
Ok(Json(files))
|
||||
}
|
||||
@@ -580,7 +642,7 @@ fn sanitize_filename(value: &str) -> String {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::is_safe_inline_image_mime;
|
||||
use super::{content_references_stored_file, is_safe_inline_image_mime};
|
||||
|
||||
#[test]
|
||||
fn only_raster_images_are_inline() {
|
||||
@@ -590,4 +652,21 @@ mod tests {
|
||||
assert!(!is_safe_inline_image_mime("text/html"));
|
||||
assert!(!is_safe_inline_image_mime("application/xml"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attachment_references_survive_origin_changes() {
|
||||
let stored = "/f/token/image.png";
|
||||
assert!(content_references_stored_file(
|
||||
"",
|
||||
"image.png",
|
||||
stored,
|
||||
None,
|
||||
));
|
||||
assert!(content_references_stored_file(
|
||||
"",
|
||||
"image.png",
|
||||
"https://old-files.example.com/f/token/image.png",
|
||||
Some("https://new-files.example.com"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user