Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
......@@ -2,12 +2,14 @@ use rocket::Route;
mod add_friend;
mod block_user;
mod change_username;
mod edit_user;
mod fetch_dms;
mod fetch_profile;
mod fetch_relationship;
mod fetch_relationships;
mod fetch_user;
mod find_mutual;
mod get_avatar;
mod get_default_avatar;
mod open_dm;
mod remove_friend;
......@@ -17,8 +19,10 @@ pub fn routes() -> Vec<Route> {
routes![
// User Information
fetch_user::req,
edit_user::req,
change_username::req,
get_default_avatar::req,
get_avatar::req,
fetch_profile::req,
// Direct Messaging
fetch_dms::req,
open_dm::req,
......
......@@ -10,6 +10,8 @@ use rocket_contrib::json::JsonValue;
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
let col = get_collection("users");
let target = target.fetch_user().await?;
match get_relationship(&user, &target.id) {
RelationshipStatus::Friend
| RelationshipStatus::Outgoing
......@@ -43,21 +45,27 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
)
) {
Ok(_) => {
try_join!(
ClientboundNotification::UserRelationship {
id: user.id.clone(),
user: target.id.clone(),
status: RelationshipStatus::None
}
.publish(user.id.clone()),
ClientboundNotification::UserRelationship {
id: target.id.clone(),
user: user.id.clone(),
status: RelationshipStatus::None
}
.publish(target.id.clone())
)
.ok();
let target = target
.from_override(&user, RelationshipStatus::None)
.await?;
let user = user
.from_override(&target, RelationshipStatus::None)
.await?;
let target_id = target.id.clone();
ClientboundNotification::UserRelationship {
id: user.id.clone(),
user: target,
status: RelationshipStatus::None,
}
.publish(user.id.clone());
ClientboundNotification::UserRelationship {
id: target_id.clone(),
user,
status: RelationshipStatus::None,
}
.publish(target_id);
Ok(json!({ "status": "None" }))
}
......
......@@ -9,97 +9,103 @@ use rocket_contrib::json::JsonValue;
#[delete("/<target>/block")]
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
let col = get_collection("users");
let target = target.fetch_user().await?;
match get_relationship(&user, &target.id) {
RelationshipStatus::Blocked => {
match get_relationship(&target.fetch_user().await?, &user.id) {
RelationshipStatus::Blocked => {
RelationshipStatus::Blocked => match get_relationship(&target, &user.id) {
RelationshipStatus::Blocked => {
col.update_one(
doc! {
"_id": &user.id,
"relations._id": &target.id
},
doc! {
"$set": {
"relations.$.status": "BlockedOther"
}
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "update_one",
with: "user",
})?;
let target = target
.from_override(&user, RelationshipStatus::BlockedOther)
.await?;
ClientboundNotification::UserRelationship {
id: user.id.clone(),
user: target,
status: RelationshipStatus::BlockedOther,
}
.publish(user.id.clone());
Ok(json!({ "status": "BlockedOther" }))
}
RelationshipStatus::BlockedOther => {
match try_join!(
col.update_one(
doc! {
"_id": &user.id,
"relations._id": &target.id
"_id": &user.id
},
doc! {
"$set": {
"relations.$.status": "BlockedOther"
"$pull": {
"relations": {
"_id": &target.id
}
}
},
None
),
col.update_one(
doc! {
"_id": &target.id
},
doc! {
"$pull": {
"relations": {
"_id": &user.id
}
}
},
None,
None
)
.await
.map_err(|_| Error::DatabaseError {
operation: "update_one",
with: "user",
})?;
ClientboundNotification::UserRelationship {
id: user.id.clone(),
user: target.id.clone(),
status: RelationshipStatus::BlockedOther,
}
.publish(user.id.clone())
.await
.ok();
) {
Ok(_) => {
let target = target
.from_override(&user, RelationshipStatus::None)
.await?;
let user = user
.from_override(&target, RelationshipStatus::None)
.await?;
let target_id = target.id.clone();
Ok(json!({ "status": "BlockedOther" }))
}
RelationshipStatus::BlockedOther => {
match try_join!(
col.update_one(
doc! {
"_id": &user.id
},
doc! {
"$pull": {
"relations": {
"_id": &target.id
}
}
},
None
),
col.update_one(
doc! {
"_id": &target.id
},
doc! {
"$pull": {
"relations": {
"_id": &user.id
}
}
},
None
)
) {
Ok(_) => {
try_join!(
ClientboundNotification::UserRelationship {
id: user.id.clone(),
user: target.id.clone(),
status: RelationshipStatus::None
}
.publish(user.id.clone()),
ClientboundNotification::UserRelationship {
id: target.id.clone(),
user: user.id.clone(),
status: RelationshipStatus::None
}
.publish(target.id.clone())
)
.ok();
ClientboundNotification::UserRelationship {
id: user.id.clone(),
user: target,
status: RelationshipStatus::None,
}
.publish(user.id.clone());
Ok(json!({ "status": "None" }))
ClientboundNotification::UserRelationship {
id: target_id.clone(),
user: user,
status: RelationshipStatus::None,
}
Err(_) => Err(Error::DatabaseError {
operation: "update_one",
with: "user",
}),
.publish(target_id);
Ok(json!({ "status": "None" }))
}
Err(_) => Err(Error::DatabaseError {
operation: "update_one",
with: "user",
}),
}
_ => Err(Error::InternalError),
}
}
_ => Err(Error::InternalError),
},
_ => Err(Error::NoEffect),
}
}
......@@ -3,67 +3,63 @@ use rocket::http::{ContentType, Status};
use rocket::request::Request;
use rocket::response::{self, Responder, Response};
use serde::Serialize;
use snafu::Snafu;
use std::io::Cursor;
use validator::ValidationErrors;
#[derive(Serialize, Debug, Snafu)]
#[derive(Serialize, Debug)]
#[serde(tag = "type")]
pub enum Error {
#[snafu(display("This error has not been labelled."))]
LabelMe,
// ? Onboarding related errors.
#[snafu(display("Already finished onboarding."))]
AlreadyOnboarded,
// ? User related errors.
#[snafu(display("Username has already been taken."))]
UsernameTaken,
#[snafu(display("This user does not exist!"))]
UnknownUser,
#[snafu(display("Already friends with this user."))]
AlreadyFriends,
#[snafu(display("Already sent a request to this user."))]
AlreadySentRequest,
#[snafu(display("You have blocked this user."))]
Blocked,
#[snafu(display("You have been blocked by this user."))]
BlockedByOther,
#[snafu(display("Not friends with target user."))]
NotFriends,
// ? Channel related errors.
#[snafu(display("This channel does not exist!"))]
UnknownChannel,
#[snafu(display("Attachment does not exist!"))]
UnknownAttachment,
#[snafu(display("Cannot edit someone else's message."))]
UnknownMessage,
CannotEditMessage,
#[snafu(display("Cannot remove yourself from a group, use delete channel instead."))]
CannotJoinCall,
TooManyAttachments,
TooManyReplies,
EmptyMessage,
CannotRemoveYourself,
#[snafu(display("Group size is too large."))]
GroupTooLarge { max: usize },
#[snafu(display("User already part of group."))]
GroupTooLarge {
max: usize,
},
AlreadyInGroup,
#[snafu(display("User is not part of the group."))]
NotInGroup,
// ? Server related errors.
UnknownServer,
InvalidRole,
Banned,
// ? General errors.
#[snafu(display("Failed to validate fields."))]
FailedValidation { error: ValidationErrors },
#[snafu(display("Encountered a database error."))]
TooManyIds,
FailedValidation {
error: ValidationErrors,
},
DatabaseError {
operation: &'static str,
with: &'static str,
},
#[snafu(display("Internal server error."))]
InternalError,
#[snafu(display("Operation cannot be performed on this object."))]
MissingPermission,
InvalidOperation,
#[snafu(display("Already created an object with this nonce."))]
InvalidCredentials,
DuplicateNonce,
#[snafu(display("This request had no effect."))]
VosoUnavailable,
NotFound,
NoEffect,
}
......@@ -86,18 +82,32 @@ impl<'r> Responder<'r, 'static> for Error {
Error::NotFriends => Status::Forbidden,
Error::UnknownChannel => Status::NotFound,
Error::UnknownMessage => Status::NotFound,
Error::UnknownAttachment => Status::BadRequest,
Error::CannotEditMessage => Status::Forbidden,
Error::CannotJoinCall => Status::BadRequest,
Error::TooManyAttachments => Status::BadRequest,
Error::TooManyReplies => Status::BadRequest,
Error::EmptyMessage => Status::UnprocessableEntity,
Error::CannotRemoveYourself => Status::BadRequest,
Error::GroupTooLarge { .. } => Status::Forbidden,
Error::AlreadyInGroup => Status::Conflict,
Error::NotInGroup => Status::NotFound,
Error::UnknownServer => Status::NotFound,
Error::InvalidRole => Status::NotFound,
Error::Banned => Status::Forbidden,
Error::FailedValidation { .. } => Status::UnprocessableEntity,
Error::DatabaseError { .. } => Status::InternalServerError,
Error::InternalError => Status::InternalServerError,
Error::MissingPermission => Status::Forbidden,
Error::InvalidOperation => Status::BadRequest,
Error::TooManyIds => Status::BadRequest,
Error::InvalidCredentials => Status::Forbidden,
Error::DuplicateNonce => Status::Conflict,
Error::VosoUnavailable => Status::BadRequest,
Error::NotFound => Status::NotFound,
Error::NoEffect => Status::Ok,
};
......
......@@ -8,22 +8,35 @@ lazy_static! {
pub static ref MONGO_URI: String =
env::var("REVOLT_MONGO_URI").expect("Missing REVOLT_MONGO_URI environment variable.");
pub static ref WS_HOST: String =
env::var("REVOLT_WS_HOST").unwrap_or_else(|_| "0.0.0.0:9000".to_string());
env::var("REVOLT_WS_HOST").unwrap_or_else(|_| "0.0.0.0:9000".to_string());
pub static ref PUBLIC_URL: String =
env::var("REVOLT_PUBLIC_URL").expect("Missing REVOLT_PUBLIC_URL environment variable.");
pub static ref APP_URL: String =
env::var("REVOLT_APP_URL").unwrap_or_else(|_| "https://app.revolt.chat".to_string());
env::var("REVOLT_APP_URL").expect("Missing REVOLT_APP_URL environment variable.");
pub static ref EXTERNAL_WS_URL: String =
env::var("REVOLT_EXTERNAL_WS_URL").expect("Missing REVOLT_EXTERNAL_WS_URL environment variable.");
pub static ref AUTUMN_URL: String =
env::var("AUTUMN_PUBLIC_URL").unwrap_or_else(|_| "https://example.com".to_string());
pub static ref JANUARY_URL: String =
env::var("JANUARY_PUBLIC_URL").unwrap_or_else(|_| "https://example.com".to_string());
pub static ref VOSO_URL: String =
env::var("VOSO_PUBLIC_URL").unwrap_or_else(|_| "https://example.com".to_string());
pub static ref VOSO_WS_HOST: String =
env::var("VOSO_WS_HOST").unwrap_or_else(|_| "wss://example.com".to_string());
pub static ref VOSO_MANAGE_TOKEN: String =
env::var("VOSO_MANAGE_TOKEN").unwrap_or_else(|_| "0".to_string());
pub static ref HCAPTCHA_KEY: String =
env::var("REVOLT_HCAPTCHA_KEY").unwrap_or_else(|_| "0x0000000000000000000000000000000000000000".to_string());
pub static ref HCAPTCHA_SITEKEY: String =
env::var("REVOLT_HCAPTCHA_SITEKEY").unwrap_or_else(|_| "10000000-ffff-ffff-ffff-000000000001".to_string());
pub static ref VAPID_PRIVATE_KEY: String =
env::var("REVOLT_VAPID_PRIVATE_KEY").expect("Missing REVOLT_VAPID_PRIVATE_KEY environment variable.");
pub static ref VAPID_PUBLIC_KEY: String =
env::var("REVOLT_VAPID_PUBLIC_KEY").expect("Missing REVOLT_VAPID_PUBLIC_KEY environment variable.");
// Application Flags
pub static ref DISABLE_REGISTRATION: bool = env::var("REVOLT_DISABLE_REGISTRATION").map_or(false, |v| v == "1");
pub static ref INVITE_ONLY: bool = env::var("REVOLT_INVITE_ONLY").map_or(false, |v| v == "1");
pub static ref USE_EMAIL: bool = env::var("REVOLT_USE_EMAIL_VERIFICATION").map_or(
env::var("REVOLT_SMTP_HOST").is_ok()
......@@ -35,6 +48,8 @@ lazy_static! {
pub static ref USE_HCAPTCHA: bool = env::var("REVOLT_HCAPTCHA_KEY").is_ok();
pub static ref USE_PROMETHEUS: bool = env::var("REVOLT_ENABLE_PROMETHEUS").map_or(false, |v| v == "1");
pub static ref USE_AUTUMN: bool = env::var("AUTUMN_PUBLIC_URL").is_ok();
pub static ref USE_JANUARY: bool = env::var("JANUARY_PUBLIC_URL").is_ok();
pub static ref USE_VOSO: bool = env::var("VOSO_PUBLIC_URL").is_ok() && env::var("VOSO_MANAGE_TOKEN").is_ok();
// SMTP Settings
pub static ref SMTP_HOST: String =
......@@ -48,9 +63,19 @@ lazy_static! {
// Application Logic Settings
pub static ref MAX_GROUP_SIZE: usize =
env::var("REVOLT_MAX_GROUP_SIZE").unwrap_or_else(|_| "50".to_string()).parse().unwrap();
pub static ref EARLY_ADOPTER_BADGE: i64 =
env::var("REVOLT_EARLY_ADOPTER_BADGE").unwrap_or_else(|_| "0".to_string()).parse().unwrap();
}
pub fn preflight_checks() {
format!("{}", *APP_URL);
format!("{}", *MONGO_URI);
format!("{}", *PUBLIC_URL);
format!("{}", *EXTERNAL_WS_URL);
format!("{}", *VAPID_PRIVATE_KEY);
format!("{}", *VAPID_PUBLIC_KEY);
if *USE_EMAIL == false {
#[cfg(not(debug_assertions))]
if !env::var("REVOLT_UNSAFE_NO_EMAIL").map_or(false, |v| v == *"1") {
......
pub const VERSION: &str = "0.5.1-alpha.21";