forked from jmug/stoatchat
chore: add policy changes
This commit is contained in:
committed by
Angelo Kontaxis
parent
db57706794
commit
964884a5de
@@ -1,13 +1,14 @@
|
|||||||
use async_tungstenite::tungstenite::{handshake, Message};
|
use async_tungstenite::tungstenite::{handshake, Message};
|
||||||
use futures::channel::oneshot::Sender;
|
use futures::channel::oneshot::Sender;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use regex::Regex;
|
||||||
use revolt_database::events::client::ReadyPayloadFields;
|
use revolt_database::events::client::ReadyPayloadFields;
|
||||||
use revolt_result::{create_error, Result};
|
use revolt_result::{create_error, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
/// matches either a single word ie "users" or a key and value ie "settings[notifications]"
|
/// matches either a single word ie "users" or a key and value ie "settings[notifications]"
|
||||||
static READY_PAYLOAD_FIELD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\w+)\])?$"#).unwrap());
|
static READY_PAYLOAD_FIELD_REGEX: Lazy<Regex> =
|
||||||
|
Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\w+)\])?$"#).unwrap());
|
||||||
|
|
||||||
/// Enumeration of supported protocol formats
|
/// Enumeration of supported protocol formats
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -22,7 +23,7 @@ pub struct ProtocolConfiguration {
|
|||||||
protocol_version: i32,
|
protocol_version: i32,
|
||||||
format: ProtocolFormat,
|
format: ProtocolFormat,
|
||||||
session_token: Option<String>,
|
session_token: Option<String>,
|
||||||
ready_payload_fields: ReadyPayloadFields
|
ready_payload_fields: ReadyPayloadFields,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProtocolConfiguration {
|
impl ProtocolConfiguration {
|
||||||
@@ -31,13 +32,13 @@ impl ProtocolConfiguration {
|
|||||||
protocol_version: i32,
|
protocol_version: i32,
|
||||||
format: ProtocolFormat,
|
format: ProtocolFormat,
|
||||||
session_token: Option<String>,
|
session_token: Option<String>,
|
||||||
ready_payload_fields: ReadyPayloadFields
|
ready_payload_fields: ReadyPayloadFields,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
protocol_version,
|
protocol_version,
|
||||||
format,
|
format,
|
||||||
session_token,
|
session_token,
|
||||||
ready_payload_fields
|
ready_payload_fields,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +127,22 @@ impl handshake::server::Callback for WebsocketHandshakeCallback {
|
|||||||
let mut protocol_version = 1;
|
let mut protocol_version = 1;
|
||||||
let mut format = ProtocolFormat::Json;
|
let mut format = ProtocolFormat::Json;
|
||||||
let mut session_token = None;
|
let mut session_token = None;
|
||||||
let mut ready_payload_fields = ReadyPayloadFields::default();
|
let mut ready_payload_fields = if params.iter().any(|(k, _)| *k == "ready") {
|
||||||
|
// If they pass the ready field, set all fields to false
|
||||||
|
|
||||||
|
ReadyPayloadFields {
|
||||||
|
users: false,
|
||||||
|
servers: false,
|
||||||
|
channels: false,
|
||||||
|
members: false,
|
||||||
|
emojis: false,
|
||||||
|
user_settings: Vec::new(),
|
||||||
|
channel_unreads: false,
|
||||||
|
policy_changes: false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ReadyPayloadFields::default()
|
||||||
|
};
|
||||||
|
|
||||||
// Parse and map parameters from key-value to known variables.
|
// Parse and map parameters from key-value to known variables.
|
||||||
for (key, value) in params {
|
for (key, value) in params {
|
||||||
@@ -143,6 +159,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback {
|
|||||||
},
|
},
|
||||||
"token" => session_token = Some(value.into()),
|
"token" => session_token = Some(value.into()),
|
||||||
"ready" => {
|
"ready" => {
|
||||||
|
// Re-enable all the fields the client specifies
|
||||||
if let Some(captures) = READY_PAYLOAD_FIELD_REGEX.captures(value) {
|
if let Some(captures) = READY_PAYLOAD_FIELD_REGEX.captures(value) {
|
||||||
if let Some(field) = captures.get(0) {
|
if let Some(field) = captures.get(0) {
|
||||||
match field.as_str() {
|
match field.as_str() {
|
||||||
@@ -154,9 +171,12 @@ impl handshake::server::Callback for WebsocketHandshakeCallback {
|
|||||||
"channel_unreads" => ready_payload_fields.channel_unreads = true,
|
"channel_unreads" => ready_payload_fields.channel_unreads = true,
|
||||||
"user_settings" => {
|
"user_settings" => {
|
||||||
if let Some(subkey) = captures.get(1) {
|
if let Some(subkey) = captures.get(1) {
|
||||||
ready_payload_fields.user_settings.push(subkey.as_str().to_string());
|
ready_payload_fields
|
||||||
|
.user_settings
|
||||||
|
.push(subkey.as_str().to_string());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
"policy_changes" => ready_payload_fields.policy_changes = true,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,7 +194,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback {
|
|||||||
protocol_version,
|
protocol_version,
|
||||||
format,
|
format,
|
||||||
session_token,
|
session_token,
|
||||||
ready_payload_fields
|
ready_payload_fields,
|
||||||
})
|
})
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -101,15 +101,17 @@ impl State {
|
|||||||
self.cache.is_bot = user.bot.is_some();
|
self.cache.is_bot = user.bot.is_some();
|
||||||
|
|
||||||
// Fetch pending policy changes.
|
// Fetch pending policy changes.
|
||||||
let policy_changes = if user.bot.is_some() {
|
let policy_changes = if user.bot.is_some() || !fields.policy_changes {
|
||||||
vec![]
|
None
|
||||||
} else {
|
} else {
|
||||||
db.fetch_policy_changes()
|
Some(
|
||||||
.await?
|
db.fetch_policy_changes()
|
||||||
.into_iter()
|
.await?
|
||||||
.filter(|policy| policy.created_time > user.last_acknowledged_policy_change)
|
.into_iter()
|
||||||
.map(Into::into)
|
.filter(|policy| policy.created_time > user.last_acknowledged_policy_change)
|
||||||
.collect()
|
.map(Into::into)
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find all relationships to the user.
|
// Find all relationships to the user.
|
||||||
@@ -176,7 +178,10 @@ impl State {
|
|||||||
.map(|x| x.id.to_string())
|
.map(|x| x.id.to_string())
|
||||||
.collect::<Vec<String>>(),
|
.collect::<Vec<String>>(),
|
||||||
)
|
)
|
||||||
.await?,
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(|emoji| emoji.into())
|
||||||
|
.collect(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -184,14 +189,23 @@ impl State {
|
|||||||
|
|
||||||
// Fetch user settings
|
// Fetch user settings
|
||||||
let user_settings = if !fields.user_settings.is_empty() {
|
let user_settings = if !fields.user_settings.is_empty() {
|
||||||
Some(db.fetch_user_settings(&user.id, &fields.user_settings).await?)
|
Some(
|
||||||
|
db.fetch_user_settings(&user.id, &fields.user_settings)
|
||||||
|
.await?,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fetch channel unreads
|
// Fetch channel unreads
|
||||||
let channel_unreads = if fields.channel_unreads {
|
let channel_unreads = if fields.channel_unreads {
|
||||||
Some(db.fetch_unreads(&user.id).await?)
|
Some(
|
||||||
|
db.fetch_unreads(&user.id)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(|unread| unread.into())
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -238,11 +252,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(EventV1::Ready {
|
Ok(EventV1::Ready {
|
||||||
users: if fields.users {
|
users: if fields.users { Some(users) } else { None },
|
||||||
Some(users)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
servers: if fields.servers {
|
servers: if fields.servers {
|
||||||
Some(servers.into_iter().map(Into::into).collect())
|
Some(servers.into_iter().map(Into::into).collect())
|
||||||
} else {
|
} else {
|
||||||
@@ -258,10 +268,9 @@ impl State {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
emojis: emojis.map(|vec| vec.into_iter().map(Into::into).collect()),
|
emojis,
|
||||||
|
|
||||||
user_settings,
|
user_settings,
|
||||||
channel_unreads: channel_unreads.map(|vec| vec.into_iter().map(Into::into).collect()),
|
channel_unreads,
|
||||||
|
|
||||||
policy_changes,
|
policy_changes,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ pub struct ReadyPayloadFields {
|
|||||||
pub members: bool,
|
pub members: bool,
|
||||||
pub emojis: bool,
|
pub emojis: bool,
|
||||||
pub user_settings: Vec<String>,
|
pub user_settings: Vec<String>,
|
||||||
pub channel_unreads: bool
|
pub channel_unreads: bool,
|
||||||
|
pub policy_changes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ReadyPayloadFields {
|
impl Default for ReadyPayloadFields {
|
||||||
@@ -40,7 +41,8 @@ impl Default for ReadyPayloadFields {
|
|||||||
members: true,
|
members: true,
|
||||||
emojis: true,
|
emojis: true,
|
||||||
user_settings: Vec::new(),
|
user_settings: Vec::new(),
|
||||||
channel_unreads: false
|
channel_unreads: false,
|
||||||
|
policy_changes: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +78,8 @@ pub enum EventV1 {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
channel_unreads: Option<Vec<ChannelUnread>>,
|
channel_unreads: Option<Vec<ChannelUnread>>,
|
||||||
|
|
||||||
policy_changes: Vec<PolicyChange>,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
policy_changes: Option<Vec<PolicyChange>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Ping response
|
/// Ping response
|
||||||
|
|||||||
Reference in New Issue
Block a user