diff --git a/Cargo.toml b/Cargo.toml index de3d032..47b99fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,48 +4,48 @@ version = "0.1.0" edition = "2024" [dependencies] -twilight-gateway = { version = "0.16", optional = true } -twilight-model = "0.16" -twilight-http = "0.16" -twilight-util = { version = "0.16", features = ["full"] } -twilight-validate = "0.16" - -serde_urlencoded = { version = "0.7", optional = true } -serde_json = "1.0" -serde_repr = "0.1" -serde = "1.0" - -futures-util = "0.3" -tokio = "1.43" -tokio-stream = "0.1" - -tracing = { version = "0.1", features = ["std"] } -tracing-subscriber = { version = "0.3", features = ["env-filter","registry", "std", "fmt"] } -opentelemetry_sdk = "0.30" -opentelemetry-appender-tracing = "0.30" -tracing-opentelemetry = "0.31" -opentelemetry = { version = "0.30", features = ["trace"] } -opentelemetry-otlp = { version = "0.30", features = ["http-proto", "grpc-tonic"] } - -mongodb = "3.2" -redis = { version = "0.29", features = ["aio", "tokio-comp"] } - -tokio-websockets = "0.11" - -humantime = "2.1" +twilight-gateway = { version = "0.17.1", optional = true } +twilight-model = "0.17.1" +twilight-http = "0.17.1" +twilight-util = { version = "0.17.0", features = ["full"] } +twilight-validate = "0.17.0" + +serde_urlencoded = { version = "0.7.1", optional = true } +serde_json = "1.0.151" +serde_repr = "0.1.21" +serde = "1.0.229" + +futures-util = "0.3.34" +tokio = { version = "1.53.1", features = ["macros", "rt-multi-thread"] } +tokio-stream = "0.1.19" + +tracing = { version = "0.1.44", features = ["std"] } +tracing-subscriber = { version = "0.3.23", features = ["env-filter","registry", "std", "fmt"] } +opentelemetry_sdk = "0.33.0" +opentelemetry-appender-tracing = "0.33.0" +tracing-opentelemetry = "0.34.0" +opentelemetry = { version = "0.33.0", features = ["trace"] } +opentelemetry-otlp = { version = "0.33.0", features = ["http-proto", "grpc-tonic"] } + +mongodb = "3.9.1" +redis = { version = "1.7.1", features = ["aio", "tokio-comp"] } + +tokio-websockets = "0.13.3" + +humantime = "2.4" chrono = "0.4" -ed25519-dalek = { version = "2.1", optional = true } -dotenv = "0.15" -reqwest = { version = "0.12" } -regex = { version = "1.5", optional = true } -dashmap = "5.2" -hex = { version = "0.4", optional = true } - -warp = { version = "0.3", optional = true } -rusty_paseto = { version = "0.7", features = ["core", "v4_local"], optional = true } -anyhow = { version = "1.0", optional = true } -json-patch = { version = "4.0", optional = true } +ed25519-dalek = { version = "3.0", optional = true } +dotenv = "0.15.0" +reqwest = { version = "0.13.5" } +regex = { version = "1.13.1", optional = true } +dashmap = "6.2.1" +hex = { version = "0.4.3", optional = true } + +warp = { version = "0.4.3", features = ["websocket", "server"], optional = true } +rusty_paseto = { version = "0.10.1", features = ["core", "v4_local"], optional = true } +anyhow = { version = "1.0.104", optional = true } +json-patch = { version = "4.2.0", optional = true } [features] all = ["custom-clients", "tasks", "http-interactions", "api", "gateway"] diff --git a/src/commands/case/edit.rs b/src/commands/case/edit.rs index 9198080..f836567 100644 --- a/src/commands/case/edit.rs +++ b/src/commands/case/edit.rs @@ -58,7 +58,8 @@ pub async fn run( embeds: Some(vec![case.to_embed(discord_http).await?]), flags: Some(MessageFlags::EPHEMERAL), title: None, - tts: None + tts: None, + poll: None, }, None)) } \ No newline at end of file diff --git a/src/commands/case/list.rs b/src/commands/case/list.rs index 4b081f2..d38b411 100644 --- a/src/commands/case/list.rs +++ b/src/commands/case/list.rs @@ -187,8 +187,10 @@ pub async fn run( choices: None, components: Some(vec![ Component::ActionRow(ActionRow { + id: None, components: vec![ Component::SelectMenu(SelectMenu { + id: None, channel_types: None, custom_id: format!("a:{}:cl:{member_id}", user.id), default_values: None, @@ -197,7 +199,8 @@ pub async fn run( max_values: Some(1), min_values: Some(1), options: Some(result), - placeholder: None + placeholder: None, + required: None, }) ] }) @@ -207,7 +210,8 @@ pub async fn run( embeds: Some(vec![embed]), flags: None, title: None, - tts: None + tts: None, + poll: None, }, None)) } \ No newline at end of file diff --git a/src/commands/case/remove.rs b/src/commands/case/remove.rs index f7894c3..e59ef91 100644 --- a/src/commands/case/remove.rs +++ b/src/commands/case/remove.rs @@ -40,7 +40,8 @@ pub async fn run( embeds: Some(vec![removed_case.to_embed(discord_http).await?]), flags: Some(MessageFlags::EPHEMERAL), title: None, - tts: None + tts: None, + poll: None, }, None)) } \ No newline at end of file diff --git a/src/commands/moderation/clear.rs b/src/commands/moderation/clear.rs index 9ad8858..8843100 100644 --- a/src/commands/moderation/clear.rs +++ b/src/commands/moderation/clear.rs @@ -98,7 +98,8 @@ pub async fn run( embeds: None, flags: Some(MessageFlags::EPHEMERAL), title: None, - tts: None + tts: None, + poll: None, }, None)) } \ No newline at end of file diff --git a/src/commands/moderation/execute.rs b/src/commands/moderation/execute.rs index 3b35dcf..01055a2 100644 --- a/src/commands/moderation/execute.rs +++ b/src/commands/moderation/execute.rs @@ -167,7 +167,8 @@ pub async fn run( embeds: Some(vec![case_embed]), flags: Some(MessageFlags::EPHEMERAL), title: None, - tts: None + tts: None, + poll: None, }, None)) } diff --git a/src/commands/options.rs b/src/commands/options.rs index 6b345d6..a959b59 100644 --- a/src/commands/options.rs +++ b/src/commands/options.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use twilight_model::application::interaction::application_command::{CommandData, CommandDataOption, CommandOptionValue}; use twilight_model::application::interaction::InteractionData; +use twilight_model::application::interaction::modal::ModalInteractionComponent; use crate::{extract, ok_or_break, ok_or_skip}; use crate::application::{Application, ConvertableOptionsList}; use crate::commands::context::InteractionContext; @@ -73,15 +74,15 @@ impl LoadOptions for InteractionContext { .await.ok_or("Unknown modal")?; self.command_text = component.command; - for action_row in &data.components { - for text_input in &action_row.components { + for modal_component in &data.components { + if let ModalInteractionComponent::TextInput(input) = modal_component { let kind = ok_or_skip!( - &component.inputs.get(text_input.custom_id.as_str()), Some + &component.inputs.get(input.custom_id.as_str()), Some ); let value = convert_value_to_option( - ok_or_skip!(&text_input.value, Some).to_owned().as_str(), kind + input.value.as_str(), kind )?; - self.options.insert(text_input.custom_id.clone(), value); + self.options.insert(input.custom_id.clone(), value); } } diff --git a/src/commands/settings/setup.rs b/src/commands/settings/setup.rs index 016ec28..f6d4afc 100644 --- a/src/commands/settings/setup.rs +++ b/src/commands/settings/setup.rs @@ -27,6 +27,7 @@ pub async fn run( embeds: None, flags: Some(MessageFlags::EPHEMERAL), title: None, - tts: None + tts: None, + poll: None, }, None)) } \ No newline at end of file diff --git a/src/server/authorize.rs b/src/server/authorize.rs index d92f6b8..e4a12d0 100644 --- a/src/server/authorize.rs +++ b/src/server/authorize.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use warp::Filter; use warp::hyper::body::Bytes; use crate::server::error::Rejection; -use crate::{err, reject, with_value}; +use crate::with_value; pub fn verify_signature( public_key: VerifyingKey, diff --git a/src/server/error.rs b/src/server/error.rs index 3de9f65..df158cc 100644 --- a/src/server/error.rs +++ b/src/server/error.rs @@ -36,7 +36,7 @@ impl Display for Rejection { // impl warp::reject:: -#[macro_export()] +#[macro_export] macro_rules! err { ($err: expr) => { Err($crate::reject!($err)) diff --git a/src/server/interaction.rs b/src/server/interaction.rs index 8de6bc5..888e096 100644 --- a/src/server/interaction.rs +++ b/src/server/interaction.rs @@ -75,7 +75,8 @@ async fn handle_command( embeds: None, flags: Some(MessageFlags::EPHEMERAL), title: None, - tts: None + tts: None, + poll: None, }, Some(InteractionResponseType::DeferredChannelMessageWithSource))) } else { diff --git a/src/server/routes/login.rs b/src/server/routes/login.rs index 6fd4832..99c6681 100644 --- a/src/server/routes/login.rs +++ b/src/server/routes/login.rs @@ -7,7 +7,7 @@ use twilight_model::user::CurrentUser; use twilight_model::util::Timestamp; use warp::{Filter, Reply}; use warp::http::StatusCode; -use crate::{env_unwrap, reject, response_type, with_value}; +use crate::{env_unwrap, response_type, with_value}; use crate::server::error::{Rejection, MapErrorIntoInternalRejection}; use crate::server::session::{Authenticator, AuthorizationInformation, Sessions}; diff --git a/src/server/session.rs b/src/server/session.rs index 0f3b3aa..474815a 100644 --- a/src/server/session.rs +++ b/src/server/session.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::sync::Arc; use rusty_paseto::core::{ImplicitAssertion, Key, Local, PasetoSymmetricKey, V4}; -use rusty_paseto::generic::GenericBuilderError; use rusty_paseto::prelude::{PasetoBuilder, PasetoParser}; use serde::Deserialize; use tokio::sync::RwLock; @@ -26,18 +25,16 @@ impl Authenticator { } } - pub fn generate_token(&self, user_id: Id) -> Result { + pub fn generate_token(&self, user_id: Id) -> Result { let user_id = user_id.id().to_string(); let assertion = ImplicitAssertion::from(user_id.as_str()); - let result = PasetoBuilder::::default() + PasetoBuilder::::default() .set_implicit_assertion(assertion) .set_no_expiration_danger_acknowledged() - .build(&self.key); - - result.map(|token| - token.strip_prefix("v4.local.").unwrap_or_default().to_string() - ) + .build(&self.key) + .map(|token| token.strip_prefix("v4.local.").unwrap_or_default().to_string()) + .map_err(rusty_paseto::Error::from) } pub fn verify_token(&self, token: &str, user_id: Id) -> bool { diff --git a/src/utils/embeds.rs b/src/utils/embeds.rs index 2a1e63f..4dd0330 100644 --- a/src/utils/embeds.rs +++ b/src/utils/embeds.rs @@ -77,6 +77,7 @@ pub fn interaction_response_data_from_embed(embed: Embed, ephemeral: bool) -> In embeds: Some(vec![embed]), flags: if ephemeral { Some(MessageFlags::EPHEMERAL) } else { None }, title: None, - tts: None + tts: None, + poll: None, } } \ No newline at end of file diff --git a/src/utils/errors.rs b/src/utils/errors.rs index 94e572d..b6008b5 100644 --- a/src/utils/errors.rs +++ b/src/utils/errors.rs @@ -111,7 +111,8 @@ impl Error { embeds: None, flags: Some(MessageFlags::EPHEMERAL), title: None, - tts: None + tts: None, + poll: None, } } } diff --git a/src/utils/modals.rs b/src/utils/modals.rs index 5263f05..f07f517 100644 --- a/src/utils/modals.rs +++ b/src/utils/modals.rs @@ -36,8 +36,9 @@ impl ModalBuilder { match input_type { RepetitiveTextInput::Reason => { self.add_custom_component(TextInput { + id: None, custom_id: "reason".to_string(), - label: "Reason".to_string(), + label: Some("Reason".to_string()), max_length: Some(512), min_length: None, placeholder: None, @@ -48,8 +49,9 @@ impl ModalBuilder { } RepetitiveTextInput::Duration(required) => { self.add_custom_component(TextInput { + id: None, custom_id: "duration".to_string(), - label: "Duration".to_string(), + label: Some("Duration".to_string()), max_length: Some(21), min_length: None, placeholder: None, @@ -60,8 +62,9 @@ impl ModalBuilder { }, RepetitiveTextInput::Member => { self.add_custom_component(TextInput { + id: None, custom_id: "member".to_string(), - label: "Member ID".to_string(), + label: Some("Member ID".to_string()), max_length: Some(21), min_length: None, placeholder: None, @@ -81,6 +84,7 @@ impl ModalBuilder { components: Some( self.inputs.iter().map(|text_input| { Component::ActionRow(ActionRow { + id: None, components: vec![Component::TextInput(text_input.clone())] }) }).collect() @@ -90,7 +94,8 @@ impl ModalBuilder { embeds: None, flags: None, title: Some(self.title.clone()), - tts: None + tts: None, + poll: None, } } } \ No newline at end of file