"devDependencies": {
"@types/jest": "^26.0.19",
"jest": "^26.6.3",
- "lemmy-js-client": "1.0.17-beta6",
+ "lemmy-js-client": "0.9.0-rc.12",
"node-fetch": "^2.6.1",
"ts-jest": "^26.4.4",
"prettier": "^2.1.2",
let name = 'A jest test federated post, updated';
let form: EditPost = {
name,
- edit_id: post.id,
+ post_id: post.id,
auth: api.auth,
nsfw: false,
};
post: Post
): Promise<PostResponse> {
let form: DeletePost = {
- edit_id: post.id,
+ post_id: post.id,
deleted: deleted,
auth: api.auth,
};
post: Post
): Promise<PostResponse> {
let form: RemovePost = {
- edit_id: post.id,
+ post_id: post.id,
removed,
auth: api.auth,
};
post: Post
): Promise<PostResponse> {
let form: StickyPost = {
- edit_id: post.id,
+ post_id: post.id,
stickied,
auth: api.auth,
};
post: Post
): Promise<PostResponse> {
let form: LockPost = {
- edit_id: post.id,
+ post_id: post.id,
locked,
auth: api.auth,
};
export async function editComment(
api: API,
- edit_id: number,
+ comment_id: number,
content = 'A jest test federated comment update'
): Promise<CommentResponse> {
let form: EditComment = {
content,
- edit_id,
+ comment_id,
auth: api.auth,
};
return api.client.editComment(form);
export async function deleteComment(
api: API,
deleted: boolean,
- edit_id: number
+ comment_id: number
): Promise<CommentResponse> {
let form: DeleteComment = {
- edit_id,
+ comment_id,
deleted,
auth: api.auth,
};
export async function removeComment(
api: API,
removed: boolean,
- edit_id: number
+ comment_id: number
): Promise<CommentResponse> {
let form: RemoveComment = {
- edit_id,
+ comment_id,
removed,
auth: api.auth,
};
export async function deleteCommunity(
api: API,
deleted: boolean,
- edit_id: number
+ community_id: number
): Promise<CommunityResponse> {
let form: DeleteCommunity = {
- edit_id,
+ community_id,
deleted,
auth: api.auth,
};
export async function removeCommunity(
api: API,
removed: boolean,
- edit_id: number
+ community_id: number
): Promise<CommunityResponse> {
let form: RemoveCommunity = {
- edit_id,
+ community_id,
removed,
auth: api.auth,
};
export async function editPrivateMessage(
api: API,
- edit_id: number
+ private_message_id: number
): Promise<PrivateMessageResponse> {
let updatedContent = 'A jest test federated private message edited';
let form: EditPrivateMessage = {
content: updatedContent,
- edit_id,
+ private_message_id,
auth: api.auth,
};
return api.client.editPrivateMessage(form);
export async function deletePrivateMessage(
api: API,
deleted: boolean,
- edit_id: number
+ private_message_id: number
): Promise<PrivateMessageResponse> {
let form: DeletePrivateMessage = {
deleted,
- edit_id,
+ private_message_id,
auth: api.auth,
};
return api.client.deletePrivateMessage(form);
username,
password: 'test',
password_verify: 'test',
- admin: false,
show_nsfw: true,
};
return api.client.register(form);
dependencies:
language-subtag-registry "~0.3.2"
-lemmy-js-client@1.0.17-beta6:
- version "1.0.17-beta6"
- resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.17-beta6.tgz#afe1e1da13172a161c4d976b1ee58fe81eb22829"
- integrity sha512-+oX7J7wht8nH4a5NQngK1GNner3TDv6ZOhQQVI5KcK7vynVVIcgveC5KBJArHBAl5acXpLs3Khmx0ZEb+sErJA==
+lemmy-js-client@0.9.0-rc.12:
+ version "0.9.0-rc.12"
+ resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.9.0-rc.12.tgz#991d31c4ef89b9bd4088a17c60b6cbaac997df41"
+ integrity sha512-SeCw9wjU89Zm4YWhr+neHC2XvqoqzJg2e42sFEgcDmnQxpPt2sND9Udu+tjGXatbz0tCu6ybGmpR5M0QT4xx9Q==
leven@^3.1.0:
version "3.1.0"
let data: &EditComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let orig_comment = blocking(context.pool(), move |conn| {
- CommentView::read(&conn, edit_id, None)
+ CommentView::read(&conn, comment_id, None)
})
.await??;
// Do the update
let content_slurs_removed = remove_slurs(&data.content.to_owned());
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let updated_comment = match blocking(context.pool(), move |conn| {
- Comment::update_content(conn, edit_id, &content_slurs_removed)
+ Comment::update_content(conn, comment_id, &content_slurs_removed)
})
.await?
{
)
.await?;
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let user_id = user.id;
let comment_view = blocking(context.pool(), move |conn| {
- CommentView::read(conn, edit_id, Some(user_id))
+ CommentView::read(conn, comment_id, Some(user_id))
})
.await??;
let data: &DeleteComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let orig_comment = blocking(context.pool(), move |conn| {
- CommentView::read(&conn, edit_id, None)
+ CommentView::read(&conn, comment_id, None)
})
.await??;
// Do the delete
let deleted = data.deleted;
let updated_comment = match blocking(context.pool(), move |conn| {
- Comment::update_deleted(conn, edit_id, deleted)
+ Comment::update_deleted(conn, comment_id, deleted)
})
.await?
{
}
// Refetch it
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let user_id = user.id;
let comment_view = blocking(context.pool(), move |conn| {
- CommentView::read(conn, edit_id, Some(user_id))
+ CommentView::read(conn, comment_id, Some(user_id))
})
.await??;
let data: &RemoveComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let orig_comment = blocking(context.pool(), move |conn| {
- CommentView::read(&conn, edit_id, None)
+ CommentView::read(&conn, comment_id, None)
})
.await??;
// Do the remove
let removed = data.removed;
let updated_comment = match blocking(context.pool(), move |conn| {
- Comment::update_removed(conn, edit_id, removed)
+ Comment::update_removed(conn, comment_id, removed)
})
.await?
{
// Mod tables
let form = ModRemoveCommentForm {
mod_user_id: user.id,
- comment_id: data.edit_id,
+ comment_id: data.comment_id,
removed: Some(removed),
reason: data.reason.to_owned(),
};
}
// Refetch it
- let edit_id = data.edit_id;
+ let comment_id = data.comment_id;
let user_id = user.id;
let comment_view = blocking(context.pool(), move |conn| {
- CommentView::read(conn, edit_id, Some(user_id))
+ CommentView::read(conn, comment_id, Some(user_id))
})
.await??;
};
// Refetch it
- let edit_id = data.comment_id;
+ let comment_id = data.comment_id;
let user_id = user.id;
let comment_view = blocking(context.pool(), move |conn| {
- CommentView::read(conn, edit_id, Some(user_id))
+ CommentView::read(conn, comment_id, Some(user_id))
})
.await??;
LemmyError,
};
use lemmy_websocket::{
- messages::{GetCommunityUsersOnline, JoinCommunityRoom, JoinModRoom, SendCommunityRoomMessage},
+ messages::{GetCommunityUsersOnline, SendCommunityRoomMessage},
LemmyContext,
UserOperation,
};
check_slurs_opt(&data.description)?;
// Verify its a mod (only mods can edit it)
- let edit_id = data.edit_id;
+ let community_id = data.community_id;
let mods: Vec<i32> = blocking(context.pool(), move |conn| {
- CommunityModeratorView::for_community(conn, edit_id)
+ CommunityModeratorView::for_community(conn, community_id)
.map(|v| v.into_iter().map(|m| m.moderator.id).collect())
})
.await??;
return Err(APIError::err("not_a_moderator").into());
}
- let edit_id = data.edit_id;
- let read_community =
- blocking(context.pool(), move |conn| Community::read(conn, edit_id)).await??;
+ let community_id = data.community_id;
+ let read_community = blocking(context.pool(), move |conn| {
+ Community::read(conn, community_id)
+ })
+ .await??;
let icon = diesel_option_overwrite(&data.icon);
let banner = diesel_option_overwrite(&data.banner);
published: None,
};
- let edit_id = data.edit_id;
+ let community_id = data.community_id;
match blocking(context.pool(), move |conn| {
- Community::update(conn, edit_id, &community_form)
+ Community::update(conn, community_id, &community_form)
})
.await?
{
// TODO there needs to be some kind of an apub update
// process for communities and users
- let edit_id = data.edit_id;
+ let community_id = data.community_id;
let user_id = user.id;
let community_view = blocking(context.pool(), move |conn| {
- CommunityView::read(conn, edit_id, Some(user_id))
+ CommunityView::read(conn, community_id, Some(user_id))
})
.await??;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
// Verify its the creator (only a creator can delete the community)
- let edit_id = data.edit_id;
- let read_community =
- blocking(context.pool(), move |conn| Community::read(conn, edit_id)).await??;
+ let community_id = data.community_id;
+ let read_community = blocking(context.pool(), move |conn| {
+ Community::read(conn, community_id)
+ })
+ .await??;
if read_community.creator_id != user.id {
return Err(APIError::err("no_community_edit_allowed").into());
}
// Do the delete
- let edit_id = data.edit_id;
+ let community_id = data.community_id;
let deleted = data.deleted;
let updated_community = match blocking(context.pool(), move |conn| {
- Community::update_deleted(conn, edit_id, deleted)
+ Community::update_deleted(conn, community_id, deleted)
})
.await?
{
updated_community.send_undo_delete(context).await?;
}
- let edit_id = data.edit_id;
+ let community_id = data.community_id;
let user_id = user.id;
let community_view = blocking(context.pool(), move |conn| {
- CommunityView::read(conn, edit_id, Some(user_id))
+ CommunityView::read(conn, community_id, Some(user_id))
})
.await??;
is_admin(context.pool(), user.id).await?;
// Do the remove
- let edit_id = data.edit_id;
+ let community_id = data.community_id;
let removed = data.removed;
let updated_community = match blocking(context.pool(), move |conn| {
- Community::update_removed(conn, edit_id, removed)
+ Community::update_removed(conn, community_id, removed)
})
.await?
{
};
let form = ModRemoveCommunityForm {
mod_user_id: user.id,
- community_id: data.edit_id,
+ community_id: data.community_id,
removed: Some(removed),
reason: data.reason.to_owned(),
expires,
updated_community.send_undo_remove(context).await?;
}
- let edit_id = data.edit_id;
+ let community_id = data.community_id;
let user_id = user.id;
let community_view = blocking(context.pool(), move |conn| {
- CommunityView::read(conn, edit_id, Some(user_id))
+ CommunityView::read(conn, community_id, Some(user_id))
})
.await??;
websocket_id,
});
}
-
-#[async_trait::async_trait(?Send)]
-impl Perform for CommunityJoin {
- type Response = CommunityJoinResponse;
-
- async fn perform(
- &self,
- context: &Data<LemmyContext>,
- websocket_id: Option<ConnectionId>,
- ) -> Result<CommunityJoinResponse, LemmyError> {
- let data: &CommunityJoin = &self;
-
- if let Some(ws_id) = websocket_id {
- context.chat_server().do_send(JoinCommunityRoom {
- community_id: data.community_id,
- id: ws_id,
- });
- }
-
- Ok(CommunityJoinResponse { joined: true })
- }
-}
-
-#[async_trait::async_trait(?Send)]
-impl Perform for ModJoin {
- type Response = ModJoinResponse;
-
- async fn perform(
- &self,
- context: &Data<LemmyContext>,
- websocket_id: Option<ConnectionId>,
- ) -> Result<ModJoinResponse, LemmyError> {
- let data: &ModJoin = &self;
-
- if let Some(ws_id) = websocket_id {
- context.chat_server().do_send(JoinModRoom {
- community_id: data.community_id,
- id: ws_id,
- });
- }
-
- Ok(ModJoinResponse { joined: true })
- }
-}
source::{
community::{CommunityModerator_, Community_},
site::Site_,
+ user::UserSafeSettings_,
},
Crud,
DbPool,
community::{Community, CommunityModerator},
post::Post,
site::Site,
- user::User_,
+ user::{UserSafeSettings, User_},
};
use lemmy_db_views_actor::{
community_user_ban_view::CommunityUserBanView,
community_view::CommunityView,
};
-use lemmy_structs::{blocking, comment::*, community::*, post::*, site::*, user::*};
+use lemmy_structs::{blocking, comment::*, community::*, post::*, site::*, user::*, websocket::*};
use lemmy_utils::{settings::Settings, APIError, ConnectionId, LemmyError};
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
use serde::Deserialize;
pub mod site;
pub mod user;
pub mod version;
+pub mod websocket;
#[async_trait::async_trait(?Send)]
pub trait Perform {
}
}
+pub(crate) async fn get_user_safe_settings_from_jwt(
+ jwt: &str,
+ pool: &DbPool,
+) -> Result<UserSafeSettings, LemmyError> {
+ let claims = match Claims::decode(&jwt) {
+ Ok(claims) => claims.claims,
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
+ };
+ let user_id = claims.id;
+ let user = blocking(pool, move |conn| UserSafeSettings::read(conn, user_id)).await??;
+ // Check for a site ban
+ if user.banned {
+ return Err(APIError::err("site_ban").into());
+ }
+ Ok(user)
+}
+
+pub(crate) async fn get_user_safe_settings_from_jwt_opt(
+ jwt: &Option<String>,
+ pool: &DbPool,
+) -> Result<Option<UserSafeSettings>, LemmyError> {
+ match jwt {
+ Some(jwt) => Ok(Some(get_user_safe_settings_from_jwt(jwt, pool).await?)),
+ None => Ok(None),
+ }
+}
+
pub(crate) async fn check_community_ban(
user_id: i32,
community_id: i32,
LemmyError,
};
use lemmy_websocket::{
- messages::{GetPostUsersOnline, JoinPostRoom, SendModRoomMessage, SendPost, SendUserRoomMessage},
+ messages::{GetPostUsersOnline, SendModRoomMessage, SendPost, SendUserRoomMessage},
LemmyContext,
UserOperation,
};
return Err(APIError::err("invalid_post_title").into());
}
- let edit_id = data.edit_id;
- let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
+ let post_id = data.post_id;
+ let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
published: None,
};
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let res = blocking(context.pool(), move |conn| {
- Post::update(conn, edit_id, &post_form)
+ Post::update(conn, post_id, &post_form)
})
.await?;
let updated_post: Post = match res {
// Send apub update
updated_post.send_update(&user, context).await?;
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let post_view = blocking(context.pool(), move |conn| {
- PostView::read(conn, edit_id, Some(user.id))
+ PostView::read(conn, post_id, Some(user.id))
})
.await??;
let data: &DeletePost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
- let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
+ let post_id = data.post_id;
+ let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
}
// Update the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let deleted = data.deleted;
let updated_post = blocking(context.pool(), move |conn| {
- Post::update_deleted(conn, edit_id, deleted)
+ Post::update_deleted(conn, post_id, deleted)
})
.await??;
}
// Refetch the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let post_view = blocking(context.pool(), move |conn| {
- PostView::read(conn, edit_id, Some(user.id))
+ PostView::read(conn, post_id, Some(user.id))
})
.await??;
let data: &RemovePost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
- let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
+ let post_id = data.post_id;
+ let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
// Update the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let removed = data.removed;
let updated_post = blocking(context.pool(), move |conn| {
- Post::update_removed(conn, edit_id, removed)
+ Post::update_removed(conn, post_id, removed)
})
.await??;
// Mod tables
let form = ModRemovePostForm {
mod_user_id: user.id,
- post_id: data.edit_id,
+ post_id: data.post_id,
removed: Some(removed),
reason: data.reason.to_owned(),
};
}
// Refetch the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let user_id = user.id;
let post_view = blocking(context.pool(), move |conn| {
- PostView::read(conn, edit_id, Some(user_id))
+ PostView::read(conn, post_id, Some(user_id))
})
.await??;
let data: &LockPost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
- let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
+ let post_id = data.post_id;
+ let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
// Update the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let locked = data.locked;
let updated_post = blocking(context.pool(), move |conn| {
- Post::update_locked(conn, edit_id, locked)
+ Post::update_locked(conn, post_id, locked)
})
.await??;
// Mod tables
let form = ModLockPostForm {
mod_user_id: user.id,
- post_id: data.edit_id,
+ post_id: data.post_id,
locked: Some(locked),
};
blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??;
updated_post.send_update(&user, context).await?;
// Refetch the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let post_view = blocking(context.pool(), move |conn| {
- PostView::read(conn, edit_id, Some(user.id))
+ PostView::read(conn, post_id, Some(user.id))
})
.await??;
let data: &StickyPost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
- let edit_id = data.edit_id;
- let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
+ let post_id = data.post_id;
+ let orig_post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
// Update the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let stickied = data.stickied;
let updated_post = blocking(context.pool(), move |conn| {
- Post::update_stickied(conn, edit_id, stickied)
+ Post::update_stickied(conn, post_id, stickied)
})
.await??;
// Mod tables
let form = ModStickyPostForm {
mod_user_id: user.id,
- post_id: data.edit_id,
+ post_id: data.post_id,
stickied: Some(stickied),
};
blocking(context.pool(), move |conn| {
updated_post.send_update(&user, context).await?;
// Refetch the post
- let edit_id = data.edit_id;
+ let post_id = data.post_id;
let post_view = blocking(context.pool(), move |conn| {
- PostView::read(conn, edit_id, Some(user.id))
+ PostView::read(conn, post_id, Some(user.id))
})
.await??;
}
}
-#[async_trait::async_trait(?Send)]
-impl Perform for PostJoin {
- type Response = PostJoinResponse;
-
- async fn perform(
- &self,
- context: &Data<LemmyContext>,
- websocket_id: Option<ConnectionId>,
- ) -> Result<PostJoinResponse, LemmyError> {
- let data: &PostJoin = &self;
-
- if let Some(ws_id) = websocket_id {
- context.chat_server().do_send(JoinPostRoom {
- post_id: data.post_id,
- id: ws_id,
- });
- }
-
- Ok(PostJoinResponse { joined: true })
- }
-}
-
/// Creates a post report and notifies the moderators of the community
#[async_trait::async_trait(?Send)]
impl Perform for CreatePostReport {
use crate::{
get_user_from_jwt,
get_user_from_jwt_opt,
+ get_user_safe_settings_from_jwt,
+ get_user_safe_settings_from_jwt_opt,
is_admin,
linked_instances,
version,
email: setup.admin_email.to_owned(),
password: setup.admin_password.to_owned(),
password_verify: setup.admin_password.to_owned(),
- admin: true,
show_nsfw: true,
captcha_uuid: None,
captcha_answer: None,
.await
.unwrap_or(1);
- let my_user = get_user_from_jwt_opt(&data.auth, context.pool())
- .await?
- .map(|mut u| {
- u.password_encrypted = "".to_string();
- u.private_key = None;
- u.public_key = None;
- u
- });
+ let my_user = get_user_safe_settings_from_jwt_opt(&data.auth, context.pool()).await?;
Ok(GetSiteResponse {
site_view,
_websocket_id: Option<ConnectionId>,
) -> Result<GetSiteResponse, LemmyError> {
let data: &TransferSite = &self;
- let mut user = get_user_from_jwt(&data.auth, context.pool()).await?;
+ let user = get_user_safe_settings_from_jwt(&data.auth, context.pool()).await?;
is_admin(context.pool(), user.id).await?;
- // TODO add a User_::read_safe() for this.
- user.password_encrypted = "".to_string();
- user.private_key = None;
- user.public_key = None;
-
let read_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??;
// Make sure user is the creator
community_follower_view::CommunityFollowerView,
community_moderator_view::CommunityModeratorView,
user_mention_view::{UserMentionQueryBuilder, UserMentionView},
- user_view::{UserViewDangerous, UserViewSafe},
+ user_view::UserViewSafe,
};
use lemmy_structs::{blocking, send_email_to_user, user::*};
use lemmy_utils::{
LemmyError,
};
use lemmy_websocket::{
- messages::{CaptchaItem, CheckCaptcha, JoinUserRoom, SendAllMessage, SendUserRoomMessage},
+ messages::{CaptchaItem, CheckCaptcha, SendAllMessage, SendUserRoomMessage},
LemmyContext,
UserOperation,
};
return Err(APIError::err("passwords_dont_match").into());
}
+ // Check if there are admins. False if admins exist
+ let no_admins = blocking(context.pool(), move |conn| {
+ UserViewSafe::admins(conn).map(|a| a.is_empty())
+ })
+ .await??;
+
// If its not the admin, check the captcha
- if !data.admin && Settings::get().captcha.enabled {
+ if !no_admins && Settings::get().captcha.enabled {
let check = context
.chat_server()
.send(CheckCaptcha {
check_slurs(&data.username)?;
- // Make sure there are no admins
- let any_admins = blocking(context.pool(), move |conn| {
- UserViewSafe::admins(conn).map(|a| a.is_empty())
- })
- .await??;
- if data.admin && !any_admins {
- return Err(APIError::err("admin_already_created").into());
- }
-
let user_keypair = generate_actor_keypair()?;
if !is_valid_username(&data.username) {
return Err(APIError::err("invalid_username").into());
preferred_username: None,
published: None,
updated: None,
- admin: data.admin,
+ admin: no_admins,
banned: Some(false),
show_nsfw: data.show_nsfw,
theme: "browser".into(),
};
// If its an admin, add them as a mod and follower to main
- if data.admin {
+ if no_admins {
let community_moderator_form = CommunityModeratorForm {
community_id: main_community.id,
user_id: inserted_user.id,
let user_id = user.map(|u| u.id);
- let (user_view, user_view_dangerous) = if let Some(auth_user_id) = user_id {
- if user_details_id == auth_user_id {
- (
- None,
- Some(
- blocking(context.pool(), move |conn| {
- UserViewDangerous::read(conn, auth_user_id)
- })
- .await??,
- ),
- )
- } else {
- (
- Some(
- blocking(context.pool(), move |conn| {
- UserViewSafe::read(conn, user_details_id)
- })
- .await??,
- ),
- None,
- )
- }
- } else {
- (
- Some(
- blocking(context.pool(), move |conn| {
- UserViewSafe::read(conn, user_details_id)
- })
- .await??,
- ),
- None,
- )
- };
+ // You don't need to return settings for the user, since this comes back with GetSite
+ // `my_user`
+ let user_view = blocking(context.pool(), move |conn| {
+ UserViewSafe::read(conn, user_details_id)
+ })
+ .await??;
let page = data.page;
let limit = data.limit;
// Return the jwt
Ok(GetUserDetailsResponse {
user_view,
- user_view_dangerous,
follows,
moderates,
comments,
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
// Checking permissions
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let orig_private_message = blocking(context.pool(), move |conn| {
- PrivateMessage::read(conn, edit_id)
+ PrivateMessage::read(conn, private_message_id)
})
.await??;
if user.id != orig_private_message.creator_id {
// Doing the update
let content_slurs_removed = remove_slurs(&data.content);
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let updated_private_message = match blocking(context.pool(), move |conn| {
- PrivateMessage::update_content(conn, edit_id, &content_slurs_removed)
+ PrivateMessage::update_content(conn, private_message_id, &content_slurs_removed)
})
.await?
{
// Send the apub update
updated_private_message.send_update(&user, context).await?;
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let message = blocking(context.pool(), move |conn| {
- PrivateMessageView::read(conn, edit_id)
+ PrivateMessageView::read(conn, private_message_id)
})
.await??;
let recipient_id = message.recipient.id;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
// Checking permissions
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let orig_private_message = blocking(context.pool(), move |conn| {
- PrivateMessage::read(conn, edit_id)
+ PrivateMessage::read(conn, private_message_id)
})
.await??;
if user.id != orig_private_message.creator_id {
}
// Doing the update
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let deleted = data.deleted;
let updated_private_message = match blocking(context.pool(), move |conn| {
- PrivateMessage::update_deleted(conn, edit_id, deleted)
+ PrivateMessage::update_deleted(conn, private_message_id, deleted)
})
.await?
{
.await?;
}
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let message = blocking(context.pool(), move |conn| {
- PrivateMessageView::read(conn, edit_id)
+ PrivateMessageView::read(conn, private_message_id)
})
.await??;
let recipient_id = message.recipient.id;
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
// Checking permissions
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let orig_private_message = blocking(context.pool(), move |conn| {
- PrivateMessage::read(conn, edit_id)
+ PrivateMessage::read(conn, private_message_id)
})
.await??;
if user.id != orig_private_message.recipient_id {
}
// Doing the update
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let read = data.read;
match blocking(context.pool(), move |conn| {
- PrivateMessage::update_read(conn, edit_id, read)
+ PrivateMessage::update_read(conn, private_message_id, read)
})
.await?
{
// No need to send an apub update
- let edit_id = data.edit_id;
+ let private_message_id = data.private_message_id;
let message = blocking(context.pool(), move |conn| {
- PrivateMessageView::read(conn, edit_id)
+ PrivateMessageView::read(conn, private_message_id)
})
.await??;
let recipient_id = message.recipient.id;
}
}
-#[async_trait::async_trait(?Send)]
-impl Perform for UserJoin {
- type Response = UserJoinResponse;
-
- async fn perform(
- &self,
- context: &Data<LemmyContext>,
- websocket_id: Option<ConnectionId>,
- ) -> Result<UserJoinResponse, LemmyError> {
- let data: &UserJoin = &self;
- let user = get_user_from_jwt(&data.auth, context.pool()).await?;
-
- if let Some(ws_id) = websocket_id {
- context.chat_server().do_send(JoinUserRoom {
- user_id: user.id,
- id: ws_id,
- });
- }
-
- Ok(UserJoinResponse { joined: true })
- }
-}
-
#[async_trait::async_trait(?Send)]
impl Perform for GetReportCount {
type Response = GetReportCountResponse;
--- /dev/null
+use crate::{get_user_from_jwt, Perform};
+use actix_web::web::Data;
+use lemmy_structs::websocket::*;
+use lemmy_utils::{ConnectionId, LemmyError};
+use lemmy_websocket::{
+ messages::{JoinCommunityRoom, JoinModRoom, JoinPostRoom, JoinUserRoom},
+ LemmyContext,
+};
+
+#[async_trait::async_trait(?Send)]
+impl Perform for UserJoin {
+ type Response = UserJoinResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ websocket_id: Option<ConnectionId>,
+ ) -> Result<UserJoinResponse, LemmyError> {
+ let data: &UserJoin = &self;
+ let user = get_user_from_jwt(&data.auth, context.pool()).await?;
+
+ if let Some(ws_id) = websocket_id {
+ context.chat_server().do_send(JoinUserRoom {
+ user_id: user.id,
+ id: ws_id,
+ });
+ }
+
+ Ok(UserJoinResponse { joined: true })
+ }
+}
+
+#[async_trait::async_trait(?Send)]
+impl Perform for CommunityJoin {
+ type Response = CommunityJoinResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ websocket_id: Option<ConnectionId>,
+ ) -> Result<CommunityJoinResponse, LemmyError> {
+ let data: &CommunityJoin = &self;
+
+ if let Some(ws_id) = websocket_id {
+ context.chat_server().do_send(JoinCommunityRoom {
+ community_id: data.community_id,
+ id: ws_id,
+ });
+ }
+
+ Ok(CommunityJoinResponse { joined: true })
+ }
+}
+
+#[async_trait::async_trait(?Send)]
+impl Perform for ModJoin {
+ type Response = ModJoinResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ websocket_id: Option<ConnectionId>,
+ ) -> Result<ModJoinResponse, LemmyError> {
+ let data: &ModJoin = &self;
+
+ if let Some(ws_id) = websocket_id {
+ context.chat_server().do_send(JoinModRoom {
+ community_id: data.community_id,
+ id: ws_id,
+ });
+ }
+
+ Ok(ModJoinResponse { joined: true })
+ }
+}
+
+#[async_trait::async_trait(?Send)]
+impl Perform for PostJoin {
+ type Response = PostJoinResponse;
+
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ websocket_id: Option<ConnectionId>,
+ ) -> Result<PostJoinResponse, LemmyError> {
+ let data: &PostJoin = &self;
+
+ if let Some(ws_id) = websocket_id {
+ context.chat_server().do_send(JoinPostRoom {
+ post_id: data.post_id,
+ id: ws_id,
+ });
+ }
+
+ Ok(PostJoinResponse { joined: true })
+ }
+}
fn safe_columns_tuple() -> Self::SafeColumns;
}
+pub trait ToSafeSettings {
+ type SafeSettingsColumns;
+ fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns;
+}
+
pub trait ViewToVec {
type DbTuple;
fn from_tuple_to_vec(tuple: Vec<Self::DbTuple>) -> Vec<Self>
-use crate::{is_email_regex, ApubObject, Crud};
+use crate::{is_email_regex, ApubObject, Crud, ToSafeSettings};
use bcrypt::{hash, DEFAULT_COST};
use diesel::{dsl::*, result::Error, *};
use lemmy_db_schema::{
naive_now,
schema::user_::dsl::*,
- source::user::{UserForm, User_},
+ source::user::{UserForm, UserSafeSettings, User_},
};
use lemmy_utils::settings::Settings;
}
}
+mod safe_settings_type {
+ use crate::ToSafeSettings;
+ use lemmy_db_schema::{schema::user_::columns::*, source::user::User_};
+
+ type Columns = (
+ id,
+ name,
+ preferred_username,
+ email,
+ avatar,
+ admin,
+ banned,
+ published,
+ updated,
+ show_nsfw,
+ theme,
+ default_sort_type,
+ default_listing_type,
+ lang,
+ show_avatars,
+ send_notifications_to_email,
+ matrix_user_id,
+ actor_id,
+ bio,
+ local,
+ last_refreshed_at,
+ banner,
+ deleted,
+ );
+
+ impl ToSafeSettings for User_ {
+ type SafeSettingsColumns = Columns;
+ fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns {
+ (
+ id,
+ name,
+ preferred_username,
+ email,
+ avatar,
+ admin,
+ banned,
+ published,
+ updated,
+ show_nsfw,
+ theme,
+ default_sort_type,
+ default_listing_type,
+ lang,
+ show_avatars,
+ send_notifications_to_email,
+ matrix_user_id,
+ actor_id,
+ bio,
+ local,
+ last_refreshed_at,
+ banner,
+ deleted,
+ )
+ }
+ }
+}
+
+pub trait UserSafeSettings_ {
+ fn read(conn: &PgConnection, user_id: i32) -> Result<UserSafeSettings, Error>;
+}
+
+impl UserSafeSettings_ for UserSafeSettings {
+ fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
+ user_
+ .select(User_::safe_settings_columns_tuple())
+ .filter(deleted.eq(false))
+ .find(user_id)
+ .first::<Self>(conn)
+ }
+}
+
impl Crud<UserForm> for User_ {
fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
user_
pub deleted: bool,
}
+/// A safe user view with only settings
+#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
+#[table_name = "user_"]
+pub struct UserSafeSettings {
+ pub id: i32,
+ pub name: String,
+ pub preferred_username: Option<String>,
+ pub email: Option<String>,
+ pub avatar: Option<String>,
+ pub admin: bool,
+ pub banned: bool,
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>,
+ pub show_nsfw: bool,
+ pub theme: String,
+ pub default_sort_type: i16,
+ pub default_listing_type: i16,
+ pub lang: String,
+ pub show_avatars: bool,
+ pub send_notifications_to_email: bool,
+ pub matrix_user_id: Option<String>,
+ pub actor_id: String,
+ pub bio: Option<String>,
+ pub local: bool,
+ pub last_refreshed_at: chrono::NaiveDateTime,
+ pub banner: Option<String>,
+ pub deleted: bool,
+}
+
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
#[table_name = "user_alias_1"]
pub struct UserAlias1 {
type UserViewSafeTuple = (UserSafe, UserAggregates);
-#[derive(Debug, Serialize, Clone)]
-pub struct UserViewDangerous {
- pub user: User_,
- pub counts: UserAggregates,
-}
-
-type UserViewDangerousTuple = (User_, UserAggregates);
-
-impl UserViewDangerous {
- pub fn read(conn: &PgConnection, id: i32) -> Result<Self, Error> {
- let (user, counts) = user_::table
- .find(id)
- .inner_join(user_aggregates::table)
- .first::<UserViewDangerousTuple>(conn)?;
- Ok(Self { user, counts })
- }
-}
-
impl UserViewSafe {
pub fn read(conn: &PgConnection, id: i32) -> Result<Self, Error> {
let (user, counts) = user_::table
#[derive(Deserialize)]
pub struct EditComment {
pub content: String,
- pub edit_id: i32,
+ pub comment_id: i32,
pub form_id: Option<String>,
pub auth: String,
}
#[derive(Deserialize)]
pub struct DeleteComment {
- pub edit_id: i32,
+ pub comment_id: i32,
pub deleted: bool,
pub auth: String,
}
#[derive(Deserialize)]
pub struct RemoveComment {
- pub edit_id: i32,
+ pub comment_id: i32,
pub removed: bool,
pub reason: Option<String>,
pub auth: String,
#[derive(Deserialize)]
pub struct EditCommunity {
- pub edit_id: i32,
+ pub community_id: i32,
pub title: String,
pub description: Option<String>,
pub icon: Option<String>,
#[derive(Deserialize)]
pub struct DeleteCommunity {
- pub edit_id: i32,
+ pub community_id: i32,
pub deleted: bool,
pub auth: String,
}
#[derive(Deserialize)]
pub struct RemoveCommunity {
- pub edit_id: i32,
+ pub community_id: i32,
pub removed: bool,
pub reason: Option<String>,
pub expires: Option<i64>,
pub user_id: i32,
pub auth: String,
}
-
-#[derive(Deserialize, Debug)]
-pub struct CommunityJoin {
- pub community_id: i32,
-}
-
-#[derive(Serialize, Clone)]
-pub struct CommunityJoinResponse {
- pub joined: bool,
-}
-
-#[derive(Deserialize, Debug)]
-pub struct ModJoin {
- pub community_id: i32,
-}
-
-#[derive(Serialize, Clone)]
-pub struct ModJoinResponse {
- pub joined: bool,
-}
pub mod post;
pub mod site;
pub mod user;
+pub mod websocket;
use diesel::PgConnection;
use lemmy_db_queries::{source::user::User, Crud, DbPool};
#[derive(Deserialize)]
pub struct EditPost {
- pub edit_id: i32,
+ pub post_id: i32,
pub name: String,
pub url: Option<String>,
pub body: Option<String>,
#[derive(Deserialize)]
pub struct DeletePost {
- pub edit_id: i32,
+ pub post_id: i32,
pub deleted: bool,
pub auth: String,
}
#[derive(Deserialize)]
pub struct RemovePost {
- pub edit_id: i32,
+ pub post_id: i32,
pub removed: bool,
pub reason: Option<String>,
pub auth: String,
#[derive(Deserialize)]
pub struct LockPost {
- pub edit_id: i32,
+ pub post_id: i32,
pub locked: bool,
pub auth: String,
}
#[derive(Deserialize)]
pub struct StickyPost {
- pub edit_id: i32,
+ pub post_id: i32,
pub stickied: bool,
pub auth: String,
}
pub auth: String,
}
-#[derive(Deserialize, Debug)]
-pub struct PostJoin {
- pub post_id: i32,
-}
-
-#[derive(Serialize, Clone)]
-pub struct PostJoinResponse {
- pub joined: bool,
-}
-
#[derive(Serialize, Deserialize)]
pub struct CreatePostReport {
pub post_id: i32,
-use lemmy_db_schema::source::{category::*, user::User_};
+use lemmy_db_schema::source::{category::*, user::UserSafeSettings};
use lemmy_db_views::{comment_view::CommentView, post_view::PostView, site_view::SiteView};
use lemmy_db_views_actor::{community_view::CommunityView, user_view::UserViewSafe};
use lemmy_db_views_moderator::{
pub banned: Vec<UserViewSafe>,
pub online: usize,
pub version: String,
- pub my_user: Option<User_>,
+ pub my_user: Option<UserSafeSettings>,
pub federated_instances: Vec<String>,
}
community_follower_view::CommunityFollowerView,
community_moderator_view::CommunityModeratorView,
user_mention_view::UserMentionView,
- user_view::{UserViewDangerous, UserViewSafe},
+ user_view::UserViewSafe,
};
use serde::{Deserialize, Serialize};
pub email: Option<String>,
pub password: String,
pub password_verify: String,
- pub admin: bool,
pub show_nsfw: bool,
pub captcha_uuid: Option<String>,
pub captcha_answer: Option<String>,
#[derive(Serialize)]
pub struct GetCaptchaResponse {
- pub ok: Option<CaptchaResponse>,
+ pub ok: Option<CaptchaResponse>, // Will be None if captchas are disabled
}
#[derive(Serialize)]
#[derive(Serialize)]
pub struct GetUserDetailsResponse {
- pub user_view: Option<UserViewSafe>,
- pub user_view_dangerous: Option<UserViewDangerous>,
+ pub user_view: UserViewSafe,
pub follows: Vec<CommunityFollowerView>,
pub moderates: Vec<CommunityModeratorView>,
pub comments: Vec<CommentView>,
#[derive(Deserialize)]
pub struct EditPrivateMessage {
- pub edit_id: i32,
+ pub private_message_id: i32,
pub content: String,
pub auth: String,
}
#[derive(Deserialize)]
pub struct DeletePrivateMessage {
- pub edit_id: i32,
+ pub private_message_id: i32,
pub deleted: bool,
pub auth: String,
}
#[derive(Deserialize)]
pub struct MarkPrivateMessageAsRead {
- pub edit_id: i32,
+ pub private_message_id: i32,
pub read: bool,
pub auth: String,
}
pub private_message_view: PrivateMessageView,
}
-#[derive(Deserialize, Debug)]
-pub struct UserJoin {
- pub auth: String,
-}
-
-#[derive(Serialize, Clone)]
-pub struct UserJoinResponse {
- pub joined: bool,
-}
-
#[derive(Serialize, Deserialize, Debug)]
pub struct GetReportCount {
pub community: Option<i32>,
--- /dev/null
+use serde::{Deserialize, Serialize};
+
+#[derive(Deserialize, Debug)]
+pub struct UserJoin {
+ pub auth: String,
+}
+
+#[derive(Serialize, Clone)]
+pub struct UserJoinResponse {
+ pub joined: bool,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct CommunityJoin {
+ pub community_id: i32,
+}
+
+#[derive(Serialize, Clone)]
+pub struct CommunityJoinResponse {
+ pub joined: bool,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct ModJoin {
+ pub community_id: i32,
+}
+
+#[derive(Serialize, Clone)]
+pub struct ModJoinResponse {
+ pub joined: bool,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct PostJoin {
+ pub post_id: i32,
+}
+
+#[derive(Serialize, Clone)]
+pub struct PostJoinResponse {
+ pub joined: bool,
+}
use actix_web::{error::ErrorBadRequest, *};
use lemmy_api::Perform;
-use lemmy_structs::{comment::*, community::*, post::*, site::*, user::*};
+use lemmy_structs::{comment::*, community::*, post::*, site::*, user::*, websocket::*};
use lemmy_utils::rate_limit::RateLimit;
use lemmy_websocket::LemmyContext;
use serde::Deserialize;