Merge branch 'master' into feat/embed_improvements

This commit is contained in:
Paul Makles
2021-09-14 20:54:21 +01:00
committed by GitHub
37 changed files with 1049 additions and 882 deletions

View File

@@ -13,14 +13,6 @@ use mongodb::{
use rocket::serde::json::Value;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct LastMessage {
#[serde(rename = "_id")]
id: String,
author: String,
short: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "channel_type")]
pub enum Channel {
@@ -36,7 +28,7 @@ pub enum Channel {
active: bool,
recipients: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
last_message: Option<LastMessage>,
last_message_id: Option<String>,
},
Group {
#[serde(rename = "_id")]
@@ -53,7 +45,7 @@ pub enum Channel {
#[serde(skip_serializing_if = "Option::is_none")]
icon: Option<File>,
#[serde(skip_serializing_if = "Option::is_none")]
last_message: Option<LastMessage>,
last_message_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
permissions: Option<i32>,
@@ -75,7 +67,7 @@ pub enum Channel {
#[serde(skip_serializing_if = "Option::is_none")]
icon: Option<File>,
#[serde(skip_serializing_if = "Option::is_none")]
last_message: Option<String>,
last_message_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
default_permissions: Option<i32>,

View File

@@ -8,15 +8,13 @@ use crate::{
use futures::StreamExt;
use mongodb::options::UpdateOptions;
use mongodb::{
bson::{doc, to_bson, DateTime},
options::FindOptions,
bson::{doc, to_bson, DateTime, Document},
};
use rauth::entities::{Model, Session};
use rocket::serde::json::Value;
use serde::{Deserialize, Serialize};
use ulid::Ulid;
use web_push::{
ContentEncoding, SubscriptionInfo, VapidSignatureBuilder, WebPushClient, WebPushMessageBuilder,
};
use web_push::{ContentEncoding, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder, WebPushClient, WebPushMessageBuilder};
use std::time::SystemTime;
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -173,7 +171,6 @@ impl Message {
nonce: None,
channel,
author,
content,
attachments: None,
edited: None,
@@ -198,76 +195,19 @@ impl Message {
let ss = self.clone();
let c_clone = channel.clone();
async_std::task::spawn(async move {
let mut set = if let Content::Text(text) = &ss.content {
doc! {
"last_message": {
"_id": ss.id.clone(),
"author": ss.author.clone(),
"short": text.chars().take(128).collect::<String>()
}
}
} else {
doc! {}
};
// ! MARK AS ACTIVE
// ! FIXME: temp code
let last_message_id = ss.id.clone();
let mut set = doc! { "last_message_id": last_message_id };
let channels = get_collection("channels");
match &c_clone {
Channel::DirectMessage { id, .. } => {
// ! MARK AS ACTIVE
set.insert("active", true);
channels
.update_one(
doc! { "_id": id },
doc! {
"$set": set
},
None,
)
.await
/*.map_err(|_| Error::DatabaseError {
operation: "update_one",
with: "channel",
})?;*/
.unwrap();
}
Channel::Group { id, .. } => {
if let Content::Text(_) = &ss.content {
channels
.update_one(
doc! { "_id": id },
doc! {
"$set": set
},
None,
)
.await
/*.map_err(|_| Error::DatabaseError {
operation: "update_one",
with: "channel",
})?;*/
.unwrap();
}
}
Channel::TextChannel { id, .. } => {
if let Content::Text(_) = &ss.content {
channels
.update_one(
doc! { "_id": id },
doc! {
"$set": {
"last_message": &ss.id
}
},
None,
)
.await
/*.map_err(|_| Error::DatabaseError {
operation: "update_one",
with: "channel",
})?;*/
.unwrap();
}
update_channels_last_message(&channels, id, &set).await;
},
Channel::Group { id, .. } | Channel::TextChannel { id, .. } => {
update_channels_last_message(&channels, id, &set).await;
}
_ => {}
}
@@ -335,60 +275,47 @@ impl Message {
}
// Fetch their corresponding sessions.
if let Ok(mut cursor) = get_collection("accounts")
.find(
doc! {
"_id": {
"$in": target_ids
},
"sessions.subscription": {
"$exists": true
}
},
FindOptions::builder()
.projection(doc! { "sessions": 1 })
.build(),
)
.await
{
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));
}
}
if target_ids.len() > 0 {
if let Ok(mut cursor) = Session::find(
&get_db(),
doc! {
"_id": {
"$in": target_ids
},
"subscription": {
"$exists": true
}
}
}
}
if subscriptions.len() > 0 {
},
None
)
.await {
let enc = serde_json::to_string(&PushNotification::new(self, &c_clone).await).unwrap();
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();
while let Some(Ok(session)) = cursor.next().await {
if let Some(sub) = session.subscription {
let subscription = SubscriptionInfo {
endpoint: sub.endpoint,
keys: SubscriptionKeys {
auth: sub.auth,
p256dh: sub.p256dh
}
};
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();
}
}
}
}
@@ -482,7 +409,7 @@ impl Message {
let attachment_ids: Vec<String> =
attachments.iter().map(|f| f.id.to_string()).collect();
get_collection("attachments")
.update_one(
.update_many(
doc! {
"_id": {
"$in": attachment_ids
@@ -497,7 +424,7 @@ impl Message {
)
.await
.map_err(|_| Error::DatabaseError {
operation: "update_one",
operation: "update_many",
with: "attachment",
})?;
}
@@ -505,3 +432,15 @@ impl Message {
Ok(())
}
}
async fn update_channels_last_message(channels: &Collection, channel_id: &String, set: &Document) {
channels
.update_one(
doc! { "_id": channel_id },
doc! { "$set": set },
None,
)
.await
.expect("Server should not run with no, or a corrupted db");
}

View File

@@ -47,6 +47,9 @@ pub enum Special {
None,
YouTube {
id: String,
#[serde(skip_serializing_if = "Option::is_none")]
timestamp: Option<String>,
},
Twitch {
content_type: TwitchType,

View File

@@ -92,7 +92,7 @@ pub struct Server {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub channels: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub categories: Option<Vec<Category>>,
@@ -108,6 +108,9 @@ pub struct Server {
#[serde(skip_serializing_if = "Option::is_none")]
pub banner: Option<File>,
#[serde(skip_serializing_if = "Option::is_none")]
pub flags: Option<i32>,
#[serde(skip_serializing_if = "if_false", default)]
pub nsfw: bool
}

View File

@@ -16,6 +16,7 @@ use crate::database::*;
use crate::notifications::websocket::is_online;
use crate::util::result::{Error, Result};
use crate::util::variables::EARLY_ADOPTER_BADGE;
use crate::util::variables::MAX_SERVER_COUNT;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum RelationshipStatus {
@@ -323,4 +324,10 @@ impl User {
.collect::<Vec<Document>>()
.await)
}
/// Check if this user can acquire another server.
pub async fn can_acquire_server(id: &str) -> Result<bool> {
let server_ids = User::fetch_server_ids(&id).await?;
Ok(server_ids.len() < *MAX_SERVER_COUNT)
}
}