diff --git a/README.md b/README.md index 6ff0454d..f16487ce 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,8 @@ cd lemmy and goto http://localhost:8536 ## Documentation -- [ActivityPub API.md](docs/API.md) +- [Websocket API for App developers](docs/api.md) +- [ActivityPub API.md](docs/apub_api_outline.md) - [Goals](docs/goals.md) - [Ranking Algorithm](docs/ranking.md) ## Support diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 00000000..a3b459b5 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,726 @@ +# Lemmy API + +This may lag behind the actual API endpoints [here](../server/src/api). + +The data types, such as `Vec`, are listed [here](../server/src/db). + +## Websocket API +### Endpoint +`host/api/v1/ws` + +### Testing with [Websocat](https://github.com/vi/websocat) +`websocat ws://127.0.0.1:8536/api/v1/ws` + +A simple test command: +`{"op": "ListCategories"}` + +## Rate limits +- 3 actions per 3 minutes for signups, post, and community creation. +- 30 actions per minute for everything else. + +## Errors +```rust +{ + op: String, + message: String, +} +``` + +## API +### List +`Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead` + +### User / Authentication / Admin +#### Login +The `jwt` string should be stored and used anywhere `auth` is called for. + +##### Request +```rust +{ + op: "Login", + data: { + username_or_email: String, + password: String + } +} +``` +##### Response +```rust +{ + op: String, + jwt: String +} +``` + + +#### Register +Only the first user will be able to be the admin. + +##### Request +```rust +{ + op: "Register", + data: { + username: String, + email: Option, + password: String, + password_verify: String, + admin: bool, + spam_timeri: i64, + } +} +``` +##### Response +```rust +{ + op: String, + jwt: String +} +``` + +#### Get User Details +##### Request +```rust +{ + op: "GetUserDetails", + data: { + user_id: Option, + username: Option, + sort: String, + page: Option, + limit: Option, + community_id: Option, + saved_only: bool, + auth: Option, + } +} +``` +##### Response +```rust +{ + op: String, + user: UserView, + follows: Vec, + moderates: Vec, + comments: Vec, + posts: Vec, +} +``` + +#### Get Replies / Inbox +##### Request +```rust +{ + op: "GetReplies", + data: { + sort: String, + page: Option, + limit: Option, + unread_only: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + replies: Vec, +} +``` + +#### Mark all replies as read +##### Request +```rust +{ + op: "MarkAllAsRead", + data: { + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + replies: Vec, +} +``` + +#### Add admin +##### Request +```rust +{ + op: "AddAdmin", + data: { + user_id: i32, + added: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + admins: Vec, +} +``` + +#### Ban user +##### Request +```rust +{ + op: "BanUser", + data: { + user_id: i32, + ban: bool, + reason: Option, + expires: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + user: UserView, + banned: bool, +} +``` + +### Site +#### List Categories +##### Request +```rust +{ + op: "ListCategories" +} +``` +##### Response +```rust +{ + op: String, + categories: Vec +} +``` + +#### Search +##### Request +```rust +{ + op: "Search", + data: { + q: String, + type_: String, + community_id: Option, + sort: String, + page: Option, + limit: Option, + } +} +``` +##### Response +```rust +{ + op: String, + comments: Vec, + posts: Vec, +} +``` + +#### Get Modlog +##### Request +```rust +{ + op: "GetModlog", + data: { + mod_user_id: Option, + community_id: Option, + page: Option, + limit: Option, + } +} +``` +##### 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, +} +``` + +#### Create Site +##### Request +```rust +{ + op: "CreateSite", + data: { + name: String, + description: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + site: SiteView, +} +``` + +#### Edit Site +##### Request +```rust +{ + op: "EditSite", + data: { + name: String, + description: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + site: SiteView, +} +``` + +#### Get Site +##### Request +```rust +{ + op: "GetSite" +} +``` +##### Response +```rust +{ + op: String, + site: Option, + admins: Vec, + banned: Vec, +} +``` + +### Community +#### Get Community +##### Request +```rust +{ + op: "GetCommunity", + data: { + id: Option, + name: Option, + auth: Option + } +} +``` +##### Response +```rust +{ + op: String, + community: CommunityView, + moderators: Vec, + admins: Vec, +} +``` + +#### Create Community +##### Request +```rust +{ + op: "CreateCommunity", + data: { + name: String, + title: String, + description: Option, + category_id: i32 , + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + community: CommunityView +} +``` + +#### List Communities +##### Request +```rust +{ + op: "ListCommunities", + data: { + sort: String, + page: Option, + limit: Option, + auth: Option + } +} +``` +##### Response +```rust +{ + op: String, + communities: Vec +} +``` + +#### Ban from Community +##### Request +```rust +{ + op: "BanFromCommunity", + data: { + community_id: i32, + user_id: i32, + ban: bool, + reason: Option, + expires: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + user: UserView, + banned: bool, +} +``` + +#### Add Mod to Community +##### Request +```rust +{ + op: "AddModToCommunity", + data: { + community_id: i32, + user_id: i32, + added: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + moderators: Vec, +} +``` + +#### Edit Community +Mods and admins can remove and lock a community, creators can delete it. + +##### Request +```rust +{ + op: "EditCommunity", + data: { + edit_id: i32, + name: String, + title: String, + description: Option, + category_id: i32, + removed: Option, + deleted: Option, + reason: Option, + expires: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + community: CommunityView +} +``` + +#### Follow Community +##### Request +```rust +{ + op: "FollowCommunity", + data: { + community_id: i32, + follow: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + community: CommunityView +} +``` + +#### Get Followed Communities +##### Request +```rust +{ + op: "GetFollowedCommunities", + data: { + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + communities: Vec +} +``` + +### Post +#### Create Post +##### Request +```rust +{ + op: "CreatePost", + data: { + name: String, + url: Option, + body: Option, + community_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + post: PostView +} +``` + +#### Get Post +##### Request +```rust +{ + op: "GetPost", + data: { + id: i32, + auth: Option + } +} +``` +##### Response +```rust +{ + op: String, + post: PostView, + comments: Vec, + community: CommunityView, + moderators: Vec, + admins: Vec, +} +``` + +#### Get Posts +##### Request +```rust +{ + op: "GetPosts", + data: { + type_: String, + sort: String, + page: Option, + limit: Option, + community_id: Option, + auth: Option + } +} +``` +##### Response +```rust +{ + op: String, + posts: Vec, +} +``` + +#### Create Post Like +##### Request +```rust +{ + op: "CreatePostLike", + data: { + post_id: i32, + score: i16, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + post: PostView +} +``` + +#### Edit Post +Mods and admins can remove and lock a post, creators can delete it. + +##### Request +```rust +{ + op: "EditPost", + data: { + edit_id: i32, + creator_id: i32, + community_id: i32, + name: String, + url: Option, + body: Option, + removed: Option, + deleted: Option, + locked: Option, + reason: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + post: PostView +} +``` + +#### Save Post +##### Request +```rust +{ + op: "SavePost", + data: { + post_id: i32, + save: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + post: PostView +} +``` + +### Comment +#### Create Comment +##### Request +```rust +{ + op: "CreateComment", + data: { + content: String, + parent_id: Option, + edit_id: Option, + post_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + comment: CommentView +} +``` + +#### Edit Comment +Mods and admins can remove a comment, creators can delete it. + +##### Request +```rust +{ + op: "EditComment", + data: { + content: String, + parent_id: Option, + edit_id: i32, + creator_id: i32, + post_id: i32, + removed: Option, + deleted: Option, + reason: Option, + read: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + comment: CommentView +} +``` + +#### Save Comment +##### Request +```rust +{ + op: "SaveComment", + data: { + comment_id: i32, + save: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + comment: CommentView +} +``` + +#### Create Comment Like +##### Request +```rust +{ + op: "CreateCommentLike", + data: { + comment_id: i32, + post_id: i32, + score: i16, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + comment: CommentView +} +``` diff --git a/docs/API.md b/docs/apub_api_outline.md similarity index 99% rename from docs/API.md rename to docs/apub_api_outline.md index 78cc81ab..e2776308 100644 --- a/docs/API.md +++ b/docs/apub_api_outline.md @@ -1,4 +1,4 @@ -# API +# Activitypub API outline - Start with the [reddit API](https://www.reddit.com/dev/api), and find [Activitypub vocab](https://www.w3.org/TR/activitystreams-vocabulary/) to match it. diff --git a/server/src/main.rs b/server/src/main.rs index fc27531b..48074316 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -192,13 +192,8 @@ fn main() { }; App::with_state(state) - // redirect to websocket.html - // .resource("/", |r| r.method(http::Method::GET).f(|_| { - // HttpResponse::Found() - // .header("LOCATION", "/static/websocket.html") - // .finish() - // })) - .resource("/service/ws", |r| r.route().f(chat_route)) + // .resource("/api/v1/rest", |r| r.method(http::Method::POST).f(|_| {}) + .resource("/api/v1/ws", |r| r.route().f(chat_route)) // static resources .resource("/", |r| r.route().f(index)) .handler( diff --git a/ui/src/env.ts b/ui/src/env.ts index aebbc57f..a0cdcdb0 100644 --- a/ui/src/env.ts +++ b/ui/src/env.ts @@ -1,4 +1,4 @@ let host = `${window.location.hostname}`; let port = `${window.location.port == "4444" ? '8536' : window.location.port}`; let endpoint = `${host}:${port}`; -export let wsUri = `${(window.location.protocol=='https:') ? 'wss://' : 'ws://'}${endpoint}/service/ws`; +export let wsUri = `${(window.location.protocol=='https:') ? 'wss://' : 'ws://'}${endpoint}/api/v1/ws`; diff --git a/ui/src/version.ts b/ui/src/version.ts index 1bc67c9b..4dc14542 100644 --- a/ui/src/version.ts +++ b/ui/src/version.ts @@ -1 +1 @@ -export let version: string = "v0.0.5-0-gf34ba11"; \ No newline at end of file +export let version: string = "v0.0.5-11-g8e22de3"; \ No newline at end of file diff --git a/ui/stack.prod.yaml b/ui/stack.prod.yaml index 85ac6f6b..ca4e1a7d 100644 --- a/ui/stack.prod.yaml +++ b/ui/stack.prod.yaml @@ -48,7 +48,7 @@ spec: backend: serviceName: lemmy-ui--prod servicePort: 5000 - - path: /service/ws + - path: /api/v1/ws backend: serviceName: lemmy-server--prod servicePort: 8536