* initial livekit support fix up code undo changes to compose file add back .env.example * move voice states to global * track current state * more stuff * fix redis key inconsistancy * split voice ops into its own library * feat(livekit): more permission handling * feat(livekit): push unfinished code * fix: include voice states in servercreate event feat: call started system message in dms * feat: implement missing permission syncs * fix: remove locked rocket version * fix: remove local testing values from config * chore: switch to ids for parameter * feat: make Channel::server return a reference * feat: support multiple voice nodes * fix: expose list of nodes * fix: respond with the url when joining a voice channel * feat: being moved between voice channels * fix: use existing node if someone is already in the voice channel * refactor: Remove VoiceChannel * chore: add pushd to debug image script * refactor: add error messages for Rabbit issues * docs: add some notes on overrides; fix defaults * fix: ensure limit is always at least 1 when sent to database * fix: change permission check for fetching channel webhooks * chore: mount API at /0.8/ as well * fix: ensure ratelimiter adjusts for version prefix * chore: bump version to 0.8.2 * chore: disable LTO because it likely overloads GitHub worker * fix: don't allow users to time themselves out closes #376 * fix: match new error type for status code * feat: init crond crate * feat: file deletion implementation * chore: fix version references * feat: add crond container definitions * chore: clarify cargo deny / tomls * feat: add company information to email footers * chore: bump version to 0.8.3 * fix: don't bump the lockfile version * fix: include `production` default value for config * chore: ignore python venv and dev script for user generation Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * test: Add tests for invite/fetch Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> * test: add utilities for common setup Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> * test: add delete server channel test Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> * feat: allow to set an icon when creating a group Signed-off-by: Nils Ponsard <nilsponsard@gmail.com> * fix: allow message pinning and unpinning for DM-like channels Signed-off-by: Bradlee Barnes <69256931+StupidRepo@users.noreply.github.com> * fix: remove SavedMessages and Group due to given permissions Signed-off-by: Bradlee Barnes <69256931+StupidRepo@users.noreply.github.com> * feat: allow bots to manage emojis (#407) * Remove bot check on emoji create Signed-off-by: Builderb <builderbgamer@gmail.com> * Remove bot check on emoji delete Signed-off-by: Builderb <builderbgamer@gmail.com> --------- Signed-off-by: Builderb <builderbgamer@gmail.com> * feat: add option to send message with missing replies Signed-off-by: ShaksterNano <54268387+shaksternano@users.noreply.github.com> * chore: bump version to 0.8.4 chore: enable webhooks in test builds * ci: downgrade lockfile * feat: Add Mass Mentions to the backend (#394) * feat: create base of push daemon Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * Add outbound senders * Make web_push send to rabbit instead (temp stuff) * feat: stability and friend requests * make vapid fr stuff not suck * swap naming of queue * move pushd into daemons folder * fix cargo file for move into daemons folder * feat: probably working fcm push notifs * comment out fcm webpush stuff since the config keys dont exist * fix fcm, name queues according to their prod status and configure routing keys * add pushd to docker * mix: Remove old code, add stuff to pushd * fix: lockfile * feat: update rocket to 5.0.1 * fix: fix queues and ack bugs * Move rabbit messsage processing into ack queue * chore: update readme * chore: optimizations for ack database hits * pushd flowchart * misc: update flowchart * exit dependancy hell * add rocket_impl flag to authifier * make the tests file of delta actually compile * fix: don't silence every push message * fix: don't silence all messages * add debug logging for sending data to rabbit from message events * validate mentions at a server membership level * put back that import that was actually important * minor fix to lockfile * update delta authifier * feat: proper permissions for push notifications * add unit test for mention sanitization * remove local file dependancy on authifier * update ports to proper defaults * fixTM the node bindings * Theoretically configure docker releases for pushd Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * declare exchange in pushd and delta * fix createbuckets script Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: reference db implementation Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: remove finally redundant code Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: changes Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: other changes Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: make channel name return result Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * Add role mention parsing * feat: update to mongo 3.1, add member generator. * integrate mass mentions into pushd * patch redis-rs with updated versions * feat: chunk role mentions * move permission bits to 37/38 to avoid livekit conflict * change role mention format to <%id> * fix the lockfile from merge * fix: PR change requests * feat: add tests * fix: i am a dumbass * fix: tests, again --------- Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com> * fix: show full branch name on github webhook messages * fix: dont leak invisible presence to others * fix: add back missing early adopter badge * fix: update branch from main * fix: update branch from main * Merge remote-tracking branch 'origin/main' into livekit * feat: private livekit nodes * fix: remove node from channel voice state * fix: get_voice_state has incorrect unique_key and allowed_sources should be lowercase * chore: bump livekit dep * feat: ability to force disconnect existing voice connection * chore: cleanup code * feat: - track call length - move voice and video limits to config - seperate VoiceInformation into model and db model - fix build scripts * fix: move call system message to daemon, check max participants when creating a token to avoid giving tokens but erroring when attempting to join, check if the channel actually supports voice * fix: dont set max participants in livekit * fix: remove VoiceChannel channel type fix: calculate user overwrites correctly fix: dont include personal info in livekit user metadata fix: revoke video permissons on denied publish fix: add video to default permissions * fix: update migration * feat: Send push notifications for dm call start/end * chore: cleanup * feat: allow users to specify who is notified when starting a call * feat: track join time * merge: branch 'main' into feat/livekit * fix: include voice-ingress in build * fix: dont presume channel has a node * chore: add error logging to internal errors * chore: add debug logging to voice ingress * refactor: seperate out disconnect logic * fix: return correct error if user is already in a voice channel * fix: dont break on user not still being in channel and force disconnecting * fix: add Speak and Listen to default permissions * fix: include channel ids in UserMoveVoiceChannel * chore: add temp sentry logging system * fix: handle track_muted and track_unmuted * fix: dont set notification recipients when empty vec is passed * fix: only send UserMoveVoiceChannel to the user * fix: preserve order of replies in message (#447) Signed-off-by: Aeledfyr <aeledfyr@gmail.com> * fix: prevent timing out members which have TimeoutMembers permission * chore: update ci * fix: temporarily disable call started system messages See #457 * fix: update code from review
311 lines
9.6 KiB
Rust
311 lines
9.6 KiB
Rust
use iso8601_timestamp::Timestamp;
|
|
use once_cell::sync::Lazy;
|
|
use regex::Regex;
|
|
|
|
use super::File;
|
|
|
|
#[cfg(feature = "validator")]
|
|
use validator::Validate;
|
|
|
|
/// Regex for valid usernames
|
|
///
|
|
/// Block zero width space
|
|
/// Block lookalike characters
|
|
pub static RE_USERNAME: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(\p{L}|[\d_.-])+$").unwrap());
|
|
|
|
/// Regex for valid display names
|
|
///
|
|
/// Block zero width space
|
|
/// Block newline and carriage return
|
|
pub static RE_DISPLAY_NAME: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[^\u200B\n\r]+$").unwrap());
|
|
|
|
auto_derived_partial!(
|
|
/// User
|
|
pub struct User {
|
|
/// Unique Id
|
|
#[cfg_attr(feature = "serde", serde(rename = "_id"))]
|
|
pub id: String,
|
|
/// Username
|
|
pub username: String,
|
|
/// Discriminator
|
|
pub discriminator: String,
|
|
/// Display name
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub display_name: Option<String>,
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
/// Avatar attachment
|
|
pub avatar: Option<File>,
|
|
/// Relationships with other users
|
|
#[cfg_attr(
|
|
feature = "serde",
|
|
serde(skip_serializing_if = "Vec::is_empty", default)
|
|
)]
|
|
pub relations: Vec<Relationship>,
|
|
|
|
/// Bitfield of user badges
|
|
///
|
|
/// https://docs.rs/revolt-models/latest/revolt_models/v0/enum.UserBadges.html
|
|
#[cfg_attr(
|
|
feature = "serde",
|
|
serde(skip_serializing_if = "crate::if_zero_u32", default)
|
|
)]
|
|
pub badges: u32,
|
|
/// User's current status
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub status: Option<UserStatus>,
|
|
|
|
/// Enum of user flags
|
|
///
|
|
/// https://docs.rs/revolt-models/latest/revolt_models/v0/enum.UserFlags.html
|
|
#[cfg_attr(
|
|
feature = "serde",
|
|
serde(skip_serializing_if = "crate::if_zero_u32", default)
|
|
)]
|
|
pub flags: u32,
|
|
/// Whether this user is privileged
|
|
#[cfg_attr(
|
|
feature = "serde",
|
|
serde(skip_serializing_if = "crate::if_false", default)
|
|
)]
|
|
pub privileged: bool,
|
|
/// Bot information
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub bot: Option<BotInformation>,
|
|
|
|
/// Current session user's relationship with this user
|
|
pub relationship: RelationshipStatus,
|
|
/// Whether this user is currently online
|
|
pub online: bool,
|
|
},
|
|
"PartialUser"
|
|
);
|
|
|
|
auto_derived!(
|
|
/// Optional fields on user object
|
|
pub enum FieldsUser {
|
|
Avatar,
|
|
StatusText,
|
|
StatusPresence,
|
|
ProfileContent,
|
|
ProfileBackground,
|
|
DisplayName,
|
|
|
|
/// Internal field, ignore this.
|
|
Internal,
|
|
}
|
|
|
|
/// User's relationship with another user (or themselves)
|
|
#[derive(Default)]
|
|
pub enum RelationshipStatus {
|
|
/// No relationship with other user
|
|
#[default]
|
|
None,
|
|
/// Other user is us
|
|
User,
|
|
/// Friends with the other user
|
|
Friend,
|
|
/// Pending friend request to user
|
|
Outgoing,
|
|
/// Incoming friend request from user
|
|
Incoming,
|
|
/// Blocked this user
|
|
Blocked,
|
|
/// Blocked by this user
|
|
BlockedOther,
|
|
}
|
|
|
|
/// Relationship entry indicating current status with other user
|
|
pub struct Relationship {
|
|
/// Other user's Id
|
|
#[cfg_attr(feature = "serde", serde(rename = "_id"))]
|
|
pub user_id: String,
|
|
/// Relationship status with them
|
|
pub status: RelationshipStatus,
|
|
}
|
|
|
|
/// Presence status
|
|
pub enum Presence {
|
|
/// User is online
|
|
Online,
|
|
/// User is not currently available
|
|
Idle,
|
|
/// User is focusing / will only receive mentions
|
|
Focus,
|
|
/// User is busy / will not receive any notifications
|
|
Busy,
|
|
/// User appears to be offline
|
|
Invisible,
|
|
}
|
|
|
|
/// User's active status
|
|
#[derive(Default)]
|
|
#[cfg_attr(feature = "validator", derive(Validate))]
|
|
pub struct UserStatus {
|
|
/// Custom status text
|
|
#[validate(length(min = 0, max = 128))]
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub text: Option<String>,
|
|
/// Current presence option
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub presence: Option<Presence>,
|
|
}
|
|
|
|
/// User's profile
|
|
#[derive(Default)]
|
|
#[cfg_attr(feature = "validator", derive(Validate))]
|
|
pub struct UserProfile {
|
|
/// Text content on user's profile
|
|
#[validate(length(min = 0, max = 2000))]
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub content: Option<String>,
|
|
/// Background visible on user's profile
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub background: Option<File>,
|
|
}
|
|
|
|
/// User badge bitfield
|
|
#[repr(u32)]
|
|
pub enum UserBadges {
|
|
/// Revolt Developer
|
|
Developer = 1,
|
|
/// Helped translate Revolt
|
|
Translator = 2,
|
|
/// Monetarily supported Revolt
|
|
Supporter = 4,
|
|
/// Responsibly disclosed a security issue
|
|
ResponsibleDisclosure = 8,
|
|
/// Revolt Founder
|
|
Founder = 16,
|
|
/// Platform moderator
|
|
PlatformModeration = 32,
|
|
/// Active monetary supporter
|
|
ActiveSupporter = 64,
|
|
/// 🦊🦝
|
|
Paw = 128,
|
|
/// Joined as one of the first 1000 users in 2021
|
|
EarlyAdopter = 256,
|
|
/// Amogus
|
|
ReservedRelevantJokeBadge1 = 512,
|
|
/// Low resolution troll face
|
|
ReservedRelevantJokeBadge2 = 1024,
|
|
}
|
|
|
|
/// User flag enum
|
|
#[repr(u32)]
|
|
pub enum UserFlags {
|
|
/// User has been suspended from the platform
|
|
SuspendedUntil = 1,
|
|
/// User has deleted their account
|
|
Deleted = 2,
|
|
/// User was banned off the platform
|
|
Banned = 4,
|
|
/// User was marked as spam and removed from platform
|
|
Spam = 8,
|
|
}
|
|
|
|
/// New user profile data
|
|
#[cfg_attr(feature = "validator", derive(Validate))]
|
|
pub struct DataUserProfile {
|
|
/// Text to set as user profile description
|
|
#[cfg_attr(feature = "validator", validate(length(min = 0, max = 2000)))]
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub content: Option<String>,
|
|
/// Attachment Id for background
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))]
|
|
pub background: Option<String>,
|
|
}
|
|
|
|
/// New user information
|
|
#[cfg_attr(feature = "validator", derive(Validate))]
|
|
pub struct DataEditUser {
|
|
/// New display name
|
|
#[cfg_attr(
|
|
feature = "validator",
|
|
validate(length(min = 2, max = 32), regex = "RE_DISPLAY_NAME")
|
|
)]
|
|
pub display_name: Option<String>,
|
|
/// Attachment Id for avatar
|
|
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))]
|
|
pub avatar: Option<String>,
|
|
|
|
/// New user status
|
|
#[cfg_attr(feature = "validator", validate)]
|
|
pub status: Option<UserStatus>,
|
|
/// New user profile data
|
|
///
|
|
/// This is applied as a partial.
|
|
#[cfg_attr(feature = "validator", validate)]
|
|
pub profile: Option<DataUserProfile>,
|
|
|
|
/// Bitfield of user badges
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub badges: Option<i32>,
|
|
/// Enum of user flags
|
|
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
|
pub flags: Option<i32>,
|
|
|
|
/// Fields to remove from user object
|
|
#[cfg_attr(feature = "serde", serde(default))]
|
|
pub remove: Vec<FieldsUser>,
|
|
}
|
|
|
|
/// User flag reponse
|
|
pub struct FlagResponse {
|
|
/// Flags
|
|
pub flags: i32,
|
|
}
|
|
|
|
/// Mutual friends, servers, groups and DMs response
|
|
pub struct MutualResponse {
|
|
/// Array of mutual user IDs that both users are friends with
|
|
pub users: Vec<String>,
|
|
/// Array of mutual server IDs that both users are in
|
|
pub servers: Vec<String>,
|
|
/// Array of mutual group and dm IDs that both users are in
|
|
pub channels: Vec<String>,
|
|
}
|
|
|
|
/// Bot information for if the user is a bot
|
|
pub struct BotInformation {
|
|
/// Id of the owner of this bot
|
|
#[cfg_attr(feature = "serde", serde(rename = "owner"))]
|
|
pub owner_id: String,
|
|
}
|
|
|
|
/// User lookup information
|
|
pub struct DataSendFriendRequest {
|
|
/// Username and discriminator combo separated by #
|
|
pub username: String,
|
|
}
|
|
);
|
|
|
|
auto_derived_partial!(
|
|
/// Voice State information for a user
|
|
pub struct UserVoiceState {
|
|
pub id: String,
|
|
pub joined_at: Timestamp,
|
|
pub is_receiving: bool,
|
|
pub is_publishing: bool,
|
|
pub screensharing: bool,
|
|
pub camera: bool,
|
|
},
|
|
"PartialUserVoiceState"
|
|
);
|
|
|
|
pub trait CheckRelationship {
|
|
fn with(&self, user: &str) -> RelationshipStatus;
|
|
}
|
|
|
|
impl CheckRelationship for Vec<Relationship> {
|
|
fn with(&self, user: &str) -> RelationshipStatus {
|
|
for entry in self {
|
|
if entry.user_id == user {
|
|
return entry.status.clone();
|
|
}
|
|
}
|
|
|
|
RelationshipStatus::None
|
|
}
|
|
}
|