diff --git a/README.md b/README.md
index e4a7d2f6e6a..e9be459db04 100644
--- a/README.md
+++ b/README.md
@@ -157,15 +157,15 @@ If you'd like to add translations, take a look a look at the [English translatio
lang | done | missing
--- | --- | ---
-de | 93% | avatar,upload_avatar,show_avatars,docs,old_password,send_notifications_to_email,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,email_already_exists
-eo | 80% | number_of_communities,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,theme,donate_to_lemmy,donate,are_you_sure,yes,no,email_already_exists
-es | 89% | avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,email_already_exists
-fr | 89% | avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,email_already_exists
-it | 89% | avatar,upload_avatar,show_avatars,archive_link,docs,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,email_already_exists
-nl | 99% | donate_to_lemmy,donate,email_already_exists
-ru | 77% | cross_posts,cross_post,number_of_communities,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,theme,donate_to_lemmy,donate,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no,email_already_exists
-sv | 89% | avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,email_already_exists
-zh | 75% | cross_posts,cross_post,users,number_of_communities,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,nsfw,show_nsfw,theme,donate_to_lemmy,donate,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no,email_already_exists
+de | 88% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,docs,message_sent,messages,old_password,matrix_user_id,private_message_disclaimer,send_notifications_to_email,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+eo | 76% | number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,theme,donate_to_lemmy,donate,from,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+es | 83% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+fr | 83% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+it | 84% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,docs,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+nl | 93% | create_private_message,send_secure_message,send_message,message,message_sent,messages,matrix_user_id,private_message_disclaimer,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+ru | 72% | cross_posts,cross_post,number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,theme,donate_to_lemmy,donate,monero,by,to,from,transfer_community,transfer_site,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+sv | 83% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
+zh | 70% | cross_posts,cross_post,users,number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,nsfw,show_nsfw,theme,donate_to_lemmy,donate,monero,by,to,from,transfer_community,transfer_site,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message
diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md
index d891697464c..c2df6223e6d 100644
--- a/docs/src/SUMMARY.md
+++ b/docs/src/SUMMARY.md
@@ -12,5 +12,5 @@
- [Contributing](contributing.md)
- [Docker Development](contributing_docker_development.md)
- [Local Development](contributing_local_development.md)
- - [Websocket API](contributing_websocket_api.md)
+ - [Websocket/HTTP API](contributing_websocket_http_api.md)
- [ActivityPub API Outline](contributing_apub_api_outline.md)
diff --git a/docs/src/contributing_websocket_api.md b/docs/src/contributing_websocket_http_api.md
similarity index 68%
rename from docs/src/contributing_websocket_api.md
rename to docs/src/contributing_websocket_http_api.md
index 16383d532b4..9e87d4faa16 100644
--- a/docs/src/contributing_websocket_api.md
+++ b/docs/src/contributing_websocket_http_api.md
@@ -5,126 +5,171 @@
- [Data types](#data-types)
- [Basic usage](#basic-usage)
- * [WebSocket Endpoint](#websocket-endpoint)
- * [Testing with Websocat](#testing-with-websocat)
- * [Testing with the WebSocket JavaScript API](#testing-with-the-websocket-javascript-api)
+ * [WebSocket](#websocket)
+ + [Testing with Websocat](#testing-with-websocat)
+ + [Testing with the WebSocket JavaScript API](#testing-with-the-websocket-javascript-api)
+ * [HTTP](#http)
+ + [Testing with Curl](#testing-with-curl)
+ - [Get Example](#get-example)
+ - [Post Example](#post-example)
- [Rate limits](#rate-limits)
- [Errors](#errors)
- [API documentation](#api-documentation)
* [Sort Types](#sort-types)
+ * [Websocket vs HTTP](#websocket-vs-http)
* [User / Authentication / Admin actions](#user--authentication--admin-actions)
+ [Login](#login)
- [Request](#request)
- [Response](#response)
+ - [HTTP](#http-1)
+ [Register](#register)
- [Request](#request-1)
- [Response](#response-1)
+ - [HTTP](#http-2)
+ [Get User Details](#get-user-details)
- [Request](#request-2)
- [Response](#response-2)
+ - [HTTP](#http-3)
+ [Save User Settings](#save-user-settings)
- [Request](#request-3)
- [Response](#response-3)
+ - [HTTP](#http-4)
+ [Get Replies / Inbox](#get-replies--inbox)
- [Request](#request-4)
- [Response](#response-4)
+ - [HTTP](#http-5)
+ [Get User Mentions](#get-user-mentions)
- [Request](#request-5)
- [Response](#response-5)
- + [Mark All As Read](#mark-all-as-read)
+ - [HTTP](#http-6)
+ + [Edit User Mention](#edit-user-mention)
- [Request](#request-6)
- [Response](#response-6)
- + [Delete Account](#delete-account)
+ - [HTTP](#http-7)
+ + [Mark All As Read](#mark-all-as-read)
- [Request](#request-7)
- [Response](#response-7)
- + [Add admin](#add-admin)
+ - [HTTP](#http-8)
+ + [Delete Account](#delete-account)
- [Request](#request-8)
- [Response](#response-8)
- + [Ban user](#ban-user)
+ - [HTTP](#http-9)
+ + [Add admin](#add-admin)
- [Request](#request-9)
- [Response](#response-9)
- * [Site](#site)
- + [List Categories](#list-categories)
+ - [HTTP](#http-10)
+ + [Ban user](#ban-user)
- [Request](#request-10)
- [Response](#response-10)
- + [Search](#search)
+ - [HTTP](#http-11)
+ * [Site](#site)
+ + [List Categories](#list-categories)
- [Request](#request-11)
- [Response](#response-11)
- + [Get Modlog](#get-modlog)
+ - [HTTP](#http-12)
+ + [Search](#search)
- [Request](#request-12)
- [Response](#response-12)
- + [Create Site](#create-site)
+ - [HTTP](#http-13)
+ + [Get Modlog](#get-modlog)
- [Request](#request-13)
- [Response](#response-13)
- + [Edit Site](#edit-site)
+ - [HTTP](#http-14)
+ + [Create Site](#create-site)
- [Request](#request-14)
- [Response](#response-14)
- + [Get Site](#get-site)
+ - [HTTP](#http-15)
+ + [Edit Site](#edit-site)
- [Request](#request-15)
- [Response](#response-15)
- + [Transfer Site](#transfer-site)
+ - [HTTP](#http-16)
+ + [Get Site](#get-site)
- [Request](#request-16)
- [Response](#response-16)
- * [Community](#community)
- + [Get Community](#get-community)
+ - [HTTP](#http-17)
+ + [Transfer Site](#transfer-site)
- [Request](#request-17)
- [Response](#response-17)
- + [Create Community](#create-community)
+ - [HTTP](#http-18)
+ * [Community](#community)
+ + [Get Community](#get-community)
- [Request](#request-18)
- [Response](#response-18)
- + [List Communities](#list-communities)
+ - [HTTP](#http-19)
+ + [Create Community](#create-community)
- [Request](#request-19)
- [Response](#response-19)
- + [Ban from Community](#ban-from-community)
+ - [HTTP](#http-20)
+ + [List Communities](#list-communities)
- [Request](#request-20)
- [Response](#response-20)
- + [Add Mod to Community](#add-mod-to-community)
+ - [HTTP](#http-21)
+ + [Ban from Community](#ban-from-community)
- [Request](#request-21)
- [Response](#response-21)
- + [Edit Community](#edit-community)
+ - [HTTP](#http-22)
+ + [Add Mod to Community](#add-mod-to-community)
- [Request](#request-22)
- [Response](#response-22)
- + [Follow Community](#follow-community)
+ - [HTTP](#http-23)
+ + [Edit Community](#edit-community)
- [Request](#request-23)
- [Response](#response-23)
- + [Get Followed Communities](#get-followed-communities)
+ - [HTTP](#http-24)
+ + [Follow Community](#follow-community)
- [Request](#request-24)
- [Response](#response-24)
- + [Transfer Community](#transfer-community)
+ - [HTTP](#http-25)
+ + [Get Followed Communities](#get-followed-communities)
- [Request](#request-25)
- [Response](#response-25)
- * [Post](#post)
- + [Create Post](#create-post)
+ - [HTTP](#http-26)
+ + [Transfer Community](#transfer-community)
- [Request](#request-26)
- [Response](#response-26)
- + [Get Post](#get-post)
+ - [HTTP](#http-27)
+ * [Post](#post)
+ + [Create Post](#create-post)
- [Request](#request-27)
- [Response](#response-27)
- + [Get Posts](#get-posts)
+ - [HTTP](#http-28)
+ + [Get Post](#get-post)
- [Request](#request-28)
- [Response](#response-28)
- + [Create Post Like](#create-post-like)
+ - [HTTP](#http-29)
+ + [Get Posts](#get-posts)
- [Request](#request-29)
- [Response](#response-29)
- + [Edit Post](#edit-post)
+ - [HTTP](#http-30)
+ + [Create Post Like](#create-post-like)
- [Request](#request-30)
- [Response](#response-30)
- + [Save Post](#save-post)
+ - [HTTP](#http-31)
+ + [Edit Post](#edit-post)
- [Request](#request-31)
- [Response](#response-31)
- * [Comment](#comment)
- + [Create Comment](#create-comment)
+ - [HTTP](#http-32)
+ + [Save Post](#save-post)
- [Request](#request-32)
- [Response](#response-32)
- + [Edit Comment](#edit-comment)
+ - [HTTP](#http-33)
+ * [Comment](#comment)
+ + [Create Comment](#create-comment)
- [Request](#request-33)
- [Response](#response-33)
- + [Save Comment](#save-comment)
+ - [HTTP](#http-34)
+ + [Edit Comment](#edit-comment)
- [Request](#request-34)
- [Response](#response-34)
- + [Create Comment Like](#create-comment-like)
+ - [HTTP](#http-35)
+ + [Save Comment](#save-comment)
- [Request](#request-35)
- [Response](#response-35)
+ - [HTTP](#http-36)
+ + [Create Comment Like](#create-comment-like)
+ - [Request](#request-36)
+ - [Response](#response-36)
+ - [HTTP](#http-37)
* [RSS / Atom feeds](#rss--atom-feeds)
+ [All](#all)
+ [Community](#community-1)
@@ -144,13 +189,13 @@
Request and response strings are in [JSON format](https://www.json.org).
-### WebSocket Endpoint
+### WebSocket
Connect to ws://***host***/api/v1/ws
to get started.
If the ***`host`*** supports secure connections, you can use wss://***host***/api/v1/ws
.
-### Testing with Websocat
+#### Testing with Websocat
[Websocat link](https://github.com/vi/websocat)
@@ -159,7 +204,7 @@ If the ***`host`*** supports secure connections, you can use wss://***host
A simple test command:
`{"op": "ListCategories"}`
-### Testing with the WebSocket JavaScript API
+#### Testing with the WebSocket JavaScript API
[WebSocket JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
```javascript
@@ -171,6 +216,32 @@ ws.onopen = function () {
}));
};
```
+### HTTP
+
+Endpoints are at http://***host***/api/v1/***endpoint***
. They'll be listed below for each action.
+
+#### Testing with Curl
+
+##### Get Example
+
+```
+curl /community/list?sort=Hot
+```
+
+##### Post Example
+
+```
+curl -i -H \
+"Content-Type: application/json" \
+-X POST \
+-d '{
+ "comment_id": X,
+ "post_id": X,
+ "score": X,
+ "auth": "..."
+}' \
+/comment/like
+```
## Rate limits
@@ -201,6 +272,11 @@ These go wherever there is a `sort` field. The available sort types are:
- `TopYear` - the most upvoted posts/communities of the current year.
- `TopAll` - the most upvoted posts/communities on the current instance.
+### Websocket vs HTTP
+
+- Below are the websocket JSON requests / responses. For HTTP, ignore all fields except those inside `data`.
+- For example, an http login will be a `POST` `{username_or_email: X, password: X}`
+
### User / Authentication / Admin actions
#### Login
@@ -220,13 +296,19 @@ The `jwt` string should be stored and used anywhere `auth` is called for.
##### Response
```rust
{
- op: String,
- jwt: String
+ op: "Login",
+ data: {
+ jwt: String,
+ }
}
```
+##### HTTP
+
+`POST /user/login`
#### Register
+
Only the first user will be able to be the admin.
##### Request
@@ -245,11 +327,17 @@ Only the first user will be able to be the admin.
##### Response
```rust
{
- op: String,
- jwt: String
+ op: "Register",
+ data: {
+ jwt: String,
+ }
}
```
+##### HTTP
+
+`POST /user/register`
+
#### Get User Details
##### Request
```rust
@@ -270,14 +358,20 @@ Only the first user will be able to be the admin.
##### Response
```rust
{
- op: String,
- user: UserView,
- follows: Vec,
- moderates: Vec,
- comments: Vec,
- posts: Vec,
+ op: "GetUserDetails",
+ data: {
+ user: UserView,
+ follows: Vec,
+ moderates: Vec,
+ comments: Vec,
+ posts: Vec,
+ }
}
```
+##### HTTP
+
+`GET /user`
+
#### Save User Settings
##### Request
```rust
@@ -295,10 +389,16 @@ Only the first user will be able to be the admin.
##### Response
```rust
{
- op: String,
- jwt: String
+ op: "SaveUserSettings",
+ data: {
+ jwt: String
+ }
}
```
+##### HTTP
+
+`PUT /save_user_settings`
+
#### Get Replies / Inbox
##### Request
```rust
@@ -316,10 +416,16 @@ Only the first user will be able to be the admin.
##### Response
```rust
{
- op: String,
- replies: Vec,
+ op: "GetReplies",
+ data: {
+ replies: Vec,
+ }
}
```
+##### HTTP
+
+`GET /user/replies`
+
#### Get User Mentions
##### Request
@@ -338,11 +444,42 @@ Only the first user will be able to be the admin.
##### Response
```rust
{
- op: String,
- mentions: Vec,
+ op: "GetUserMentions",
+ data: {
+ mentions: Vec,
+ }
}
```
+##### HTTP
+
+`GET /user/mentions`
+
+#### Edit User Mention
+##### Request
+```rust
+{
+ op: "EditUserMention",
+ data: {
+ user_mention_id: i32,
+ read: Option,
+ auth: String,
+ }
+}
+```
+##### Response
+```rust
+{
+ op: "EditUserMention",
+ data: {
+ mention: UserMentionView,
+ }
+}
+```
+##### HTTP
+
+`PUT /user/mention`
+
#### Mark All As Read
Marks all user replies and mentions as read.
@@ -359,11 +496,17 @@ Marks all user replies and mentions as read.
##### Response
```rust
{
- op: String,
- replies: Vec,
+ op: "MarkAllAsRead",
+ data: {
+ replies: Vec,
+ }
}
```
+##### HTTP
+
+`POST /user/mark_all_as_read`
+
#### Delete Account
*Permananently deletes your posts and comments*
@@ -381,11 +524,17 @@ Marks all user replies and mentions as read.
##### Response
```rust
{
- op: String,
- jwt: String,
+ op: "DeleteAccount",
+ data: {
+ jwt: String,
+ }
}
```
+##### HTTP
+
+`POST /user/delete_account`
+
#### Add admin
##### Request
```rust
@@ -401,10 +550,15 @@ Marks all user replies and mentions as read.
##### Response
```rust
{
- op: String,
- admins: Vec,
+ op: "AddAdmin",
+ data: {
+ admins: Vec,
+ }
}
```
+##### HTTP
+
+`POST /admin/add`
#### Ban user
##### Request
@@ -423,11 +577,16 @@ Marks all user replies and mentions as read.
##### Response
```rust
{
- op: String,
- user: UserView,
- banned: bool,
+ op: "BanUser",
+ data: {
+ user: UserView,
+ banned: bool,
+ }
}
```
+##### HTTP
+
+`POST /user/ban`
### Site
#### List Categories
@@ -440,13 +599,19 @@ Marks all user replies and mentions as read.
##### Response
```rust
{
- op: String,
- categories: Vec
+ op: "ListCategories",
+ data: {
+ categories: Vec
+ }
}
```
+##### HTTP
+
+`GET /categories`
#### Search
-Search types are `Both, Comments, Posts`.
+
+Search types are `All, Comments, Posts, Communities, Users, Url`
##### Request
```rust
@@ -459,17 +624,26 @@ Search types are `Both, Comments, Posts`.
sort: String,
page: Option,
limit: Option,
+ auth?: Option,
}
}
```
##### Response
```rust
{
- op: String,
- comments: Vec,
- posts: Vec,
+ op: "Search",
+ data: {
+ type_: String,
+ comments: Vec,
+ posts: Vec,
+ communities: Vec,
+ users: Vec,
+ }
}
```
+##### HTTP
+
+`POST /search`
#### Get Modlog
##### Request
@@ -487,18 +661,24 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- removed_posts: Vec,
- locked_posts: Vec,
- removed_comments: Vec,
- removed_communities: Vec,
- banned_from_community: Vec,
- banned: Vec,
- added_to_community: Vec,
- added: Vec,
+ op: "GetModlog",
+ data: {
+ removed_posts: Vec,
+ locked_posts: Vec,
+ removed_comments: Vec,
+ removed_communities: Vec,
+ banned_from_community: Vec,
+ banned: Vec,
+ added_to_community: Vec,
+ added: Vec,
+ }
}
```
+##### HTTP
+
+`GET /modlog`
+
#### Create Site
##### Request
```rust
@@ -514,11 +694,17 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- site: SiteView,
+ op: "CreateSite",
+ data: {
+ site: SiteView,
+ }
}
```
+##### HTTP
+
+`POST /site`
+
#### Edit Site
##### Request
```rust
@@ -534,10 +720,15 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- site: SiteView,
+ op: "EditSite",
+ data: {
+ site: SiteView,
+ }
}
```
+##### HTTP
+
+`PUT /site`
#### Get Site
##### Request
@@ -549,12 +740,17 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- site: Option,
- admins: Vec,
- banned: Vec,
+ op: "GetSite",
+ data: {
+ site: Option,
+ admins: Vec,
+ banned: Vec,
+ }
}
```
+##### HTTP
+
+`GET /site`
#### Transfer Site
##### Request
@@ -570,12 +766,17 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- site: Option,
- admins: Vec,
- banned: Vec,
+ op: "TransferSite",
+ data: {
+ site: Option,
+ admins: Vec,
+ banned: Vec,
+ }
}
```
+##### HTTP
+
+`POST /site/transfer`
### Community
#### Get Community
@@ -593,12 +794,17 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- community: CommunityView,
- moderators: Vec,
- admins: Vec,
+ op: "GetCommunity",
+ data: {
+ community: CommunityView,
+ moderators: Vec,
+ admins: Vec,
+ }
}
```
+##### HTTP
+
+`GET /community`
#### Create Community
##### Request
@@ -617,10 +823,15 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- community: CommunityView
+ op: "CreateCommunity",
+ data: {
+ community: CommunityView
+ }
}
```
+##### HTTP
+
+`POST /community`
#### List Communities
##### Request
@@ -638,10 +849,15 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- communities: Vec
+ op: "ListCommunities",
+ data: {
+ communities: Vec
+ }
}
```
+##### HTTP
+
+`GET /community/list`
#### Ban from Community
##### Request
@@ -661,11 +877,16 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- user: UserView,
- banned: bool,
+ op: "BanFromCommunity",
+ data: {
+ user: UserView,
+ banned: bool,
+ }
}
```
+##### HTTP
+
+`POST /community/ban_user`
#### Add Mod to Community
##### Request
@@ -683,10 +904,15 @@ Search types are `Both, Comments, Posts`.
##### Response
```rust
{
- op: String,
- moderators: Vec,
+ op: "AddModToCommunity",
+ data: {
+ moderators: Vec,
+ }
}
```
+##### HTTP
+
+`POST /community/mod`
#### Edit Community
Mods and admins can remove and lock a community, creators can delete it.
@@ -712,10 +938,15 @@ Mods and admins can remove and lock a community, creators can delete it.
##### Response
```rust
{
- op: String,
- community: CommunityView
+ op: "EditCommunity",
+ data: {
+ community: CommunityView
+ }
}
```
+##### HTTP
+
+`PUT /community`
#### Follow Community
##### Request
@@ -732,10 +963,15 @@ Mods and admins can remove and lock a community, creators can delete it.
##### Response
```rust
{
- op: String,
- community: CommunityView
+ op: "FollowCommunity",
+ data: {
+ community: CommunityView
+ }
}
```
+##### HTTP
+
+`POST /community/follow`
#### Get Followed Communities
##### Request
@@ -750,10 +986,15 @@ Mods and admins can remove and lock a community, creators can delete it.
##### Response
```rust
{
- op: String,
- communities: Vec
+ op: "GetFollowedCommunities",
+ data: {
+ communities: Vec
+ }
}
```
+##### HTTP
+
+`GET /user/followed_communities`
#### Transfer Community
##### Request
@@ -770,12 +1011,17 @@ Mods and admins can remove and lock a community, creators can delete it.
##### Response
```rust
{
- op: String,
- community: CommunityView,
- moderators: Vec,
- admins: Vec,
+ op: "TransferCommunity",
+ data: {
+ community: CommunityView,
+ moderators: Vec,
+ admins: Vec,
+ }
}
```
+##### HTTP
+
+`POST /community/transfer`
### Post
#### Create Post
@@ -795,10 +1041,15 @@ Mods and admins can remove and lock a community, creators can delete it.
##### Response
```rust
{
- op: String,
- post: PostView
+ op: "CreatePost",
+ data: {
+ post: PostView
+ }
}
```
+##### HTTP
+
+`POST /post`
#### Get Post
##### Request
@@ -814,16 +1065,22 @@ Mods and admins can remove and lock a community, creators can delete it.
##### Response
```rust
{
- op: String,
- post: PostView,
- comments: Vec,
- community: CommunityView,
- moderators: Vec,
- admins: Vec,
+ op: "GetPost",
+ data: {
+ post: PostView,
+ comments: Vec,
+ community: CommunityView,
+ moderators: Vec,
+ admins: Vec,
+ }
}
```
+##### HTTP
+
+`GET /post`
#### Get Posts
+
Post listing types are `All, Subscribed, Community`
##### Request
@@ -843,12 +1100,18 @@ Post listing types are `All, Subscribed, Community`
##### Response
```rust
{
- op: String,
- posts: Vec,
+ op: "GetPosts",
+ data: {
+ posts: Vec,
+ }
}
```
+##### HTTP
+
+`GET /post/list`
#### Create Post Like
+
`score` can be 0, -1, or 1
##### Request
@@ -865,12 +1128,18 @@ Post listing types are `All, Subscribed, Community`
##### Response
```rust
{
- op: String,
- post: PostView
+ op: "CreatePostLike",
+ data: {
+ post: PostView
+ }
}
```
+##### HTTP
+
+`POST /post/like`
#### Edit Post
+
Mods and admins can remove and lock a post, creators can delete it.
##### Request
@@ -895,11 +1164,17 @@ Mods and admins can remove and lock a post, creators can delete it.
##### Response
```rust
{
- op: String,
- post: PostView
+ op: "EditPost",
+ data: {
+ post: PostView
+ }
}
```
+##### HTTP
+
+`PUT /post`
+
#### Save Post
##### Request
```rust
@@ -915,10 +1190,15 @@ Mods and admins can remove and lock a post, creators can delete it.
##### Response
```rust
{
- op: String,
- post: PostView
+ op: "SavePost",
+ data: {
+ post: PostView
+ }
}
```
+##### HTTP
+
+`POST /post/save`
### Comment
#### Create Comment
@@ -938,12 +1218,19 @@ Mods and admins can remove and lock a post, creators can delete it.
##### Response
```rust
{
- op: String,
- comment: CommentView
+ op: "CreateComment",
+ data: {
+ comment: CommentView
+ }
}
```
+##### HTTP
+
+`POST /comment`
+
#### Edit Comment
+
Mods and admins can remove a comment, creators can delete it.
##### Request
@@ -967,10 +1254,15 @@ Mods and admins can remove a comment, creators can delete it.
##### Response
```rust
{
- op: String,
- comment: CommentView
+ op: "EditComment",
+ data: {
+ comment: CommentView
+ }
}
```
+##### HTTP
+
+`PUT /comment`
#### Save Comment
##### Request
@@ -987,12 +1279,18 @@ Mods and admins can remove a comment, creators can delete it.
##### Response
```rust
{
- op: String,
- comment: CommentView
+ op: "SaveComment",
+ data: {
+ comment: CommentView
+ }
}
```
+##### HTTP
+
+`POST /comment/save`
#### Create Comment Like
+
`score` can be 0, -1, or 1
##### Request
@@ -1010,10 +1308,15 @@ Mods and admins can remove a comment, creators can delete it.
##### Response
```rust
{
- op: String,
- comment: CommentView
+ op: "CreateCommentLike",
+ data: {
+ comment: CommentView
+ }
}
```
+##### HTTP
+
+`POST /comment/like`
### RSS / Atom feeds
diff --git a/server/.rustfmt.toml b/server/.rustfmt.toml
index b1fce9c9a57..684a7f8a27a 100644
--- a/server/.rustfmt.toml
+++ b/server/.rustfmt.toml
@@ -1,2 +1,2 @@
tab_spaces = 2
-edition="2018"
+edition="2018"
\ No newline at end of file
diff --git a/server/migrations/2020-01-21-001001_create_private_message/down.sql b/server/migrations/2020-01-21-001001_create_private_message/down.sql
new file mode 100644
index 00000000000..0d951e3eafa
--- /dev/null
+++ b/server/migrations/2020-01-21-001001_create_private_message/down.sql
@@ -0,0 +1,34 @@
+-- Drop the triggers
+drop trigger refresh_private_message on private_message;
+drop function refresh_private_message();
+
+-- Drop the view and table
+drop view private_message_view cascade;
+drop table private_message;
+
+-- Rebuild the old views
+drop view user_view cascade;
+create view user_view as
+select
+u.id,
+u.name,
+u.avatar,
+u.email,
+u.fedi_name,
+u.admin,
+u.banned,
+u.show_avatars,
+u.send_notifications_to_email,
+u.published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
+
+create materialized view user_mview as select * from user_view;
+
+create unique index idx_user_mview_id on user_mview (id);
+
+-- Drop the columns
+alter table user_ drop column matrix_user_id;
diff --git a/server/migrations/2020-01-21-001001_create_private_message/up.sql b/server/migrations/2020-01-21-001001_create_private_message/up.sql
new file mode 100644
index 00000000000..48e16dd83d6
--- /dev/null
+++ b/server/migrations/2020-01-21-001001_create_private_message/up.sql
@@ -0,0 +1,90 @@
+-- Creating private message
+create table private_message (
+ id serial primary key,
+ creator_id int references user_ on update cascade on delete cascade not null,
+ recipient_id int references user_ on update cascade on delete cascade not null,
+ content text not null,
+ deleted boolean default false not null,
+ read boolean default false not null,
+ published timestamp not null default now(),
+ updated timestamp
+);
+
+-- Create the view and materialized view which has the avatar and creator name
+create view private_message_view as
+select
+pm.*,
+u.name as creator_name,
+u.avatar as creator_avatar,
+u2.name as recipient_name,
+u2.avatar as recipient_avatar
+from private_message pm
+inner join user_ u on u.id = pm.creator_id
+inner join user_ u2 on u2.id = pm.recipient_id;
+
+create materialized view private_message_mview as select * from private_message_view;
+
+create unique index idx_private_message_mview_id on private_message_mview (id);
+
+-- Create the triggers
+create or replace function refresh_private_message()
+returns trigger language plpgsql
+as $$
+begin
+ refresh materialized view concurrently private_message_mview;
+ return null;
+end $$;
+
+create trigger refresh_private_message
+after insert or update or delete or truncate
+on private_message
+for each statement
+execute procedure refresh_private_message();
+
+-- Update user to include matrix id
+alter table user_ add column matrix_user_id text unique;
+
+drop view user_view cascade;
+create view user_view as
+select
+u.id,
+u.name,
+u.avatar,
+u.email,
+u.matrix_user_id,
+u.fedi_name,
+u.admin,
+u.banned,
+u.show_avatars,
+u.send_notifications_to_email,
+u.published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
+
+create materialized view user_mview as select * from user_view;
+
+create unique index idx_user_mview_id on user_mview (id);
+
+-- This is what a group pm table would look like
+-- Not going to do it now because of the complications
+--
+-- create table private_message (
+-- id serial primary key,
+-- creator_id int references user_ on update cascade on delete cascade not null,
+-- content text not null,
+-- deleted boolean default false not null,
+-- published timestamp not null default now(),
+-- updated timestamp
+-- );
+--
+-- create table private_message_recipient (
+-- id serial primary key,
+-- private_message_id int references private_message on update cascade on delete cascade not null,
+-- recipient_id int references user_ on update cascade on delete cascade not null,
+-- read boolean default false not null,
+-- published timestamp not null default now(),
+-- unique(private_message_id, recipient_id)
+-- )
diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs
index 61cc9506334..8efb30fbde4 100644
--- a/server/src/api/comment.rs
+++ b/server/src/api/comment.rs
@@ -7,7 +7,7 @@ use diesel::PgConnection;
pub struct CreateComment {
content: String,
parent_id: Option,
- edit_id: Option,
+ edit_id: Option, // TODO this isn't used
pub post_id: i32,
auth: String,
}
@@ -15,7 +15,7 @@ pub struct CreateComment {
#[derive(Serialize, Deserialize)]
pub struct EditComment {
content: String,
- parent_id: Option,
+ parent_id: Option, // TODO why are the parent_id, creator_id, post_id, etc fields required? They aren't going to change
edit_id: i32,
creator_id: i32,
pub post_id: i32,
@@ -35,7 +35,6 @@ pub struct SaveComment {
#[derive(Serialize, Deserialize, Clone)]
pub struct CommentResponse {
- op: String,
pub comment: CommentView,
}
@@ -53,7 +52,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -63,12 +62,12 @@ impl Perform for Oper {
// Check for a community ban
let post = Post::read(&conn, data.post_id)?;
if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() {
- return Err(APIError::err(&self.op, "community_ban").into());
+ return Err(APIError::err("community_ban").into());
}
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
let content_slurs_removed = remove_slurs(&data.content.to_owned());
@@ -86,7 +85,7 @@ impl Perform for Oper {
let inserted_comment = match Comment::create(&conn, &comment_form) {
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_create_comment").into()),
+ Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
};
// Scan the comment for user mentions, add those rows
@@ -193,13 +192,12 @@ impl Perform for Oper {
let _inserted_like = match CommentLike::like(&conn, &like_form) {
Ok(like) => like,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_comment").into()),
+ Err(_e) => return Err(APIError::err("couldnt_like_comment").into()),
};
let comment_view = CommentView::read(&conn, inserted_comment.id, Some(user_id))?;
Ok(CommentResponse {
- op: self.op.to_string(),
comment: comment_view,
})
}
@@ -211,7 +209,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -231,17 +229,17 @@ impl Perform for Oper {
editors.append(&mut UserView::admins(&conn)?.into_iter().map(|a| a.id).collect());
if !editors.contains(&user_id) {
- return Err(APIError::err(&self.op, "no_comment_edit_allowed").into());
+ return Err(APIError::err("no_comment_edit_allowed").into());
}
// Check for a community ban
if CommunityUserBanView::get(&conn, user_id, orig_comment.community_id).is_ok() {
- return Err(APIError::err(&self.op, "community_ban").into());
+ return Err(APIError::err("community_ban").into());
}
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
}
@@ -264,7 +262,7 @@ impl Perform for Oper {
let _updated_comment = match Comment::update(&conn, data.edit_id, &comment_form) {
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment").into()),
+ Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
};
// Scan the comment for user mentions, add those rows
@@ -310,7 +308,6 @@ impl Perform for Oper {
let comment_view = CommentView::read(&conn, data.edit_id, Some(user_id))?;
Ok(CommentResponse {
- op: self.op.to_string(),
comment: comment_view,
})
}
@@ -322,7 +319,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -335,19 +332,18 @@ impl Perform for Oper {
if data.save {
match CommentSaved::save(&conn, &comment_saved_form) {
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_comment").into()),
+ Err(_e) => return Err(APIError::err("couldnt_save_comment").into()),
};
} else {
match CommentSaved::unsave(&conn, &comment_saved_form) {
Ok(comment) => comment,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_comment").into()),
+ Err(_e) => return Err(APIError::err("couldnt_save_comment").into()),
};
}
let comment_view = CommentView::read(&conn, data.comment_id, Some(user_id))?;
Ok(CommentResponse {
- op: self.op.to_string(),
comment: comment_view,
})
}
@@ -359,7 +355,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -368,19 +364,19 @@ impl Perform for Oper {
if data.score == -1 {
let site = SiteView::read(&conn)?;
if !site.enable_downvotes {
- return Err(APIError::err(&self.op, "downvotes_disabled").into());
+ return Err(APIError::err("downvotes_disabled").into());
}
}
// Check for a community ban
let post = Post::read(&conn, data.post_id)?;
if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() {
- return Err(APIError::err(&self.op, "community_ban").into());
+ return Err(APIError::err("community_ban").into());
}
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
let like_form = CommentLikeForm {
@@ -398,7 +394,7 @@ impl Perform for Oper {
if do_add {
let _inserted_like = match CommentLike::like(&conn, &like_form) {
Ok(like) => like,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_comment").into()),
+ Err(_e) => return Err(APIError::err("couldnt_like_comment").into()),
};
}
@@ -406,7 +402,6 @@ impl Perform for Oper {
let liked_comment = CommentView::read(&conn, data.comment_id, Some(user_id))?;
Ok(CommentResponse {
- op: self.op.to_string(),
comment: liked_comment,
})
}
diff --git a/server/src/api/community.rs b/server/src/api/community.rs
index 0bf846c3d9d..c765aa9dd84 100644
--- a/server/src/api/community.rs
+++ b/server/src/api/community.rs
@@ -11,7 +11,6 @@ pub struct GetCommunity {
#[derive(Serialize, Deserialize)]
pub struct GetCommunityResponse {
- op: String,
community: CommunityView,
moderators: Vec,
admins: Vec,
@@ -29,7 +28,6 @@ pub struct CreateCommunity {
#[derive(Serialize, Deserialize, Clone)]
pub struct CommunityResponse {
- op: String,
pub community: CommunityView,
}
@@ -43,7 +41,6 @@ pub struct ListCommunities {
#[derive(Serialize, Deserialize)]
pub struct ListCommunitiesResponse {
- op: String,
communities: Vec,
}
@@ -59,7 +56,6 @@ pub struct BanFromCommunity {
#[derive(Serialize, Deserialize)]
pub struct BanFromCommunityResponse {
- op: String,
user: UserView,
banned: bool,
}
@@ -74,7 +70,6 @@ pub struct AddModToCommunity {
#[derive(Serialize, Deserialize)]
pub struct AddModToCommunityResponse {
- op: String,
moderators: Vec,
}
@@ -107,7 +102,6 @@ pub struct GetFollowedCommunities {
#[derive(Serialize, Deserialize)]
pub struct GetFollowedCommunitiesResponse {
- op: String,
communities: Vec,
}
@@ -141,19 +135,19 @@ impl Perform for Oper {
data.name.to_owned().unwrap_or_else(|| "main".to_string()),
) {
Ok(community) => community.id,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
}
}
};
let community_view = match CommunityView::read(&conn, community_id, user_id) {
Ok(community) => community,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
let moderators = match CommunityModeratorView::for_community(&conn, community_id) {
Ok(moderators) => moderators,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
let site_creator_id = Site::read(&conn, 1)?.creator_id;
@@ -164,7 +158,6 @@ impl Perform for Oper {
// Return the jwt
Ok(GetCommunityResponse {
- op: self.op.to_string(),
community: community_view,
moderators,
admins,
@@ -178,21 +171,21 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
if has_slurs(&data.name)
|| has_slurs(&data.title)
|| (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
{
- return Err(APIError::err(&self.op, "no_slurs").into());
+ return Err(APIError::err("no_slurs").into());
}
let user_id = claims.id;
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
// When you create a community, make sure the user becomes a moderator and a follower
@@ -210,7 +203,7 @@ impl Perform for Oper {
let inserted_community = match Community::create(&conn, &community_form) {
Ok(community) => community,
- Err(_e) => return Err(APIError::err(&self.op, "community_already_exists").into()),
+ Err(_e) => return Err(APIError::err("community_already_exists").into()),
};
let community_moderator_form = CommunityModeratorForm {
@@ -221,9 +214,7 @@ impl Perform for Oper {
let _inserted_community_moderator =
match CommunityModerator::join(&conn, &community_moderator_form) {
Ok(user) => user,
- Err(_e) => {
- return Err(APIError::err(&self.op, "community_moderator_already_exists").into())
- }
+ Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
};
let community_follower_form = CommunityFollowerForm {
@@ -234,13 +225,12 @@ impl Perform for Oper {
let _inserted_community_follower =
match CommunityFollower::follow(&conn, &community_follower_form) {
Ok(user) => user,
- Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists").into()),
+ Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
};
let community_view = CommunityView::read(&conn, inserted_community.id, Some(user_id))?;
Ok(CommunityResponse {
- op: self.op.to_string(),
community: community_view,
})
}
@@ -251,19 +241,19 @@ impl Perform for Oper {
let data: &EditCommunity = &self.data;
if has_slurs(&data.name) || has_slurs(&data.title) {
- return Err(APIError::err(&self.op, "no_slurs").into());
+ return Err(APIError::err("no_slurs").into());
}
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
// Verify its a mod
@@ -276,7 +266,7 @@ impl Perform for Oper {
);
editors.append(&mut UserView::admins(&conn)?.into_iter().map(|a| a.id).collect());
if !editors.contains(&user_id) {
- return Err(APIError::err(&self.op, "no_community_edit_allowed").into());
+ return Err(APIError::err("no_community_edit_allowed").into());
}
let community_form = CommunityForm {
@@ -293,7 +283,7 @@ impl Perform for Oper {
let _updated_community = match Community::update(&conn, data.edit_id, &community_form) {
Ok(community) => community,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_community").into()),
+ Err(_e) => return Err(APIError::err("couldnt_update_community").into()),
};
// Mod tables
@@ -315,7 +305,6 @@ impl Perform for Oper {
let community_view = CommunityView::read(&conn, data.edit_id, Some(user_id))?;
Ok(CommunityResponse {
- op: self.op.to_string(),
community: community_view,
})
}
@@ -354,10 +343,7 @@ impl Perform for Oper {
.list()?;
// Return the jwt
- Ok(ListCommunitiesResponse {
- op: self.op.to_string(),
- communities,
- })
+ Ok(ListCommunitiesResponse { communities })
}
}
@@ -367,7 +353,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -380,19 +366,18 @@ impl Perform for Oper {
if data.follow {
match CommunityFollower::follow(&conn, &community_follower_form) {
Ok(user) => user,
- Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists").into()),
+ Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
};
} else {
match CommunityFollower::ignore(&conn, &community_follower_form) {
Ok(user) => user,
- Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists").into()),
+ Err(_e) => return Err(APIError::err("community_follower_already_exists").into()),
};
}
let community_view = CommunityView::read(&conn, data.community_id, Some(user_id))?;
Ok(CommunityResponse {
- op: self.op.to_string(),
community: community_view,
})
}
@@ -404,7 +389,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -412,14 +397,11 @@ impl Perform for Oper {
let communities: Vec =
match CommunityFollowerView::for_user(&conn, user_id) {
Ok(communities) => communities,
- Err(_e) => return Err(APIError::err(&self.op, "system_err_login").into()),
+ Err(_e) => return Err(APIError::err("system_err_login").into()),
};
// Return the jwt
- Ok(GetFollowedCommunitiesResponse {
- op: self.op.to_string(),
- communities,
- })
+ Ok(GetFollowedCommunitiesResponse { communities })
}
}
@@ -429,7 +411,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -442,12 +424,12 @@ impl Perform for Oper {
if data.ban {
match CommunityUserBan::ban(&conn, &community_user_ban_form) {
Ok(user) => user,
- Err(_e) => return Err(APIError::err(&self.op, "community_user_already_banned").into()),
+ Err(_e) => return Err(APIError::err("community_user_already_banned").into()),
};
} else {
match CommunityUserBan::unban(&conn, &community_user_ban_form) {
Ok(user) => user,
- Err(_e) => return Err(APIError::err(&self.op, "community_user_already_banned").into()),
+ Err(_e) => return Err(APIError::err("community_user_already_banned").into()),
};
}
@@ -470,7 +452,6 @@ impl Perform for Oper {
let user_view = UserView::read(&conn, data.user_id)?;
Ok(BanFromCommunityResponse {
- op: self.op.to_string(),
user: user_view,
banned: data.ban,
})
@@ -483,7 +464,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -496,16 +477,12 @@ impl Perform for Oper {
if data.added {
match CommunityModerator::join(&conn, &community_moderator_form) {
Ok(user) => user,
- Err(_e) => {
- return Err(APIError::err(&self.op, "community_moderator_already_exists").into())
- }
+ Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
};
} else {
match CommunityModerator::leave(&conn, &community_moderator_form) {
Ok(user) => user,
- Err(_e) => {
- return Err(APIError::err(&self.op, "community_moderator_already_exists").into())
- }
+ Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
};
}
@@ -520,10 +497,7 @@ impl Perform for Oper {
let moderators = CommunityModeratorView::for_community(&conn, data.community_id)?;
- Ok(AddModToCommunityResponse {
- op: self.op.to_string(),
- moderators,
- })
+ Ok(AddModToCommunityResponse { moderators })
}
}
@@ -533,7 +507,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -548,7 +522,7 @@ impl Perform for Oper {
// Make sure user is the creator, or an admin
if user_id != read_community.creator_id && !admins.iter().map(|a| a.id).any(|x| x == user_id) {
- return Err(APIError::err(&self.op, "not_an_admin").into());
+ return Err(APIError::err("not_an_admin").into());
}
let community_form = CommunityForm {
@@ -565,7 +539,7 @@ impl Perform for Oper {
let _updated_community = match Community::update(&conn, data.community_id, &community_form) {
Ok(community) => community,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_community").into()),
+ Err(_e) => return Err(APIError::err("couldnt_update_community").into()),
};
// You also have to re-do the community_moderator table, reordering it.
@@ -588,9 +562,7 @@ impl Perform for Oper {
let _inserted_community_moderator =
match CommunityModerator::join(&conn, &community_moderator_form) {
Ok(user) => user,
- Err(_e) => {
- return Err(APIError::err(&self.op, "community_moderator_already_exists").into())
- }
+ Err(_e) => return Err(APIError::err("community_moderator_already_exists").into()),
};
}
@@ -605,17 +577,16 @@ impl Perform for Oper {
let community_view = match CommunityView::read(&conn, data.community_id, Some(user_id)) {
Ok(community) => community,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
let moderators = match CommunityModeratorView::for_community(&conn, data.community_id) {
Ok(moderators) => moderators,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_community").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
};
// Return the jwt
Ok(GetCommunityResponse {
- op: self.op.to_string(),
community: community_view,
moderators,
admins,
diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs
index e3580447685..cb09d7fa034 100644
--- a/server/src/api/mod.rs
+++ b/server/src/api/mod.rs
@@ -8,6 +8,8 @@ use crate::db::moderator_views::*;
use crate::db::password_reset_request::*;
use crate::db::post::*;
use crate::db::post_view::*;
+use crate::db::private_message::*;
+use crate::db::private_message_view::*;
use crate::db::site::*;
use crate::db::site_view::*;
use crate::db::user::*;
@@ -26,73 +28,27 @@ pub mod post;
pub mod site;
pub mod user;
-#[derive(EnumString, ToString, Debug)]
-pub enum UserOperation {
- Login,
- Register,
- CreateCommunity,
- CreatePost,
- ListCommunities,
- ListCategories,
- GetPost,
- GetCommunity,
- CreateComment,
- EditComment,
- SaveComment,
- CreateCommentLike,
- GetPosts,
- CreatePostLike,
- EditPost,
- SavePost,
- EditCommunity,
- FollowCommunity,
- GetFollowedCommunities,
- GetUserDetails,
- GetReplies,
- GetUserMentions,
- EditUserMention,
- GetModlog,
- BanFromCommunity,
- AddModToCommunity,
- CreateSite,
- EditSite,
- GetSite,
- AddAdmin,
- BanUser,
- Search,
- MarkAllAsRead,
- SaveUserSettings,
- TransferCommunity,
- TransferSite,
- DeleteAccount,
- PasswordReset,
- PasswordChange,
-}
-
#[derive(Fail, Debug)]
-#[fail(display = "{{\"op\":\"{}\", \"error\":\"{}\"}}", op, message)]
+#[fail(display = "{{\"error\":\"{}\"}}", message)]
pub struct APIError {
- pub op: String,
pub message: String,
}
impl APIError {
- pub fn err(op: &UserOperation, msg: &str) -> Self {
+ pub fn err(msg: &str) -> Self {
APIError {
- op: op.to_string(),
message: msg.to_string(),
}
}
}
pub struct Oper {
- op: UserOperation,
data: T,
}
impl Oper {
- pub fn new(op: UserOperation, data: T) -> Oper {
- Oper { op, data }
+ pub fn new(data: T) -> Oper {
+ Oper { data }
}
}
diff --git a/server/src/api/post.rs b/server/src/api/post.rs
index b0fcdd0c1b9..3f211453c9a 100644
--- a/server/src/api/post.rs
+++ b/server/src/api/post.rs
@@ -14,7 +14,6 @@ pub struct CreatePost {
#[derive(Serialize, Deserialize, Clone)]
pub struct PostResponse {
- op: String,
pub post: PostView,
}
@@ -26,7 +25,6 @@ pub struct GetPost {
#[derive(Serialize, Deserialize)]
pub struct GetPostResponse {
- op: String,
post: PostView,
comments: Vec,
community: CommunityView,
@@ -46,7 +44,6 @@ pub struct GetPosts {
#[derive(Serialize, Deserialize)]
pub struct GetPostsResponse {
- op: String,
posts: Vec,
}
@@ -59,7 +56,6 @@ pub struct CreatePostLike {
#[derive(Serialize, Deserialize)]
pub struct CreatePostLikeResponse {
- op: String,
post: PostView,
}
@@ -93,23 +89,23 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) {
- return Err(APIError::err(&self.op, "no_slurs").into());
+ return Err(APIError::err("no_slurs").into());
}
let user_id = claims.id;
// Check for a community ban
if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() {
- return Err(APIError::err(&self.op, "community_ban").into());
+ return Err(APIError::err("community_ban").into());
}
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
let post_form = PostForm {
@@ -128,7 +124,7 @@ impl Perform for Oper {
let inserted_post = match Post::create(&conn, &post_form) {
Ok(post) => post,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_create_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_create_post").into()),
};
// They like their own post by default
@@ -141,19 +137,16 @@ impl Perform for Oper {
// Only add the like if the score isnt 0
let _inserted_like = match PostLike::like(&conn, &like_form) {
Ok(like) => like,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_like_post").into()),
};
// Refetch the view
let post_view = match PostView::read(&conn, inserted_post.id, Some(user_id)) {
Ok(post) => post,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
};
- Ok(PostResponse {
- op: self.op.to_string(),
- post: post_view,
- })
+ Ok(PostResponse { post: post_view })
}
}
@@ -174,7 +167,7 @@ impl Perform for Oper {
let post_view = match PostView::read(&conn, data.id, user_id) {
Ok(post) => post,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
};
let comments = CommentQueryBuilder::create(&conn)
@@ -195,7 +188,6 @@ impl Perform for Oper {
// Return the jwt
Ok(GetPostResponse {
- op: self.op.to_string(),
post: post_view,
comments,
community,
@@ -241,13 +233,10 @@ impl Perform for Oper {
.list()
{
Ok(posts) => posts,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_get_posts").into()),
+ Err(_e) => return Err(APIError::err("couldnt_get_posts").into()),
};
- Ok(GetPostsResponse {
- op: self.op.to_string(),
- posts,
- })
+ Ok(GetPostsResponse { posts })
}
}
@@ -257,7 +246,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -266,19 +255,19 @@ impl Perform for Oper {
if data.score == -1 {
let site = SiteView::read(&conn)?;
if !site.enable_downvotes {
- return Err(APIError::err(&self.op, "downvotes_disabled").into());
+ return Err(APIError::err("downvotes_disabled").into());
}
}
// Check for a community ban
let post = Post::read(&conn, data.post_id)?;
if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() {
- return Err(APIError::err(&self.op, "community_ban").into());
+ return Err(APIError::err("community_ban").into());
}
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
let like_form = PostLikeForm {
@@ -295,20 +284,17 @@ impl Perform for Oper {
if do_add {
let _inserted_like = match PostLike::like(&conn, &like_form) {
Ok(like) => like,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_like_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_like_post").into()),
};
}
let post_view = match PostView::read(&conn, data.post_id, Some(user_id)) {
Ok(post) => post,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_find_post").into()),
};
// just output the score
- Ok(CreatePostLikeResponse {
- op: self.op.to_string(),
- post: post_view,
- })
+ Ok(CreatePostLikeResponse { post: post_view })
}
}
@@ -316,12 +302,12 @@ impl Perform for Oper {
fn perform(&self, conn: &PgConnection) -> Result {
let data: &EditPost = &self.data;
if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) {
- return Err(APIError::err(&self.op, "no_slurs").into());
+ return Err(APIError::err("no_slurs").into());
}
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -336,17 +322,17 @@ impl Perform for Oper {
);
editors.append(&mut UserView::admins(&conn)?.into_iter().map(|a| a.id).collect());
if !editors.contains(&user_id) {
- return Err(APIError::err(&self.op, "no_post_edit_allowed").into());
+ return Err(APIError::err("no_post_edit_allowed").into());
}
// Check for a community ban
if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() {
- return Err(APIError::err(&self.op, "community_ban").into());
+ return Err(APIError::err("community_ban").into());
}
// Check for a site ban
if UserView::read(&conn, user_id)?.banned {
- return Err(APIError::err(&self.op, "site_ban").into());
+ return Err(APIError::err("site_ban").into());
}
let post_form = PostForm {
@@ -365,7 +351,7 @@ impl Perform for Oper {
let _updated_post = match Post::update(&conn, data.edit_id, &post_form) {
Ok(post) => post,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_update_post").into()),
};
// Mod tables
@@ -399,10 +385,7 @@ impl Perform for Oper {
let post_view = PostView::read(&conn, data.edit_id, Some(user_id))?;
- Ok(PostResponse {
- op: self.op.to_string(),
- post: post_view,
- })
+ Ok(PostResponse { post: post_view })
}
}
@@ -412,7 +395,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -425,20 +408,17 @@ impl Perform for Oper {
if data.save {
match PostSaved::save(&conn, &post_saved_form) {
Ok(post) => post,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_save_post").into()),
};
} else {
match PostSaved::unsave(&conn, &post_saved_form) {
Ok(post) => post,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_save_post").into()),
+ Err(_e) => return Err(APIError::err("couldnt_save_post").into()),
};
}
let post_view = PostView::read(&conn, data.post_id, Some(user_id))?;
- Ok(PostResponse {
- op: self.op.to_string(),
- post: post_view,
- })
+ Ok(PostResponse { post: post_view })
}
}
diff --git a/server/src/api/site.rs b/server/src/api/site.rs
index ce07724a38e..a5faf34dd82 100644
--- a/server/src/api/site.rs
+++ b/server/src/api/site.rs
@@ -7,7 +7,6 @@ pub struct ListCategories;
#[derive(Serialize, Deserialize)]
pub struct ListCategoriesResponse {
- op: String,
categories: Vec,
}
@@ -24,7 +23,6 @@ pub struct Search {
#[derive(Serialize, Deserialize)]
pub struct SearchResponse {
- op: String,
type_: String,
comments: Vec,
posts: Vec,
@@ -42,7 +40,6 @@ pub struct GetModlog {
#[derive(Serialize, Deserialize)]
pub struct GetModlogResponse {
- op: String,
removed_posts: Vec,
locked_posts: Vec,
stickied_posts: Vec,
@@ -79,13 +76,11 @@ pub struct GetSite;
#[derive(Serialize, Deserialize)]
pub struct SiteResponse {
- op: String,
site: SiteView,
}
#[derive(Serialize, Deserialize)]
pub struct GetSiteResponse {
- op: String,
site: Option,
admins: Vec,
banned: Vec,
@@ -105,10 +100,7 @@ impl Perform for Oper {
let categories: Vec = Category::list_all(&conn)?;
// Return the jwt
- Ok(ListCategoriesResponse {
- op: self.op.to_string(),
- categories,
- })
+ Ok(ListCategoriesResponse { categories })
}
}
@@ -172,7 +164,6 @@ impl Perform for Oper {
// Return the jwt
Ok(GetModlogResponse {
- op: self.op.to_string(),
removed_posts,
locked_posts,
stickied_posts,
@@ -192,20 +183,20 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
if has_slurs(&data.name)
|| (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
{
- return Err(APIError::err(&self.op, "no_slurs").into());
+ return Err(APIError::err("no_slurs").into());
}
let user_id = claims.id;
// Make sure user is an admin
if !UserView::read(&conn, user_id)?.admin {
- return Err(APIError::err(&self.op, "not_an_admin").into());
+ return Err(APIError::err("not_an_admin").into());
}
let site_form = SiteForm {
@@ -220,15 +211,12 @@ impl Perform for Oper {
match Site::create(&conn, &site_form) {
Ok(site) => site,
- Err(_e) => return Err(APIError::err(&self.op, "site_already_exists").into()),
+ Err(_e) => return Err(APIError::err("site_already_exists").into()),
};
let site_view = SiteView::read(&conn)?;
- Ok(SiteResponse {
- op: self.op.to_string(),
- site: site_view,
- })
+ Ok(SiteResponse { site: site_view })
}
}
@@ -238,20 +226,20 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
if has_slurs(&data.name)
|| (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap()))
{
- return Err(APIError::err(&self.op, "no_slurs").into());
+ return Err(APIError::err("no_slurs").into());
}
let user_id = claims.id;
// Make sure user is an admin
if !UserView::read(&conn, user_id)?.admin {
- return Err(APIError::err(&self.op, "not_an_admin").into());
+ return Err(APIError::err("not_an_admin").into());
}
let found_site = Site::read(&conn, 1)?;
@@ -268,15 +256,12 @@ impl Perform for Oper {
match Site::update(&conn, 1, &site_form) {
Ok(site) => site,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_site").into()),
+ Err(_e) => return Err(APIError::err("couldnt_update_site").into()),
};
let site_view = SiteView::read(&conn)?;
- Ok(SiteResponse {
- op: self.op.to_string(),
- site: site_view,
- })
+ Ok(SiteResponse { site: site_view })
}
}
@@ -301,7 +286,6 @@ impl Perform for Oper {
let banned = UserView::banned(&conn)?;
Ok(GetSiteResponse {
- op: self.op.to_string(),
site: site_view,
admins,
banned,
@@ -419,7 +403,6 @@ impl Perform for Oper {
// Return the jwt
Ok(SearchResponse {
- op: self.op.to_string(),
type_: data.type_.to_owned(),
comments,
posts,
@@ -435,7 +418,7 @@ impl Perform for Oper {
let claims = match Claims::decode(&data.auth) {
Ok(claims) => claims.claims,
- Err(_e) => return Err(APIError::err(&self.op, "not_logged_in").into()),
+ Err(_e) => return Err(APIError::err("not_logged_in").into()),
};
let user_id = claims.id;
@@ -444,7 +427,7 @@ impl Perform for Oper {
// Make sure user is the creator
if read_site.creator_id != user_id {
- return Err(APIError::err(&self.op, "not_an_admin").into());
+ return Err(APIError::err("not_an_admin").into());
}
let site_form = SiteForm {
@@ -459,7 +442,7 @@ impl Perform for Oper {
match Site::update(&conn, 1, &site_form) {
Ok(site) => site,
- Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_site").into()),
+ Err(_e) => return Err(APIError::err("couldnt_update_site").into()),
};
// Mod tables
@@ -484,7 +467,6 @@ impl Perform for Oper {
let banned = UserView::banned(&conn)?;
Ok(GetSiteResponse {
- op: self.op.to_string(),
site: Some(site_view),
admins,
banned,
diff --git a/server/src/api/user.rs b/server/src/api/user.rs
index ac700acad53..8d2db104cd2 100644
--- a/server/src/api/user.rs
+++ b/server/src/api/user.rs
@@ -30,6 +30,7 @@ pub struct SaveUserSettings {
lang: String,
avatar: Option,
email: Option,
+ matrix_user_id: Option,
new_password: Option,
new_password_verify: Option,
old_password: Option,
@@ -40,7 +41,6 @@ pub struct SaveUserSettings {
#[derive(Serialize, Deserialize)]
pub struct LoginResponse {
- op: String,
jwt: String,
}
@@ -58,7 +58,6 @@ pub struct GetUserDetails {
#[derive(Serialize, Deserialize)]
pub struct GetUserDetailsResponse {
- op: String,
user: UserView,
follows: Vec,
moderates: Vec,
@@ -69,13 +68,11 @@ pub struct GetUserDetailsResponse {
#[derive(Serialize, Deserialize)]
pub struct GetRepliesResponse {
- op: String,
replies: Vec,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserMentionsResponse {
- op: String,
mentions: Vec,
}
@@ -93,7 +90,6 @@ pub struct AddAdmin {
#[derive(Serialize, Deserialize)]
pub struct AddAdminResponse {
- op: String,
admins: Vec,
}
@@ -108,7 +104,6 @@ pub struct BanUser {
#[derive(Serialize, Deserialize)]
pub struct BanUserResponse {
- op: String,
user: UserView,
banned: bool,
}
@@ -140,7 +135,6 @@ pub struct EditUserMention {
#[derive(Serialize, Deserialize, Clone)]
pub struct UserMentionResponse {
- op: String,
mention: UserMentionView,
}
@@ -156,9 +150,7 @@ pub struct PasswordReset {
}
#[derive(Serialize, Deserialize, Clone)]
-pub struct PasswordResetResponse {
- op: String,
-}
+pub struct PasswordResetResponse {}
#[derive(Serialize, Deserialize)]
pub struct PasswordChange {
@@ -167,6 +159,40 @@ pub struct PasswordChange {
password_verify: String,
}
+#[derive(Serialize, Deserialize)]
+pub struct CreatePrivateMessage {
+ content: String,
+ recipient_id: i32,
+ auth: String,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct EditPrivateMessage {
+ edit_id: i32,
+ content: Option,
+ deleted: Option