Merge remote-tracking branch 'origin/main' into feat/audit-log

Signed-off-by: Zomatree <me@zomatree.live>
This commit is contained in:
Zomatree
2026-06-23 15:31:44 +01:00
225 changed files with 116692 additions and 4772 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "revolt-models"
version = "0.12.1"
version = "0.13.7"
edition = "2021"
license = "MIT"
authors = ["Paul Makles <me@insrt.uk>"]
@@ -41,6 +41,7 @@ iso8601-timestamp = { workspace = true, features = ["schema", "bson"] }
# Spec Generation
schemars = { workspace = true, features = ["indexmap2"], optional = true }
utoipa = { workspace = true, optional = true }
serde_json = { workspace = true }
# Validation
validator = { workspace = true, features = ["derive"], optional = true }

View File

@@ -0,0 +1,70 @@
auto_derived!(
/// # Change Email Data
pub struct DataChangeEmail {
/// Valid email address
pub email: String,
/// Current password
pub current_password: String,
}
/// # Change Data
pub struct DataChangePassword {
/// New password
pub password: String,
/// Current password
pub current_password: String,
}
/// # Account Deletion Token
pub struct DataAccountDeletion {
/// Deletion token
pub token: String,
}
/// # Account Data
pub struct DataCreateAccount {
/// Valid email address
pub email: String,
/// Password
pub password: String,
/// Invite code
pub invite: Option<String>,
/// Captcha verification code
pub captcha: Option<String>,
}
pub struct AccountInfo {
#[serde(rename = "_id")]
pub id: String,
pub email: String,
}
/// # Password Reset
pub struct DataPasswordReset {
/// Reset token
pub token: String,
/// New password
pub password: String,
/// Whether to logout all sessions
#[serde(default)]
pub remove_sessions: bool,
}
/// # Resend Information
pub struct DataResendVerification {
/// Email associated with the account
pub email: String,
/// Captcha verification code
pub captcha: Option<String>,
}
/// # Reset Information
pub struct DataSendPasswordReset {
/// Email associated with the account
pub email: String,
/// Captcha verification code
pub captcha: Option<String>,
}
);

View File

@@ -314,6 +314,12 @@ auto_derived!(
/// Only used when the user is the first one connected.
pub recipients: Option<Vec<String>>,
}
pub struct ChannelSlowmode {
pub channel_id: String,
pub duration: u64,
pub retry_after: u64,
}
);
impl Channel {

View File

@@ -54,4 +54,22 @@ auto_derived!(
#[serde(default)]
pub nsfw: bool,
}
/// Partial emoji representation
#[derive(Default)]
pub struct PartialEmoji {
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub name: Option<String>,
}
/// Edit emoji information
#[cfg_attr(feature = "validator", derive(Validate))]
pub struct DataEditEmoji {
/// Emoji name
#[cfg_attr(
feature = "validator",
validate(length(min = 1, max = 32), regex = "RE_EMOJI")
)]
pub name: Option<String>,
}
);

View File

@@ -261,7 +261,7 @@ auto_derived!(
pub nonce: Option<String>,
/// Message content to send
#[cfg_attr(feature = "validator", validate(length(min = 0, max = 2000)))]
#[cfg_attr(feature = "validator", validate(length(min = 0)))]
pub content: Option<String>,
/// Attachments to include in message
pub attachments: Option<Vec<String>>,
@@ -345,7 +345,7 @@ auto_derived!(
#[cfg_attr(feature = "validator", derive(Validate))]
pub struct DataEditMessage {
/// New message content
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 2000)))]
#[cfg_attr(feature = "validator", validate(length(min = 1)))]
pub content: Option<String>,
/// Embeds to include in the message
#[cfg_attr(feature = "validator", validate(length(min = 0, max = 10)))]

View File

@@ -0,0 +1,68 @@
auto_derived!(
pub struct MFATicket {
/// Unique Id
#[serde(rename = "_id")]
pub id: String,
/// Account Id
pub account_id: String,
/// Unique Token
pub token: String,
/// Whether this ticket has been validated
/// (can be used for account actions)
pub validated: bool,
/// Whether this ticket is authorised
/// (can be used to log a user in)
pub authorised: bool,
/// TOTP code at time of ticket creation
pub last_totp_code: Option<String>,
}
#[serde(untagged)]
pub enum ResponseVerify {
NoTicket,
WithTicket {
/// Authorised MFA ticket, can be used to log in
ticket: MFATicket,
},
}
/// MFA response
#[serde(untagged)]
pub enum MFAResponse {
Password { password: String },
Recovery { recovery_code: String },
Totp { totp_code: String },
}
#[derive(Default)]
pub struct MultiFactorStatus {
#[serde(skip_serializing_if = "crate::if_false", default)]
pub email_otp: bool,
#[serde(skip_serializing_if = "crate::if_false", default)]
pub trusted_handover: bool,
#[serde(skip_serializing_if = "crate::if_false", default)]
pub email_mfa: bool,
#[serde(skip_serializing_if = "crate::if_false", default)]
pub totp_mfa: bool,
#[serde(skip_serializing_if = "crate::if_false", default)]
pub security_key_mfa: bool,
#[serde(skip_serializing_if = "crate::if_false", default)]
pub recovery_active: bool,
}
pub enum MFAMethod {
Password,
Recovery,
Totp,
}
/// # Totp Secret
pub struct ResponseTotpSecret {
pub secret: String,
}
);

View File

@@ -15,6 +15,9 @@ mod server_members;
mod servers;
mod user_settings;
mod users;
mod accounts;
mod mfa_tickets;
mod sessions;
pub use audit_logs::*;
pub use bots::*;
@@ -33,3 +36,6 @@ pub use server_members::*;
pub use servers::*;
pub use user_settings::*;
pub use users::*;
pub use accounts::*;
pub use mfa_tickets::*;
pub use sessions::*;

View File

@@ -52,6 +52,9 @@ auto_derived_partial!(
/// Member's nickname
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub nickname: Option<String>,
/// Member's pronouns
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub pronouns: Option<String>,
/// Avatar attachment
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub avatar: Option<File>,
@@ -89,6 +92,7 @@ auto_derived!(
/// Optional fields on server member object
pub enum FieldsMember {
Nickname,
Pronouns,
Avatar,
Roles,
Timeout,
@@ -136,6 +140,9 @@ auto_derived!(
/// Member nickname
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 32)))]
pub nickname: Option<String>,
/// Member pronouns
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 24)))]
pub pronouns: Option<String>,
/// Attachment Id to set for avatar
pub avatar: Option<String>,
/// Array of role ids

View File

@@ -106,6 +106,9 @@ auto_derived_partial!(
/// Ranking of this role
#[cfg_attr(feature = "serde", serde(default))]
pub rank: i64,
/// Role icon
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub icon: Option<File>,
},
"PartialRole"
);
@@ -123,6 +126,7 @@ auto_derived!(
/// Optional fields on server object
pub enum FieldsRole {
Colour,
Icon,
}
/// Channel category
@@ -278,6 +282,11 @@ auto_derived!(
///
/// **Removed** - no effect, use the edit server role positions route
pub rank: Option<i64>,
/// Role icon
///
/// Provide an Autumn attachment Id.
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))]
pub icon: Option<String>,
/// Fields to remove from role object
#[cfg_attr(feature = "serde", serde(default))]
pub remove: Vec<FieldsRole>,

View File

@@ -0,0 +1,88 @@
use iso8601_timestamp::Timestamp;
use crate::v0::{MFAMethod, MFAResponse};
auto_derived!(
pub struct Session {
/// Unique Id
#[serde(rename = "_id")]
pub id: String,
/// User Id
pub user_id: String,
/// Session token
pub token: String,
/// Display name
pub name: String,
/// When the session was last logged in
pub last_seen: Timestamp,
/// Where the session is originating from
#[serde(skip_serializing_if = "Option::is_none")]
pub origin: Option<String>,
/// Web Push subscription
#[serde(skip_serializing_if = "Option::is_none")]
pub subscription: Option<WebPushSubscription>,
}
/// Web Push subscription
pub struct WebPushSubscription {
pub endpoint: String,
pub p256dh: String,
pub auth: String,
}
/// # Edit Data
pub struct DataEditSession {
/// Session friendly name
pub friendly_name: String,
}
pub struct SessionInfo {
#[serde(rename = "_id")]
pub id: String,
pub name: String,
}
/// # Login Data
#[serde(untagged)]
pub enum DataLogin {
Email {
/// Email
email: String,
/// Password
password: String,
/// Friendly name used for the session
friendly_name: Option<String>,
},
MFA {
/// Unvalidated or authorised MFA ticket
///
/// Used to resolve the correct account
mfa_ticket: String,
/// Valid MFA response
///
/// This will take precedence over the `password` field where applicable
mfa_response: Option<MFAResponse>,
/// Friendly name used for the session
friendly_name: Option<String>,
},
}
#[serde(tag = "result")]
pub enum ResponseLogin {
Success(Session),
MFA {
ticket: String,
allowed_methods: Vec<MFAMethod>,
},
Disabled {
user_id: String,
},
}
);

View File

@@ -32,6 +32,9 @@ auto_derived_partial!(
/// Display name
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub display_name: Option<String>,
/// User's pronouns
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub pronouns: Option<String>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
/// Avatar attachment
pub avatar: Option<File>,
@@ -89,6 +92,7 @@ auto_derived!(
ProfileContent,
ProfileBackground,
DisplayName,
Pronouns,
/// Internal field, ignore this.
Internal,
@@ -225,6 +229,9 @@ auto_derived!(
validate(length(min = 2, max = 32), regex = "RE_DISPLAY_NAME")
)]
pub display_name: Option<String>,
/// New pronouns
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 24)))]
pub pronouns: Option<String>,
/// Attachment Id for avatar
#[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))]
pub avatar: Option<String>,