Replace client-side tag URLs with collection IDs
This commit is contained in:
parent
be67972760
commit
d09770913b
8 changed files with 55 additions and 19 deletions
|
@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
### Changed
|
||||
|
||||
- Make `delete-emoji` command accept emoji name and hostname instead of ID.
|
||||
- Replaced client-side tag URLs with collection IDs.
|
||||
|
||||
### Security
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use crate::activitypub::{
|
|||
local_actor_subscribers,
|
||||
local_emoji_id,
|
||||
local_object_id,
|
||||
local_tag_collection,
|
||||
},
|
||||
types::{Attachment, EmojiTag, EmojiTagImage, LinkTag, SimpleTag},
|
||||
vocabulary::*,
|
||||
|
@ -25,7 +26,6 @@ use crate::models::{
|
|||
users::types::User,
|
||||
};
|
||||
use crate::utils::files::get_file_url;
|
||||
use crate::web_client::urls::get_tag_page_url;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Serialize)]
|
||||
|
@ -136,11 +136,11 @@ pub fn build_note(
|
|||
tags.push(Tag::SimpleTag(tag));
|
||||
};
|
||||
for tag_name in &post.tags {
|
||||
let tag_page_url = get_tag_page_url(instance_url, tag_name);
|
||||
let tag_href = local_tag_collection(instance_url, tag_name);
|
||||
let tag = SimpleTag {
|
||||
name: format!("#{}", tag_name),
|
||||
tag_type: HASHTAG.to_string(),
|
||||
href: tag_page_url,
|
||||
href: tag_href,
|
||||
};
|
||||
tags.push(Tag::SimpleTag(tag));
|
||||
};
|
||||
|
@ -327,7 +327,11 @@ mod tests {
|
|||
username: "author".to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
let post = Post { author, ..Default::default() };
|
||||
let post = Post {
|
||||
author,
|
||||
tags: vec!["test".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
let note = build_note(INSTANCE_HOSTNAME, INSTANCE_URL, &post);
|
||||
|
||||
assert_eq!(
|
||||
|
@ -345,6 +349,13 @@ mod tests {
|
|||
assert_eq!(note.cc, vec![
|
||||
local_actor_followers(INSTANCE_URL, "author"),
|
||||
]);
|
||||
assert_eq!(note.tag.len(), 1);
|
||||
let tag = match note.tag[0] {
|
||||
Tag::SimpleTag(ref tag) => tag,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(tag.name, "#test");
|
||||
assert_eq!(tag.href, "https://example.com/collections/tags/test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -24,6 +24,7 @@ impl LocalActorCollection {
|
|||
}
|
||||
}
|
||||
|
||||
// Mastodon and Pleroma use the same actor ID format
|
||||
pub fn local_actor_id(instance_url: &str, username: &str) -> String {
|
||||
format!("{}/users/{}", instance_url, username)
|
||||
}
|
||||
|
@ -65,6 +66,10 @@ pub fn local_emoji_id(instance_url: &str, emoji_name: &str) -> String {
|
|||
format!("{}/objects/emojis/{}", instance_url, emoji_name)
|
||||
}
|
||||
|
||||
pub fn local_tag_collection(instance_url: &str, tag_name: &str) -> String {
|
||||
format!("{}/collections/tags/{}", instance_url, tag_name)
|
||||
}
|
||||
|
||||
pub fn parse_local_actor_id(
|
||||
instance_url: &str,
|
||||
actor_id: &str,
|
||||
|
|
|
@ -18,7 +18,11 @@ use crate::models::{
|
|||
posts::queries::{get_post_by_id, get_posts_by_author},
|
||||
users::queries::get_user_by_name,
|
||||
};
|
||||
use crate::web_client::urls::{get_post_page_url, get_profile_page_url};
|
||||
use crate::web_client::urls::{
|
||||
get_post_page_url,
|
||||
get_profile_page_url,
|
||||
get_tag_page_url,
|
||||
};
|
||||
use super::actors::types::{get_local_actor, get_instance_actor};
|
||||
use super::builders::create_note::{
|
||||
build_emoji_tag,
|
||||
|
@ -364,6 +368,18 @@ pub async fn emoji_view(
|
|||
Ok(response)
|
||||
}
|
||||
|
||||
#[get("/collections/tags/{tag_name}")]
|
||||
pub async fn tag_view(
|
||||
config: web::Data<Config>,
|
||||
tag_name: web::Path<String>,
|
||||
) -> Result<HttpResponse, HttpError> {
|
||||
let page_url = get_tag_page_url(&config.instance_url(), &tag_name);
|
||||
let response = HttpResponse::Found()
|
||||
.append_header(("Location", page_url))
|
||||
.finish();
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_web::http::{
|
||||
|
|
|
@ -159,6 +159,7 @@ async fn main() -> std::io::Result<()> {
|
|||
.service(activitypub::instance_actor_scope())
|
||||
.service(activitypub::object_view)
|
||||
.service(activitypub::emoji_view)
|
||||
.service(activitypub::tag_view)
|
||||
.service(atom::get_atom_feed)
|
||||
.service(nodeinfo::get_nodeinfo)
|
||||
.service(nodeinfo::get_nodeinfo_2_0)
|
||||
|
|
|
@ -285,7 +285,7 @@ pub async fn search(
|
|||
posts,
|
||||
).await?;
|
||||
let hashtags = tags.into_iter()
|
||||
.map(Tag::from_tag_name)
|
||||
.map(|tag_name| Tag::from_tag_name(&config.instance_url(), tag_name))
|
||||
.collect();
|
||||
Ok(SearchResults { accounts, statuses, hashtags })
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use chrono::{DateTime, Utc};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::activitypub::identifiers::local_tag_collection;
|
||||
use crate::mastodon_api::accounts::types::Account;
|
||||
use crate::mastodon_api::media::types::Attachment;
|
||||
use crate::models::{
|
||||
|
@ -39,11 +40,11 @@ pub struct Tag {
|
|||
}
|
||||
|
||||
impl Tag {
|
||||
pub fn from_tag_name(tag_name: String) -> Self {
|
||||
pub fn from_tag_name(instance_url: &str, tag_name: String) -> Self {
|
||||
let tag_url = local_tag_collection(instance_url, &tag_name);
|
||||
Tag {
|
||||
name: tag_name,
|
||||
// TODO: add link to tag page
|
||||
url: "".to_string(),
|
||||
url: tag_url,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +109,7 @@ impl Status {
|
|||
.map(|item| Mention::from_profile(item, instance_url))
|
||||
.collect();
|
||||
let tags: Vec<Tag> = post.tags.into_iter()
|
||||
.map(Tag::from_tag_name)
|
||||
.map(|tag_name| Tag::from_tag_name(instance_url, tag_name))
|
||||
.collect();
|
||||
let emojis: Vec<CustomEmoji> = post.emojis.into_iter()
|
||||
.map(|emoji| CustomEmoji::from_db(instance_url, emoji))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use regex::{Captures, Regex};
|
||||
|
||||
use crate::activitypub::identifiers::local_tag_collection;
|
||||
use crate::errors::ValidationError;
|
||||
use crate::web_client::urls::get_tag_page_url;
|
||||
use super::links::is_inside_code_block;
|
||||
|
||||
const HASHTAG_RE: &str = r"(?m)(?P<before>^|\s|>|[\(])#(?P<tag>[^\s<]+)";
|
||||
|
@ -45,11 +45,11 @@ pub fn replace_hashtags(instance_url: &str, text: &str, tags: &[String]) -> Stri
|
|||
let tag_name = tag.to_lowercase();
|
||||
let after = secondary_caps["after"].to_string();
|
||||
if tags.contains(&tag_name) {
|
||||
let tag_page_url = get_tag_page_url(instance_url, &tag_name);
|
||||
let tag_url = local_tag_collection(instance_url, &tag_name);
|
||||
return format!(
|
||||
r#"{}<a class="hashtag" href="{}">#{}</a>{}"#,
|
||||
before,
|
||||
tag_page_url,
|
||||
tag_url,
|
||||
tag,
|
||||
after,
|
||||
);
|
||||
|
@ -101,13 +101,14 @@ mod tests {
|
|||
let output = replace_hashtags(INSTANCE_URL, TEXT_WITH_TAGS, &tags);
|
||||
|
||||
let expected_output = concat!(
|
||||
r#"@user1@server1 some text <a class="hashtag" href="https://example.com/tag/testtag">#TestTag</a>."#, "\n",
|
||||
r#"<a class="hashtag" href="https://example.com/tag/tag1">#TAG1</a> <a class="hashtag" href="https://example.com/tag/tag1">#tag1</a> "#,
|
||||
r#"@user1@server1 some text <a class="hashtag" href="https://example.com/collections/tags/testtag">#TestTag</a>."#, "\n",
|
||||
r#"<a class="hashtag" href="https://example.com/collections/tags/tag1">#TAG1</a> "#,
|
||||
r#"<a class="hashtag" href="https://example.com/collections/tags/tag1">#tag1</a> "#,
|
||||
r#"#test_underscore #test*special "#,
|
||||
r#"more text (<a class="hashtag" href="https://example.com/tag/tag2">#tag2</a>) text "#,
|
||||
r#"<a class="hashtag" href="https://example.com/tag/tag3">#tag3</a>, "#,
|
||||
r#"<a class="hashtag" href="https://example.com/tag/tag4">#tag4</a>:<br>"#,
|
||||
r#"end with <a class="hashtag" href="https://example.com/tag/tag5">#tag5</a>"#,
|
||||
r#"more text (<a class="hashtag" href="https://example.com/collections/tags/tag2">#tag2</a>) text "#,
|
||||
r#"<a class="hashtag" href="https://example.com/collections/tags/tag3">#tag3</a>, "#,
|
||||
r#"<a class="hashtag" href="https://example.com/collections/tags/tag4">#tag4</a>:<br>"#,
|
||||
r#"end with <a class="hashtag" href="https://example.com/collections/tags/tag5">#tag5</a>"#,
|
||||
);
|
||||
assert_eq!(output, expected_output);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue