Compare commits

..
14 Commits
32 changed files with 223 additions and 99 deletions
+37
View File
@@ -0,0 +1,37 @@
name: Build documentation
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write # To push a branch
pages: write # To push to a GitHub Pages site
id-token: write # To update the deployment status
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install latest mdbook
run: |
tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name')
url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz"
mkdir mdbook
curl -sSL $url | tar -xz --directory=./mdbook
echo `pwd`/mdbook >> $GITHUB_PATH
- name: Build Book
run: |
cd doc
mdbook build
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: "doc/book"
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
-36
View File
@@ -1,36 +0,0 @@
name: "CLA Assistant"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]
jobs:
CLAssistant:
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
# Beta Release
uses: cla-assistant/github-action@v2.1.3-beta
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# the below token should have repo scope and must be manually added by you in the repository's secret
PERSONAL_ACCESS_TOKEN : ${{ secrets.PAT }}
with:
path-to-signatures: 'signatures/version1/cla.json'
path-to-document: 'https://github.com/revoltchat/cla/blob/master/CLA.md' # e.g. a CLA or a DCO document
# branch should not be protected
branch: 'master'
allowlist: insertish,bot*
#below are the optional inputs - If the optional inputs are not given, then default values will be taken
remote-organization-name: revoltchat
remote-repository-name: cla
create-file-commit-message: 'cla(create): creating file for storing CLA Signatures'
signed-commit-message: 'cla(sign): $contributorName has signed the CLA in #$pullRequestNo'
#custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
#custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
#custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'
#lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true)
#use-dco-flag: true - If you are using DCO instead of CLA
+1
View File
@@ -10,6 +10,7 @@ on:
- ".github/**"
- "!.github/workflows/docker.yml"
- ".vscode/**"
- "doc/**"
- ".gitignore"
- "LICENSE"
- "README"
+8
View File
@@ -2,6 +2,14 @@ name: Rust build, test, and generate specification
on:
push:
paths-ignore:
- ".github/**"
- "!.github/workflows/rust.yaml"
- ".vscode/**"
- "doc/**"
- ".gitignore"
- "LICENSE"
- "README"
pull_request:
branches: [main]
Generated
+8 -8
View File
@@ -3408,7 +3408,7 @@ dependencies = [
[[package]]
name = "revolt-bonfire"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"async-std",
"async-tungstenite",
@@ -3435,7 +3435,7 @@ dependencies = [
[[package]]
name = "revolt-config"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"async-std",
"cached",
@@ -3451,7 +3451,7 @@ dependencies = [
[[package]]
name = "revolt-database"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"async-lock",
"async-recursion",
@@ -3497,7 +3497,7 @@ dependencies = [
[[package]]
name = "revolt-delta"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"async-channel",
"async-std",
@@ -3543,7 +3543,7 @@ dependencies = [
[[package]]
name = "revolt-models"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"indexmap",
"iso8601-timestamp 0.2.11",
@@ -3560,7 +3560,7 @@ dependencies = [
[[package]]
name = "revolt-permissions"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"async-std",
"async-trait",
@@ -3575,7 +3575,7 @@ dependencies = [
[[package]]
name = "revolt-presence"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"async-std",
"log",
@@ -3586,7 +3586,7 @@ dependencies = [
[[package]]
name = "revolt-result"
version = "0.7.1"
version = "0.7.2"
dependencies = [
"revolt_okapi",
"revolt_rocket_okapi",
-1
View File
@@ -19,7 +19,6 @@ RUN sh /tmp/build-image-layer.sh tools
COPY Cargo.toml Cargo.lock ./
COPY crates/bonfire/Cargo.toml ./crates/bonfire/
COPY crates/delta/Cargo.toml ./crates/delta/
COPY crates/quark/Cargo.toml ./crates/quark/
COPY crates/core/config/Cargo.toml ./crates/core/config/
COPY crates/core/database/Cargo.toml ./crates/core/database/
COPY crates/core/models/Cargo.toml ./crates/core/models/
-1
View File
@@ -15,7 +15,6 @@ COPY scripts/build-image-layer.sh /tmp/
COPY Cargo.toml Cargo.lock ./
COPY crates/bonfire/Cargo.toml ./crates/bonfire/
COPY crates/delta/Cargo.toml ./crates/delta/
COPY crates/quark/Cargo.toml ./crates/quark/
COPY crates/core/config/Cargo.toml ./crates/core/config/
COPY crates/core/database/Cargo.toml ./crates/core/database/
COPY crates/core/models/Cargo.toml ./crates/core/models/
+10 -11
View File
@@ -2,17 +2,16 @@
This is a monorepo for the Revolt backend.
| Crate | Path | Description |
| ------------------ | -------------------------------------------------- | --------------------------------- |
| `core/config` | [crates/core/config](crates/core/config) | Core: Configuration |
| `core/database` | [crates/core/database](crates/core/database) | Core: Database Implementation |
| `core/models` | [crates/core/models](crates/core/models) | Core: API Models |
| `core/permissions` | [crates/core/permissions](crates/core/permissions) | Core: Permission Logic |
| `core/presence` | [crates/core/presence](crates/core/presence) | Core: User Presence |
| `core/result` | [crates/core/result](crates/core/result) | Core: Result and Error types |
| `delta` | [crates/delta](crates/delta) | REST API server |
| `bonfire` | [crates/bonfire](crates/bonfire) | WebSocket events server |
| `quark` | [crates/quark](crates/quark) | Models and logic (**DEPRECATED**) |
| Crate | Path | Description |
| ------------------ | -------------------------------------------------- | ----------------------------- |
| `core/config` | [crates/core/config](crates/core/config) | Core: Configuration |
| `core/database` | [crates/core/database](crates/core/database) | Core: Database Implementation |
| `core/models` | [crates/core/models](crates/core/models) | Core: API Models |
| `core/permissions` | [crates/core/permissions](crates/core/permissions) | Core: Permission Logic |
| `core/presence` | [crates/core/presence](crates/core/presence) | Core: User Presence |
| `core/result` | [crates/core/result](crates/core/result) | Core: Result and Error types |
| `delta` | [crates/delta](crates/delta) | REST API server |
| `bonfire` | [crates/bonfire](crates/bonfire) | WebSocket events server |
Note: `january`, `autumn`, and `vortex` are yet to be moved into this monorepo.
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-bonfire"
version = "0.7.1"
version = "0.7.2"
license = "AGPL-3.0-or-later"
edition = "2021"
@@ -38,7 +38,7 @@ revolt-result = { path = "../core/result" }
revolt-models = { path = "../core/models" }
revolt-config = { path = "../core/config" }
revolt-database = { path = "../core/database" }
revolt-permissions = { version = "0.7.1", path = "../core/permissions" }
revolt-permissions = { version = "0.7.2", path = "../core/permissions" }
revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] }
# redis
+1 -1
View File
@@ -15,7 +15,7 @@ mod websocket;
#[async_std::main]
async fn main() {
// Configure requirements for Bonfire.
revolt_config::configure!();
revolt_config::configure!(events);
database::connect().await;
// Clean up the current region information.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-config"
version = "0.7.1"
version = "0.7.2"
edition = "2021"
license = "AGPL-3.0-or-later"
authors = ["Paul Makles <me@insrt.uk>"]
+4 -3
View File
@@ -1,5 +1,3 @@
sentry_dsn = ""
[database]
mongodb = "mongodb://database"
redis = "redis://redis/"
@@ -14,7 +12,6 @@ voso_legacy = ""
voso_legacy_ws = ""
[api]
staging = false
[api.registration]
invite_only = false
@@ -68,3 +65,7 @@ background_size = 6000000
icon_size = 2500000
banner_size = 6000000
emoji_size = 500000
[sentry]
api = ""
events = ""
+19 -12
View File
@@ -6,6 +6,9 @@ use futures_locks::RwLock;
use once_cell::sync::Lazy;
use serde::Deserialize;
#[cfg(not(debug_assertions))]
use std::env;
static CONFIG_BUILDER: Lazy<RwLock<Config>> = Lazy::new(|| {
RwLock::new({
let mut builder = Config::builder().add_source(File::from_str(
@@ -93,7 +96,6 @@ pub struct ApiWorkers {
#[derive(Deserialize, Debug, Clone)]
pub struct Api {
pub staging: bool,
pub registration: ApiRegistration,
pub smtp: ApiSmtp,
pub vapid: ApiVapid,
@@ -138,13 +140,19 @@ pub struct Features {
pub webhooks_enabled: bool,
}
#[derive(Deserialize, Debug, Clone)]
pub struct Sentry {
pub api: String,
pub events: String,
}
#[derive(Deserialize, Debug, Clone)]
pub struct Settings {
pub database: Database,
pub hosts: Hosts,
pub api: Api,
pub features: Features,
pub sentry_dsn: String,
pub sentry: Sentry,
}
impl Settings {
@@ -188,7 +196,7 @@ pub async fn config() -> Settings {
}
/// Configure logging and common Rust variables
pub async fn setup_logging(release: &'static str) -> Option<sentry::ClientInitGuard> {
pub async fn setup_logging(release: &'static str, dsn: String) -> Option<sentry::ClientInitGuard> {
dotenv::dotenv().ok();
if std::env::var("RUST_LOG").is_err() {
@@ -202,12 +210,11 @@ pub async fn setup_logging(release: &'static str) -> Option<sentry::ClientInitGu
pretty_env_logger::init();
log::info!("Starting {release}");
let config = config().await;
if config.sentry_dsn.is_empty() {
if dsn.is_empty() {
None
} else {
Some(sentry::init((
config.sentry_dsn,
dsn,
sentry::ClientOptions {
release: Some(release.into()),
..Default::default()
@@ -218,12 +225,12 @@ pub async fn setup_logging(release: &'static str) -> Option<sentry::ClientInitGu
#[macro_export]
macro_rules! configure {
() => {
let _sentry = $crate::setup_logging(concat!(
env!("CARGO_PKG_NAME"),
"@",
env!("CARGO_PKG_VERSION")
))
($application: ident) => {
let config = $crate::config().await;
let _sentry = $crate::setup_logging(
concat!(env!("CARGO_PKG_NAME"), "@", env!("CARGO_PKG_VERSION")),
config.sentry.$application,
)
.await;
};
}
+6 -6
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-database"
version = "0.7.1"
version = "0.7.2"
edition = "2021"
license = "AGPL-3.0-or-later"
authors = ["Paul Makles <me@insrt.uk>"]
@@ -23,13 +23,13 @@ default = ["mongodb", "async-std-runtime", "tasks"]
[dependencies]
# Core
revolt-config = { version = "0.7.1", path = "../config" }
revolt-result = { version = "0.7.1", path = "../result" }
revolt-models = { version = "0.7.1", path = "../models", features = [
revolt-config = { version = "0.7.2", path = "../config" }
revolt-result = { version = "0.7.2", path = "../result" }
revolt-models = { version = "0.7.2", path = "../models", features = [
"validator",
] }
revolt-presence = { version = "0.7.1", path = "../presence" }
revolt-permissions = { version = "0.7.1", path = "../permissions", features = [
revolt-presence = { version = "0.7.2", path = "../presence" }
revolt-permissions = { version = "0.7.2", path = "../permissions", features = [
"serde",
"bson",
] }
@@ -5,8 +5,9 @@ use crate::{
bson::{doc, from_bson, from_document, to_document, Bson, DateTime, Document},
options::FindOptions,
},
MongoDb, DISCRIMINATOR_SEARCH_SPACE,
Invite, MongoDb, DISCRIMINATOR_SEARCH_SPACE,
};
use bson::oid::ObjectId;
use futures::StreamExt;
use rand::seq::SliceRandom;
use revolt_permissions::DEFAULT_WEBHOOK_PERMISSIONS;
@@ -19,7 +20,7 @@ struct MigrationInfo {
revision: i32,
}
pub const LATEST_REVISION: i32 = 26;
pub const LATEST_REVISION: i32 = 27;
pub async fn migrate_database(db: &MongoDb) {
let migrations = db.col::<Document>("migrations");
@@ -983,6 +984,93 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 {
.expect("Failed to create ratelimit_events index.");
}
if revision <= 26 {
info!("Running migration [revision 26 / 15-05-2024]: fix invites being incorrectly serialized with wrong enum tagging.");
auto_derived!(
pub enum OldInvite {
Server {
#[serde(rename = "_id")]
code: String,
server: String,
creator: String,
channel: String,
},
Group {
#[serde(rename = "_id")]
code: String,
creator: String,
channel: String,
},
}
);
#[derive(serde::Serialize, serde::Deserialize)]
struct Outer {
_id: ObjectId,
#[serde(flatten)]
invite: OldInvite,
}
let invites = db
.db()
.collection::<Outer>("channel_invites")
.find(
doc! {
"type": { "$exists": false }
},
None,
)
.await
.expect("failed to find invites")
.filter_map(|s| async { s.ok() })
.collect::<Vec<Outer>>()
.await
.into_iter()
.map(|invite| match invite.invite {
OldInvite::Server {
code,
server,
creator,
channel,
} => Invite::Server {
code,
server,
creator,
channel,
},
OldInvite::Group {
code,
creator,
channel,
} => Invite::Group {
code,
creator,
channel,
},
})
.collect::<Vec<Invite>>();
if !invites.is_empty() {
db.db()
.collection("channel_invites")
.insert_many(invites, None)
.await
.expect("failed to insert corrected invite");
db.db()
.collection::<Outer>("channel_invites")
.delete_many(
doc! {
"type": { "$exists": false }
},
None,
)
.await
.expect("failed to find invites");
}
}
// Need to migrate fields on attachments, change `user_id`, `object_id`, etc to `parent`.
// Reminder to update LATEST_REVISION when adding new migrations.
@@ -10,6 +10,7 @@ static ALPHABET: [char; 54] = [
auto_derived!(
/// Invite
#[serde(tag = "type")]
pub enum Invite {
/// Invite to a specific server channel
Server {
@@ -284,7 +284,7 @@ impl User {
db.fetch_user(
&db.fetch_bot_by_token(token)
.await
.map_err(|_| create_error!(InternalError))?
.map_err(|_| create_error!(InvalidSession))?
.id,
)
.await
@@ -60,7 +60,7 @@ impl AbstractUsers for MongoDb {
.map_err(|_| create_database_error!("find_one", "sessions"))?
.ok_or_else(|| create_error!(InvalidSession))?;
self.fetch_user(&session.id).await
self.fetch_user(&session.user_id).await
}
/// Fetch multiple users by their ids
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-models"
version = "0.7.1"
version = "0.7.2"
edition = "2021"
license = "AGPL-3.0-or-later"
authors = ["Paul Makles <me@insrt.uk>"]
@@ -19,8 +19,8 @@ default = ["serde", "partials", "rocket"]
[dependencies]
# Core
revolt-config = { version = "0.7.1", path = "../config" }
revolt-permissions = { version = "0.7.1", path = "../permissions" }
revolt-config = { version = "0.7.2", path = "../config" }
revolt-permissions = { version = "0.7.2", path = "../permissions" }
# Utility
regex = "1"
@@ -2,6 +2,7 @@ use super::{Channel, File, Server, User};
auto_derived!(
/// Invite
#[serde(tag = "type")]
pub enum Invite {
/// Invite to a specific server channel
Server {
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-permissions"
version = "0.7.1"
version = "0.7.2"
edition = "2021"
license = "AGPL-3.0-or-later"
authors = ["Paul Makles <me@insrt.uk>"]
@@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] }
[dependencies]
# Core
revolt-result = { version = "0.7.1", path = "../result" }
revolt-result = { version = "0.7.2", path = "../result" }
# Utility
auto_ops = "0.3.0"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-presence"
version = "0.7.1"
version = "0.7.2"
edition = "2021"
license = "AGPL-3.0-or-later"
authors = ["Paul Makles <me@insrt.uk>"]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-result"
version = "0.7.1"
version = "0.7.2"
edition = "2021"
license = "AGPL-3.0-or-later"
authors = ["Paul Makles <me@insrt.uk>"]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "revolt-delta"
version = "0.7.1"
version = "0.7.2"
license = "AGPL-3.0-or-later"
authors = ["Paul Makles <paulmakles@gmail.com>"]
edition = "2018"
+1 -1
View File
@@ -194,7 +194,7 @@ pub async fn authifier_config() -> AuthifierConfig {
#[launch]
async fn rocket() -> _ {
// Configure logging and environment
revolt_config::configure!();
revolt_config::configure!(api);
// Start web server
web().await
+3
View File
@@ -31,6 +31,9 @@ in pkgs.mkShell {
pkgs.rustfmt
pkgs.pkgconfig
pkgs.openssl.dev
# mdbook
pkgs.mdbook
];
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
+1
View File
@@ -0,0 +1 @@
book
+6
View File
@@ -0,0 +1,6 @@
[book]
authors = []
language = "en"
multilingual = false
src = "src"
title = "Revolt Backend"
+7
View File
@@ -0,0 +1,7 @@
# Summary
- [Introduction](./hello.md)
- [Project Structure]()
- [Testing]()
- [Writing a new database test]()
- [Writing a new API test]()
+5
View File
@@ -0,0 +1,5 @@
# Revolt Backend
Welcome to the developer documentation for the Revolt backend.
This is very much incomplete and needs more work!
-3
View File
@@ -24,7 +24,6 @@ deps() {
mkdir -p \
crates/bonfire/src \
crates/delta/src \
crates/quark/src \
crates/core/config/src \
crates/core/database/src \
crates/core/models/src \
@@ -35,7 +34,6 @@ deps() {
tee crates/bonfire/src/main.rs |
tee crates/delta/src/main.rs
echo '' |
tee crates/quark/src/lib.rs |
tee crates/core/config/src/lib.rs |
tee crates/core/database/src/lib.rs |
tee crates/core/models/src/lib.rs |
@@ -54,7 +52,6 @@ apps() {
touch -am \
crates/bonfire/src/main.rs \
crates/delta/src/main.rs \
crates/quark/src/lib.rs \
crates/core/config/src/lib.rs \
crates/core/database/src/lib.rs \
crates/core/models/src/lib.rs \
Regular → Executable
+1 -1
View File
@@ -11,7 +11,7 @@ echo "[profile.release]" >> Cargo.toml
echo "debug = true" >> Cargo.toml
TAG=$1-debug
echo "Building images, will tag for ghcr.io with $TAG-debug!"
echo "Building images, will tag for ghcr.io with $TAG!"
docker build -t ghcr.io/revoltchat/base:latest -f Dockerfile.useCurrentArch .
docker build -t ghcr.io/revoltchat/server:$TAG - < crates/delta/Dockerfile
docker build -t ghcr.io/revoltchat/bonfire:$TAG - < crates/bonfire/Dockerfile