1
0
mirror of https://github.com/spacebarchat/docs.git synced 2024-11-09 20:02:32 +01:00

🎨 restructure

This commit is contained in:
Flam3rboy 2021-09-02 02:24:06 +02:00
parent 22221568e6
commit d8600c9278
20 changed files with 443 additions and 398 deletions

View File

@ -1,45 +0,0 @@
# Configuration
## Philosophy
Every fosscord server instance should be completely configurable in every way, without the need to change the source code.
The config should have reasonable defaults similar to discord.
Only in special cases it should require a third party config value.
The config should be changeable over the admin fosscord-dashboard and update in realtime without the need to restart the servers
The very first time the server starts, it saves to default config in the database. The next start it will load the config from the database.
## Getting Started for Contributors
You **should not** `get()` the Config in the root of your file and it instead load the config every time you access a value
Import ``Config`` from fosscord-server-util:
```js
// at the top of the file import the Config file from /src/util/Config.ts
import { Config } from "@fosscord-server-util";
```
Access the Config in your route:
```js
router.get("/", (req: Request, res: Response) => {
// call Config.get() to get the whole config object and then just access the property you want
const { allowNewRegistration } = Config.get().register;
});
```
`Config.get()` returns the current config object and is not expensive at all
### Add own values to the Config
The default Config is located in [server-util `/src/util/Config.ts`](https://github.com/fosscord/fosscord-server-util/blob/master/src/util/Config.ts) and exports a `interface DefaultOptions` and a `const DefaultOptions` object with reasonable default values.
To add your own values to the config, add the properties to the `interface` with corresponding types and add default values to `const DefaultOptions`.
Also you don't need to worry about updating "old config versions", because new values will automatically be synced with the database.
Note, however, that if the database already has a default value it won't update it.

View File

@ -8,7 +8,8 @@ Everything should be configurable by the user/admin to their security needs.
Once encryption is enabled you can't disable it anymore. _(Plain text channels need be created as such)_
End to end encryption should also be possible on unsupported servers e.g. discord.com. _(through special formatted messages)_
End to end encryption should also be possible on unsupported servers e.g. discord.com. _(through special formatted messages)_
Based on the concept that the server cannot be trusted and could be compromised.
_more coming soon_

View File

@ -1,112 +0,0 @@
## General
All routes are located in the directory ``/src/routes/`` and are loaded on start by a the [lambert-server](https://www.npmjs.com/package/lambert-server) package.
The HTTP API path is generated automatically based on the folder structure, so it is important that you name your files accordingly.
If you want to use URL Params like ``:id`` in e.g. ``/users/:id`` you need to use ``#`` instead of ``:`` for the folder/filename, because of file naming issues on windows.
``index.ts`` files **won't** serve ``/api/index`` and instead alias the parent folder e.g. ``/api/``
Your file needs to default export a [express.Router()](https://expressjs.com/de/4x/api.html#router):
```ts
import { Router } from express
const router = Router();
export default router;
```
Now you can just use any regular express function on the router variable e.g:
```ts
router.get("/", (req, res) => {});
router.post("/", (req, res) => {});
router.get("/members", (req, res) => {});
```
## Authentication
Every request must contain the authorization header except the ``/login`` and ``/register`` route.
You can add additional non-auth routes in [``/src/middlewares/Authentication.ts``](https://github.com/fosscord/fosscord-api/blob/master/src/middlewares/Authentication.ts#L5)
To access the user id for the current request use ``req.user_id``
## Body Validation
We use a custom body validation logic from lambert-server to check if the JSON body is valid.
To import the function from ``/src/util/instanceOf.ts`` use:
```ts
import { check } from "/src/util/instanceOf";
```
Now you can use the [middleware](http://expressjs.com/en/guide/using-middleware.html) ``check`` for your routes by calling check with your Body Schema.
```ts
router.post("/", check(...), (req,res) => {});
```
### Schema
A Schema is a Object Structure with key-value objects that checks if the supplied body is an instance of the specified class.
```ts
{ id: String, roles: [String] }
```
_Notice if you use e.g. BigInt even if you can't supply it with JSON, it will automatically convert the supplied JSON number/string to a BigInt._
_Also if you want to check for an array of, just put the type inside ``[]``_
#### Optional Parameter
You can specify optional parameters if you prefix the key with a ``$`` (dollar sign) e.g.: ``{ $captcha: String }``, this will make the captcha property in the body optional.
#### Limit String length
Additionally import the class ``Length`` from instanceOf and specify the type by making a new ``Length`` Object taking following parameters:
```ts
import { Length } from "/src/util/instanceOf";
const min = 2;
const max = 32;
const type = String;
{ username: new Length(min, max, type) }
```
this will limit the maximum string/number/array length to the ``min`` and ``max`` value.
### Example:
```ts
import { check, Length } from "/src/util/instanceOf";
const SCHEMA = { username: new Length(2, 32, String), age: Number, $posts: [{ title: String }] }
app.post("/", check(SCHEMA), (req, res) => {});
```
## Throw Errors
If the body validation fails it will automatically throw an error.
The ``errors`` structure is a key-value Object describing what field contained the error:
```json
{
"code": 50035,
"message": "Invalid Form Body",
"errors": {
"email": {
"_errors": [
{
"message": "Email is already registered",
"code": "EMAIL_ALREADY_REGISTERED"
}
]
},
"username": {
"_errors": [
{
"message": "Must be between 2 - 32 in length",
"code": "BASE_TYPE_BAD_LENGTH"
}
]
}
}
}
```
To manually throw a ``FieldError`` import ``FieldErrors``
```ts
import { FieldErrors } from /src/util/instanceOf
```
To make sure your errors are understood in all languages translate it with [i18next](https://www.i18next.com/translation-function/essentials) and ``req.t``
So after you have checked the field is invalid throw the ``FieldErrors``
```ts
throw FieldErrors(( login: { message: req.t("auth:login.INVALID_LOGIN"), code: "INVALID_LOGIN" }});
```

View File

@ -1,26 +0,0 @@
## Translation
We use [i18next](https://www.i18next.com/) to manage translation/localization in _some_ API Responses.
The `.json` language files are located in `/locales` and are separated by namespaces.
## Source code
We use [TypeScript](https://www.typescriptlang.org/) (JavaScript with types).
The `.ts` source files are located in `/src/` and will be compiled to `.js` in the `/dist/` directory.
### Middlewares
All Express [Middlewares](http://expressjs.com/en/guide/writing-middleware.html) are in the directory `/src/middlewares/` and need to be manually loaded in `/src/Server.ts`.
### Routes
All Express [Router](http://expressjs.com/en/4x/api.html#router) Routes are in the directory `/src/routes/` and are automatically registered based on the file structure.
### Models
All Database Typescript interface models are in the directory `/src/models/`
### Util
All Utility functions are in the directory `/src/util/`.

View File

Before

Width:  |  Height:  |  Size: 677 KiB

After

Width:  |  Height:  |  Size: 677 KiB

View File

25
docs/client/plugins.md Normal file
View File

@ -0,0 +1,25 @@
# Plugins
## Philosophy
- Plugins are executed in their environment to prevent security issues
- Plugins can create their own UI and loaded in a separate view _(similar to vscode extensions)_
- Plugins can access the component Api and therefore extend the client UI
- Plugins can access the WebSocket Connection/Rest API and intercept/transform events
- Plugins are restricted and can only do actions with the corresponding permission
- Plugins should be accessible through a store that needs to verify the plugins (with dev options to sideload plugins/add other stores)
## Permissions
- Can't access the user's token (token plugins should rather be directly integrated into the client (e.g. account switcher))
- All permissions must meet the purpose of the plugin and must justify why they need the certain permission to be approved
- Shouldn't be able to make any request, except if it:
- Requests permission to access the api of the network
- Requests permission to access a specific domain (e.g. plugins backend)
- Requests permission to access all domains
- Shouldn't be able to intercept events, except if it:
- Requests permission to a specific event(s)
- Requests permission to all events
- Needs to request permission to be able to extend the client's UI
_more coming soon_

11
docs/client/themes.md Normal file
View File

@ -0,0 +1,11 @@
# Themes
## Philosophy
- Themes should look all the same on all platforms
- Themes should be made with an visual theme editor to easily create and edit your own themes
- Themes should be combinable to use multiple themes at once
- Themes should be installable and submit to a Store with voting options
- Guilds should be able to specify their own themes
_more coming soon_

View File

@ -1,7 +0,0 @@
# Contributing
## Setup
Follow the server [setup guide](/setup) to setup the development environment
_Contribution guide coming soon._

384
docs/contributing/server.md Normal file
View File

@ -0,0 +1,384 @@
# Server
## Requirements
Follow the server [setup guide](/setup) to setup the development environment
## Gateway
The Gateway is a WebSocket server that is responsible for listening and emitting events.
You can find the Roadmap overview [here](https://github.com/fosscord/fosscord-gateway/projects/3).
For documentation, head over to the [Discord docs](https://discord.dev). (our own documention is not written yet)
If you want to work on a feature please comment on the corresponding issue so we can assign it you that nobody implements something twice.
For the WebSocket, we use [ws](https://www.npmjs.com/package/ws) and we'll write our own packet handler for the individual opcodes and events.
## API
The API is a HTTP REST server that process requests and manipulates the database.
You can find the api documentation [here](/api/).
You can find the Roadmap overview [here](https://github.com/fosscord/fosscord-server/issues/140).
Every route has its own [issue](https://github.com/fosscord/fosscord-api/issues?q=is%3Aopen+is%3Aissue+label%3ARoute).
If you want to work on a feature please comment on the corresponding issue or write us on our [development server](https://discord.gg/ZrnGQP6p3d) so we can assign and discuss it and nobody implements something twice.
### Structure
You can find the [API directory](https://github.com/fosscord/fosscord-server/tree/master/api) in the [fosscord-server](https://github.com/fosscord/fosscord-server) Github repository.
Inside it you can find:
#### Translation
We use [i18next](https://www.i18next.com/) to manage translation/localization in _some_ API Responses.
The `.json` language files are located in `/api/locales/` and are separated by namespaces.
#### Source code
We use [TypeScript](https://www.typescriptlang.org/) (JavaScript with types).
The `.ts` source files are located in [`/api/src/`](https://github.com/fosscord/fosscord-server/tree/master/api/src) and will be compiled to `.js` in the `/api/dist/` directory.
#### Middlewares
All Express [Middlewares](http://expressjs.com/en/guide/writing-middleware.html) are in [`/api/src/middlewares/`](https://github.com/fosscord/fosscord-server/tree/master/api/src/middlewares) and need to be manually loaded by [`/api/src/Server.ts`](https://github.com/fosscord/fosscord-server/blob/master/api/src/Server.ts).
#### Routes
All Express [Router](http://expressjs.com/en/4x/api.html#router) routes are in [`/api/src/routes/`](https://github.com/fosscord/fosscord-server/tree/master/api/src/routes) and are automatically registered based on the file structure.
#### Models
All database TypeORM entities are located in [`/util/src/entities`](https://github.com/fosscord/fosscord-server/tree/master/util/src/entities)
#### Util
All Utility functions are in the directory `/src/util/` and in [`@fosscord/util`](https://github.com/fosscord/fosscord-server/tree/master/util)
## Configuration
### Philosophy
Every fosscord server instance should be completely configurable in every way, without the need to change the source code.
The config should have reasonable defaults similar to discord.
Only in special cases it should require a third party config value.
The config should be changeable over the admin fosscord-dashboard and update in realtime without the need to restart the servers
The very first time the server starts, it saves to default config in the database. The next start it will load the config from the database.
### Example
You **should not** `get()` the Config in the root of your file and it instead load the config every time you access a value
Import `Config` from fosscord-server-util:
```js
// at the top of the file import the Config file from /src/util/Config.ts
import { Config } from "@fosscord-server-util";
```
Access the Config in your route:
```js
router.get("/", (req: Request, res: Response) => {
// call Config.get() to get the whole config object and then just access the property you want
const { allowNewRegistration } = Config.get().register;
});
```
`Config.get()` returns the current config object and is not expensive at all
### Extending
The default Config is located in [server-util `/src/util/Config.ts`](https://github.com/fosscord/fosscord-server-util/blob/master/src/util/Config.ts) and exports a `interface DefaultOptions` and a `const DefaultOptions` object with reasonable default values.
To add your own values to the config, add the properties to the `interface` with corresponding types and add default values to `const DefaultOptions`.
Also you don't need to worry about updating "old config versions", because new values will automatically be synced with the database.
Note, however, that if the database already has a default value it won't update it.
## Routes
All routes are located in the directory `/src/routes/` and are loaded on start by a the [lambert-server](https://www.npmjs.com/package/lambert-server) package.
The HTTP API path is generated automatically based on the folder structure, so it is important that you name your files accordingly.
If you want to use URL Params like `:id` in e.g. `/users/:id` you need to use `#` instead of `:` for the folder/filename, because of file naming issues on windows.
`index.ts` files **won't** serve `/api/index` and instead alias the parent folder e.g. `/api/`
Your file needs to default export a [express.Router()](https://expressjs.com/de/4x/api.html#router):
```ts
import { Router } from express;
const router = Router();
export default router;
```
Now you can just use any regular express function on the router variable e.g:
```ts
router.get("/", (req, res) => {});
router.post("/", (req, res) => {});
router.get("/members", (req, res) => {});
```
### Authentication
Every request must contain the authorization header except the `/login` and `/register` route.
You can add additional non-auth routes in [`/src/middlewares/Authentication.ts`](https://github.com/fosscord/fosscord-api/blob/master/src/middlewares/Authentication.ts#L5)
To access the user id for the current request use `req.user_id`
### Body Validation
We use a custom body validation logic from lambert-server to check if the JSON body is valid.
To import the function from `/src/util/instanceOf.ts` use:
```ts
import { check } from "/src/util/instanceOf";
```
Now you can use the [middleware](http://expressjs.com/en/guide/using-middleware.html) `check` for your routes by calling check with your Body Schema.
```ts
router.post("/", check(...), (req,res) => {});
```
#### Schema
A Schema is a Object Structure with key-value objects that checks if the supplied body is an instance of the specified class.
```ts
{ id: String, roles: [String] }
```
_Notice if you use e.g. BigInt even if you can't supply it with JSON, it will automatically convert the supplied JSON number/string to a BigInt._
_Also if you want to check for an array of, just put the type inside `[]`_
#### Optional Parameter
You can specify optional parameters if you prefix the key with a `$` (dollar sign) e.g.: `{ $captcha: String }`, this will make the captcha property in the body optional.
#### Limit String length
Additionally import the class `Length` from instanceOf and specify the type by making a new `Length` Object taking following parameters:
```ts
import { Length } from "/src/util/instanceOf";
const min = 2;
const max = 32;
const type = String;
{
username: new Length(min, max, type);
}
```
this will limit the maximum string/number/array length to the `min` and `max` value.
#### Example
```ts
import { check, Length } from "/src/util/instanceOf";
const SCHEMA = { username: new Length(2, 32, String), age: Number, $posts: [{ title: String }] };
app.post("/", check(SCHEMA), (req, res) => {});
```
#### Throw Errors
If the body validation fails it will automatically throw an error.
The `errors` structure is a key-value Object describing what field contained the error:
```json
{
"code": 50035,
"message": "Invalid Form Body",
"errors": {
"email": {
"_errors": [
{
"message": "Email is already registered",
"code": "EMAIL_ALREADY_REGISTERED"
}
]
},
"username": {
"_errors": [
{
"message": "Must be between 2 - 32 in length",
"code": "BASE_TYPE_BAD_LENGTH"
}
]
}
}
}
```
To manually throw a `FieldError` import `FieldErrors`
```ts
import { FieldErrors } from /src/iltu / instanceOf;
```
To make sure your errors are understood in all languages translate it with [i18next](https://www.i18next.com/translation-function/essentials) and `req.t`
So after you have checked the field is invalid throw the `FieldErrors`
```ts
throw FieldErrors(( login: { message: req.t("auth:login.INVALID_LOGIN"), code: "INVALID_LOGIN" }});
```
## Database
### Philosophy
The instance hoster should be able to use any database they want for their specific size and purpose.
That is why we use [typeorm](https://typeorm.io/) for database entities (models) for every data structure we use, because typeorm supports many different database engines.
We use strings for all ids and bitfields (Tho when working with bitfields we convert it to BigInts and pass it to the utility `BitField` class)
### General
Have a look at the [typeorm documentation](https://typeorm.io/) to get familiar with it or watch this [tutorial](https://youtu.be/Paz0gnODPE0).
TypeORM supports MySQL, MariaDB, Postgres, CockroachDB, SQLite, Microsoft SQL Server, Oracle, SAP Hana, sql.js
### Getting Started
Import the entity you want to select, manipulate, delete or insert from `@fosscord/util`
[List of all entities](https://github.com/fosscord/fosscord-server/blob/typeorm/util/src/entities/index.ts): `Application, Attachment, AuditLog, Ban, BaseClass, Channel, Config, ConnectedAccount, Emoji, Guild, Invite, Member, Message, RateLimit, ReadState, Recipient, Relationship, Role, Sticker, Team, TeamMember, Template, User, VoiceState, Webhook`
### Example database query
```ts
import { Guild } from "fosscord-server-util";
await new Guild({ ... }).save(); // inserts a new guild or updates it if it already exists
const guild = await Guild.findOne({ id: "23948723947932" }).exec(); // searches for a guild
await Guild.delete({ owner_id: "34975309473" }) // deletes all guilds of the specific owner
```
### Entities
The typeorm database entities are located in [`util/src/entities/`](https://github.com/fosscord/fosscord-server/tree/master/util/src/entities).
To add your own database entity, create a new file, export the model and import/export it in [`util/src/entities/index.ts`](https://github.com/fosscord/fosscord-server/tree/master/util/src/entities/index.ts).
#### Example entity
```ts
@Entity("users")
export class User extends BaseClass {
// id column is automatically added by BaseClass
@Column()
username: string;
@JoinColumn({ name: "connected_account_ids" })
@OneToMany(() => ConnectedAccount, (account: ConnectedAccount) => account.user)
connected_accounts: ConnectedAccount[];
static async getPublicUser(user_id: string, opts?: FindOneOptions<User>) {
return await User.findOneOrFail(
{ id: user_id },
{ ...opts, select: [...PublicUserProjection, ...(opts?.select || [])] }
);
}
}
```
## Emit Events
Most Routes modify the database and therefore need to inform the clients with events for data changes.
Events are either stored locally if the server was started through the bundle or in RabbitMQ and are distributed to the gateway servers.
You can find all events on the [discord docs page](https://discord.com/developers/docs/topics/gateway#commands-and-events) and in [`util/src/interfaces/Event.ts`](https://github.com/fosscord/fosscord-server/blob/master/util/src/interfaces/Event.ts).
To emit an event import the `emitEvent` function from `@fosscord/util`
```ts
import { emitEvent } from "../../../util/Event";
```
You need to specify whom you want to send the event to, to do that either pass `guild_id`, `user_id` or `channel_id`.
Additionally you need to set the [eventname](https://github.com/fosscord/fosscord-server/blob/typeorm/util/src/interfaces/Event.ts#L465) e.g. `GUILD_DELETE`.
```ts
{
guild_id?: bigint; // specify this if this event should be sent to all guild members
channel_id?: bigint; // specify this if this event should be sent to all channel members
user_id?: bigint; // specify this if this event should be sent to the specific user
event: string; // the EVENTNAME, you can find all gateway event names in the @fosscord/util Events file
data?: any; // event payload data
}
```
For easy intellisense, annotate the parameter with the corresponding [Event interface](https://github.com/fosscord/fosscord-server/blob/typeorm/util/src/interfaces/Event.ts) from `@fosscord/util`:
```ts
import { GuildDeleteEvent } from "@fosscord/util";
emitEvent({...} as GuildDeleteEvent);
```
### Example
Putting it all together:
```ts
await emitEvent({
user_id: "3297349345345874",
event: "GUILD_DELETE",
data: {
id: "96784598743975349",
},
} as GuildDeleteEvent);
```
## Permissions
To get the permission for a guild member import the `getPermission` from `fosscord-server-util`.
```ts
import { getPermission } from "fosscord-server-util";
```
The first argument is the user_id the second the guild_id and the third an optional channel_id
```ts
const permissions = await getPermission(user_id: string, guild_id: string, channel_id?: string)
const permissions = await getPermission("106142653265366125", "4061326832657368175")
```
### Example
```ts
const perms = await getPermission(req.userid, guild_id);
// preferred method: Use this if you want to check if a user lacks a certain permission and abort the operation
perms.hasThrow("MANAGE_GUILD") // will throw an error if the users lacks the permission
if (perms.has("MANAGE_GUILD")) {
...
}
```

View File

@ -1,9 +1,7 @@
# Installation
# UI Framework
- see: [@fosscord/ui](https://www.npmjs.com/package/@fosscord/ui)
# Contribution
## Requirements
You should be familiar with:

View File

@ -1,9 +0,0 @@
# Gateway
### [Status overview](https://github.com/fosscord/fosscord-gateway/projects/3)
This is the fosscord WebSocket Gateway Server.
For documentation, head over to the [Discord docs](https://discord.dev).
If you want to work on a feature please comment on the corresponding issue so we can assign it you that nobody implements something twice.

View File

@ -1 +0,0 @@
For the WebSocket, we use [ws](https://www.npmjs.com/package/ws) and we'll write our own packet handler for the individual opcodes and events.

View File

@ -2,8 +2,7 @@
### What is Fosscord?
Fosscord is a free open source selfhostable chat, voice and video
discord-compatible platform
Fosscord is a free open source selfhostable discord compatible chat, voice and video platform
### Why the name Fosscord?
@ -37,7 +36,7 @@ features, so that it is not opinionated.
### Concept
<img src="img/architecture.png" alt="Architecture">
<img src="assets/architecture.png" alt="Architecture">
### Why backwards compatible to Discord?

View File

@ -1,19 +0,0 @@
## Philosophy
- Plugins are executed in their environment to prevent security issues
- Plugins can create their own UI and loaded in a separate view _(similar to vscode extensions)_
- Plugins can access the component Api and therefore extend the client UI
- Plugins can access the WebSocket Connection/Rest API and intercept/transform events
- Plugins are restricted and can only do actions with the corresponding permission
- Plugins should be accessible through a store that needs to verify the plugins (with dev options to sideload plugins/add other stores)
## Permissions
- Can't access the user's token (token plugins should rather be directly integrated into the client (e.g. account switcher))
- All permissions must meet the purpose of the plugin and must justify why they need the certain permission to be approved
- Shouldn't be able to make any request, except if it:
- Requests permission to access the api of the network
- Requests permission to access a specific domain (e.g. plugins backend)
- Requests permission to access all domains
- Shouldn't be able to intercept events, except if it:
- Requests permission to a specific event(s)
- Requests permission to all events
- Needs to request permission to be able to extend the client's UI

View File

@ -1,12 +1,12 @@
## Links
- [Documentation](https://docs.fosscord.com)
- [Roadmap](https://fosscord.notion.site/2c7fe9e73f9842d3bab3a4912dedd091) (Notion to-do board synced with GitHub issues)
- [Status](https://status.fosscord.com/) (Status page of the offical foscord instance)
- [GitHub](https://github.com/fosscord/) (GitHub organization)
- [OpenCollective](https://opencollective.com/fosscord) (Financially support the project to cover server costs and other expenses)
- [Discord server](https://discord.gg/ZrnGQP6p3d) (for support & organization (If we are finished we'll host our own support server))
- [Tor Hidden Service](http://7jexqzsbqndcsh6y7hybtaf5us5vt7mya7hi4fbi2tid6zazno3h44qd.onion/) (Better privacy for TOR users)
- [Documentation](https://docs.fosscord.com)
- [Roadmap](https://fosscord.notion.site/2c7fe9e73f9842d3bab3a4912dedd091) (Notion to-do board synced with GitHub issues)
- [Status](https://status.fosscord.com/) (Status page of the offical foscord instance)
- [GitHub](https://github.com/fosscord/) (GitHub organization)
- [OpenCollective](https://opencollective.com/fosscord) (Financially support the project to cover server costs and other expenses)
- [Discord server](https://discord.gg/ZrnGQP6p3d) (for support & organization (If we are finished we'll host our own support server))
- [Tor Hidden Service](http://7jexqzsbqndcsh6y7hybtaf5us5vt7mya7hi4fbi2tid6zazno3h44qd.onion/) (Better privacy for TOR users)
## Project structure
@ -17,13 +17,14 @@ Fosscord consists of many repositories, which together make up the client and th
- **[fosscord-server](https://github.com/fosscord/fosscord-api) is the complete Fosscord Server**
Contains:
- [gateway](https://github.com/fosscord/fosscord-server/tree/master/gateway) is the WebSocket Gateway server
- [rtc](https://github.com/fosscord/fosscord-server/tree/master/rtc) will be the rtc server for voice and video sharing.
- [webrtc-server](https://github.com/fosscord/fosscord-server/tree/master/webrtc-server) is a _javascript_ fosscord webrtc server for voice and video communication
- [dashboard](https://github.com/fosscord/fosscord-server/tree/master/dashboard) An admin dashboard for the server (analytics, settings, administration, trust & safety)
- [util](https://github.com/fosscord/fosscord-server/tree/master/server-util) contains all shared logic like Database Models, Utility functions...
- [cdn](https://github.com/fosscord/fosscord-server/tree/master/cdn) is the content-delivery-content (CDN) that stores user uploaded images.
- [api](https://github.com/fosscord/fosscord-server/tree/master/api) a HTTP REST server
- [gateway](https://github.com/fosscord/fosscord-server/tree/master/gateway) a WebSocket Gateway server
- [rtc](https://github.com/fosscord/fosscord-server/tree/master/rtc) a _C++_ webrtc server for voice and video sharing.
- [webrtc-server](https://github.com/fosscord/fosscord-server/tree/master/webrtc-server) a _javascript_ webrtc server for voice and video communication
- [dashboard](https://github.com/fosscord/fosscord-server/tree/master/dashboard) An admin dashboard for the server (analytics, settings, administration, trust & safety)
- [util](https://github.com/fosscord/fosscord-server/tree/master/util) contains all shared logic like Database Models, Utility functions...
- [cdn](https://github.com/fosscord/fosscord-server/tree/master/cdn) is the content-delivery-content (CDN) that stores user uploaded images.
### Client

View File

@ -1,116 +0,0 @@
# Database
## Philosophy
The instance hoster should be able to use any database they want for their specific size and purpose.
That is why we use [typeorm](https://typeorm.io/) for database entities (models) for every data structure we use, because typeorm supports many different database engines.
We use strings for all ids and bitfields (Tho when working with bitfields we convert it to BigInts and pass it to the utility `BitField` class)
## Documentation
Have a look at the [typeorm documentation](https://typeorm.io/) to get familiar with it or watch this [tutorial](https://youtu.be/Paz0gnODPE0).
TypeORM supports MySQL, MariaDB, Postgres, CockroachDB, SQLite, Microsoft SQL Server, Oracle, SAP Hana, sql.js
## Getting Started
Import the entity you want to select, manipulate, delete or insert from `@fosscord/util`
[List of all entities](https://github.com/fosscord/fosscord-server/blob/typeorm/util/src/entities/index.ts): `Application, Attachment, AuditLog, Ban, BaseClass, Channel, Config, ConnectedAccount, Emoji, Guild, Invite, Member, Message, RateLimit, ReadState, Recipient, Relationship, Role, Sticker, Team, TeamMember, Template, User, VoiceState, Webhook`
### Example database query
```ts
import { Guild } from "fosscord-server-util";
await new Guild({ ... }).save(); // inserts a new guild or updates it if it already exists
const guild = await Guild.findOne({ id: "23948723947932" }).exec(); // searches for a guild
await Guild.delete({ owner_id: "34975309473" })
```
## Entities
The typeorm database entities are located in [`util/src/entities/`](https://github.com/fosscord/fosscord-server/tree/master/util/src/entities).
To add your own database entity, create a new file, export the model and import/export it in [`util/src/entities/index.ts`](<(https://github.com/fosscord/fosscord-server/tree/master/util/src/entities/index.ts)>).
### Example entity
```ts
@Entity("users")
export class User extends BaseClass {
// id column is automatically added by BaseClass
@Column()
username: string;
@JoinColumn({ name: "connected_account_ids" })
@OneToMany(() => ConnectedAccount, (account: ConnectedAccount) => account.user)
connected_accounts: ConnectedAccount[];
static async getPublicUser(user_id: string, opts?: FindOneOptions<User>) {
const user = await User.findOne(
{ id: user_id },
{
...opts,
select: [...PublicUserProjection, ...(opts?.select || [])],
}
);
if (!user) throw new HTTPError("User not found", 404);
return user;
}
}
```
## Emit events
Most Routes modify the database and therefore need to inform the clients with events for data changes.
Events are either stored locally if the server was started through the bundle or in RabbitMQ and are distributed to the gateway servers.
You can find all events on the [discord docs page](https://discord.com/developers/docs/topics/gateway#commands-and-events) and in [`util/src/interfaces/Event.ts`](https://github.com/fosscord/fosscord-server/blob/master/util/src/interfaces/Event.ts).
To emit an event import the `emitEvent` function from `@fosscord/util`
```ts
import { emitEvent } from "../../../util/Event";
```
You need to specify whom you want to send the event to, to do that either pass `guild_id`, `user_id` or `channel_id`.
Additionally you need to set the [eventname](https://github.com/fosscord/fosscord-server/blob/typeorm/util/src/interfaces/Event.ts#L465) e.g. `GUILD_DELETE`.
```ts
{
guild_id?: bigint; // specify this if this event should be sent to all guild members
channel_id?: bigint; // specify this if this event should be sent to all channel members
user_id?: bigint; // specify this if this event should be sent to the specific user
event: string; // the EVENTNAME, you can find all gateway event names in the @fosscord/util Events file
data?: any; // event payload data
}
```
For easy intellisense, annotate the parameter with the corresponding [Event interface](https://github.com/fosscord/fosscord-server/blob/typeorm/util/src/interfaces/Event.ts) from `@fosscord/util`:
```ts
import { GuildDeleteEvent } from "@fosscord/util";
emitEvent({...} as GuildDeleteEvent);
```
### Example emit event
Putting it all together:
```ts
await emitEvent({
user_id: "3297349345345874",
event: "GUILD_DELETE",
data: {
id: "96784598743975349",
},
} as GuildDeleteEvent);
```

View File

@ -1,25 +0,0 @@
To get the permission for a guild member import the `getPermission` from `fosscord-server-util`.
```ts
import { getPermission } from "fosscord-server-util";
```
The first argument is the user_id the second the guild_id and the third an optional channel_id
```ts
const permissions = await getPermission(user_id: string, guild_id: string, channel_id?: string)
const permissions = await getPermission("106142653265366125", "4061326832657368175")
```
### Example
```ts
const perms = await getPermission(req.userid, guild_id);
// preferred method: Use this if you want to check if a user lacks a certain permission and abort the operation
perms.hasThrow("MANAGE_GUILD") // will throw an error if the users lacks the permission
if (perms.has("MANAGE_GUILD")) {
...
}
```

View File

@ -1,8 +1,6 @@
# Setup
# Setup Server
## Server
### [Download](https://github.com/fosscord/fosscord-server/releases)
## [Download](https://github.com/fosscord/fosscord-server/releases)
This is the stable fosscord-server release.
@ -12,7 +10,7 @@ Double click the file to start the server. (The first time it takes longer as it
You can now access it on [http://localhost:3001](http://localhost:3001).
### With terminal/shell
## With terminal/shell
This is the latest bleeding edge version of fosscord-server, which may have bugs.
@ -31,7 +29,7 @@ npm start
You can now access it on [http://localhost:3001](http://localhost:3001)
### Docker
## Docker
Optionally if you want to use Docker:
@ -42,9 +40,3 @@ docker-compose up
```
You can now access it on [http://localhost:3001](http://localhost:3001)
## Client
Our client is not ready for the public. _([help contributing](https://github.com/fosscord/fosscord-client))_
However the server already has a discord test client built in, which can be used to access Fosscord.

View File

@ -1,6 +0,0 @@
[Status overview](https://github.com/fosscord/fosscord-ui/projects/2)
This UI Framework includes all _static_ Fosscord CSS Components.
## Usage:
View the [demo](https://ui.fosscord.com/test) and make use of its [source code](https://github.com/fosscord/fosscord-ui).