forked from jmug/stoatchat
Format code.
This commit is contained in:
@@ -20,42 +20,29 @@ use web_push::{
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum MessageEmbed {
|
||||
Dummy
|
||||
Dummy,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum SystemMessage {
|
||||
#[serde(rename = "text")]
|
||||
Text {
|
||||
content: String
|
||||
},
|
||||
Text { content: String },
|
||||
#[serde(rename = "user_added")]
|
||||
UserAdded {
|
||||
id: String,
|
||||
by: String
|
||||
},
|
||||
UserAdded { id: String, by: String },
|
||||
#[serde(rename = "user_remove")]
|
||||
UserRemove {
|
||||
id: String,
|
||||
by: String
|
||||
},
|
||||
UserRemove { id: String, by: String },
|
||||
#[serde(rename = "user_left")]
|
||||
UserLeft {
|
||||
id: String
|
||||
},
|
||||
UserLeft { id: String },
|
||||
#[serde(rename = "channel_renamed")]
|
||||
ChannelRenamed {
|
||||
name: String,
|
||||
by: String
|
||||
},
|
||||
ChannelRenamed { name: String, by: String },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
pub enum Content {
|
||||
Text(String),
|
||||
SystemMessage(SystemMessage)
|
||||
SystemMessage(SystemMessage),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
@@ -87,7 +74,7 @@ impl Message {
|
||||
content,
|
||||
attachment: None,
|
||||
edited: None,
|
||||
embeds: None
|
||||
embeds: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +161,7 @@ impl Message {
|
||||
}
|
||||
|
||||
// Fetch their corresponding sessions.
|
||||
let mut cursor = get_collection("accounts")
|
||||
if let Ok(mut cursor) = get_collection("accounts")
|
||||
.find(
|
||||
doc! {
|
||||
"_id": {
|
||||
@@ -189,41 +176,43 @@ impl Message {
|
||||
.build(),
|
||||
)
|
||||
.await
|
||||
.unwrap(); // !FIXME
|
||||
{
|
||||
let mut subscriptions = vec![];
|
||||
while let Some(result) = cursor.next().await {
|
||||
if let Ok(doc) = result {
|
||||
if let Ok(sessions) = doc.get_array("sessions") {
|
||||
for session in sessions {
|
||||
if let Some(doc) = session.as_document() {
|
||||
if let Ok(sub) = doc.get_document("subscription") {
|
||||
let endpoint = sub.get_str("endpoint").unwrap().to_string();
|
||||
let p256dh = sub.get_str("p256dh").unwrap().to_string();
|
||||
let auth = sub.get_str("auth").unwrap().to_string();
|
||||
|
||||
let mut subscriptions = vec![];
|
||||
while let Some(result) = cursor.next().await {
|
||||
if let Ok(doc) = result {
|
||||
if let Ok(sessions) = doc.get_array("sessions") {
|
||||
for session in sessions {
|
||||
if let Some(doc) = session.as_document() {
|
||||
if let Ok(sub) = doc.get_document("subscription") {
|
||||
let endpoint = sub.get_str("endpoint").unwrap().to_string();
|
||||
let p256dh = sub.get_str("p256dh").unwrap().to_string();
|
||||
let auth = sub.get_str("auth").unwrap().to_string();
|
||||
|
||||
subscriptions.push(SubscriptionInfo::new(endpoint, p256dh, auth));
|
||||
subscriptions
|
||||
.push(SubscriptionInfo::new(endpoint, p256dh, auth));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if subscriptions.len() > 0 {
|
||||
let client = WebPushClient::new();
|
||||
let key = base64::decode_config(VAPID_PRIVATE_KEY.clone(), base64::URL_SAFE).unwrap();
|
||||
if subscriptions.len() > 0 {
|
||||
let client = WebPushClient::new();
|
||||
let key =
|
||||
base64::decode_config(VAPID_PRIVATE_KEY.clone(), base64::URL_SAFE).unwrap();
|
||||
|
||||
for subscription in subscriptions {
|
||||
let mut builder = WebPushMessageBuilder::new(&subscription).unwrap();
|
||||
let sig_builder =
|
||||
VapidSignatureBuilder::from_pem(std::io::Cursor::new(&key), &subscription)
|
||||
.unwrap();
|
||||
let signature = sig_builder.build().unwrap();
|
||||
builder.set_vapid_signature(signature);
|
||||
builder.set_payload(ContentEncoding::AesGcm, enc.as_bytes());
|
||||
let m = builder.build().unwrap();
|
||||
client.send(m).await.ok();
|
||||
for subscription in subscriptions {
|
||||
let mut builder = WebPushMessageBuilder::new(&subscription).unwrap();
|
||||
let sig_builder =
|
||||
VapidSignatureBuilder::from_pem(std::io::Cursor::new(&key), &subscription)
|
||||
.unwrap();
|
||||
let signature = sig_builder.build().unwrap();
|
||||
builder.set_vapid_signature(signature);
|
||||
builder.set_payload(ContentEncoding::AesGcm, enc.as_bytes());
|
||||
let m = builder.build().unwrap();
|
||||
client.send(m).await.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +244,7 @@ impl Message {
|
||||
"deleted": true
|
||||
}
|
||||
},
|
||||
None
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use mongodb::bson::doc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::options::{Collation, FindOneOptions};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::database::*;
|
||||
use validator::Validate;
|
||||
use crate::util::result::{Error, Result};
|
||||
use crate::notifications::websocket::is_online;
|
||||
use crate::database::permissions::user::UserPermissions;
|
||||
use crate::database::*;
|
||||
use crate::notifications::websocket::is_online;
|
||||
use crate::util::result::{Error, Result};
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
pub enum RelationshipStatus {
|
||||
@@ -37,14 +37,14 @@ pub enum Badge {
|
||||
pub struct UserStatus {
|
||||
#[validate(length(min = 1, max = 128))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
text: Option<String>
|
||||
text: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Validate, Serialize, Deserialize, Debug)]
|
||||
pub struct UserProfile {
|
||||
#[validate(length(min = 1, max = 2000))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
content: Option<String>
|
||||
content: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@@ -54,7 +54,7 @@ pub struct User {
|
||||
pub username: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub relations: Option<Vec<Relationship>>,
|
||||
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub badges: Option<i32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@@ -101,7 +101,7 @@ impl User {
|
||||
/// Utility function for checking claimed usernames.
|
||||
pub async fn is_username_taken(username: &str) -> Result<bool> {
|
||||
if username == "revolt" && username == "admin" {
|
||||
return Ok(true)
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
if get_collection("users")
|
||||
|
||||
@@ -56,7 +56,9 @@ impl<'a> PermissionCalculator<'a> {
|
||||
let perms = self.for_user(recipient).await?;
|
||||
|
||||
if perms.get_send_message() {
|
||||
return Ok(ChannelPermission::View + ChannelPermission::SendMessage + ChannelPermission::VoiceCall);
|
||||
return Ok(ChannelPermission::View
|
||||
+ ChannelPermission::SendMessage
|
||||
+ ChannelPermission::VoiceCall);
|
||||
}
|
||||
|
||||
return Ok(ChannelPermission::View as u32);
|
||||
@@ -71,7 +73,10 @@ impl<'a> PermissionCalculator<'a> {
|
||||
.find(|x| *x == &self.perspective.id)
|
||||
.is_some()
|
||||
{
|
||||
Ok(ChannelPermission::View + ChannelPermission::SendMessage + ChannelPermission::ManageChannel + ChannelPermission::VoiceCall)
|
||||
Ok(ChannelPermission::View
|
||||
+ ChannelPermission::SendMessage
|
||||
+ ChannelPermission::ManageChannel
|
||||
+ ChannelPermission::VoiceCall)
|
||||
} else {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
@@ -26,12 +26,8 @@ pub enum WebSocketError {
|
||||
#[serde(tag = "type")]
|
||||
pub enum ServerboundNotification {
|
||||
Authenticate(Session),
|
||||
BeginTyping {
|
||||
channel: String
|
||||
},
|
||||
EndTyping {
|
||||
channel: String
|
||||
}
|
||||
BeginTyping { channel: String },
|
||||
EndTyping { channel: String },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@@ -71,11 +67,11 @@ pub enum ClientboundNotification {
|
||||
},
|
||||
ChannelStartTyping {
|
||||
id: String,
|
||||
user: String
|
||||
user: String,
|
||||
},
|
||||
ChannelStopTyping {
|
||||
id: String,
|
||||
user: String
|
||||
user: String,
|
||||
},
|
||||
|
||||
UserUpdate {
|
||||
|
||||
@@ -171,7 +171,7 @@ async fn accept(stream: TcpStream) {
|
||||
|
||||
ClientboundNotification::ChannelStartTyping {
|
||||
id: channel.clone(),
|
||||
user
|
||||
user,
|
||||
}
|
||||
.publish(channel)
|
||||
.await
|
||||
@@ -194,7 +194,7 @@ async fn accept(stream: TcpStream) {
|
||||
|
||||
ClientboundNotification::ChannelStopTyping {
|
||||
id: channel.clone(),
|
||||
user
|
||||
user,
|
||||
}
|
||||
.publish(channel)
|
||||
.await
|
||||
|
||||
@@ -102,7 +102,7 @@ pub async fn req(user: User, target: Ref) -> Result<()> {
|
||||
Message::create(
|
||||
"00000000000000000000000000".to_string(),
|
||||
id.clone(),
|
||||
Content::SystemMessage(SystemMessage::UserLeft { id: user.id })
|
||||
Content::SystemMessage(SystemMessage::UserLeft { id: user.id }),
|
||||
)
|
||||
.publish(&target)
|
||||
.await
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::database::*;
|
||||
use crate::util::result::{Error, Result};
|
||||
use crate::notifications::events::ClientboundNotification;
|
||||
use crate::util::result::{Error, Result};
|
||||
|
||||
use mongodb::bson::{doc, to_document};
|
||||
use validator::Validate;
|
||||
use rocket_contrib::json::Json;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Validate, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
@@ -21,9 +21,9 @@ pub struct Data {
|
||||
pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
|
||||
info.validate()
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
|
||||
if info.name.is_none() && info.description.is_none() {
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let target = target.fetch_channel().await?;
|
||||
@@ -31,7 +31,7 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
|
||||
.with_channel(&target)
|
||||
.for_channel()
|
||||
.await?;
|
||||
|
||||
|
||||
if !perm.get_manage_channel() {
|
||||
Err(Error::MissingPermission)?
|
||||
}
|
||||
@@ -49,7 +49,7 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
|
||||
|
||||
ClientboundNotification::ChannelUpdate {
|
||||
id: id.clone(),
|
||||
data: json!(info.0)
|
||||
data: json!(info.0),
|
||||
}
|
||||
.publish(id.clone())
|
||||
.await
|
||||
@@ -59,7 +59,10 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
|
||||
Message::create(
|
||||
"00000000000000000000000000".to_string(),
|
||||
id.clone(),
|
||||
Content::SystemMessage(SystemMessage::ChannelRenamed { name: name.clone(), by: user.id })
|
||||
Content::SystemMessage(SystemMessage::ChannelRenamed {
|
||||
name: name.clone(),
|
||||
by: user.id,
|
||||
}),
|
||||
)
|
||||
.publish(&target)
|
||||
.await
|
||||
@@ -68,6 +71,6 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(Error::InvalidOperation)
|
||||
_ => Err(Error::InvalidOperation),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,10 @@ pub async fn req(user: User, target: Ref, member: Ref) -> Result<()> {
|
||||
Message::create(
|
||||
"00000000000000000000000000".to_string(),
|
||||
id.clone(),
|
||||
Content::SystemMessage(SystemMessage::UserAdded { id: member.id, by: user.id })
|
||||
Content::SystemMessage(SystemMessage::UserAdded {
|
||||
id: member.id,
|
||||
by: user.id,
|
||||
}),
|
||||
)
|
||||
.publish(&channel)
|
||||
.await
|
||||
|
||||
@@ -56,7 +56,10 @@ pub async fn req(user: User, target: Ref, member: Ref) -> Result<()> {
|
||||
Message::create(
|
||||
"00000000000000000000000000".to_string(),
|
||||
id.clone(),
|
||||
Content::SystemMessage(SystemMessage::UserRemove { id: member.id, by: user.id })
|
||||
Content::SystemMessage(SystemMessage::UserRemove {
|
||||
id: member.id,
|
||||
by: user.id,
|
||||
}),
|
||||
)
|
||||
.publish(&channel)
|
||||
.await
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
use crate::database::*;
|
||||
use crate::util::result::{Error, Result};
|
||||
use crate::util::variables::{USE_VOSO, VOSO_URL, VOSO_MANAGE_TOKEN};
|
||||
use crate::util::variables::{USE_VOSO, VOSO_MANAGE_TOKEN, VOSO_URL};
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use rocket_contrib::json::JsonValue;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct CreateUserResponse {
|
||||
token: String
|
||||
token: String,
|
||||
}
|
||||
|
||||
#[post("/<target>/join_call")]
|
||||
pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||
if !*USE_VOSO {
|
||||
return Err(Error::VosoUnavailable)
|
||||
return Err(Error::VosoUnavailable);
|
||||
}
|
||||
|
||||
let target = target.fetch_channel().await?;
|
||||
@@ -21,9 +21,9 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||
.with_channel(&target)
|
||||
.for_channel()
|
||||
.await?;
|
||||
|
||||
|
||||
if !perm.get_voice_call() {
|
||||
return Err(Error::MissingPermission)
|
||||
return Err(Error::MissingPermission);
|
||||
}
|
||||
|
||||
// To join a call:
|
||||
@@ -32,39 +32,51 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||
let client = reqwest::Client::new();
|
||||
let result = client
|
||||
.get(&format!("{}/room/{}", *VOSO_URL, target.id()))
|
||||
.header(reqwest::header::AUTHORIZATION, VOSO_MANAGE_TOKEN.to_string())
|
||||
.header(
|
||||
reqwest::header::AUTHORIZATION,
|
||||
VOSO_MANAGE_TOKEN.to_string(),
|
||||
)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
|
||||
match result {
|
||||
Err(_) => return Err(Error::VosoUnavailable),
|
||||
Ok(result) => {
|
||||
match result.status() {
|
||||
reqwest::StatusCode::OK => (),
|
||||
reqwest::StatusCode::NOT_FOUND => {
|
||||
if let Err(_) = client
|
||||
.post(&format!("{}/room/{}", *VOSO_URL, target.id()))
|
||||
.header(reqwest::header::AUTHORIZATION, VOSO_MANAGE_TOKEN.to_string())
|
||||
.send()
|
||||
.await {
|
||||
return Err(Error::VosoUnavailable)
|
||||
}
|
||||
},
|
||||
_ => return Err(Error::VosoUnavailable)
|
||||
Ok(result) => match result.status() {
|
||||
reqwest::StatusCode::OK => (),
|
||||
reqwest::StatusCode::NOT_FOUND => {
|
||||
if let Err(_) = client
|
||||
.post(&format!("{}/room/{}", *VOSO_URL, target.id()))
|
||||
.header(
|
||||
reqwest::header::AUTHORIZATION,
|
||||
VOSO_MANAGE_TOKEN.to_string(),
|
||||
)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
return Err(Error::VosoUnavailable);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => return Err(Error::VosoUnavailable),
|
||||
},
|
||||
}
|
||||
|
||||
// Then create a user for the room.
|
||||
if let Ok(response) = client
|
||||
.post(&format!("{}/room/{}/user/{}", *VOSO_URL, target.id(), user.id))
|
||||
.header(reqwest::header::AUTHORIZATION, VOSO_MANAGE_TOKEN.to_string())
|
||||
.post(&format!(
|
||||
"{}/room/{}/user/{}",
|
||||
*VOSO_URL,
|
||||
target.id(),
|
||||
user.id
|
||||
))
|
||||
.header(
|
||||
reqwest::header::AUTHORIZATION,
|
||||
VOSO_MANAGE_TOKEN.to_string(),
|
||||
)
|
||||
.send()
|
||||
.await {
|
||||
let res: CreateUserResponse = response.json()
|
||||
.await
|
||||
.map_err(|_| Error::InvalidOperation)?;
|
||||
|
||||
.await
|
||||
{
|
||||
let res: CreateUserResponse = response.json().await.map_err(|_| Error::InvalidOperation)?;
|
||||
|
||||
Ok(json!(res))
|
||||
} else {
|
||||
Err(Error::VosoUnavailable)
|
||||
|
||||
@@ -26,7 +26,7 @@ pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<JsonVal
|
||||
message
|
||||
.validate()
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
|
||||
if message.content.len() == 0 && message.attachment.is_none() {
|
||||
return Err(Error::EmptyMessage);
|
||||
}
|
||||
@@ -119,7 +119,7 @@ pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<JsonVal
|
||||
attachment,
|
||||
nonce: Some(message.nonce.clone()),
|
||||
edited: None,
|
||||
embeds: None
|
||||
embeds: None,
|
||||
};
|
||||
|
||||
msg.clone().publish(&target).await?;
|
||||
|
||||
@@ -28,21 +28,22 @@ pub async fn req(session: Session, user: Option<User>, data: Json<Data>) -> Resu
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
if User::is_username_taken(&data.username).await? {
|
||||
return Err(Error::UsernameTaken)
|
||||
return Err(Error::UsernameTaken);
|
||||
}
|
||||
|
||||
get_collection("users").insert_one(
|
||||
doc! {
|
||||
"_id": session.user_id,
|
||||
"username": &data.username
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "insert_one",
|
||||
with: "user",
|
||||
})?;
|
||||
get_collection("users")
|
||||
.insert_one(
|
||||
doc! {
|
||||
"_id": session.user_id,
|
||||
"username": &data.username
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "insert_one",
|
||||
with: "user",
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::util::variables::{
|
||||
AUTUMN_URL, DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, INVITE_ONLY, USE_AUTUMN, APP_URL,
|
||||
USE_EMAIL, USE_HCAPTCHA, VAPID_PUBLIC_KEY, USE_VOSO, VOSO_URL, VOSO_WS_HOST
|
||||
APP_URL, AUTUMN_URL, DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, INVITE_ONLY,
|
||||
USE_AUTUMN, USE_EMAIL, USE_HCAPTCHA, USE_VOSO, VAPID_PUBLIC_KEY, VOSO_URL, VOSO_WS_HOST,
|
||||
};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use crate::database::*;
|
||||
use crate::util::result::{Error, Result};
|
||||
use crate::notifications::events::ClientboundNotification;
|
||||
use crate::util::result::{Error, Result};
|
||||
|
||||
use mongodb::bson::doc;
|
||||
use rauth::auth::{Auth, Session};
|
||||
use regex::Regex;
|
||||
use mongodb::bson::doc;
|
||||
use rocket::State;
|
||||
use validator::Validate;
|
||||
use rocket_contrib::json::Json;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
// ! FIXME: should be global somewhere; maybe use config(?)
|
||||
lazy_static! {
|
||||
@@ -24,10 +24,15 @@ pub struct Data {
|
||||
}
|
||||
|
||||
#[patch("/username", data = "<data>")]
|
||||
pub async fn req(auth: State<'_, Auth>, session: Session, user: User, data: Json<Data>) -> Result<()> {
|
||||
pub async fn req(
|
||||
auth: State<'_, Auth>,
|
||||
session: Session,
|
||||
user: User,
|
||||
data: Json<Data>,
|
||||
) -> Result<()> {
|
||||
data.validate()
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
|
||||
auth.verify_password(&session, data.password.clone())
|
||||
.await
|
||||
.map_err(|_| Error::InvalidCredentials)?;
|
||||
@@ -35,24 +40,23 @@ pub async fn req(auth: State<'_, Auth>, session: Session, user: User, data: Json
|
||||
let mut set = doc! {};
|
||||
if let Some(username) = &data.username {
|
||||
if User::is_username_taken(&username).await? {
|
||||
return Err(Error::UsernameTaken)
|
||||
return Err(Error::UsernameTaken);
|
||||
}
|
||||
|
||||
set.insert("username", username.clone());
|
||||
}
|
||||
|
||||
|
||||
get_collection("users")
|
||||
.update_one(
|
||||
doc! { "_id": &user.id },
|
||||
doc! { "$set": set },
|
||||
None
|
||||
)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError { operation: "update_one", with: "user" })?;
|
||||
.update_one(doc! { "_id": &user.id }, doc! { "$set": set }, None)
|
||||
.await
|
||||
.map_err(|_| Error::DatabaseError {
|
||||
operation: "update_one",
|
||||
with: "user",
|
||||
})?;
|
||||
|
||||
ClientboundNotification::UserUpdate {
|
||||
id: user.id.clone(),
|
||||
data: json!(data.0)
|
||||
data: json!(data.0),
|
||||
}
|
||||
.publish(user.id.clone())
|
||||
.await
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
use crate::database::*;
|
||||
use crate::util::result::{Error, Result};
|
||||
use crate::notifications::events::ClientboundNotification;
|
||||
use crate::util::result::{Error, Result};
|
||||
|
||||
use mongodb::bson::{doc, to_document};
|
||||
use validator::Validate;
|
||||
use rocket_contrib::json::Json;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Validate, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
status: Option<UserStatus>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
profile: Option<UserProfile>
|
||||
profile: Option<UserProfile>,
|
||||
}
|
||||
|
||||
#[patch("/", data = "<data>")]
|
||||
pub async fn req(user: User, data: Json<Data>) -> Result<()> {
|
||||
data.validate()
|
||||
.map_err(|error| Error::FailedValidation { error })?;
|
||||
|
||||
|
||||
get_collection("users")
|
||||
.update_one(
|
||||
doc! { "_id": &user.id },
|
||||
@@ -31,7 +31,7 @@ pub async fn req(user: User, data: Json<Data>) -> Result<()> {
|
||||
|
||||
ClientboundNotification::UserUpdate {
|
||||
id: user.id.clone(),
|
||||
data: json!(data.0)
|
||||
data: json!(data.0),
|
||||
}
|
||||
.publish(user.id.clone())
|
||||
.await
|
||||
|
||||
@@ -11,7 +11,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
||||
.with_user(&target)
|
||||
.for_user_given()
|
||||
.await?;
|
||||
|
||||
|
||||
if !perm.get_view_profile() {
|
||||
Err(Error::MissingPermission)?
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ lazy_static! {
|
||||
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 VOSO_URL: String =
|
||||
@@ -24,7 +24,7 @@ lazy_static! {
|
||||
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 =
|
||||
|
||||
Reference in New Issue
Block a user