Basic Web Push support.
This commit is contained in:
66
Cargo.lock
generated
66
Cargo.lock
generated
@@ -243,6 +243,16 @@ version = "0.2.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
|
checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5032d51da2741729bfdaeb2664d9b8c6d9fd1e2b90715c660b6def36628499c2"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"safemem",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@@ -686,6 +696,15 @@ dependencies = [
|
|||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "erased-serde"
|
||||||
|
version = "0.3.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0465971a8cc1fa2455c8465aaa377131e1f1cf4983280f474a13e68793aa770c"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "err-derive"
|
name = "err-derive"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@@ -2454,10 +2473,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "revolt"
|
name = "revolt"
|
||||||
version = "0.3.3-alpha.5"
|
version = "0.3.3-alpha.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
"async-std",
|
||||||
"async-tungstenite",
|
"async-tungstenite",
|
||||||
|
"base64 0.13.0",
|
||||||
"bitfield",
|
"bitfield",
|
||||||
"chrono",
|
"chrono",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
@@ -2489,6 +2509,7 @@ dependencies = [
|
|||||||
"ulid",
|
"ulid",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
"validator",
|
"validator",
|
||||||
|
"web-push",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2501,7 +2522,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"spin",
|
"spin",
|
||||||
"untrusted",
|
"untrusted 0.7.1",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
@@ -2673,6 +2694,12 @@ version = "1.0.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "safemem"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schannel"
|
name = "schannel"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
@@ -2705,7 +2732,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
|
checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"untrusted",
|
"untrusted 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3477,6 +3504,12 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -3678,6 +3711,31 @@ version = "0.2.70"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
|
checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-push"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8353dd6c7cfb9a02737fd6dc9a66a80dca2a93fb690f6ad264d2a7672e6f1c0"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.7.0",
|
||||||
|
"chrono",
|
||||||
|
"erased-serde",
|
||||||
|
"futures",
|
||||||
|
"http",
|
||||||
|
"hyper",
|
||||||
|
"hyper-tls",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"native-tls",
|
||||||
|
"openssl",
|
||||||
|
"ring",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"time 0.1.44",
|
||||||
|
"untrusted 0.6.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.47"
|
version = "0.3.47"
|
||||||
@@ -3695,7 +3753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"untrusted",
|
"untrusted 0.7.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "revolt"
|
name = "revolt"
|
||||||
version = "0.3.3-alpha.5"
|
version = "0.3.3-alpha.6"
|
||||||
authors = ["Paul Makles <paulmakles@gmail.com>"]
|
authors = ["Paul Makles <paulmakles@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
base64 = "0.13.0"
|
||||||
futures = "0.3.8"
|
futures = "0.3.8"
|
||||||
impl_ops = "0.1.1"
|
impl_ops = "0.1.1"
|
||||||
|
web-push = "0.7.2"
|
||||||
many-to-many = "0.1.2"
|
many-to-many = "0.1.2"
|
||||||
ctrlc = { version = "3.0", features = ["termination"] }
|
ctrlc = { version = "3.0", features = ["termination"] }
|
||||||
async-std = { version = "1.8.0", features = ["tokio02", "attributes"] }
|
async-std = { version = "1.8.0", features = ["tokio02", "attributes"] }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
@@ -17,5 +17,5 @@ pub struct File {
|
|||||||
metadata: Metadata,
|
metadata: Metadata,
|
||||||
content_type: String,
|
content_type: String,
|
||||||
|
|
||||||
message_id: Option<String>
|
message_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ pub enum Channel {
|
|||||||
impl Channel {
|
impl Channel {
|
||||||
pub fn id(&self) -> &str {
|
pub fn id(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
Channel::SavedMessages { id, .. } => id,
|
Channel::SavedMessages { id, .. }
|
||||||
Channel::DirectMessage { id, .. } => id,
|
| Channel::DirectMessage { id, .. }
|
||||||
Channel::Group { id, .. } => id,
|
| Channel::Group { id, .. } => id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
|
use crate::util::variables::VAPID_PRIVATE_KEY;
|
||||||
use crate::{
|
use crate::{
|
||||||
database::*,
|
database::*,
|
||||||
notifications::events::ClientboundNotification,
|
notifications::{events::ClientboundNotification, websocket::is_online},
|
||||||
util::result::{Error, Result},
|
util::result::{Error, Result},
|
||||||
};
|
};
|
||||||
use mongodb::bson::{doc, to_bson, DateTime};
|
|
||||||
|
use futures::StreamExt;
|
||||||
|
use mongodb::{
|
||||||
|
bson::{doc, to_bson, DateTime},
|
||||||
|
options::FindOptions,
|
||||||
|
};
|
||||||
use rocket_contrib::json::JsonValue;
|
use rocket_contrib::json::JsonValue;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
|
use web_push::{ContentEncoding, SubscriptionInfo, VapidSignatureBuilder, WebPushClient, WebPushMessageBuilder};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
@@ -49,7 +56,7 @@ impl Message {
|
|||||||
|
|
||||||
// ! FIXME: temp code
|
// ! FIXME: temp code
|
||||||
let channels = get_collection("channels");
|
let channels = get_collection("channels");
|
||||||
match channel {
|
match &channel {
|
||||||
Channel::DirectMessage { id, .. } => {
|
Channel::DirectMessage { id, .. } => {
|
||||||
channels
|
channels
|
||||||
.update_one(
|
.update_one(
|
||||||
@@ -96,11 +103,84 @@ impl Message {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let enc = serde_json::to_string(&self).unwrap();
|
||||||
ClientboundNotification::Message(self)
|
ClientboundNotification::Message(self)
|
||||||
.publish(channel.id().to_string())
|
.publish(channel.id().to_string())
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Web Push Test Code
|
||||||
|
! FIXME: temp code
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Find all offline users.
|
||||||
|
let mut target_ids = vec![];
|
||||||
|
match &channel {
|
||||||
|
Channel::DirectMessage { recipients, .. } | Channel::Group { recipients, .. } => {
|
||||||
|
for recipient in recipients {
|
||||||
|
// if !is_online(recipient) {
|
||||||
|
target_ids.push(recipient.clone());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch their corresponding sessions.
|
||||||
|
let mut cursor = get_collection("accounts")
|
||||||
|
.find(
|
||||||
|
doc! {
|
||||||
|
"_id": {
|
||||||
|
"$in": target_ids
|
||||||
|
},
|
||||||
|
"sessions.subscription": {
|
||||||
|
"$exists": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
FindOptions::builder()
|
||||||
|
.projection(doc! { "sessions": 1 })
|
||||||
|
.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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
let response = client.send(m).await.unwrap();
|
||||||
|
dbg!(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
mod autumn;
|
||||||
mod channel;
|
mod channel;
|
||||||
mod guild;
|
mod guild;
|
||||||
mod message;
|
mod message;
|
||||||
mod user;
|
mod user;
|
||||||
mod autumn;
|
|
||||||
|
|
||||||
|
pub use autumn::*;
|
||||||
pub use channel::*;
|
pub use channel::*;
|
||||||
pub use guild::*;
|
pub use guild::*;
|
||||||
pub use message::*;
|
pub use message::*;
|
||||||
pub use user::*;
|
pub use user::*;
|
||||||
pub use autumn::*;
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
ids: Vec<String>
|
ids: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/<target>/messages/stale", data = "<data>")]
|
#[post("/<target>/messages/stale", data = "<data>")]
|
||||||
@@ -35,7 +35,7 @@ pub async fn req(user: User, target: Ref, data: Json<Options>) -> Result<JsonVal
|
|||||||
},
|
},
|
||||||
"channel": target.id()
|
"channel": target.id()
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError {
|
.map_err(|_| Error::DatabaseError {
|
||||||
@@ -47,12 +47,11 @@ pub async fn req(user: User, target: Ref, data: Json<Options>) -> Result<JsonVal
|
|||||||
let mut found_ids = vec![];
|
let mut found_ids = vec![];
|
||||||
while let Some(result) = cursor.next().await {
|
while let Some(result) = cursor.next().await {
|
||||||
if let Ok(doc) = result {
|
if let Ok(doc) = result {
|
||||||
let msg = from_document::<Message>(doc)
|
let msg = from_document::<Message>(doc).map_err(|_| Error::DatabaseError {
|
||||||
.map_err(|_| Error::DatabaseError {
|
operation: "from_document",
|
||||||
operation: "from_document",
|
with: "message",
|
||||||
with: "message",
|
})?;
|
||||||
})?;
|
|
||||||
|
|
||||||
found_ids.push(msg.id.clone());
|
found_ids.push(msg.id.clone());
|
||||||
if msg.edited.is_some() {
|
if msg.edited.is_some() {
|
||||||
updated.push(msg);
|
updated.push(msg);
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
use crate::database::*;
|
use crate::database::*;
|
||||||
use crate::util::result::{Error, Result};
|
use crate::util::result::{Error, Result};
|
||||||
|
|
||||||
use mongodb::{bson::{doc, from_document}, options::FindOneOptions};
|
use mongodb::{
|
||||||
|
bson::{doc, from_document},
|
||||||
|
options::FindOneOptions,
|
||||||
|
};
|
||||||
use rocket_contrib::json::{Json, JsonValue};
|
use rocket_contrib::json::{Json, JsonValue};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
@@ -41,7 +44,7 @@ pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<JsonVal
|
|||||||
},
|
},
|
||||||
FindOneOptions::builder()
|
FindOneOptions::builder()
|
||||||
.projection(doc! { "_id": 1 })
|
.projection(doc! { "_id": 1 })
|
||||||
.build()
|
.build(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError {
|
.map_err(|_| Error::DatabaseError {
|
||||||
@@ -64,33 +67,40 @@ pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<JsonVal
|
|||||||
"$exists": false
|
"$exists": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError {
|
.map_err(|_| Error::DatabaseError {
|
||||||
operation: "find_one",
|
operation: "find_one",
|
||||||
with: "attachment",
|
with: "attachment",
|
||||||
})? {
|
})?
|
||||||
let attachment = from_document::<File>(doc)
|
{
|
||||||
.map_err(|_| Error::DatabaseError { operation: "from_document", with: "attachment" })?;
|
let attachment = from_document::<File>(doc).map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "from_document",
|
||||||
|
with: "attachment",
|
||||||
|
})?;
|
||||||
|
|
||||||
attachments.update_one(
|
attachments
|
||||||
doc! {
|
.update_one(
|
||||||
"_id": &attachment.id
|
doc! {
|
||||||
},
|
"_id": &attachment.id
|
||||||
doc! {
|
},
|
||||||
"$set": {
|
doc! {
|
||||||
"message_id": &id
|
"$set": {
|
||||||
}
|
"message_id": &id
|
||||||
},
|
}
|
||||||
None
|
},
|
||||||
)
|
None,
|
||||||
.await
|
)
|
||||||
.map_err(|_| Error::DatabaseError { operation: "update_one", with: "attachment" })?;
|
.await
|
||||||
|
.map_err(|_| Error::DatabaseError {
|
||||||
|
operation: "update_one",
|
||||||
|
with: "attachment",
|
||||||
|
})?;
|
||||||
|
|
||||||
Some(attachment)
|
Some(attachment)
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::UnknownAttachment)
|
return Err(Error::UnknownAttachment);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use rocket::Rocket;
|
|||||||
mod channels;
|
mod channels;
|
||||||
mod guild;
|
mod guild;
|
||||||
mod onboard;
|
mod onboard;
|
||||||
|
mod push;
|
||||||
mod root;
|
mod root;
|
||||||
mod users;
|
mod users;
|
||||||
|
|
||||||
@@ -15,4 +16,5 @@ pub fn mount(rocket: Rocket) -> Rocket {
|
|||||||
.mount("/users", users::routes())
|
.mount("/users", users::routes())
|
||||||
.mount("/channels", channels::routes())
|
.mount("/channels", channels::routes())
|
||||||
.mount("/guild", guild::routes())
|
.mount("/guild", guild::routes())
|
||||||
|
.mount("/push", push::routes())
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/routes/push/mod.rs
Normal file
8
src/routes/push/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
use rocket::Route;
|
||||||
|
|
||||||
|
mod subscribe;
|
||||||
|
mod unsubscribe;
|
||||||
|
|
||||||
|
pub fn routes() -> Vec<Route> {
|
||||||
|
routes![subscribe::req, unsubscribe::req]
|
||||||
|
}
|
||||||
36
src/routes/push/subscribe.rs
Normal file
36
src/routes/push/subscribe.rs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
use crate::database::*;
|
||||||
|
use crate::util::result::{Error, Result};
|
||||||
|
|
||||||
|
use mongodb::bson::{doc, to_document};
|
||||||
|
use rauth::auth::Session;
|
||||||
|
use rocket_contrib::json::Json;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Subscription {
|
||||||
|
endpoint: String,
|
||||||
|
p256dh: String,
|
||||||
|
auth: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/subscribe", data = "<data>")]
|
||||||
|
pub async fn req(session: Session, data: Json<Subscription>) -> Result<()> {
|
||||||
|
let data = data.into_inner();
|
||||||
|
let col = get_collection("accounts")
|
||||||
|
.update_one(
|
||||||
|
doc! {
|
||||||
|
"_id": session.user_id,
|
||||||
|
"sessions.id": session.id.unwrap()
|
||||||
|
},
|
||||||
|
doc! {
|
||||||
|
"$set": {
|
||||||
|
"sessions.$.subscription": to_document(&data).unwrap()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
26
src/routes/push/unsubscribe.rs
Normal file
26
src/routes/push/unsubscribe.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use crate::database::*;
|
||||||
|
use crate::util::result::{Error, Result};
|
||||||
|
|
||||||
|
use mongodb::bson::doc;
|
||||||
|
use rauth::auth::Session;
|
||||||
|
|
||||||
|
#[post("/unsubscribe")]
|
||||||
|
pub async fn req(session: Session) -> Result<()> {
|
||||||
|
let col = get_collection("accounts")
|
||||||
|
.update_one(
|
||||||
|
doc! {
|
||||||
|
"_id": session.user_id,
|
||||||
|
"sessions.id": session.id.unwrap()
|
||||||
|
},
|
||||||
|
doc! {
|
||||||
|
"$unset": {
|
||||||
|
"sessions.$.subscription": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::util::variables::{
|
use crate::util::variables::{
|
||||||
DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, INVITE_ONLY, USE_EMAIL, USE_HCAPTCHA, USE_AUTUMN, AUTUMN_URL
|
AUTUMN_URL, DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, INVITE_ONLY, USE_AUTUMN,
|
||||||
|
USE_EMAIL, USE_HCAPTCHA, VAPID_PUBLIC_KEY,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
@@ -8,7 +9,7 @@ use rocket_contrib::json::JsonValue;
|
|||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub async fn root() -> JsonValue {
|
pub async fn root() -> JsonValue {
|
||||||
json!({
|
json!({
|
||||||
"revolt": "0.3.3-alpha.5",
|
"revolt": "0.3.3-alpha.6",
|
||||||
"features": {
|
"features": {
|
||||||
"registration": !*DISABLE_REGISTRATION,
|
"registration": !*DISABLE_REGISTRATION,
|
||||||
"captcha": {
|
"captcha": {
|
||||||
@@ -23,5 +24,6 @@ pub async fn root() -> JsonValue {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ws": *EXTERNAL_WS_URL,
|
"ws": *EXTERNAL_WS_URL,
|
||||||
|
"vapid": *VAPID_PUBLIC_KEY
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use crate::database::*;
|
|||||||
use crate::util::result::{Error, Result};
|
use crate::util::result::{Error, Result};
|
||||||
|
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
use mongodb::bson::{doc, Document};
|
||||||
use mongodb::options::FindOptions;
|
use mongodb::options::FindOptions;
|
||||||
use mongodb::bson::{Document, doc};
|
|
||||||
use rocket_contrib::json::JsonValue;
|
use rocket_contrib::json::JsonValue;
|
||||||
|
|
||||||
#[get("/<target>/mutual")]
|
#[get("/<target>/mutual")]
|
||||||
@@ -19,9 +19,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
{ "recipients": &target.id }
|
{ "recipients": &target.id }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
FindOptions::builder()
|
FindOptions::builder().projection(doc! { "_id": 1 }).build(),
|
||||||
.projection(doc! { "_id": 1 })
|
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::DatabaseError {
|
.map_err(|_| Error::DatabaseError {
|
||||||
@@ -35,7 +33,5 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
|
|||||||
.filter_map(|x| x.get_str("_id").ok().map(|x| x.to_string()))
|
.filter_map(|x| x.get_str("_id").ok().map(|x| x.to_string()))
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
Ok(json!({
|
Ok(json!({ "channels": channels }))
|
||||||
"channels": channels
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ lazy_static! {
|
|||||||
env::var("REVOLT_HCAPTCHA_KEY").unwrap_or_else(|_| "0x0000000000000000000000000000000000000000".to_string());
|
env::var("REVOLT_HCAPTCHA_KEY").unwrap_or_else(|_| "0x0000000000000000000000000000000000000000".to_string());
|
||||||
pub static ref HCAPTCHA_SITEKEY: String =
|
pub static ref HCAPTCHA_SITEKEY: String =
|
||||||
env::var("REVOLT_HCAPTCHA_SITEKEY").unwrap_or_else(|_| "10000000-ffff-ffff-ffff-000000000001".to_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
|
// Application Flags
|
||||||
pub static ref DISABLE_REGISTRATION: bool = env::var("REVOLT_DISABLE_REGISTRATION").map_or(false, |v| v == "1");
|
pub static ref DISABLE_REGISTRATION: bool = env::var("REVOLT_DISABLE_REGISTRATION").map_or(false, |v| v == "1");
|
||||||
@@ -48,6 +52,8 @@ lazy_static! {
|
|||||||
// Application Logic Settings
|
// Application Logic Settings
|
||||||
pub static ref MAX_GROUP_SIZE: usize =
|
pub static ref MAX_GROUP_SIZE: usize =
|
||||||
env::var("REVOLT_MAX_GROUP_SIZE").unwrap_or_else(|_| "50".to_string()).parse().unwrap();
|
env::var("REVOLT_MAX_GROUP_SIZE").unwrap_or_else(|_| "50".to_string()).parse().unwrap();
|
||||||
|
pub static ref PUSH_LIMIT: usize =
|
||||||
|
env::var("REVOLT_PUSH_LIMIT").unwrap_or_else(|_| "50".to_string()).parse().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preflight_checks() {
|
pub fn preflight_checks() {
|
||||||
|
|||||||
Reference in New Issue
Block a user