Compare commits
8
Commits
20241002-5
...
20241024-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df07426019 | ||
|
|
c30d9a2620 | ||
|
|
7b44317705 | ||
|
|
876068a37e | ||
|
|
397b9878e1 | ||
|
|
d9deadc65a | ||
|
|
58d3c5cc2e | ||
|
|
520fb02fb6 |
Generated
+12
-12
@@ -5580,7 +5580,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-autumn"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"axum-macros",
|
||||
@@ -5617,7 +5617,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-bonfire"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-channel 2.3.1",
|
||||
"async-std",
|
||||
@@ -5647,7 +5647,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-config"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"cached",
|
||||
@@ -5664,7 +5664,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-database"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-lock 2.8.0",
|
||||
"async-recursion",
|
||||
@@ -5712,7 +5712,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-delta"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-channel 1.6.1",
|
||||
"async-std",
|
||||
@@ -5759,7 +5759,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-files"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"aes-gcm 0.10.3",
|
||||
"aws-config",
|
||||
@@ -5782,7 +5782,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-january"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-recursion",
|
||||
"axum",
|
||||
@@ -5810,7 +5810,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-models"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"indexmap 1.9.3",
|
||||
"iso8601-timestamp 0.2.11",
|
||||
@@ -5828,7 +5828,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-nodejs-bindings"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"neon",
|
||||
@@ -5841,7 +5841,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-permissions"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"async-trait",
|
||||
@@ -5856,7 +5856,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-presence"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"log",
|
||||
@@ -5867,7 +5867,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "revolt-result"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"revolt_okapi",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-nodejs-bindings"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
description = "Node.js bindings for the Revolt software"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
license = "MIT"
|
||||
@@ -20,6 +20,6 @@ serde = { version = "1", features = ["derive"] }
|
||||
|
||||
async-std = "1.12.0"
|
||||
|
||||
revolt-config = { version = "0.7.18", path = "../../core/config" }
|
||||
revolt-result = { version = "0.7.18", path = "../../core/result" }
|
||||
revolt-database = { version = "0.7.18", path = "../../core/database" }
|
||||
revolt-config = { version = "0.7.19", path = "../../core/config" }
|
||||
revolt-result = { version = "0.7.19", path = "../../core/result" }
|
||||
revolt-database = { version = "0.7.19", path = "../../core/database" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-bonfire"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
license = "AGPL-3.0-or-later"
|
||||
edition = "2021"
|
||||
|
||||
@@ -41,7 +41,7 @@ revolt-result = { path = "../core/result" }
|
||||
revolt-models = { path = "../core/models" }
|
||||
revolt-config = { path = "../core/config" }
|
||||
revolt-database = { path = "../core/database" }
|
||||
revolt-permissions = { version = "0.7.18", path = "../core/permissions" }
|
||||
revolt-permissions = { version = "0.7.19", path = "../core/permissions" }
|
||||
revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] }
|
||||
|
||||
# redis
|
||||
|
||||
@@ -301,25 +301,23 @@ async fn listener(
|
||||
PayloadType::Json => message
|
||||
.value
|
||||
.as_str()
|
||||
.and_then(|s| serde_json::from_str::<EventV1>(s.as_ref()).ok()),
|
||||
.and_then(|s| report_internal_error!(serde_json::from_str::<EventV1>(s.as_ref())).ok()),
|
||||
PayloadType::Msgpack => message
|
||||
.value
|
||||
.as_bytes()
|
||||
.and_then(|b| rmp_serde::from_slice::<EventV1>(b).ok()),
|
||||
.and_then(|b| report_internal_error!(rmp_serde::from_slice::<EventV1>(b)).ok()),
|
||||
PayloadType::Bincode => message
|
||||
.value
|
||||
.as_bytes()
|
||||
.and_then(|b| bincode::deserialize::<EventV1>(b).ok()),
|
||||
.and_then(|b| report_internal_error!(bincode::deserialize::<EventV1>(b)).ok()),
|
||||
};
|
||||
|
||||
let Some(mut event) = event else {
|
||||
let err = format!(
|
||||
"Failed to deserialise an event for {}! Introspection: `{:?}`",
|
||||
"Failed to deserialise event for {}: `{:?}`",
|
||||
message.channel,
|
||||
message
|
||||
.value
|
||||
.as_string()
|
||||
.map(|x| x.chars().take(32).collect::<String>())
|
||||
);
|
||||
|
||||
error!("{}", err);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-config"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
@@ -35,4 +35,4 @@ pretty_env_logger = "0.4.0"
|
||||
sentry = "0.31.5"
|
||||
|
||||
# Core
|
||||
revolt-result = { version = "0.7.18", path = "../result", optional = true }
|
||||
revolt-result = { version = "0.7.19", path = "../result", optional = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-database"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
license = "AGPL-3.0-or-later"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
@@ -24,15 +24,15 @@ default = ["mongodb", "async-std-runtime", "tasks"]
|
||||
|
||||
[dependencies]
|
||||
# Core
|
||||
revolt-config = { version = "0.7.18", path = "../config", features = [
|
||||
revolt-config = { version = "0.7.19", path = "../config", features = [
|
||||
"report-macros",
|
||||
] }
|
||||
revolt-result = { version = "0.7.18", path = "../result" }
|
||||
revolt-models = { version = "0.7.18", path = "../models", features = [
|
||||
revolt-result = { version = "0.7.19", path = "../result" }
|
||||
revolt-models = { version = "0.7.19", path = "../models", features = [
|
||||
"validator",
|
||||
] }
|
||||
revolt-presence = { version = "0.7.18", path = "../presence" }
|
||||
revolt-permissions = { version = "0.7.18", path = "../permissions", features = [
|
||||
revolt-presence = { version = "0.7.19", path = "../presence" }
|
||||
revolt-permissions = { version = "0.7.19", path = "../permissions", features = [
|
||||
"serde",
|
||||
"bson",
|
||||
] }
|
||||
|
||||
@@ -2,7 +2,10 @@ use authifier::AuthifierEvent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use revolt_models::v0::{
|
||||
AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialWebhook, RemovalIntention, Report, Server, User, UserSettings, Webhook
|
||||
AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsMessage,
|
||||
FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message,
|
||||
PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser,
|
||||
PartialWebhook, RemovalIntention, Report, Server, User, UserSettings, Webhook,
|
||||
};
|
||||
use revolt_result::Error;
|
||||
|
||||
@@ -89,6 +92,7 @@ pub enum EventV1 {
|
||||
id: String,
|
||||
channel: String,
|
||||
data: PartialMessage,
|
||||
#[serde(default)]
|
||||
clear: Vec<FieldsMessage>,
|
||||
},
|
||||
|
||||
@@ -140,6 +144,7 @@ pub enum EventV1 {
|
||||
ServerUpdate {
|
||||
id: String,
|
||||
data: PartialServer,
|
||||
#[serde(default)]
|
||||
clear: Vec<FieldsServer>,
|
||||
},
|
||||
|
||||
@@ -150,6 +155,7 @@ pub enum EventV1 {
|
||||
ServerMemberUpdate {
|
||||
id: MemberCompositeKey,
|
||||
data: PartialMember,
|
||||
#[serde(default)]
|
||||
clear: Vec<FieldsMember>,
|
||||
},
|
||||
|
||||
@@ -168,6 +174,7 @@ pub enum EventV1 {
|
||||
id: String,
|
||||
role_id: String,
|
||||
data: PartialRole,
|
||||
#[serde(default)]
|
||||
clear: Vec<FieldsRole>,
|
||||
},
|
||||
|
||||
@@ -178,6 +185,7 @@ pub enum EventV1 {
|
||||
UserUpdate {
|
||||
id: String,
|
||||
data: PartialUser,
|
||||
#[serde(default)]
|
||||
clear: Vec<FieldsUser>,
|
||||
event_id: Option<String>,
|
||||
},
|
||||
@@ -212,6 +220,7 @@ pub enum EventV1 {
|
||||
ChannelUpdate {
|
||||
id: String,
|
||||
data: PartialChannel,
|
||||
#[serde(default)]
|
||||
clear: Vec<FieldsChannel>,
|
||||
},
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use std::{collections::HashSet, hash::RandomState};
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use iso8601_timestamp::Timestamp;
|
||||
@@ -338,7 +338,34 @@ impl Message {
|
||||
}
|
||||
|
||||
if !mentions.is_empty() {
|
||||
message.mentions.replace(mentions.into_iter().collect());
|
||||
// FIXME: temp fix to stop spam attacks
|
||||
match channel {
|
||||
Channel::DirectMessage { ref recipients, .. }
|
||||
| Channel::Group { ref recipients, .. } => {
|
||||
let recipients_hash: HashSet<&String, RandomState> =
|
||||
HashSet::from_iter(recipients.iter());
|
||||
|
||||
mentions.retain(|m| recipients_hash.contains(m));
|
||||
}
|
||||
Channel::TextChannel { ref server, .. }
|
||||
| Channel::VoiceChannel { ref server, .. } => {
|
||||
let mentions_vec = Vec::from_iter(mentions.iter().cloned());
|
||||
let valid_members = db.fetch_members(server.as_str(), &mentions_vec[..]).await;
|
||||
if let Ok(valid_members) = valid_members {
|
||||
let valid_ids: HashSet<String, RandomState> = HashSet::from_iter(
|
||||
valid_members.iter().map(|member| member.id.user.clone()),
|
||||
);
|
||||
mentions.retain(|m| valid_ids.contains(m));
|
||||
} else {
|
||||
revolt_config::capture_error(&valid_members.unwrap_err());
|
||||
}
|
||||
}
|
||||
Channel::SavedMessages { .. } => mentions.clear(),
|
||||
}
|
||||
|
||||
if !mentions.is_empty() {
|
||||
message.mentions.replace(mentions.into_iter().collect());
|
||||
}
|
||||
}
|
||||
|
||||
if !replies.is_empty() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-files"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
license = "AGPL-3.0-or-later"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
@@ -20,10 +20,10 @@ typenum = "1.17.0"
|
||||
aws-config = "1.5.5"
|
||||
aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] }
|
||||
|
||||
revolt-config = { version = "0.7.18", path = "../config", features = [
|
||||
revolt-config = { version = "0.7.19", path = "../config", features = [
|
||||
"report-macros",
|
||||
] }
|
||||
revolt-result = { version = "0.7.18", path = "../result" }
|
||||
revolt-result = { version = "0.7.19", path = "../result" }
|
||||
|
||||
# image processing
|
||||
jxl-oxide = "0.8.1"
|
||||
|
||||
@@ -124,13 +124,24 @@ pub fn image_size(f: &NamedTempFile) -> Option<(usize, usize)> {
|
||||
}
|
||||
|
||||
/// Determine size of image with buffer
|
||||
pub fn image_size_vec(v: &[u8]) -> Option<(usize, usize)> {
|
||||
if let Ok(size) = imagesize::blob_size(v)
|
||||
.inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}"))
|
||||
{
|
||||
Some((size.width, size.height))
|
||||
} else {
|
||||
None
|
||||
pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> {
|
||||
match mime {
|
||||
"image/svg+xml" => {
|
||||
let tree =
|
||||
report_internal_error!(usvg::Tree::from_data(v, &Default::default())).ok()?;
|
||||
|
||||
let size = tree.size();
|
||||
Some((size.width() as usize, size.height() as usize))
|
||||
}
|
||||
_ => {
|
||||
if let Ok(size) = imagesize::blob_size(v)
|
||||
.inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}"))
|
||||
{
|
||||
Some((size.width, size.height))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-models"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
@@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"]
|
||||
|
||||
[dependencies]
|
||||
# Core
|
||||
revolt-config = { version = "0.7.18", path = "../config" }
|
||||
revolt-permissions = { version = "0.7.18", path = "../permissions" }
|
||||
revolt-config = { version = "0.7.19", path = "../config" }
|
||||
revolt-permissions = { version = "0.7.19", path = "../permissions" }
|
||||
|
||||
# Utility
|
||||
regex = "1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-permissions"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
@@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] }
|
||||
|
||||
[dependencies]
|
||||
# Core
|
||||
revolt-result = { version = "0.7.18", path = "../result" }
|
||||
revolt-result = { version = "0.7.19", path = "../result" }
|
||||
|
||||
# Utility
|
||||
auto_ops = "0.3.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-presence"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
license = "AGPL-3.0-or-later"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-result"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["Paul Makles <me@insrt.uk>"]
|
||||
|
||||
@@ -80,6 +80,7 @@ impl IntoResponse for Error {
|
||||
ErrorType::FileTooLarge { .. } => StatusCode::UNPROCESSABLE_ENTITY,
|
||||
ErrorType::FileTypeNotAllowed => StatusCode::BAD_REQUEST,
|
||||
ErrorType::ImageProcessingFailed => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
ErrorType::NoEmbedData => StatusCode::BAD_REQUEST,
|
||||
};
|
||||
|
||||
(status, Json(&self)).into_response()
|
||||
|
||||
@@ -163,6 +163,7 @@ pub enum ErrorType {
|
||||
},
|
||||
FileTypeNotAllowed,
|
||||
ImageProcessingFailed,
|
||||
NoEmbedData,
|
||||
|
||||
// ? Legacy errors
|
||||
VosoUnavailable,
|
||||
|
||||
@@ -85,6 +85,7 @@ impl<'r> Responder<'r, 'static> for Error {
|
||||
ErrorType::FileTooLarge { .. } => Status::UnprocessableEntity,
|
||||
ErrorType::FileTypeNotAllowed => Status::BadRequest,
|
||||
ErrorType::ImageProcessingFailed => Status::InternalServerError,
|
||||
ErrorType::NoEmbedData => Status::BadRequest,
|
||||
};
|
||||
|
||||
// Serialize the error data structure into JSON.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-delta"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
license = "AGPL-3.0-or-later"
|
||||
authors = ["Paul Makles <paulmakles@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-autumn"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
@@ -42,12 +42,12 @@ tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
|
||||
# Core crates
|
||||
revolt-files = { version = "0.7.18", path = "../../core/files" }
|
||||
revolt-config = { version = "0.7.18", path = "../../core/config" }
|
||||
revolt-database = { version = "0.7.18", path = "../../core/database", features = [
|
||||
revolt-files = { version = "0.7.19", path = "../../core/files" }
|
||||
revolt-config = { version = "0.7.19", path = "../../core/config" }
|
||||
revolt-database = { version = "0.7.19", path = "../../core/database", features = [
|
||||
"axum-impl",
|
||||
] }
|
||||
revolt-result = { version = "0.7.18", path = "../../core/result", features = [
|
||||
revolt-result = { version = "0.7.19", path = "../../core/result", features = [
|
||||
"utoipa",
|
||||
"axum",
|
||||
] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revolt-january"
|
||||
version = "0.7.18"
|
||||
version = "0.7.19"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
@@ -31,13 +31,13 @@ tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
|
||||
# Core crates
|
||||
revolt-config = { version = "0.7.18", path = "../../core/config" }
|
||||
revolt-models = { version = "0.7.18", path = "../../core/models" }
|
||||
revolt-result = { version = "0.7.18", path = "../../core/result", features = [
|
||||
revolt-config = { version = "0.7.19", path = "../../core/config" }
|
||||
revolt-models = { version = "0.7.19", path = "../../core/models" }
|
||||
revolt-result = { version = "0.7.19", path = "../../core/result", features = [
|
||||
"utoipa",
|
||||
"axum",
|
||||
] }
|
||||
revolt-files = { version = "0.7.18", path = "../../core/files" }
|
||||
revolt-files = { version = "0.7.19", path = "../../core/files" }
|
||||
|
||||
# Axum / web server
|
||||
axum = { version = "0.7.5" }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use axum::{extract::Query, response::IntoResponse, routing::get, Json, Router};
|
||||
use reqwest::header;
|
||||
use revolt_result::Result;
|
||||
use revolt_models::v0::Embed;
|
||||
use revolt_result::{create_error, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
@@ -87,5 +88,9 @@ async fn embed(
|
||||
Query(UrlQuery { url }): Query<UrlQuery>,
|
||||
// TypedHeader(Authorization(_bearer)): TypedHeader<Authorization<Bearer>>,
|
||||
) -> Result<impl IntoResponse> {
|
||||
Request::generate_embed(url).await.map(Json)
|
||||
match Request::generate_embed(url).await {
|
||||
Ok(Embed::None) => Err(create_error!(NoEmbedData)),
|
||||
result => result,
|
||||
}
|
||||
.map(Json)
|
||||
}
|
||||
|
||||
@@ -122,20 +122,21 @@ impl Request {
|
||||
_ => Ok(None),
|
||||
}
|
||||
} else {
|
||||
let response = if let Some(Request { response, .. }) = request {
|
||||
response
|
||||
let request = if let Some(request) = request {
|
||||
request
|
||||
} else {
|
||||
let Request { response, mime } = Request::new(url).await?;
|
||||
if matches!(mime.type_(), mime::IMAGE) {
|
||||
response
|
||||
let request = Request::new(url).await?;
|
||||
if matches!(request.mime.type_(), mime::IMAGE) {
|
||||
request
|
||||
} else {
|
||||
return Err(create_error!(FileTypeNotAllowed));
|
||||
}
|
||||
};
|
||||
|
||||
if let Some((width, height)) =
|
||||
image_size_vec(&report_internal_error!(response.bytes().await)?)
|
||||
{
|
||||
if let Some((width, height)) = image_size_vec(
|
||||
&report_internal_error!(request.response.bytes().await)?,
|
||||
request.mime.as_ref(),
|
||||
) {
|
||||
Ok(Some(Image {
|
||||
url: url.to_owned(),
|
||||
width,
|
||||
|
||||
@@ -156,8 +156,13 @@ pub async fn create_website_embed(original_url: &str, document: &str) -> Option<
|
||||
}
|
||||
}
|
||||
|
||||
// remove image if video exists
|
||||
if metadata.video.is_some() {
|
||||
metadata.image.take();
|
||||
}
|
||||
|
||||
// fetch image size if missing
|
||||
if metadata.special.is_none() && metadata.image.is_none() {
|
||||
if metadata.special.is_none() {
|
||||
if let Some(Image {
|
||||
width, height, url, ..
|
||||
}) = &metadata.image
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
- [Introduction](./hello.md)
|
||||
- [Project Structure]()
|
||||
- [Creating new API features](./new_features.md)
|
||||
- [Testing]()
|
||||
- [Writing a new database test]()
|
||||
- [Writing a new API test]()
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# New API features
|
||||
|
||||
New API features must be documented where appropriate, this document aims to cover everywhere you need to update for new features.
|
||||
|
||||
Before writing new API features, generally a good idea to:
|
||||
|
||||
- Consult with other developers in the [Revolt Developers space](https://rvlt.gg/API)
|
||||
- If it's a relatively big feature, also [write an RFC](https://github.com/revoltchat/rfcs)
|
||||
|
||||
When your feature is ready to release, ensure to:
|
||||
|
||||
- Update backend documentation (what you're reading now!) if applicable
|
||||
- Update the [developers documentation](https://github.com/revoltchat/wiki) if applicable
|
||||
- Update the Feature Matrix (or ask someone that can to do so)
|
||||
- Ensure it is properly listed in the backend release changelog
|
||||
Reference in New Issue
Block a user