fix: stacks manage page when user deletes profile

add: allow moderators to view deleted posts
This commit is contained in:
trisua 2025-05-16 16:09:21 -04:00
parent 4c26879d00
commit 81307752c2
14 changed files with 211 additions and 29 deletions

View file

@ -227,6 +227,14 @@ and show_community and community.id != config.town_square or question %}
>
{{ icon "user-round" }}
</span>
{% endif %} {% if post.is_deleted %}
<span
title="Deleted"
class="flex items-center"
style="color: var(--color-primary)"
>
{{ icon "trash-2" }}
</span>
{% endif %}
</div>

View file

@ -138,7 +138,7 @@ pub async fn update_title_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_channel_title(id, user, &req.title).await {
match data.update_channel_title(id, &user, &req.title).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Channel updated".to_string(),
@ -160,7 +160,7 @@ pub async fn update_position_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_channel_position(id, user, req.position).await {
match data.update_channel_position(id, &user, req.position).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Channel updated".to_string(),

View file

@ -117,7 +117,7 @@ pub async fn update_context_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_community_context(id, user, req.context).await {
match data.update_community_context(id, &user, req.context).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Community updated".to_string(),
@ -140,7 +140,7 @@ pub async fn update_read_access_request(
};
match data
.update_community_read_access(id, user, req.access)
.update_community_read_access(id, &user, req.access)
.await
{
Ok(_) => Json(ApiReturn {
@ -165,7 +165,7 @@ pub async fn update_write_access_request(
};
match data
.update_community_write_access(id, user, req.access)
.update_community_write_access(id, &user, req.access)
.await
{
Ok(_) => Json(ApiReturn {
@ -190,7 +190,7 @@ pub async fn update_join_access_request(
};
match data
.update_community_join_access(id, user, req.access)
.update_community_join_access(id, &user, req.access)
.await
{
Ok(_) => Json(ApiReturn {

View file

@ -183,7 +183,7 @@ pub async fn update_name_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_emoji_name(id, user, &req.name).await {
match data.update_emoji_name(id, &user, &req.name).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Emoji updated".to_string(),

View file

@ -173,6 +173,31 @@ pub async fn delete_request(
None => return Json(Error::NotAllowed.into()),
};
match data.fake_delete_post(id, user, true).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Post deleted".to_string(),
payload: (),
}),
Err(e) => Json(e.into()),
}
}
pub async fn real_delete_request(
jar: CookieJar,
Extension(data): Extension<State>,
Path(id): Path<usize>,
) -> impl IntoResponse {
let data = &(data.read().await).0;
let user = match get_user_from_token!(jar, data) {
Some(ua) => ua,
None => return Json(Error::NotAllowed.into()),
};
if !user.permissions.check(FinePermission::MANAGE_POSTS) {
return Json(Error::NotAllowed.into());
}
match data.delete_post(id, user).await {
Ok(_) => Json(ApiReturn {
ok: true,

View file

@ -93,6 +93,10 @@ pub fn routes() -> Router {
// posts
.route("/posts", post(communities::posts::create_request))
.route("/posts/{id}", delete(communities::posts::delete_request))
.route(
"/posts/{id}/real_delete",
delete(communities::posts::real_delete_request),
)
.route(
"/posts/{id}/repost",
post(communities::posts::create_repost_request),

View file

@ -43,7 +43,7 @@ pub async fn update_name_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_stack_name(id, user, &req.name).await {
match data.update_stack_name(id, &user, &req.name).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Stack updated".to_string(),
@ -65,7 +65,7 @@ pub async fn update_privacy_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_stack_privacy(id, user, req.privacy).await {
match data.update_stack_privacy(id, &user, req.privacy).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Stack updated".to_string(),
@ -87,7 +87,7 @@ pub async fn update_mode_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_stack_mode(id, user, req.mode).await {
match data.update_stack_mode(id, &user, req.mode).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Stack updated".to_string(),
@ -109,7 +109,7 @@ pub async fn update_sort_request(
None => return Json(Error::NotAllowed.into()),
};
match data.update_stack_sort(id, user, req.sort).await {
match data.update_stack_sort(id, &user, req.sort).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "Stack updated".to_string(),
@ -152,7 +152,7 @@ pub async fn add_user_request(
};
stack.users.push(other_user.id);
match data.update_stack_users(id, user, stack.users).await {
match data.update_stack_users(id, &user, stack.users).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "User added".to_string(),
@ -191,7 +191,7 @@ pub async fn remove_user_request(
None => return Json(Error::GeneralNotFound("user".to_string()).into()),
});
match data.update_stack_users(id, user, stack.users).await {
match data.update_stack_users(id, &user, stack.users).await {
Ok(_) => Json(ApiReturn {
ok: true,
message: "User removed".to_string(),

View file

@ -589,6 +589,33 @@ pub async fn post_request(
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
};
if post.is_deleted {
// act like the post doesn't exist (if missing MANAGE_POSTS)
if let Some(ref ua) = user {
if !ua.permissions.check(FinePermission::MANAGE_POSTS) {
return Err(Html(
render_error(
Error::GeneralNotFound("post".to_string()),
&jar,
&data,
&user,
)
.await,
));
}
} else {
return Err(Html(
render_error(
Error::GeneralNotFound("post".to_string()),
&jar,
&data,
&user,
)
.await,
));
}
}
let community = match data.0.get_community_by_id(post.community).await {
Ok(c) => c,
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),

View file

@ -120,15 +120,29 @@ pub async fn manage_request(
));
}
let mut new_users = stack.users.clone();
let mut changed_stack_users: bool = false;
let mut users: Vec<User> = Vec::new();
for uid in &stack.users {
users.push(match data.0.get_user_by_id(uid.to_owned()).await {
Ok(ua) => ua,
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
Err(_) => {
// user deleted profile, remove from list
new_users.remove(stack.users.iter().position(|x| x == uid).unwrap());
changed_stack_users = true;
continue;
}
});
}
if changed_stack_users {
if let Err(e) = data.0.update_stack_users(stack.id, &user, new_users).await {
return Err(Html(render_error(e, &jar, &data, &None).await));
}
}
let lang = get_lang!(jar, data.0);
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;