Compare commits

..

2 Commits

Author SHA1 Message Date
Ginger dfe690ef85 ci: Add dispatch test workflow 2026-01-12 11:30:42 -05:00
Ginger 7752dfdc8d fix(ci): Forbid our packages from being published to a crate repository 2026-01-12 11:05:56 -05:00
21 changed files with 147 additions and 124 deletions
+57
View File
@@ -0,0 +1,57 @@
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log Level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
tags:
description: 'Test scenario tags'
required: false
type: boolean
boolean_default_true:
description: 'Test scenario tags'
required: true
type: boolean
default: true
boolean_default_false:
description: 'Test scenario tags'
required: false
type: boolean
default: false
number1_default:
description: 'Number w. default'
default: '100'
type: number
number2:
description: 'Number w/o. default'
type: number
string1_default:
description: 'String w. default'
default: 'Hello world'
type: string
string2:
description: 'String w/o. default'
required: true
type: string
jobs:
test:
runs-on: docker
container:
image: code.forgejo.org/oci/debian:trixie
options: "--volume /srv/example:/srv/example"
steps:
- name: save and display context
run: |
d=/srv/example/workflow-dispatch/contexts/$FORGEJO_EVENT_NAME
mkdir -p $d
tee $d/github <<'EOF'
${{ toJSON(github) }}
EOF
-21
View File
@@ -1,24 +1,3 @@
# Continuwuity 0.5.3 (2026-01-12)
## Features
- Improve the display of nested configuration with the `!admin server show-config` command. Contributed by @Jade (#1279)
## Bugfixes
- Fixed `M_BAD_JSON` error when sending invites to other servers or when providing joins. Contributed by @nex (#1286)
## Docs
- Improve admin command documentation generation. Contributed by @ginger (#1280)
## Misc
- Improve timeout-related code for federation and URL previews. Contributed by @Jade
# Continuwuity 0.5.2 (2026-01-09)
## Features
Generated
+11 -11
View File
@@ -954,7 +954,7 @@ dependencies = [
[[package]]
name = "conduwuit"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"clap",
"conduwuit_admin",
@@ -986,7 +986,7 @@ dependencies = [
[[package]]
name = "conduwuit_admin"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"clap",
"conduwuit_api",
@@ -1008,7 +1008,7 @@ dependencies = [
[[package]]
name = "conduwuit_api"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"async-trait",
"axum 0.7.9",
@@ -1041,14 +1041,14 @@ dependencies = [
[[package]]
name = "conduwuit_build_metadata"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"built",
]
[[package]]
name = "conduwuit_core"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"argon2",
"arrayvec",
@@ -1109,7 +1109,7 @@ dependencies = [
[[package]]
name = "conduwuit_database"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"async-channel",
"conduwuit_core",
@@ -1128,7 +1128,7 @@ dependencies = [
[[package]]
name = "conduwuit_macros"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"itertools 0.14.0",
"proc-macro2",
@@ -1138,7 +1138,7 @@ dependencies = [
[[package]]
name = "conduwuit_router"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"axum 0.7.9",
"axum-client-ip",
@@ -1173,7 +1173,7 @@ dependencies = [
[[package]]
name = "conduwuit_service"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"async-trait",
"base64 0.22.1",
@@ -1214,7 +1214,7 @@ dependencies = [
[[package]]
name = "conduwuit_web"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"askama 0.14.0",
"axum 0.7.9",
@@ -6216,7 +6216,7 @@ dependencies = [
[[package]]
name = "xtask"
version = "0.5.3"
version = "0.5.2"
dependencies = [
"askama 0.15.1",
"cargo_metadata",
+3 -1
View File
@@ -12,7 +12,9 @@ license = "Apache-2.0"
# See also `rust-toolchain.toml`
readme = "README.md"
repository = "https://forgejo.ellis.link/continuwuation/continuwuity"
version = "0.5.3"
version = "0.5.2"
# Do not allow publishing, we handle that ourselves
publish = false
[workspace.metadata.crane]
name = "conduwuit"
+4 -2
View File
@@ -1759,6 +1759,10 @@
#
#config_reload_signal = true
# This item is undocumented. Please contribute documentation for it.
#
#ldap = false
[global.tls]
# Path to a valid TLS certificate file.
@@ -1926,8 +1930,6 @@
#
#admin_filter = ""
[global.antispam]
[global.antispam.meowlnir]
# The base URL on which to contact Meowlnir (before /_meowlnir/antispam).
-7
View File
@@ -1,8 +1 @@
tag-message = "chore: Release v{{version}}"
tag-prefix = ""
shared-version = true
publish = false
sign-commit = true
sign-tag = true
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
path = "mod.rs"
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
path = "mod.rs"
+10 -1
View File
@@ -178,6 +178,15 @@ async fn create_join_event(
}
}
let origin: OwnedServerName = serde_json::from_value(
value
.get("origin")
.ok_or_else(|| err!(Request(BadJson("Event does not have an origin server name."))))?
.clone()
.into(),
)
.map_err(|e| err!(Request(BadJson("Event has an invalid origin server name: {e}"))))?;
trace!("Signing send_join event");
services
.server_keys
@@ -195,7 +204,7 @@ async fn create_join_event(
let pdu_id = services
.rooms
.event_handler
.handle_incoming_pdu(sender.server_name(), room_id, &event_id, value.clone(), true)
.handle_incoming_pdu(&origin, room_id, &event_id, value.clone(), true)
.boxed()
.await?
.ok_or_else(|| err!(Request(InvalidParam("Could not accept as timeline event."))))?;
+10 -1
View File
@@ -136,6 +136,15 @@ pub(crate) async fn create_knock_event_v1_route(
return Err!(Request(InvalidParam("state_key does not match sender user of event.")));
}
let origin: OwnedServerName = serde_json::from_value(
value
.get("origin")
.ok_or_else(|| err!(Request(BadJson("Event does not have an origin server name."))))?
.clone()
.into(),
)
.map_err(|e| err!(Request(BadJson("Event has an invalid origin server name: {e}"))))?;
let mut event: JsonObject = serde_json::from_str(body.pdu.get())
.map_err(|e| err!(Request(InvalidParam("Invalid knock event PDU: {e}"))))?;
@@ -154,7 +163,7 @@ pub(crate) async fn create_knock_event_v1_route(
let pdu_id = services
.rooms
.event_handler
.handle_incoming_pdu(sender.server_name(), &body.room_id, &event_id, value.clone(), true)
.handle_incoming_pdu(&origin, &body.room_id, &event_id, value.clone(), true)
.boxed()
.await?
.ok_or_else(|| err!(Request(InvalidParam("Could not accept as timeline event."))))?;
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
build = "build.rs"
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
path = "mod.rs"
+6 -11
View File
@@ -53,7 +53,8 @@
### For more information, see:
### https://continuwuity.org/configuration.html
"#,
ignore = "config_paths catchall"
ignore = "config_paths catchall well_known tls blurhashing \
allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure antispam"
)]
pub struct Config {
// Paths to config file(s). Not supposed to be set manually in the config file,
@@ -104,7 +105,7 @@ pub struct Config {
#[serde(default = "default_port")]
port: ListeningPort,
/// display: nested
// external structure; separate section
#[serde(default)]
pub tls: TlsConfig,
@@ -723,7 +724,7 @@ pub struct Config {
#[serde(default = "default_default_room_version")]
pub default_room_version: RoomVersionId,
/// display: nested
// external structure; separate section
#[serde(default)]
pub well_known: WellKnownConfig,
@@ -2029,22 +2030,19 @@ pub struct Config {
/// etc. This is a hidden argument that should NOT be used in production as
/// it is highly insecure and I will personally yell at you if I catch you
/// using this.
///
/// display: hidden
#[serde(default)]
pub allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure:
bool,
/// display: nested
// external structure; separate section
#[serde(default)]
pub ldap: LdapConfig,
/// Configuration for antispam support
/// display: nested
#[serde(default)]
pub antispam: Option<Antispam>,
/// display: nested
// external structure; separate section
#[serde(default)]
pub blurhashing: BlurhashConfig,
#[serde(flatten)]
@@ -2261,11 +2259,8 @@ struct ListeningAddr {
}
#[derive(Clone, Debug, Deserialize)]
#[config_example_generator(filename = "conduwuit-example.toml", section = "global.antispam")]
pub struct Antispam {
/// display: nested
pub meowlnir: Option<MeowlnirConfig>,
/// display: nested
pub draupnir: Option<DraupnirConfig>,
}
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
path = "mod.rs"
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
name = "conduwuit_macros"
+35 -69
View File
@@ -78,8 +78,6 @@ fn generate_example(input: &ItemStruct, args: &[Meta], write: bool) -> Result<To
}
let mut summary: Vec<TokenStream2> = Vec::new();
let mut nested_displays: Vec<TokenStream2> = Vec::new();
if let Fields::Named(FieldsNamed { named, .. }) = &input.fields {
for field in named {
let Some(ident) = &field.ident else {
@@ -94,6 +92,35 @@ fn generate_example(input: &ItemStruct, args: &[Meta], write: bool) -> Result<To
continue;
};
let doc = get_doc_comment(field)
.unwrap_or_else(|| undocumented.into())
.trim_end()
.to_owned();
let doc = if doc.ends_with('#') {
format!("{doc}\n")
} else {
format!("{doc}\n#\n")
};
let default = get_doc_comment_line(field, "default")
.or_else(|| get_default(field))
.unwrap_or_default();
let default = if !default.is_empty() {
format!(" {default}")
} else {
default
};
if let Some(file) = file.as_mut() {
file.write_fmt(format_args!("\n{doc}"))
.expect("written to config file");
file.write_fmt(format_args!("#{ident} ={default}\n"))
.expect("written to config file");
}
let display = get_doc_comment_line(field, "display");
let display_directive = |key| {
display
@@ -102,77 +129,17 @@ fn generate_example(input: &ItemStruct, args: &[Meta], write: bool) -> Result<To
.flat_map(|display| display.split(' '))
.any(|directive| directive == key)
};
let is_nested = display_directive("nested");
let is_hidden = display_directive("hidden");
// Only generate config file entries for non-nested, visible types
if !is_nested && !is_hidden {
let doc = get_doc_comment(field)
.unwrap_or_else(|| undocumented.into())
.trim_end()
.to_owned();
let doc = if doc.ends_with('#') {
format!("{doc}\n")
if !display_directive("hidden") {
let value = if display_directive("sensitive") {
quote! { "***********" }
} else {
format!("{doc}\n#\n")
quote! { format_args!("{:?}", self.#ident) }
};
let default = get_doc_comment_line(field, "default")
.or_else(|| get_default(field))
.unwrap_or_default();
let default = if !default.is_empty() {
format!(" {default}")
} else {
default
};
if let Some(file) = file.as_mut() {
file.write_fmt(format_args!("\n{doc}"))
.expect("written to config file");
file.write_fmt(format_args!("#{ident} ={default}\n"))
.expect("written to config file");
}
}
// Generate Display implementation for all fields
let name = ident.to_string();
if display_directive("sensitive") {
let name = ident.to_string();
summary.push(quote! {
writeln!(out, "| {} | {} |", #name, "***********")?;
});
} else if is_nested {
let is_option = matches!(type_name.as_str(), "Option");
if is_option {
summary.push(quote! {
writeln!(out, "| {} | {} |", #name,
if self.#ident.is_some() { "[configured]" } else { "None" })?;
});
nested_displays.push(quote! {
if let Some(nested) = &self.#ident {
writeln!(out)?;
writeln!(out, "## {}", #name)?;
write!(out, "{}", nested)?;
}
});
} else {
summary.push(quote! {
writeln!(out, "| {} | [configured] |", #name)?;
});
nested_displays.push(quote! {
writeln!(out)?;
writeln!(out, "## {}", #name)?;
write!(out, "{}", &self.#ident)?;
});
}
} else {
summary.push(quote! {
writeln!(out, "| {} | {:?} |", #name, self.#ident)?;
writeln!(out, "| {} | {} |", #name, #value)?;
});
}
}
@@ -192,7 +159,6 @@ fn fmt(&self, out: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(out, "| name | value |")?;
writeln!(out, "| :--- | :--- |")?;
#( #summary )*
#( #nested_displays )*
Ok(())
}
}
+1
View File
@@ -9,6 +9,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
metadata.crane.workspace = true
[lib]
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
path = "mod.rs"
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
path = "mod.rs"
+1
View File
@@ -6,6 +6,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[lib]
path = "mod.rs"
+1
View File
@@ -8,6 +8,7 @@ license.workspace = true
readme.workspace = true
repository.workspace = true
version.workspace = true
publish.workspace = true
[dependencies]
conduwuit-admin.workspace = true