Merge pull request #1358 from LemmyNet/v2_api_additions_1
A few API v2 changes based on nutomic's suggestions.
This commit is contained in:
commit
24c78de5f0
22 changed files with 444 additions and 354 deletions
|
@ -14,7 +14,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^26.0.19",
|
"@types/jest": "^26.0.19",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"lemmy-js-client": "1.0.17-beta6",
|
"lemmy-js-client": "0.9.0-rc.12",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"ts-jest": "^26.4.4",
|
"ts-jest": "^26.4.4",
|
||||||
"prettier": "^2.1.2",
|
"prettier": "^2.1.2",
|
||||||
|
|
|
@ -144,7 +144,7 @@ export async function editPost(api: API, post: Post): Promise<PostResponse> {
|
||||||
let name = 'A jest test federated post, updated';
|
let name = 'A jest test federated post, updated';
|
||||||
let form: EditPost = {
|
let form: EditPost = {
|
||||||
name,
|
name,
|
||||||
edit_id: post.id,
|
post_id: post.id,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
nsfw: false,
|
nsfw: false,
|
||||||
};
|
};
|
||||||
|
@ -157,7 +157,7 @@ export async function deletePost(
|
||||||
post: Post
|
post: Post
|
||||||
): Promise<PostResponse> {
|
): Promise<PostResponse> {
|
||||||
let form: DeletePost = {
|
let form: DeletePost = {
|
||||||
edit_id: post.id,
|
post_id: post.id,
|
||||||
deleted: deleted,
|
deleted: deleted,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -170,7 +170,7 @@ export async function removePost(
|
||||||
post: Post
|
post: Post
|
||||||
): Promise<PostResponse> {
|
): Promise<PostResponse> {
|
||||||
let form: RemovePost = {
|
let form: RemovePost = {
|
||||||
edit_id: post.id,
|
post_id: post.id,
|
||||||
removed,
|
removed,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -183,7 +183,7 @@ export async function stickyPost(
|
||||||
post: Post
|
post: Post
|
||||||
): Promise<PostResponse> {
|
): Promise<PostResponse> {
|
||||||
let form: StickyPost = {
|
let form: StickyPost = {
|
||||||
edit_id: post.id,
|
post_id: post.id,
|
||||||
stickied,
|
stickied,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -196,7 +196,7 @@ export async function lockPost(
|
||||||
post: Post
|
post: Post
|
||||||
): Promise<PostResponse> {
|
): Promise<PostResponse> {
|
||||||
let form: LockPost = {
|
let form: LockPost = {
|
||||||
edit_id: post.id,
|
post_id: post.id,
|
||||||
locked,
|
locked,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -376,12 +376,12 @@ export async function createComment(
|
||||||
|
|
||||||
export async function editComment(
|
export async function editComment(
|
||||||
api: API,
|
api: API,
|
||||||
edit_id: number,
|
comment_id: number,
|
||||||
content = 'A jest test federated comment update'
|
content = 'A jest test federated comment update'
|
||||||
): Promise<CommentResponse> {
|
): Promise<CommentResponse> {
|
||||||
let form: EditComment = {
|
let form: EditComment = {
|
||||||
content,
|
content,
|
||||||
edit_id,
|
comment_id,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
return api.client.editComment(form);
|
return api.client.editComment(form);
|
||||||
|
@ -390,10 +390,10 @@ export async function editComment(
|
||||||
export async function deleteComment(
|
export async function deleteComment(
|
||||||
api: API,
|
api: API,
|
||||||
deleted: boolean,
|
deleted: boolean,
|
||||||
edit_id: number
|
comment_id: number
|
||||||
): Promise<CommentResponse> {
|
): Promise<CommentResponse> {
|
||||||
let form: DeleteComment = {
|
let form: DeleteComment = {
|
||||||
edit_id,
|
comment_id,
|
||||||
deleted,
|
deleted,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -403,10 +403,10 @@ export async function deleteComment(
|
||||||
export async function removeComment(
|
export async function removeComment(
|
||||||
api: API,
|
api: API,
|
||||||
removed: boolean,
|
removed: boolean,
|
||||||
edit_id: number
|
comment_id: number
|
||||||
): Promise<CommentResponse> {
|
): Promise<CommentResponse> {
|
||||||
let form: RemoveComment = {
|
let form: RemoveComment = {
|
||||||
edit_id,
|
comment_id,
|
||||||
removed,
|
removed,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -468,10 +468,10 @@ export async function getCommunity(
|
||||||
export async function deleteCommunity(
|
export async function deleteCommunity(
|
||||||
api: API,
|
api: API,
|
||||||
deleted: boolean,
|
deleted: boolean,
|
||||||
edit_id: number
|
community_id: number
|
||||||
): Promise<CommunityResponse> {
|
): Promise<CommunityResponse> {
|
||||||
let form: DeleteCommunity = {
|
let form: DeleteCommunity = {
|
||||||
edit_id,
|
community_id,
|
||||||
deleted,
|
deleted,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -481,10 +481,10 @@ export async function deleteCommunity(
|
||||||
export async function removeCommunity(
|
export async function removeCommunity(
|
||||||
api: API,
|
api: API,
|
||||||
removed: boolean,
|
removed: boolean,
|
||||||
edit_id: number
|
community_id: number
|
||||||
): Promise<CommunityResponse> {
|
): Promise<CommunityResponse> {
|
||||||
let form: RemoveCommunity = {
|
let form: RemoveCommunity = {
|
||||||
edit_id,
|
community_id,
|
||||||
removed,
|
removed,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
|
@ -506,12 +506,12 @@ export async function createPrivateMessage(
|
||||||
|
|
||||||
export async function editPrivateMessage(
|
export async function editPrivateMessage(
|
||||||
api: API,
|
api: API,
|
||||||
edit_id: number
|
private_message_id: number
|
||||||
): Promise<PrivateMessageResponse> {
|
): Promise<PrivateMessageResponse> {
|
||||||
let updatedContent = 'A jest test federated private message edited';
|
let updatedContent = 'A jest test federated private message edited';
|
||||||
let form: EditPrivateMessage = {
|
let form: EditPrivateMessage = {
|
||||||
content: updatedContent,
|
content: updatedContent,
|
||||||
edit_id,
|
private_message_id,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
return api.client.editPrivateMessage(form);
|
return api.client.editPrivateMessage(form);
|
||||||
|
@ -520,11 +520,11 @@ export async function editPrivateMessage(
|
||||||
export async function deletePrivateMessage(
|
export async function deletePrivateMessage(
|
||||||
api: API,
|
api: API,
|
||||||
deleted: boolean,
|
deleted: boolean,
|
||||||
edit_id: number
|
private_message_id: number
|
||||||
): Promise<PrivateMessageResponse> {
|
): Promise<PrivateMessageResponse> {
|
||||||
let form: DeletePrivateMessage = {
|
let form: DeletePrivateMessage = {
|
||||||
deleted,
|
deleted,
|
||||||
edit_id,
|
private_message_id,
|
||||||
auth: api.auth,
|
auth: api.auth,
|
||||||
};
|
};
|
||||||
return api.client.deletePrivateMessage(form);
|
return api.client.deletePrivateMessage(form);
|
||||||
|
@ -538,7 +538,6 @@ export async function registerUser(
|
||||||
username,
|
username,
|
||||||
password: 'test',
|
password: 'test',
|
||||||
password_verify: 'test',
|
password_verify: 'test',
|
||||||
admin: false,
|
|
||||||
show_nsfw: true,
|
show_nsfw: true,
|
||||||
};
|
};
|
||||||
return api.client.register(form);
|
return api.client.register(form);
|
||||||
|
|
|
@ -3225,10 +3225,10 @@ language-tags@^1.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
language-subtag-registry "~0.3.2"
|
language-subtag-registry "~0.3.2"
|
||||||
|
|
||||||
lemmy-js-client@1.0.17-beta6:
|
lemmy-js-client@0.9.0-rc.12:
|
||||||
version "1.0.17-beta6"
|
version "0.9.0-rc.12"
|
||||||
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.17-beta6.tgz#afe1e1da13172a161c4d976b1ee58fe81eb22829"
|
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.9.0-rc.12.tgz#991d31c4ef89b9bd4088a17c60b6cbaac997df41"
|
||||||
integrity sha512-+oX7J7wht8nH4a5NQngK1GNner3TDv6ZOhQQVI5KcK7vynVVIcgveC5KBJArHBAl5acXpLs3Khmx0ZEb+sErJA==
|
integrity sha512-SeCw9wjU89Zm4YWhr+neHC2XvqoqzJg2e42sFEgcDmnQxpPt2sND9Udu+tjGXatbz0tCu6ybGmpR5M0QT4xx9Q==
|
||||||
|
|
||||||
leven@^3.1.0:
|
leven@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
|
|
|
@ -182,9 +182,9 @@ impl Perform for EditComment {
|
||||||
let data: &EditComment = &self;
|
let data: &EditComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
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| {
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(&conn, edit_id, None)
|
CommentView::read(&conn, comment_id, None)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
@ -197,9 +197,9 @@ impl Perform for EditComment {
|
||||||
|
|
||||||
// Do the update
|
// Do the update
|
||||||
let content_slurs_removed = remove_slurs(&data.content.to_owned());
|
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| {
|
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?
|
||||||
{
|
{
|
||||||
|
@ -223,10 +223,10 @@ impl Perform for EditComment {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let comment_id = data.comment_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -258,9 +258,9 @@ impl Perform for DeleteComment {
|
||||||
let data: &DeleteComment = &self;
|
let data: &DeleteComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
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| {
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(&conn, edit_id, None)
|
CommentView::read(&conn, comment_id, None)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ impl Perform for DeleteComment {
|
||||||
// Do the delete
|
// Do the delete
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_comment = match blocking(context.pool(), move |conn| {
|
let updated_comment = match blocking(context.pool(), move |conn| {
|
||||||
Comment::update_deleted(conn, edit_id, deleted)
|
Comment::update_deleted(conn, comment_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -290,10 +290,10 @@ impl Perform for DeleteComment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch it
|
// Refetch it
|
||||||
let edit_id = data.edit_id;
|
let comment_id = data.comment_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -338,9 +338,9 @@ impl Perform for RemoveComment {
|
||||||
let data: &RemoveComment = &self;
|
let data: &RemoveComment = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
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| {
|
let orig_comment = blocking(context.pool(), move |conn| {
|
||||||
CommentView::read(&conn, edit_id, None)
|
CommentView::read(&conn, comment_id, None)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ impl Perform for RemoveComment {
|
||||||
// Do the remove
|
// Do the remove
|
||||||
let removed = data.removed;
|
let removed = data.removed;
|
||||||
let updated_comment = match blocking(context.pool(), move |conn| {
|
let updated_comment = match blocking(context.pool(), move |conn| {
|
||||||
Comment::update_removed(conn, edit_id, removed)
|
Comment::update_removed(conn, comment_id, removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -363,7 +363,7 @@ impl Perform for RemoveComment {
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModRemoveCommentForm {
|
let form = ModRemoveCommentForm {
|
||||||
mod_user_id: user.id,
|
mod_user_id: user.id,
|
||||||
comment_id: data.edit_id,
|
comment_id: data.comment_id,
|
||||||
removed: Some(removed),
|
removed: Some(removed),
|
||||||
reason: data.reason.to_owned(),
|
reason: data.reason.to_owned(),
|
||||||
};
|
};
|
||||||
|
@ -380,10 +380,10 @@ impl Perform for RemoveComment {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch it
|
// Refetch it
|
||||||
let edit_id = data.edit_id;
|
let comment_id = data.comment_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -454,10 +454,10 @@ impl Perform for MarkCommentAsRead {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Refetch it
|
// Refetch it
|
||||||
let edit_id = data.comment_id;
|
let comment_id = data.comment_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let comment_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ use lemmy_utils::{
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
messages::{GetCommunityUsersOnline, JoinCommunityRoom, JoinModRoom, SendCommunityRoomMessage},
|
messages::{GetCommunityUsersOnline, SendCommunityRoomMessage},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
UserOperation,
|
UserOperation,
|
||||||
};
|
};
|
||||||
|
@ -233,9 +233,9 @@ impl Perform for EditCommunity {
|
||||||
check_slurs_opt(&data.description)?;
|
check_slurs_opt(&data.description)?;
|
||||||
|
|
||||||
// Verify its a mod (only mods can edit it)
|
// 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| {
|
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())
|
.map(|v| v.into_iter().map(|m| m.moderator.id).collect())
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
@ -243,9 +243,11 @@ impl Perform for EditCommunity {
|
||||||
return Err(APIError::err("not_a_moderator").into());
|
return Err(APIError::err("not_a_moderator").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let community_id = data.community_id;
|
||||||
let read_community =
|
let read_community = blocking(context.pool(), move |conn| {
|
||||||
blocking(context.pool(), move |conn| Community::read(conn, edit_id)).await??;
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
|
||||||
let icon = diesel_option_overwrite(&data.icon);
|
let icon = diesel_option_overwrite(&data.icon);
|
||||||
let banner = diesel_option_overwrite(&data.banner);
|
let banner = diesel_option_overwrite(&data.banner);
|
||||||
|
@ -273,9 +275,9 @@ impl Perform for EditCommunity {
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let community_id = data.community_id;
|
||||||
match blocking(context.pool(), move |conn| {
|
match blocking(context.pool(), move |conn| {
|
||||||
Community::update(conn, edit_id, &community_form)
|
Community::update(conn, community_id, &community_form)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -286,10 +288,10 @@ impl Perform for EditCommunity {
|
||||||
// TODO there needs to be some kind of an apub update
|
// TODO there needs to be some kind of an apub update
|
||||||
// process for communities and users
|
// process for communities and users
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let community_id = data.community_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let community_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -314,18 +316,20 @@ impl Perform for DeleteCommunity {
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Verify its the creator (only a creator can delete the community)
|
// Verify its the creator (only a creator can delete the community)
|
||||||
let edit_id = data.edit_id;
|
let community_id = data.community_id;
|
||||||
let read_community =
|
let read_community = blocking(context.pool(), move |conn| {
|
||||||
blocking(context.pool(), move |conn| Community::read(conn, edit_id)).await??;
|
Community::read(conn, community_id)
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
if read_community.creator_id != user.id {
|
if read_community.creator_id != user.id {
|
||||||
return Err(APIError::err("no_community_edit_allowed").into());
|
return Err(APIError::err("no_community_edit_allowed").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the delete
|
// Do the delete
|
||||||
let edit_id = data.edit_id;
|
let community_id = data.community_id;
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_community = match blocking(context.pool(), move |conn| {
|
let updated_community = match blocking(context.pool(), move |conn| {
|
||||||
Community::update_deleted(conn, edit_id, deleted)
|
Community::update_deleted(conn, community_id, deleted)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -340,10 +344,10 @@ impl Perform for DeleteCommunity {
|
||||||
updated_community.send_undo_delete(context).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 user_id = user.id;
|
||||||
let community_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -371,10 +375,10 @@ impl Perform for RemoveCommunity {
|
||||||
is_admin(context.pool(), user.id).await?;
|
is_admin(context.pool(), user.id).await?;
|
||||||
|
|
||||||
// Do the remove
|
// Do the remove
|
||||||
let edit_id = data.edit_id;
|
let community_id = data.community_id;
|
||||||
let removed = data.removed;
|
let removed = data.removed;
|
||||||
let updated_community = match blocking(context.pool(), move |conn| {
|
let updated_community = match blocking(context.pool(), move |conn| {
|
||||||
Community::update_removed(conn, edit_id, removed)
|
Community::update_removed(conn, community_id, removed)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -389,7 +393,7 @@ impl Perform for RemoveCommunity {
|
||||||
};
|
};
|
||||||
let form = ModRemoveCommunityForm {
|
let form = ModRemoveCommunityForm {
|
||||||
mod_user_id: user.id,
|
mod_user_id: user.id,
|
||||||
community_id: data.edit_id,
|
community_id: data.community_id,
|
||||||
removed: Some(removed),
|
removed: Some(removed),
|
||||||
reason: data.reason.to_owned(),
|
reason: data.reason.to_owned(),
|
||||||
expires,
|
expires,
|
||||||
|
@ -406,10 +410,10 @@ impl Perform for RemoveCommunity {
|
||||||
updated_community.send_undo_remove(context).await?;
|
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 user_id = user.id;
|
||||||
let community_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -864,47 +868,3 @@ fn send_community_websocket(
|
||||||
websocket_id,
|
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 })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use lemmy_db_queries::{
|
||||||
source::{
|
source::{
|
||||||
community::{CommunityModerator_, Community_},
|
community::{CommunityModerator_, Community_},
|
||||||
site::Site_,
|
site::Site_,
|
||||||
|
user::UserSafeSettings_,
|
||||||
},
|
},
|
||||||
Crud,
|
Crud,
|
||||||
DbPool,
|
DbPool,
|
||||||
|
@ -12,13 +13,13 @@ use lemmy_db_schema::source::{
|
||||||
community::{Community, CommunityModerator},
|
community::{Community, CommunityModerator},
|
||||||
post::Post,
|
post::Post,
|
||||||
site::Site,
|
site::Site,
|
||||||
user::User_,
|
user::{UserSafeSettings, User_},
|
||||||
};
|
};
|
||||||
use lemmy_db_views_actor::{
|
use lemmy_db_views_actor::{
|
||||||
community_user_ban_view::CommunityUserBanView,
|
community_user_ban_view::CommunityUserBanView,
|
||||||
community_view::CommunityView,
|
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_utils::{settings::Settings, APIError, ConnectionId, LemmyError};
|
||||||
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
|
use lemmy_websocket::{serialize_websocket_message, LemmyContext, UserOperation};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -32,6 +33,7 @@ pub mod post;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
pub mod version;
|
pub mod version;
|
||||||
|
pub mod websocket;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
pub trait Perform {
|
pub trait Perform {
|
||||||
|
@ -97,6 +99,33 @@ pub(crate) async fn get_user_from_jwt_opt(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
pub(crate) async fn check_community_ban(
|
||||||
user_id: i32,
|
user_id: i32,
|
||||||
community_id: i32,
|
community_id: i32,
|
||||||
|
|
|
@ -46,7 +46,7 @@ use lemmy_utils::{
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
messages::{GetPostUsersOnline, JoinPostRoom, SendModRoomMessage, SendPost, SendUserRoomMessage},
|
messages::{GetPostUsersOnline, SendModRoomMessage, SendPost, SendUserRoomMessage},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
UserOperation,
|
UserOperation,
|
||||||
};
|
};
|
||||||
|
@ -376,8 +376,8 @@ impl Perform for EditPost {
|
||||||
return Err(APIError::err("invalid_post_title").into());
|
return Err(APIError::err("invalid_post_title").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
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?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
|
@ -411,9 +411,9 @@ impl Perform for EditPost {
|
||||||
published: None,
|
published: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let res = blocking(context.pool(), move |conn| {
|
let res = blocking(context.pool(), move |conn| {
|
||||||
Post::update(conn, edit_id, &post_form)
|
Post::update(conn, post_id, &post_form)
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
let updated_post: Post = match res {
|
let updated_post: Post = match res {
|
||||||
|
@ -432,9 +432,9 @@ impl Perform for EditPost {
|
||||||
// Send apub update
|
// Send apub update
|
||||||
updated_post.send_update(&user, context).await?;
|
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| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -462,8 +462,8 @@ impl Perform for DeletePost {
|
||||||
let data: &DeletePost = &self;
|
let data: &DeletePost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
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?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
|
@ -473,10 +473,10 @@ impl Perform for DeletePost {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_post = blocking(context.pool(), move |conn| {
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
Post::update_deleted(conn, edit_id, deleted)
|
Post::update_deleted(conn, post_id, deleted)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
@ -488,9 +488,9 @@ impl Perform for DeletePost {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let post_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -518,8 +518,8 @@ impl Perform for RemovePost {
|
||||||
let data: &RemovePost = &self;
|
let data: &RemovePost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
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?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
|
@ -527,17 +527,17 @@ impl Perform for RemovePost {
|
||||||
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let removed = data.removed;
|
let removed = data.removed;
|
||||||
let updated_post = blocking(context.pool(), move |conn| {
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
Post::update_removed(conn, edit_id, removed)
|
Post::update_removed(conn, post_id, removed)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModRemovePostForm {
|
let form = ModRemovePostForm {
|
||||||
mod_user_id: user.id,
|
mod_user_id: user.id,
|
||||||
post_id: data.edit_id,
|
post_id: data.post_id,
|
||||||
removed: Some(removed),
|
removed: Some(removed),
|
||||||
reason: data.reason.to_owned(),
|
reason: data.reason.to_owned(),
|
||||||
};
|
};
|
||||||
|
@ -554,10 +554,10 @@ impl Perform for RemovePost {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let user_id = user.id;
|
let user_id = user.id;
|
||||||
let post_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -585,8 +585,8 @@ impl Perform for LockPost {
|
||||||
let data: &LockPost = &self;
|
let data: &LockPost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
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?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
|
@ -594,17 +594,17 @@ impl Perform for LockPost {
|
||||||
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let locked = data.locked;
|
let locked = data.locked;
|
||||||
let updated_post = blocking(context.pool(), move |conn| {
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
Post::update_locked(conn, edit_id, locked)
|
Post::update_locked(conn, post_id, locked)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModLockPostForm {
|
let form = ModLockPostForm {
|
||||||
mod_user_id: user.id,
|
mod_user_id: user.id,
|
||||||
post_id: data.edit_id,
|
post_id: data.post_id,
|
||||||
locked: Some(locked),
|
locked: Some(locked),
|
||||||
};
|
};
|
||||||
blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??;
|
blocking(context.pool(), move |conn| ModLockPost::create(conn, &form)).await??;
|
||||||
|
@ -613,9 +613,9 @@ impl Perform for LockPost {
|
||||||
updated_post.send_update(&user, context).await?;
|
updated_post.send_update(&user, context).await?;
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let post_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -643,8 +643,8 @@ impl Perform for StickyPost {
|
||||||
let data: &StickyPost = &self;
|
let data: &StickyPost = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let orig_post = blocking(context.pool(), move |conn| Post::read(conn, edit_id)).await??;
|
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?;
|
check_community_ban(user.id, orig_post.community_id, context.pool()).await?;
|
||||||
|
|
||||||
|
@ -652,17 +652,17 @@ impl Perform for StickyPost {
|
||||||
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
is_mod_or_admin(context.pool(), user.id, orig_post.community_id).await?;
|
||||||
|
|
||||||
// Update the post
|
// Update the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let stickied = data.stickied;
|
let stickied = data.stickied;
|
||||||
let updated_post = blocking(context.pool(), move |conn| {
|
let updated_post = blocking(context.pool(), move |conn| {
|
||||||
Post::update_stickied(conn, edit_id, stickied)
|
Post::update_stickied(conn, post_id, stickied)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
let form = ModStickyPostForm {
|
let form = ModStickyPostForm {
|
||||||
mod_user_id: user.id,
|
mod_user_id: user.id,
|
||||||
post_id: data.edit_id,
|
post_id: data.post_id,
|
||||||
stickied: Some(stickied),
|
stickied: Some(stickied),
|
||||||
};
|
};
|
||||||
blocking(context.pool(), move |conn| {
|
blocking(context.pool(), move |conn| {
|
||||||
|
@ -675,9 +675,9 @@ impl Perform for StickyPost {
|
||||||
updated_post.send_update(&user, context).await?;
|
updated_post.send_update(&user, context).await?;
|
||||||
|
|
||||||
// Refetch the post
|
// Refetch the post
|
||||||
let edit_id = data.edit_id;
|
let post_id = data.post_id;
|
||||||
let post_view = blocking(context.pool(), move |conn| {
|
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??;
|
.await??;
|
||||||
|
|
||||||
|
@ -733,28 +733,6 @@ impl Perform for SavePost {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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
|
/// Creates a post report and notifies the moderators of the community
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for CreatePostReport {
|
impl Perform for CreatePostReport {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
get_user_from_jwt,
|
get_user_from_jwt,
|
||||||
get_user_from_jwt_opt,
|
get_user_from_jwt_opt,
|
||||||
|
get_user_safe_settings_from_jwt,
|
||||||
|
get_user_safe_settings_from_jwt_opt,
|
||||||
is_admin,
|
is_admin,
|
||||||
linked_instances,
|
linked_instances,
|
||||||
version,
|
version,
|
||||||
|
@ -274,7 +276,6 @@ impl Perform for GetSite {
|
||||||
email: setup.admin_email.to_owned(),
|
email: setup.admin_email.to_owned(),
|
||||||
password: setup.admin_password.to_owned(),
|
password: setup.admin_password.to_owned(),
|
||||||
password_verify: setup.admin_password.to_owned(),
|
password_verify: setup.admin_password.to_owned(),
|
||||||
admin: true,
|
|
||||||
show_nsfw: true,
|
show_nsfw: true,
|
||||||
captcha_uuid: None,
|
captcha_uuid: None,
|
||||||
captcha_answer: None,
|
captcha_answer: None,
|
||||||
|
@ -322,14 +323,7 @@ impl Perform for GetSite {
|
||||||
.await
|
.await
|
||||||
.unwrap_or(1);
|
.unwrap_or(1);
|
||||||
|
|
||||||
let my_user = get_user_from_jwt_opt(&data.auth, context.pool())
|
let my_user = get_user_safe_settings_from_jwt_opt(&data.auth, context.pool()).await?;
|
||||||
.await?
|
|
||||||
.map(|mut u| {
|
|
||||||
u.password_encrypted = "".to_string();
|
|
||||||
u.private_key = None;
|
|
||||||
u.public_key = None;
|
|
||||||
u
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(GetSiteResponse {
|
Ok(GetSiteResponse {
|
||||||
site_view,
|
site_view,
|
||||||
|
@ -519,15 +513,10 @@ impl Perform for TransferSite {
|
||||||
_websocket_id: Option<ConnectionId>,
|
_websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<GetSiteResponse, LemmyError> {
|
) -> Result<GetSiteResponse, LemmyError> {
|
||||||
let data: &TransferSite = &self;
|
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?;
|
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??;
|
let read_site = blocking(context.pool(), move |conn| Site::read_simple(conn)).await??;
|
||||||
|
|
||||||
// Make sure user is the creator
|
// Make sure user is the creator
|
||||||
|
|
|
@ -57,7 +57,7 @@ use lemmy_db_views_actor::{
|
||||||
community_follower_view::CommunityFollowerView,
|
community_follower_view::CommunityFollowerView,
|
||||||
community_moderator_view::CommunityModeratorView,
|
community_moderator_view::CommunityModeratorView,
|
||||||
user_mention_view::{UserMentionQueryBuilder, UserMentionView},
|
user_mention_view::{UserMentionQueryBuilder, UserMentionView},
|
||||||
user_view::{UserViewDangerous, UserViewSafe},
|
user_view::UserViewSafe,
|
||||||
};
|
};
|
||||||
use lemmy_structs::{blocking, send_email_to_user, user::*};
|
use lemmy_structs::{blocking, send_email_to_user, user::*};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
|
@ -78,7 +78,7 @@ use lemmy_utils::{
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
messages::{CaptchaItem, CheckCaptcha, JoinUserRoom, SendAllMessage, SendUserRoomMessage},
|
messages::{CaptchaItem, CheckCaptcha, SendAllMessage, SendUserRoomMessage},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
UserOperation,
|
UserOperation,
|
||||||
};
|
};
|
||||||
|
@ -147,8 +147,14 @@ impl Perform for Register {
|
||||||
return Err(APIError::err("passwords_dont_match").into());
|
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 its not the admin, check the captcha
|
||||||
if !data.admin && Settings::get().captcha.enabled {
|
if !no_admins && Settings::get().captcha.enabled {
|
||||||
let check = context
|
let check = context
|
||||||
.chat_server()
|
.chat_server()
|
||||||
.send(CheckCaptcha {
|
.send(CheckCaptcha {
|
||||||
|
@ -169,15 +175,6 @@ impl Perform for Register {
|
||||||
|
|
||||||
check_slurs(&data.username)?;
|
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()?;
|
let user_keypair = generate_actor_keypair()?;
|
||||||
if !is_valid_username(&data.username) {
|
if !is_valid_username(&data.username) {
|
||||||
return Err(APIError::err("invalid_username").into());
|
return Err(APIError::err("invalid_username").into());
|
||||||
|
@ -194,7 +191,7 @@ impl Perform for Register {
|
||||||
preferred_username: None,
|
preferred_username: None,
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
admin: data.admin,
|
admin: no_admins,
|
||||||
banned: Some(false),
|
banned: Some(false),
|
||||||
show_nsfw: data.show_nsfw,
|
show_nsfw: data.show_nsfw,
|
||||||
theme: "browser".into(),
|
theme: "browser".into(),
|
||||||
|
@ -280,7 +277,7 @@ impl Perform for Register {
|
||||||
};
|
};
|
||||||
|
|
||||||
// If its an admin, add them as a mod and follower to main
|
// If its an admin, add them as a mod and follower to main
|
||||||
if data.admin {
|
if no_admins {
|
||||||
let community_moderator_form = CommunityModeratorForm {
|
let community_moderator_form = CommunityModeratorForm {
|
||||||
community_id: main_community.id,
|
community_id: main_community.id,
|
||||||
user_id: inserted_user.id,
|
user_id: inserted_user.id,
|
||||||
|
@ -509,39 +506,12 @@ impl Perform for GetUserDetails {
|
||||||
|
|
||||||
let user_id = user.map(|u| u.id);
|
let user_id = user.map(|u| u.id);
|
||||||
|
|
||||||
let (user_view, user_view_dangerous) = if let Some(auth_user_id) = user_id {
|
// You don't need to return settings for the user, since this comes back with GetSite
|
||||||
if user_details_id == auth_user_id {
|
// `my_user`
|
||||||
(
|
let user_view = blocking(context.pool(), move |conn| {
|
||||||
None,
|
UserViewSafe::read(conn, user_details_id)
|
||||||
Some(
|
})
|
||||||
blocking(context.pool(), move |conn| {
|
.await??;
|
||||||
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,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
|
@ -591,7 +561,6 @@ impl Perform for GetUserDetails {
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(GetUserDetailsResponse {
|
Ok(GetUserDetailsResponse {
|
||||||
user_view,
|
user_view,
|
||||||
user_view_dangerous,
|
|
||||||
follows,
|
follows,
|
||||||
moderates,
|
moderates,
|
||||||
comments,
|
comments,
|
||||||
|
@ -1129,9 +1098,9 @@ impl Perform for EditPrivateMessage {
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Checking permissions
|
// 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| {
|
let orig_private_message = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::read(conn, edit_id)
|
PrivateMessage::read(conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
if user.id != orig_private_message.creator_id {
|
if user.id != orig_private_message.creator_id {
|
||||||
|
@ -1140,9 +1109,9 @@ impl Perform for EditPrivateMessage {
|
||||||
|
|
||||||
// Doing the update
|
// Doing the update
|
||||||
let content_slurs_removed = remove_slurs(&data.content);
|
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| {
|
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?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -1153,9 +1122,9 @@ impl Perform for EditPrivateMessage {
|
||||||
// Send the apub update
|
// Send the apub update
|
||||||
updated_private_message.send_update(&user, context).await?;
|
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| {
|
let message = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(conn, edit_id)
|
PrivateMessageView::read(conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
let recipient_id = message.recipient.id;
|
let recipient_id = message.recipient.id;
|
||||||
|
@ -1188,9 +1157,9 @@ impl Perform for DeletePrivateMessage {
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Checking permissions
|
// 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| {
|
let orig_private_message = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::read(conn, edit_id)
|
PrivateMessage::read(conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
if user.id != orig_private_message.creator_id {
|
if user.id != orig_private_message.creator_id {
|
||||||
|
@ -1198,10 +1167,10 @@ impl Perform for DeletePrivateMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doing the update
|
// Doing the update
|
||||||
let edit_id = data.edit_id;
|
let private_message_id = data.private_message_id;
|
||||||
let deleted = data.deleted;
|
let deleted = data.deleted;
|
||||||
let updated_private_message = match blocking(context.pool(), move |conn| {
|
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?
|
||||||
{
|
{
|
||||||
|
@ -1218,9 +1187,9 @@ impl Perform for DeletePrivateMessage {
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let edit_id = data.edit_id;
|
let private_message_id = data.private_message_id;
|
||||||
let message = blocking(context.pool(), move |conn| {
|
let message = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(conn, edit_id)
|
PrivateMessageView::read(conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
let recipient_id = message.recipient.id;
|
let recipient_id = message.recipient.id;
|
||||||
|
@ -1253,9 +1222,9 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
|
||||||
// Checking permissions
|
// 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| {
|
let orig_private_message = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::read(conn, edit_id)
|
PrivateMessage::read(conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
if user.id != orig_private_message.recipient_id {
|
if user.id != orig_private_message.recipient_id {
|
||||||
|
@ -1263,10 +1232,10 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Doing the update
|
// Doing the update
|
||||||
let edit_id = data.edit_id;
|
let private_message_id = data.private_message_id;
|
||||||
let read = data.read;
|
let read = data.read;
|
||||||
match blocking(context.pool(), move |conn| {
|
match blocking(context.pool(), move |conn| {
|
||||||
PrivateMessage::update_read(conn, edit_id, read)
|
PrivateMessage::update_read(conn, private_message_id, read)
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -1276,9 +1245,9 @@ impl Perform for MarkPrivateMessageAsRead {
|
||||||
|
|
||||||
// No need to send an apub update
|
// 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| {
|
let message = blocking(context.pool(), move |conn| {
|
||||||
PrivateMessageView::read(conn, edit_id)
|
PrivateMessageView::read(conn, private_message_id)
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
let recipient_id = message.recipient.id;
|
let recipient_id = message.recipient.id;
|
||||||
|
@ -1329,29 +1298,6 @@ impl Perform for GetPrivateMessages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for GetReportCount {
|
impl Perform for GetReportCount {
|
||||||
type Response = GetReportCountResponse;
|
type Response = GetReportCountResponse;
|
||||||
|
|
97
lemmy_api/src/websocket.rs
Normal file
97
lemmy_api/src/websocket.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
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 })
|
||||||
|
}
|
||||||
|
}
|
|
@ -137,6 +137,11 @@ pub trait ToSafe {
|
||||||
fn safe_columns_tuple() -> Self::SafeColumns;
|
fn safe_columns_tuple() -> Self::SafeColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ToSafeSettings {
|
||||||
|
type SafeSettingsColumns;
|
||||||
|
fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ViewToVec {
|
pub trait ViewToVec {
|
||||||
type DbTuple;
|
type DbTuple;
|
||||||
fn from_tuple_to_vec(tuple: Vec<Self::DbTuple>) -> Vec<Self>
|
fn from_tuple_to_vec(tuple: Vec<Self::DbTuple>) -> Vec<Self>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{is_email_regex, ApubObject, Crud};
|
use crate::{is_email_regex, ApubObject, Crud, ToSafeSettings};
|
||||||
use bcrypt::{hash, DEFAULT_COST};
|
use bcrypt::{hash, DEFAULT_COST};
|
||||||
use diesel::{dsl::*, result::Error, *};
|
use diesel::{dsl::*, result::Error, *};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
naive_now,
|
naive_now,
|
||||||
schema::user_::dsl::*,
|
schema::user_::dsl::*,
|
||||||
source::user::{UserForm, User_},
|
source::user::{UserForm, UserSafeSettings, User_},
|
||||||
};
|
};
|
||||||
use lemmy_utils::settings::Settings;
|
use lemmy_utils::settings::Settings;
|
||||||
|
|
||||||
|
@ -140,6 +140,82 @@ mod safe_type_alias_2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_ {
|
impl Crud<UserForm> for User_ {
|
||||||
fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
|
fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
|
||||||
user_
|
user_
|
||||||
|
|
|
@ -52,6 +52,35 @@ pub struct UserSafe {
|
||||||
pub deleted: bool,
|
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)]
|
#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
|
||||||
#[table_name = "user_alias_1"]
|
#[table_name = "user_alias_1"]
|
||||||
pub struct UserAlias1 {
|
pub struct UserAlias1 {
|
||||||
|
|
|
@ -22,24 +22,6 @@ pub struct UserViewSafe {
|
||||||
|
|
||||||
type UserViewSafeTuple = (UserSafe, UserAggregates);
|
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 {
|
impl UserViewSafe {
|
||||||
pub fn read(conn: &PgConnection, id: i32) -> Result<Self, Error> {
|
pub fn read(conn: &PgConnection, id: i32) -> Result<Self, Error> {
|
||||||
let (user, counts) = user_::table
|
let (user, counts) = user_::table
|
||||||
|
|
|
@ -13,21 +13,21 @@ pub struct CreateComment {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EditComment {
|
pub struct EditComment {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub edit_id: i32,
|
pub comment_id: i32,
|
||||||
pub form_id: Option<String>,
|
pub form_id: Option<String>,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct DeleteComment {
|
pub struct DeleteComment {
|
||||||
pub edit_id: i32,
|
pub comment_id: i32,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct RemoveComment {
|
pub struct RemoveComment {
|
||||||
pub edit_id: i32,
|
pub comment_id: i32,
|
||||||
pub removed: bool,
|
pub removed: bool,
|
||||||
pub reason: Option<String>,
|
pub reason: Option<String>,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
|
|
|
@ -82,7 +82,7 @@ pub struct AddModToCommunityResponse {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EditCommunity {
|
pub struct EditCommunity {
|
||||||
pub edit_id: i32,
|
pub community_id: i32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
|
@ -94,14 +94,14 @@ pub struct EditCommunity {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct DeleteCommunity {
|
pub struct DeleteCommunity {
|
||||||
pub edit_id: i32,
|
pub community_id: i32,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct RemoveCommunity {
|
pub struct RemoveCommunity {
|
||||||
pub edit_id: i32,
|
pub community_id: i32,
|
||||||
pub removed: bool,
|
pub removed: bool,
|
||||||
pub reason: Option<String>,
|
pub reason: Option<String>,
|
||||||
pub expires: Option<i64>,
|
pub expires: Option<i64>,
|
||||||
|
@ -131,23 +131,3 @@ pub struct TransferCommunity {
|
||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
pub auth: String,
|
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,
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ pub mod community;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
pub mod websocket;
|
||||||
|
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use lemmy_db_queries::{source::user::User, Crud, DbPool};
|
use lemmy_db_queries::{source::user::User, Crud, DbPool};
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub struct CreatePostLike {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EditPost {
|
pub struct EditPost {
|
||||||
pub edit_id: i32,
|
pub post_id: i32,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub url: Option<String>,
|
pub url: Option<String>,
|
||||||
pub body: Option<String>,
|
pub body: Option<String>,
|
||||||
|
@ -74,14 +74,14 @@ pub struct EditPost {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct DeletePost {
|
pub struct DeletePost {
|
||||||
pub edit_id: i32,
|
pub post_id: i32,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct RemovePost {
|
pub struct RemovePost {
|
||||||
pub edit_id: i32,
|
pub post_id: i32,
|
||||||
pub removed: bool,
|
pub removed: bool,
|
||||||
pub reason: Option<String>,
|
pub reason: Option<String>,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
|
@ -89,14 +89,14 @@ pub struct RemovePost {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct LockPost {
|
pub struct LockPost {
|
||||||
pub edit_id: i32,
|
pub post_id: i32,
|
||||||
pub locked: bool,
|
pub locked: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct StickyPost {
|
pub struct StickyPost {
|
||||||
pub edit_id: i32,
|
pub post_id: i32,
|
||||||
pub stickied: bool,
|
pub stickied: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
@ -108,16 +108,6 @@ pub struct SavePost {
|
||||||
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)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct CreatePostReport {
|
pub struct CreatePostReport {
|
||||||
pub post_id: i32,
|
pub post_id: i32,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
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::{comment_view::CommentView, post_view::PostView, site_view::SiteView};
|
||||||
use lemmy_db_views_actor::{community_view::CommunityView, user_view::UserViewSafe};
|
use lemmy_db_views_actor::{community_view::CommunityView, user_view::UserViewSafe};
|
||||||
use lemmy_db_views_moderator::{
|
use lemmy_db_views_moderator::{
|
||||||
|
@ -105,7 +105,7 @@ pub struct GetSiteResponse {
|
||||||
pub banned: Vec<UserViewSafe>,
|
pub banned: Vec<UserViewSafe>,
|
||||||
pub online: usize,
|
pub online: usize,
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub my_user: Option<User_>,
|
pub my_user: Option<UserSafeSettings>,
|
||||||
pub federated_instances: Vec<String>,
|
pub federated_instances: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use lemmy_db_views_actor::{
|
||||||
community_follower_view::CommunityFollowerView,
|
community_follower_view::CommunityFollowerView,
|
||||||
community_moderator_view::CommunityModeratorView,
|
community_moderator_view::CommunityModeratorView,
|
||||||
user_mention_view::UserMentionView,
|
user_mention_view::UserMentionView,
|
||||||
user_view::{UserViewDangerous, UserViewSafe},
|
user_view::UserViewSafe,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ pub struct Register {
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
pub password_verify: String,
|
pub password_verify: String,
|
||||||
pub admin: bool,
|
|
||||||
pub show_nsfw: bool,
|
pub show_nsfw: bool,
|
||||||
pub captcha_uuid: Option<String>,
|
pub captcha_uuid: Option<String>,
|
||||||
pub captcha_answer: Option<String>,
|
pub captcha_answer: Option<String>,
|
||||||
|
@ -34,7 +33,7 @@ pub struct GetCaptcha {}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct GetCaptchaResponse {
|
pub struct GetCaptchaResponse {
|
||||||
pub ok: Option<CaptchaResponse>,
|
pub ok: Option<CaptchaResponse>, // Will be None if captchas are disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -84,8 +83,7 @@ pub struct GetUserDetails {
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct GetUserDetailsResponse {
|
pub struct GetUserDetailsResponse {
|
||||||
pub user_view: Option<UserViewSafe>,
|
pub user_view: UserViewSafe,
|
||||||
pub user_view_dangerous: Option<UserViewDangerous>,
|
|
||||||
pub follows: Vec<CommunityFollowerView>,
|
pub follows: Vec<CommunityFollowerView>,
|
||||||
pub moderates: Vec<CommunityModeratorView>,
|
pub moderates: Vec<CommunityModeratorView>,
|
||||||
pub comments: Vec<CommentView>,
|
pub comments: Vec<CommentView>,
|
||||||
|
@ -195,21 +193,21 @@ pub struct CreatePrivateMessage {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EditPrivateMessage {
|
pub struct EditPrivateMessage {
|
||||||
pub edit_id: i32,
|
pub private_message_id: i32,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct DeletePrivateMessage {
|
pub struct DeletePrivateMessage {
|
||||||
pub edit_id: i32,
|
pub private_message_id: i32,
|
||||||
pub deleted: bool,
|
pub deleted: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct MarkPrivateMessageAsRead {
|
pub struct MarkPrivateMessageAsRead {
|
||||||
pub edit_id: i32,
|
pub private_message_id: i32,
|
||||||
pub read: bool,
|
pub read: bool,
|
||||||
pub auth: String,
|
pub auth: String,
|
||||||
}
|
}
|
||||||
|
@ -232,16 +230,6 @@ pub struct PrivateMessageResponse {
|
||||||
pub private_message_view: PrivateMessageView,
|
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)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct GetReportCount {
|
pub struct GetReportCount {
|
||||||
pub community: Option<i32>,
|
pub community: Option<i32>,
|
||||||
|
|
41
lemmy_structs/src/websocket.rs
Normal file
41
lemmy_structs/src/websocket.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
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,
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use actix_web::{error::ErrorBadRequest, *};
|
use actix_web::{error::ErrorBadRequest, *};
|
||||||
use lemmy_api::Perform;
|
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_utils::rate_limit::RateLimit;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
Loading…
Reference in a new issue