Fixing federation docs, running markdown format. (#161)

This commit is contained in:
Dessalines 2023-03-03 08:35:56 -05:00 committed by GitHub
parent df93527044
commit a0f06f31c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 251 additions and 217 deletions

View file

@ -2,13 +2,13 @@
## About The Project
Front Page|Post
---|---
![main screen](/docs/en/about/main_screen.png)|![chat screen](/docs/en/about/chat_screen.png)
| Front Page | Post |
| ---------------------------------------------- | ---------------------------------------------- |
| ![main screen](/docs/en/about/main_screen.png) | ![chat screen](/docs/en/about/chat_screen.png) |
[Lemmy](https://github.com/LemmyNet/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse).
*The word “fediverse” (federated universe) refers to the network of all Lemmy servers [and other projects](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/), users of which are able to talk to each other seamlessly.*
_The word “fediverse” (federated universe) refers to the network of all Lemmy servers [and other projects](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/), users of which are able to talk to each other seamlessly._
Like email, whether you sign up on GMail or Outlook, you know youll be able to email everyone you need to, as long as you know their address. On Lemmy you're able to subscribe to communities on any other server, and can have discussions with users registered elsewhere.
@ -18,7 +18,7 @@ There are no shareholders, and no targeted advertising: only people sharing the
Each lemmy server can set its own moderation policy; appointing site-wide admins, and community moderators to keep out the trolls, and foster a healthy, non-toxic environment where all can feel comfortable contributing.
*Note: Federation is still in active development*
_Note: Federation is still in active development_
### Why's it called Lemmy?

View file

@ -18,7 +18,7 @@
- i18n / internationalization support.
- RSS / Atom feeds for `All`, `Subscribed`, `Inbox`, `User`, and `Community`.
- Cross-posting support.
- A *similar post search* when creating new posts. Great for question / answer communities.
- A _similar post search_ when creating new posts. Great for question / answer communities.
- Moderation abilities.
- Public Moderation Logs.
- Can sticky posts to the top of communities.

View file

@ -6,11 +6,11 @@ So you want to join Lemmy and get posting. Great! Here's how to dive straight in
The first thing you have to do is **choose your server**. This is an extra step compared to sites like Reddit, but isnt as difficult as it may seem.
*Like with email, your identity is hosted by the server you sign up on. So for example, I joined lemmy.ml so to mention me you can type @retiolus@lemmy.ml in your post.*
_Like with email, your identity is hosted by the server you sign up on. So for example, I joined lemmy.ml so to mention me you can type @retiolus@lemmy.ml in your post._
If what you want to talk about most fits into a clear category (maybe its video games or art or queer life or coding or fiction, etc) then it might be worth making your first server one where that will primarily host that sort of content itll be easier to make connections and find like-minded folk. Think of your server as a neighbourhood or a venue, where the general chatter can have a specific focus.
*You have the ability to view all public local posts that have been made by people on your server in the “Local” tab.*
_You have the ability to view all public local posts that have been made by people on your server in the “Local” tab._
If you arent here to stick mainly to one topic, youll likely want to pick a server that caters to general interests. Either way, theres a helpful servers list on [join-lemmy.org](https://join-lemmy.org/instances).
@ -30,7 +30,7 @@ Head to the Login page `(https://your.server/login)` of your server and choose y
Next thing to do is upload your profile picture, give the settings page `(https://your.server/settings)` a good once-over (and do come back to it when youve been on Lemmy a week or so just to make any tweaks that might help your experience) and get ready to introduce yourself.
*Some interesting settings worth checking are: your default feed sorting filter between subscribed, local or all and your default sorting type.*
_Some interesting settings worth checking are: your default feed sorting filter between subscribed, local or all and your default sorting type._
While you can simply enjoy reading Lemmy, the real fun begins as you dive in and start participating yourself by posting, voting and commenting.
@ -56,17 +56,17 @@ The standard Lemmy interface has a single feed. You can change the content of th
**All**, or the **federated timeline**, is a view of all the public posts your servers knows about from across the whole network (including local ones). The most common reason that something appears in the federated timeline is that someone from your server might follow a community that's on another server.
| Type | Description |
| --- | --- |
| Posts | Only displays publications |
| Comments | Displays only comments |
| \-\-\- | \-\-\- |
| Active | Trending sort based on the score, and the most recent comment time. |
| Hot | Trending sort based on the score, and the post creation time. |
| New | The newest items. |
| Most Comments | The posts with the most comments. |
| New Comments | The posts with most recent comments, IE a forum-style sort. |
| Top | The highest scoring items in the given time frame. |
| Type | Description |
| ------------- | ------------------------------------------------------------------- |
| Posts | Only displays publications |
| Comments | Displays only comments |
| \-\-\- | \-\-\- |
| Active | Trending sort based on the score, and the most recent comment time. |
| Hot | Trending sort based on the score, and the post creation time. |
| New | The newest items. |
| Most Comments | The posts with the most comments. |
| New Comments | The posts with most recent comments, IE a forum-style sort. |
| Top | The highest scoring items in the given time frame. |
For more detail, check the [Post and Comment Ranking details](https://join-lemmy.org/docs/en/about/ranking.html).
@ -74,22 +74,22 @@ For more detail, check the [Post and Comment Ranking details](https://join-lemmy
Lemmy's posts are done using Markdown, there are of course shortcuts for you to use when writing but here is a table to help you if you want to go further.
Type | Or | … to Get
--- | --- | ---
\*Italic\* | \_Italic\_ | _Italic_
\*\*Bold\*\* | \_\_Bold\_\_ | **Bold**
\# Heading 1 | Heading 1 <br> ========= | <h4>Heading 1</h4>
\## Heading 2 | Heading 2 <br>--------- | <h5>Heading 2</h5>
\[Link\](http://a.com) | \[Link\]\[1\]<br><br>\[1\]: http://b.org | [Link](https://commonmark.org/)
!\[Image\](http://url/a.png) | !\[Image\]\[1\]<br><br>\[1\]: http://url/b.jpg | ![Markdown](https://commonmark.org/help/images/favicon.png)
\> Blockquote | | <blockquote>Blockquote</blockquote>
\* List <br>\* List <br>\* List | \- List <br>\- List <br>\- List <br> | * List <br>* List <br>* List <br>
1\. One <br>2\. Two <br>3\. Three | 1) One<br>2) Two<br>3) Three | 1. One<br>2. Two<br>3. Three
Horizontal Rule <br>\--- | Horizontal Rule<br>\*\*\* | Horizontal Rule <br><hr>
\`Inline code\` with backticks | |`Inline code` with backticks
\`\`\`<br>\# code block <br>print '3 backticks or'<br>print 'indent 4 spaces' <br>\`\`\` | ····\# code block<br>····print '3 backticks or'<br>····print 'indent 4 spaces' | \# code block <br>print '3 backticks or'<br>print 'indent 4 spaces'
::: spoiler hidden or nsfw stuff<br>*a bunch of spoilers here*<br>::: | | <details><summary> hidden or nsfw stuff </summary><p><em>a bunch of spoilers here</em></p></details>
Some ~subscript~ text | | Some <sub>subscript</sub> text
Some ^superscript^ text | | Some <sup>superscript</sup> text
| Type | Or | … to Get |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
| \*Italic\* | \_Italic\_ | _Italic_ |
| \*\*Bold\*\* | \_\_Bold\_\_ | **Bold** |
| \# Heading 1 | Heading 1 <br> ========= | <h4>Heading 1</h4> |
| \## Heading 2 | Heading 2 <br>--------- | <h5>Heading 2</h5> |
| \[Link\](http://a.com) | \[Link\]\[1\]<br><br>\[1\]: http://b.org | [Link](https://commonmark.org/) |
| !\[Image\](http://url/a.png) | !\[Image\]\[1\]<br><br>\[1\]: http://url/b.jpg | ![Markdown](https://commonmark.org/help/images/favicon.png) |
| \> Blockquote | | <blockquote>Blockquote</blockquote> |
| \* List <br>\* List <br>\* List | \- List <br>\- List <br>\- List <br> | _ List <br>_ List <br>\* List <br> |
| 1\. One <br>2\. Two <br>3\. Three | 1) One<br>2) Two<br>3) Three | 1. One<br>2. Two<br>3. Three |
| Horizontal Rule <br>\--- | Horizontal Rule<br>\*\*\* | Horizontal Rule <br><hr> |
| \`Inline code\` with backticks | | `Inline code` with backticks |
| \`\`\`<br>\# code block <br>print '3 backticks or'<br>print 'indent 4 spaces' <br>\`\`\` | ····\# code block<br>····print '3 backticks or'<br>····print 'indent 4 spaces' | \# code block <br>print '3 backticks or'<br>print 'indent 4 spaces' |
| ::: spoiler hidden or nsfw stuff<br>_a bunch of spoilers here_<br>::: | | <details><summary> hidden or nsfw stuff </summary><p><em>a bunch of spoilers here</em></p></details> |
| Some ~subscript~ text | | Some <sub>subscript</sub> text |
| Some ^superscript^ text | | Some <sup>superscript</sup> text |
[CommonMark Tutorial](https://commonmark.org/help/tutorial/)

View file

@ -10,7 +10,7 @@
### Reddit
Does not take the lifetime of the thread into account, [giving early comments an overwhelming advantage over later ones,](https://minimaxir.com/2016/11/first-comment/) with the effect being even worse in small communities. New comments pool at the bottom of the thread, effectively killing off discussion and making each thread a race to comment early. This lowers the quality of conversation and rewards comments that are repetitive and spammy.
Does not take the lifetime of the thread into account, [giving early comments an overwhelming advantage over later ones,](https://minimaxir.com/2016/11/first-comment/) with the effect being even worse in small communities. New comments pool at the bottom of the thread, effectively killing off discussion and making each thread a race to comment early. This lowers the quality of conversation and rewards comments that are repetitive and spammy.
### Hacker News
@ -18,7 +18,7 @@ While far superior to Reddit's implementation for its decay of scores over time,
### Lemmy
Counterbalances the snowballing effect of votes over time with a logarithmic scale. Negates the inherent advantage of early comments while still ensuring that votes still matter in the long-term, not nuking older popular comments.
Counterbalances the snowballing effect of votes over time with a logarithmic scale. Negates the inherent advantage of early comments while still ensuring that votes still matter in the long-term, not nuking older popular comments.
```
Rank = ScaleFactor * log(Max(1, 3 + Score)) / (Time + 2)^Gravity
@ -27,6 +27,7 @@ Score = Upvotes - Downvotes
Time = time since submission (in hours)
Gravity = Decay gravity, 1.8 is default
```
- Lemmy uses the same `Rank` algorithm above, in two sorts: `Active`, and `Hot`.
- `Active` uses the post votes, and latest comment time (limited to two days).
- `Hot` uses the post votes, and the post published time.
@ -41,6 +42,6 @@ A plot of rank over 24 hours, of scores of 1, 5, 10, 100, 1000, with a scale fac
#### Active User counts
Lemmy also shows counts of *active users* for your site, and its communities. These are counted within the last `day`, `week`, `month`, and `half year`, and are cached on starting up lemmy, and every hour.
Lemmy also shows counts of _active users_ for your site, and its communities. These are counted within the last `day`, `week`, `month`, and `half year`, and are cached on starting up lemmy, and every hour.
An active user is someone who has posted or commented on our instance or community within the last given time frame. For site counts, only local users are counted. For community counts, federated users are included.

View file

@ -5,20 +5,24 @@ Information for Lemmy instance admins, and those who want to run a server.
If you have any problems in the installation, you can ask for help in [!lemmy_support](https://lemmy.ml/c/lemmy_support). Do not use Github for support.
## Install
### Official/Supported methods
Lemmy has two primary installation methods:
Lemmy has two primary installation methods:
- [Manually with Docker](install_docker.md)
- [Automated with Ansible](install_ansible.md)
We recommend using Ansible, because it simplifies the installation and also makes updating easier.
Lemmy uses roughly 150 MB of RAM in the default Docker installation. CPU usage is negligible.
Lemmy uses roughly 150 MB of RAM in the default Docker installation. CPU usage is negligible.
### Other installation methods
> ⚠️ **Under your own risk.**
In some cases, it might be necessary to use different installation methods.
- [From Scratch](from_scratch.md)
- [Yunohost](https://install-app.yunohost.org/?app=lemmy) ([source code](https://github.com/YunoHost-Apps/lemmy_ynh))
- [On Amazon Web Services (AWS)](on_aws.md)

View file

@ -48,4 +48,4 @@ handle @lemmy-hdr {
handle @lemmy-post {
reverse_proxy http://lemmy_lemmy_1:8536
}
```
```

View file

@ -6,7 +6,7 @@ Lemmy has three types of federation:
- BlockList: Explicitly list instances to not connect to. Federation is open to all other instances.
- Open: Federate with all potential instances.
**Federation is not set up by default.** You can add this [this federation block](https://github.com/lemmynet/lemmy/blob/main/config/config.hjson#L64) to your `lemmy.hjson`, and ask other servers to add you to their allowlist.
**Federation is enabled by default.** You can add allowed and blocked instances, by adding a comma-delimited list in your instance admin panel. IE to only federate with these instances, add: `enterprise.lemmy.ml,lemmy.ml` to the allowed instances section.
Lemmy uses the ActivityPub protocol (a W3C standard) to enable federation between different servers (often called instances). This is very similar to the way email works. For example, if you use gmail.com, then you can not only send mails to other gmail.com users, but also to yahoo.com, yandex.ru and so on. Email uses the SMTP protocol to achieve this, so you can think of ActivityPub as "SMTP for social media". The amount of different actions possible on social media (post, comment, like, share, etc) means that ActivityPub is much more complicated than SMTP.
@ -25,7 +25,7 @@ You can see the list of linked instances by following the "Instances" link at th
## Fetching communities
If you search for a community first time, 20 posts are fetched initially. Only if a least one user on your instance subscribes to the remote community, will the community send updates to your instance. Updates include:
If you search for a community first time, 20 posts are fetched initially. Only if a least one user on your instance subscribes to the remote community, will the community send updates to your instance. Updates include:
- New posts, comments
- Votes

View file

@ -27,6 +27,7 @@ To test that your instance federation is working correctly execute `curl -H 'Acc
## Inclusion on join-lemmy.org instance list
To be included in the list of Lemmy instances on [join-lemmy.org](https://join-lemmy.org/instances) you must meet the following requirements:
- [x] Federate with at least one instance from the list
- [x] Have a site description and icon
- [x] Be patient and wait the site to be updated, there's no fixed schedule for that
@ -36,6 +37,7 @@ In the meantime you can always promote your server on other social networks like
## Keeping up to date
You can subscribe to the Github RSS feeds to be informed of the latest releases:
- [lemmy](https://github.com/LemmyNet/lemmy/releases.atom)
- [lemmy-ui](https://github.com/LemmyNet/lemmy-ui/releases.atom)
- [lemmy-js-client](https://github.com/LemmyNet/lemmy-js-client/releases.atom)

View file

@ -1,4 +1,4 @@
# From Scratch
# From Scratch
These instructions are written for Ubuntu 20.04.
@ -24,11 +24,12 @@ chmod 755 /usr/bin/magick
```
Compile and install Lemmy, setup database:
```bash
apt install pkg-config libssl-dev libpq-dev postgresql
# installs latest release, you can also specify one with --version
# The --locked argument uses the exact versions of dependencies specified in
# `cargo.lock`at release time. Running it without the flag will use newer minor
# `cargo.lock`at release time. Running it without the flag will use newer minor
# release versions of those dependencies, which are not always guaranteed to compile.
# Remove the parameter `--features embed-pictrs` if you don't require image hosting.
cargo install lemmy_server --target-dir /usr/bin/ --locked --features embed-pictrs
@ -39,6 +40,7 @@ adduser lemmy --system --disabled-login --no-create-home --group
```
Minimal Lemmy config, put this in `/etc/lemmy/lemmy.hjson` (see [here](https://github.com/LemmyNet/lemmy/blob/main/config/config.hjson) for more config options). Run `chown lemmy:lemmy /etc/lemmy/ -R` to set the correct owner.
```hjson
{
database: {
@ -58,7 +60,8 @@ Minimal Lemmy config, put this in `/etc/lemmy/lemmy.hjson` (see [here](https://g
}
```
Systemd unit file, so that Lemmy automatically starts and stops, logs are handled via journalctl etc. Put this file into /etc/systemd/system/lemmy.service, then run `systemctl enable lemmy` and `systemctl start lemmy`.
Systemd unit file, so that Lemmy automatically starts and stops, logs are handled via journalctl etc. Put this file into /etc/systemd/system/lemmy.service, then run `systemctl enable lemmy` and `systemctl start lemmy`.
```
[Unit]
Description=Lemmy - A link aggregator for the fediverse
@ -88,6 +91,7 @@ If you did everything right, the Lemmy logs from `journalctl -u lemmy` should sh
### Install lemmy-ui (web frontend)
Install dependencies (nodejs and yarn in Ubuntu 20.04 repos are too old)
```bash
# https://classic.yarnpkg.com/en/docs/install/#debian-stable
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
@ -98,6 +102,7 @@ sudo apt install nodejs yarn
```
Clone the git repo, checkout the version you want (0.16.7 in this case), and compile it.
```bash
mkdir /var/lib/lemmy-ui
cd /var/lib/lemmy-ui
@ -112,6 +117,7 @@ exit
```
Add another systemd unit file, this time for lemmy-ui. You need to replace example.com with your actual domain. Put the file in `/etc/systemd/system/lemmy-ui.service`, then run `systemctl enable lemmy-ui` and `systemctl start lemmy-ui`.
```
[Unit]
Description=Lemmy UI - Web frontend for Lemmy
@ -141,21 +147,25 @@ If everything went right, the command `curl -I localhost:1234` should show `200
### Configure reverse proxy and TLS
Install dependencies
```bash
apt install nginx certbot python3-certbot-nginx
```
Request Let's Encrypt TLS certificate (just follow the instructions)
```bash
certbot certonly --nginx
```
Let's Encrypt certificates should be renewed automatically, so add the line below to your crontab, by running `sudo crontab -e`. Replace example.com with your actual domain.
```
@daily certbot certonly --nginx --cert-name example.com -d example.com --deploy-hook 'nginx -s reload'
```
Finally, add the nginx config. After downloading, you need to replace some variables in the file.
```bash
curl https://raw.githubusercontent.com/LemmyNet/lemmy-ansible/main/templates/nginx.conf \
--output /etc/nginx/sites-enabled/lemmy.conf
@ -201,7 +211,7 @@ cd /var/lib/pictrs-source
git checkout main
git pull --tags
# check docker-compose.yml for pict-rs version used by lemmy
# https://github.com/LemmyNet/lemmy-ansible/blob/main/templates/docker-compose.yml#L40
# https://github.com/LemmyNet/lemmy-ansible/blob/main/templates/docker-compose.yml#L40
git checkout v0.2.6-r2
# or simply add the bin folder to your $PATH
$HOME/.cargo/bin/cargo build --release

View file

@ -9,20 +9,20 @@ to AWS using their [Cloud Development Kit](https://docs.aws.amazon.com/cdk/lates
### Included:
* ECS fargate cluster
* Lemmy-UI
* Lemmy
* Pictrs
* CloudFront CDN
* EFS storage for image uploads
* Aurora Serverless Postgres DB
* Bastion VPC host
* Load balancers for Lemmy
* DNS records for your site
- ECS fargate cluster
- Lemmy-UI
- Lemmy
- Pictrs
- CloudFront CDN
- EFS storage for image uploads
- Aurora Serverless Postgres DB
- Bastion VPC host
- Load balancers for Lemmy
- DNS records for your site
## Quickstart
Clone the [Lemmy-CDK]( https://github.com/jetbridge/lemmy-cdk).
Clone the [Lemmy-CDK](https://github.com/jetbridge/lemmy-cdk).
Clone [Lemmy](https://github.com/LemmyNet/lemmy) and [Lemmy-UI](https://github.com/LemmyNet/lemmy-ui) to the directory above this.
@ -41,13 +41,14 @@ cdk deploy
```
## Cost
This is *not* the cheapest way to run Lemmy. The Serverless Aurora DB can run you ~$90/mo if it doesn't go to sleep.
This is _not_ the cheapest way to run Lemmy. The Serverless Aurora DB can run you ~$90/mo if it doesn't go to sleep.
## Useful CDK commands
* `npm run build` compile typescript to js
* `npm run watch` watch for changes and compile
* `npm run test` perform the jest unit tests
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
- `npm run build` compile typescript to js
- `npm run watch` watch for changes and compile
- `npm run test` perform the jest unit tests
- `cdk deploy` deploy this stack to your default AWS account/region
- `cdk diff` compare deployed stack with current state
- `cdk synth` emits the synthesized CloudFormation template

View file

@ -4,4 +4,4 @@ Lemmy uses [Bootstrap v4](https://getbootstrap.com/), and very few custom css cl
If you installed Lemmy with Docker, save your theme file to `./volumes/lemmy-ui/extra_themes`. For native installation (without Docker), themes are loaded by lemmy-ui from ./extra_themes folder. A different path can be specified with LEMMY_UI_EXTRA_THEMES_FOLDER environment variable.
After a theme is added, users can select it under `/settings`. Admins can set a theme as site default under `/admin`.
After a theme is added, users can select it under `/settings`. Admins can set a theme as site default under `/admin`.

View file

@ -39,6 +39,7 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
### Other instances can't fetch local objects (community, post, etc)
Your reverse proxy (eg nginx) needs to forward requests with header `Accept: application/activity+json` to the backend. This is handled by the following lines:
```
set $proxpass "http://0.0.0.0:{{ lemmy_ui_port }}";
if ($http_accept = "application/activity+json") {
@ -51,12 +52,14 @@ proxy_pass $proxpass;
```
You can test that it works correctly by running the following commands, all of them should return valid JSON:
```
curl -H "Accept: application/activity+json" https://your-instance.com/u/some-local-user
curl -H "Accept: application/activity+json" https://your-instance.com/c/some-local-community
curl -H "Accept: application/activity+json" https://your-instance.com/post/123 # the id of a local post
curl -H "Accept: application/activity+json" https://your-instance.com/comment/123 # the id of a local comment
```
### Fetching remote objects works, but posting/commenting in remote communities fails
Check that [federation is allowed on both instances](../federation/administration.md#instance-allowlist-and-blocklist).

View file

@ -20,7 +20,7 @@ The next step is building a Docker image from your frontend. If you forked an ex
- LEMMY_INTERNAL_HOST=lemmy:8536
- LEMMY_EXTERNAL_HOST=localhost:8536
- LEMMY_HTTPS=false
depends_on:
depends_on:
- lemmy
```
@ -45,17 +45,17 @@ Lemmy does rate limiting for many actions based on the client IP. But if you mak
Here is an example snipped for NodeJS:
```javascript
function setForwardedHeaders(
headers: IncomingHttpHeaders
): { [key: string]: string } {
function setForwardedHeaders(headers: IncomingHttpHeaders): {
[key: string]: string,
} {
let out = {
host: headers.host,
};
if (headers['x-real-ip']) {
out['x-real-ip'] = headers['x-real-ip'];
if (headers["x-real-ip"]) {
out["x-real-ip"] = headers["x-real-ip"];
}
if (headers['x-forwarded-for']) {
out['x-forwarded-for'] = headers['x-forwarded-for'];
if (headers["x-forwarded-for"]) {
out["x-forwarded-for"] = headers["x-forwarded-for"];
}
return out;

View file

@ -6,11 +6,11 @@ This contains extras not in the [API docs](/api).
- [Curl Examples](#curl-examples)
- [HTTP API exclusive features](#http-api-exclusive-features)
* [RSS/Atom feeds](#rssatom-feeds)
* [Images](#images)
+ [Create (request)](#create-request)
+ [Create (response)](#create-response)
+ [Delete](#delete)
- [RSS/Atom feeds](#rssatom-feeds)
- [Images](#images)
- [Create (request)](#create-request)
- [Create (response)](#create-response)
- [Delete](#delete)
<!-- tocstop -->
@ -57,13 +57,13 @@ Lemmy forwards image requests to a locally running Pictrs.
`GET /pictrs/image/{filename}?format={webp, jpg, ...}&thumbnail={96}`
*Format and thumbnail are optional.*
_Format and thumbnail are optional._
#### Create (request)
Uploaded content must be valid multipart/form-data with an image array located within the images[] key.
`POST /pictrs/image`
`POST /pictrs/image`
#### Create (response)

View file

@ -32,6 +32,6 @@ pub fn list_posts() -> GetPostsResponse {
```
You can also look at the following real-world projects as examples:
- [lemmyBB](https://github.com/Nutomic/lemmyBB)
- [lemmy-stats-crawler](https://yerbamate.ml/LemmyNet/lemmy-stats-crawler)
-

View file

@ -12,7 +12,6 @@ Information about contributing to Lemmy, whether it is translating, testing, des
Check out [Lemmy's Weblate](https://weblate.yerbamate.ml/projects/lemmy/) for translations. You can also help by [translating this documentation](https://github.com/LemmyNet/lemmy-docs#adding-a-new-language).
## Architecture
### Front end
@ -25,13 +24,13 @@ Check out [Lemmy's Weblate](https://weblate.yerbamate.ml/projects/lemmy/) for tr
### Back end
- The back end is written in `rust`, using `diesel`, and `actix`.
- The server source code is split into main sections in `src`. These include:
- The server source code is split into main sections in `src`. These include:
- `db` - The low level database actions.
- Database additions are done using diesel migrations. Run `diesel migration generate xxxxx` to add new things.
- `api` - The high level user interactions (things like `CreateComment`)
- `routes` - The server endpoints .
- `apub` - The activitypub conversions.
- `websocket` - Creates the websocket server.
- `websocket` - Creates the websocket server.
## Linting / Formatting

View file

@ -1,6 +1,7 @@
# Docker Development
## Dependencies
### Debian-based distro
```bash
@ -26,9 +27,10 @@ cd docker/dev
and go to http://localhost:1236
*Note: many features (like docs and pictures) will not work without using an nginx profile like that in `ansible/templates/nginx.conf`.
\*Note: many features (like docs and pictures) will not work without using an nginx profile like that in `ansible/templates/nginx.conf`.
To speed up the Docker compile, add the following to `/etc/docker/daemon.json` and restart Docker.
```
{
"features": {

View file

@ -11,19 +11,20 @@ cd docker/federation
The federation test sets up 5 instances:
Instance | Username | Location | Notes
--- | --- | --- | ---
lemmy-alpha | lemmy_alpha | [127.0.0.1:8540](http://127.0.0.1:8540) | federated with all other instances
lemmy-beta | lemmy_beta | [127.0.0.1:8550](http://127.0.0.1:8550) | federated with all other instances
lemmy-gamma | lemmy_gamma | [127.0.0.1:8560](http://127.0.0.1:8560) | federated with all other instances
lemmy-delta | lemmy_delta | [127.0.0.1:8570](http://127.0.0.1:8570) | only allows federation with lemmy-beta
lemmy-epsilon | lemmy_epsilon | [127.0.0.1:8580](http://127.0.0.1:8580) | uses blocklist, has lemmy-alpha blocked
| Instance | Username | Location | Notes |
| ------------- | ------------- | --------------------------------------- | --------------------------------------- |
| lemmy-alpha | lemmy_alpha | [127.0.0.1:8540](http://127.0.0.1:8540) | federated with all other instances |
| lemmy-beta | lemmy_beta | [127.0.0.1:8550](http://127.0.0.1:8550) | federated with all other instances |
| lemmy-gamma | lemmy_gamma | [127.0.0.1:8560](http://127.0.0.1:8560) | federated with all other instances |
| lemmy-delta | lemmy_delta | [127.0.0.1:8570](http://127.0.0.1:8570) | only allows federation with lemmy-beta |
| lemmy-epsilon | lemmy_epsilon | [127.0.0.1:8580](http://127.0.0.1:8580) | uses blocklist, has lemmy-alpha blocked |
You can log into each using the instance name, and `lemmy` as the password, IE (`lemmy_alpha`, `lemmy`).
You can log into each using the instance name, and `lemmy` as the password, IE (`lemmy_alpha`, `lemmy`).
To start federation between instances, visit one of them and search for a user, community or post, like this. Note that
the Lemmy backend runs on a different port than the frontend, so you have to increment the port number from
the Lemmy backend runs on a different port than the frontend, so you have to increment the port number from
the URL bar by one.
- `!main@lemmy-alpha:8541`
- `http://lemmy-beta:8551/post/3`
- `@lemmy-gamma@lemmy-gamma:8561`
@ -35,8 +36,8 @@ Firefox containers are a good way to test them interacting.
Note that federation is currently in alpha. **Only use it for testing**, not on any production server, and be aware that turning on federation may break your instance.
Follow the normal installation instructions, either with [Ansible](../administration/install_ansible.md) or
[manually](../administration/install_docker.md). Then replace the line `image: dessalines/lemmy:v0.x.x` in
`/lemmy/docker-compose.yml` with `image: dessalines/lemmy:federation`. Add and configure [this federation block](https://github.com/lemmynet/lemmy/blob/main/config/config.hjson#L64) to your `lemmy.hjson`.
[manually](../administration/install_docker.md). Then replace the line `image: dessalines/lemmy:v0.x.x` in
`/lemmy/docker-compose.yml` with `image: dessalines/lemmy:federation`.
Afterwards, and whenever you want to update to the latest version, run these commands on the server:
@ -52,7 +53,7 @@ sudo docker-compose up -d
- check_is_apub_valid : Makes sure its in our allowed instances list
- Lower level checks: To make sure that the user that creates/updates/removes a post is actually on the same instance as that post
For the last point, note that we are *not* checking whether the actor that sends the create activity for a post is
For the last point, note that we are _not_ checking whether the actor that sends the create activity for a post is
actually identical to the post's creator, or that the user that removes a post is a mod/admin. These things are checked
by the API code, and its the responsibility of each instance to check user permissions. This does not leave any attack
vector, as a normal instance user cant do actions that violate the API rules. The only one who could do that is the

View file

@ -1,9 +1,11 @@
# Local Development
### Install build requirements
Install Rust using [the recommended option on rust-lang.org](https://www.rust-lang.org/tools/install) (rustup).
#### Debian-based distro
```
sudo apt install git cargo libssl-dev pkg-config libpq-dev curl
# install yarn
@ -13,6 +15,7 @@ sudo apt update && sudo apt install yarn
```
#### Arch-based distro
```
sudo pacman -S git cargo libssl-dev pkg-config libpq-dev curl
# install yarn (stable)
@ -20,6 +23,7 @@ curl -o- -L https://yarnpkg.com/install.sh | bash
```
#### macOS
Install [Homebrew](https://brew.sh/) if you don't already have it installed.
Finally, install Node and Yarn.
@ -29,6 +33,7 @@ brew install node yarn
```
### Get the back end source code
```
git clone https://github.com/LemmyNet/lemmy.git --recursive
# or alternatively from gitea
@ -36,18 +41,22 @@ git clone https://github.com/LemmyNet/lemmy.git --recursive
```
### Build the backend (Rust)
```
cargo build
# for development, use `cargo check` instead)
```
### Get the front end source code
```
git clone https://github.com/LemmyNet/lemmy-ui.git --recursive
```
### Setup postgresql
#### Debian-based disto
```
sudo apt install postgresql
sudo systemctl start postgresql
@ -59,6 +68,7 @@ export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
```
#### Arch-based distro
```
sudo pacman -S postgresql
sudo systemctl start postgresql
@ -70,6 +80,7 @@ export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
```
#### macOS
```
brew install postgresql
brew services start postgresql
@ -82,6 +93,7 @@ export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
```
### Run a local development instance
```
cd lemmy
cargo run

View file

@ -11,8 +11,8 @@ In general, our handling of branches is the one described in [A stable mainline
- Make a beta or release candidate version with `docker/prod/deploy.sh`
- Do the same for `lemmy-ui`: `./deploy.sh 0.x.0-rc-x`
- Deploy to federation test instances
- Keeping one instance at the last stable version to test federation compatibility (automate this with ansible)
- `ansible-playbook -i federation playbooks/site.yml --vault-password-file vault_pass -e rc_version=0.x.0-rc.x`
- Keeping one instance at the last stable version to test federation compatibility (automate this with ansible)
- `ansible-playbook -i federation playbooks/site.yml --vault-password-file vault_pass -e rc_version=0.x.0-rc.x`
- Test that everything works as expected, make new beta/rc releases if needed
- Deploy to lemmy.ml, to discover remaining problems
- If that went well, make the official `0.x.0` release with `docker/prod/deploy.sh`

View file

@ -23,6 +23,7 @@ Install the [Local development dependencies](local_development.md), and add the
```
Then use the following script to run the tests:
```
cd api_tests
./run-federation-test.bash

View file

@ -17,7 +17,7 @@ For an overview of how federation in Lemmy works on a technical level, check out
## Federation Modes
Through the combination of federation config options, there are a couple different federation modes, differing in their restrictiveness. For now we don't recommend to use open federation, because moderation tools are lacking and there might be security problems in the federation code. Open federation should be fine for test instances and smaller instances, but bigger instances should prefer to use a more closed federation.
Through the combination of federation config options, there are a couple different federation modes, differing in their restrictiveness. For now we don't recommend to use open federation, because moderation tools are lacking and there might be security problems in the federation code. Open federation should be fine for test instances and smaller instances, but bigger instances should prefer to use a more closed federation.
It is important to note that these settings only affect sending and receiving of data between instances. If allow federation with a certain instance, and then remove it from the allowlist, this will not affect previously federated data. These communities, users, posts and comments will still be shown. They will just not be updated anymore. And even if an instance is blocked, it can still fetch and display public data from your instance.

View file

@ -10,43 +10,43 @@ Before reading this, have a look at our [Federation Overview](contributing_feder
- [Context](#context)
- [Actors](#actors)
* [Community](#community)
* [User](#user)
* [Instance](#instance)
- [Community](#community)
- [User](#user)
- [Instance](#instance)
- [Objects](#objects)
* [Post](#post)
* [Comment](#comment)
* [Private Message](#private-message)
- [Post](#post)
- [Comment](#comment)
- [Private Message](#private-message)
- [Collections](#collections)
* [Community Outbox](#community-outbox)
* [Community Followers](#community-followers)
* [Community Moderators](#community-moderators)
* [User Outbox](#user-outbox)
- [Community Outbox](#community-outbox)
- [Community Followers](#community-followers)
- [Community Moderators](#community-moderators)
- [User Outbox](#user-outbox)
- [Activities](#activities)
* [User to Community](#user-to-community)
+ [Follow](#follow)
+ [Unfollow](#unfollow)
+ [Report Post or Comment](#report-post-or-comment)
* [Community to User](#community-to-user)
+ [Accept Follow](#accept-follow)
+ [Announce](#announce)
* [Announcable](#announcable)
+ [Create or Update Post](#create-or-update-post)
+ [Create or Update Comment](#create-or-update-comment)
+ [Like Post or Comment](#like-post-or-comment)
+ [Dislike Post or Comment](#dislike-post-or-comment)
+ [Undo Like or Dislike Post or Comment](#undo-like-or-dislike-post-or-comment)
+ [Delete Post or Comment](#delete-post-or-comment)
+ [Remove Post or Comment](#remove-post-or-comment)
+ [Undo Delete or Remove](#undo-delete-or-remove)
+ [Add Mod](#add-mod)
+ [Remove Mod](#remove-mod)
+ [Block User](#block-user)
+ [Undo Block User](#undo-block-user)
* [User to User](#user-to-user)
+ [Create or Update Private message](#create-or-update-private-message)
+ [Delete Private Message](#delete-private-message)
+ [Undo Delete Private Message](#undo-delete-private-message)
- [User to Community](#user-to-community)
- [Follow](#follow)
- [Unfollow](#unfollow)
- [Report Post or Comment](#report-post-or-comment)
- [Community to User](#community-to-user)
- [Accept Follow](#accept-follow)
- [Announce](#announce)
- [Announcable](#announcable)
- [Create or Update Post](#create-or-update-post)
- [Create or Update Comment](#create-or-update-comment)
- [Like Post or Comment](#like-post-or-comment)
- [Dislike Post or Comment](#dislike-post-or-comment)
- [Undo Like or Dislike Post or Comment](#undo-like-or-dislike-post-or-comment)
- [Delete Post or Comment](#delete-post-or-comment)
- [Remove Post or Comment](#remove-post-or-comment)
- [Undo Delete or Remove](#undo-delete-or-remove)
- [Add Mod](#add-mod)
- [Remove Mod](#remove-mod)
- [Block User](#block-user)
- [Undo Block User](#undo-block-user)
- [User to User](#user-to-user)
- [Create or Update Private message](#create-or-update-private-message)
- [Delete Private Message](#delete-private-message)
- [Undo Delete Private Message](#undo-delete-private-message)
<!-- tocstop -->
@ -72,22 +72,22 @@ Receives activities from user: `Follow`, `Undo/Follow`, `Create`, `Update`, `Lik
{{#include ../../../include/crates/apub/assets/lemmy/objects/group.json}}
```
| Field Name | Description |
|---|---|
| `preferredUsername` | Name of the actor |
| `name` | Title of the community |
| `sensitive` | True indicates that all posts in the community are nsfw |
| `attributedTo` | First the community creator, then all the remaining moderators |
| `content` | Text for the community sidebar, usually containing a description and rules |
| `icon` | Icon, shown next to the community name |
| `image` | Banner image, shown on top of the community page |
| `inbox` | ActivityPub inbox URL |
| `outbox` | ActivityPub outbox URL, only contains up to 20 latest posts, no comments, votes or other activities |
| `followers` | Follower collection URL, only contains the number of followers, no references to individual followers |
| `endpoints` | Contains URL of shared inbox |
| `published` | Datetime when the community was first created |
| `updated` | Datetime when the community was last changed |
| `publicKey` | The public key used to verify signatures from this actor |
| Field Name | Description |
| ------------------- | ----------------------------------------------------------------------------------------------------- |
| `preferredUsername` | Name of the actor |
| `name` | Title of the community |
| `sensitive` | True indicates that all posts in the community are nsfw |
| `attributedTo` | First the community creator, then all the remaining moderators |
| `content` | Text for the community sidebar, usually containing a description and rules |
| `icon` | Icon, shown next to the community name |
| `image` | Banner image, shown on top of the community page |
| `inbox` | ActivityPub inbox URL |
| `outbox` | ActivityPub outbox URL, only contains up to 20 latest posts, no comments, votes or other activities |
| `followers` | Follower collection URL, only contains the number of followers, no references to individual followers |
| `endpoints` | Contains URL of shared inbox |
| `published` | Datetime when the community was first created |
| `updated` | Datetime when the community was last changed |
| `publicKey` | The public key used to verify signatures from this actor |
### User
@ -103,18 +103,18 @@ Sends and receives activities from/to other users: `Create/Note`, `Update/Note`,
{{#include ../../../include/crates/apub/assets/lemmy/objects/person.json}}
```
| Field Name | Description |
|---|---|
| `preferredUsername` | Name of the actor |
| `name` | The user's displayname |
| `content` | User bio |
| `icon` | The user's avatar, shown next to the username |
| `image` | The user's banner, shown on top of the profile |
| `inbox` | ActivityPub inbox URL |
| `endpoints` | Contains URL of shared inbox |
| `published` | Datetime when the user signed up |
| `updated` | Datetime when the user profile was last changed |
| `publicKey` | The public key used to verify signatures from this actor |
| Field Name | Description |
| ------------------- | -------------------------------------------------------- |
| `preferredUsername` | Name of the actor |
| `name` | The user's displayname |
| `content` | User bio |
| `icon` | The user's avatar, shown next to the username |
| `image` | The user's banner, shown on top of the profile |
| `inbox` | ActivityPub inbox URL |
| `endpoints` | Contains URL of shared inbox |
| `published` | Datetime when the user signed up |
| `updated` | Datetime when the user profile was last changed |
| `publicKey` | The public key used to verify signatures from this actor |
The user inbox is not actually implemented yet, and is only a placeholder for ActivityPub implementations which require it.
@ -127,7 +127,7 @@ Represents a Lemmy instance, and is used to federate global data like the instan
```
| Field Name | Description |
|-------------|----------------------------------------------------------|
| ----------- | -------------------------------------------------------- |
| `name` | Instance name |
| `summary` | Short description |
| `content` | Long description (sidebar) |
@ -149,19 +149,19 @@ A page with title, and optional URL and text content. The URL often leads to an
{{#include ../../../include/crates/apub/assets/lemmy/objects/page.json}}
```
| Field Name | Description |
|---|---|
| `attributedTo` | ID of the user which created this post |
| `to` | ID of the community where it was posted to |
| `name` | Title of the post |
| `content` | Body of the post |
| `url` | An arbitrary link to be shared |
| `image` | Thumbnail for `url`, only present if it is an image link |
| `commentsEnabled` | False indicates that the post is locked, and no comments can be added |
| `sensitive` | True marks the post as NSFW, blurs the thumbnail and hides it from users with NSFW settign disabled |
| `stickied` | True means that it is shown on top of the community |
| `published` | Datetime when the post was created |
| `updated` | Datetime when the post was edited (not present if it was never edited) |
| Field Name | Description |
| ----------------- | --------------------------------------------------------------------------------------------------- |
| `attributedTo` | ID of the user which created this post |
| `to` | ID of the community where it was posted to |
| `name` | Title of the post |
| `content` | Body of the post |
| `url` | An arbitrary link to be shared |
| `image` | Thumbnail for `url`, only present if it is an image link |
| `commentsEnabled` | False indicates that the post is locked, and no comments can be added |
| `sensitive` | True marks the post as NSFW, blurs the thumbnail and hides it from users with NSFW settign disabled |
| `stickied` | True means that it is shown on top of the community |
| `published` | Datetime when the post was created |
| `updated` | Datetime when the post was edited (not present if it was never edited) |
### Comment
@ -171,14 +171,14 @@ A reply to a post, or reply to another comment. Contains only text (including re
{{#include ../../../include/crates/apub/assets/lemmy/objects/note.json}}
```
| Field Name | Description |
|---|---|
| `attributedTo` | ID of the user who created the comment |
| `to` | Community where the comment was made |
| `content` | The comment text |
| `inReplyTo` | IDs of the post where this comment was made, and the parent comment. If this is a top-level comment, `inReplyTo` only contains the post |
| `published` | Datetime when the comment was created |
| `updated` | Datetime when the comment was edited (not present if it was never edited) |
| Field Name | Description |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `attributedTo` | ID of the user who created the comment |
| `to` | Community where the comment was made |
| `content` | The comment text |
| `inReplyTo` | IDs of the post where this comment was made, and the parent comment. If this is a top-level comment, `inReplyTo` only contains the post |
| `published` | Datetime when the comment was created |
| `updated` | Datetime when the comment was edited (not present if it was never edited) |
### Private Message
@ -188,13 +188,13 @@ A direct message from one user to another. Can not include additional users. Thr
{{#include ../../../include/crates/apub/assets/lemmy/objects/chat_message.json}}
```
| Field Name | Description |
|---|---|
| `attributedTo` | ID of the user who created this private message |
| `to` | ID of the recipient |
| `content` | The text of the private message |
| `published` | Datetime when the message was created |
| `updated` | Datetime when the message was edited (not present if it was never edited) |
| Field Name | Description |
| -------------- | ------------------------------------------------------------------------- |
| `attributedTo` | ID of the user who created this private message |
| `to` | ID of the recipient |
| `content` | The text of the private message |
| `published` | Datetime when the message was created |
| `updated` | Datetime when the message was edited (not present if it was never edited) |
## Collections
@ -246,7 +246,6 @@ Clicking on the unsubscribe button in a community causes an `Undo/Follow` to be
{{#include ../../../include/crates/apub/assets/lemmy/activities/following/undo_follow.json}}
```
#### Report Post or Comment
Reports a post or comment for rule violation, so that mods/admins review it.
@ -376,7 +375,7 @@ Reverts a previous user block.
### User to User
#### Create or Update Private message
#### Create or Update Private message
Creates a new private message between two users.

View file

@ -1,15 +1,14 @@
# Federation Overview
This document is for anyone who wants to know how Lemmy federation works, without being overly technical. It is meant provide a high-level overview of ActivityPub federation in Lemmy. If you are implementing ActivityPub yourself and want to be compatible with Lemmy, read our [ActivityPub API outline](contributing_apub_api_outline.md).
## Documentation conventions
To keep things simple, sometimes you will see things formatted like `Create/Note` or `Delete/Event` or `Undo/Follow`. The thing before the slash is the Activity, and the thing after the slash is the Object inside the Activity, in an `object` property. So these are to be read as follows:
* `Create/Note`: a `Create` activity containing a `Note` in the `object` field
* `Delete/Event`: a `Delete` activity containing an `Event` in the `object` field
* `Undo/Follow`: an `Undo` activity containing a `Follow` in the `object` field
- `Create/Note`: a `Create` activity containing a `Note` in the `object` field
- `Delete/Event`: a `Delete` activity containing an `Event` in the `object` field
- `Undo/Follow`: an `Undo` activity containing a `Follow` in the `object` field
In Lemmy we use some specific terms to refer to ActivityPub items. They are essentially our specific implementations of well-known ActivityPub concepts:
@ -20,13 +19,13 @@ In Lemmy we use some specific terms to refer to ActivityPub items. They are esse
This document has three main sections:
* __Federation philosophy__ lays out the general model of how this is intended to federate
* __User Activities__ describes which actions that a User can take to interact
* __Community Activities__ describes what the Community does in response to certain User actions
- **Federation philosophy** lays out the general model of how this is intended to federate
- **User Activities** describes which actions that a User can take to interact
- **Community Activities** describes what the Community does in response to certain User actions
## Federation philosophy
The primary Actor in Lemmy is the Community. Each community resides on a single instance, and consists of a list of Posts and a list of followers. The primary interaction is that of a User sending a Post or Comment related activity to the Community inbox, which then announces it to all its followers.
The primary Actor in Lemmy is the Community. Each community resides on a single instance, and consists of a list of Posts and a list of followers. The primary interaction is that of a User sending a Post or Comment related activity to the Community inbox, which then announces it to all its followers.
Each Community has a specific creator User, who is responsible for setting rules, appointing moderators, and removing content that violates the rules.
@ -50,8 +49,8 @@ After following a Community, the "Follow" button is replaced by "Unfollow". Clic
### Create a Post
When a user creates a new Post in a given Community, it is sent as `Create/Page` to the Community
inbox.
When a user creates a new Post in a given Community, it is sent as `Create/Page` to the Community
inbox.
### Create a Comment
@ -112,12 +111,12 @@ The Community is essentially a bot, which will only do anything in reaction to a
### Accept follow
If the Community receives a `Follow` activity, it automatically responds with `Accept/Follow`. It also adds the User to its list of followers.
If the Community receives a `Follow` activity, it automatically responds with `Accept/Follow`. It also adds the User to its list of followers.
### Unfollow
Upon receiving an `Undo/Follow`, the Community removes the User from its followers list.
### Announce
If the Community receives any Post or Comment related activity (Create, Update, Like, Dislike, Remove, Delete, Undo), it will Announce this to its followers. For this, an Announce is created with the Community as actor, and the received activity as object. Following instances thus stay updated about any actions in Communities they follow.

View file

@ -6,15 +6,15 @@ The **community creator** is this first **moderator** of a community since he cr
An **administrator** has full rights on the entire server, and thus also in each community.
| Action | Result | Permission level |
| --- | --- | --- |
| lock | Prevents making new comments under the post | Moderator |
| sticky | Pin the publication to the top of the community listing | Moderator |
| remove | Delete the post | Moderator |
| ban | Ban user from the community | Moderator |
| appoint as mod | Gives the user moderator status | Moderator |
| appoint as admin | Gives the user administrator status | Admin |
| ban from site | Ban user from the server | Admin |
| Action | Result | Permission level |
| ---------------- | ------------------------------------------------------- | ---------------- |
| lock | Prevents making new comments under the post | Moderator |
| sticky | Pin the publication to the top of the community listing | Moderator |
| remove | Delete the post | Moderator |
| ban | Ban user from the community | Moderator |
| appoint as mod | Gives the user moderator status | Moderator |
| appoint as admin | Gives the user administrator status | Admin |
| ban from site | Ban user from the server | Admin |
To take a moderation action on a user, you need a post from that user and click on the 3 dots at the bottom right of the title.