Rebrand to INBUXA: product name, protocol greetings, sign-in page, calendar templates, logos, README
One branding module (types::brand!) supplies the name to every protocol greeting, the HTTP realm, the startup banner, Received headers, the user agent, the IMAP ID response and calendar PRODIDs. The sign-in and calendar pages take ihasmail's palette and font and the INBUXA logo, and calendar emails embed the INBUXA lockup. Default calendar and address book names follow. Protocol identifiers (urn:stalwart:jmap, vnd.stalwart Sieve extensions) and upstream copyright notices are unchanged.
This commit is contained in:
@@ -90,7 +90,7 @@ impl Scripting {
|
||||
.with_protected_headers(untrusted.protected_headers)
|
||||
.with_vacation_default_subject(untrusted.default_subject)
|
||||
.with_vacation_subject_prefix(untrusted.default_subject_prefix)
|
||||
.with_env_variable("name", "Stalwart Server")
|
||||
.with_env_variable("name", types::brand_server!())
|
||||
.with_env_variable("version", VERSION_PUBLIC)
|
||||
.with_env_variable("location", "MS")
|
||||
.with_env_variable("phase", "during");
|
||||
|
||||
@@ -190,7 +190,7 @@ impl Network {
|
||||
}),
|
||||
info: Info {
|
||||
provider: Provider {
|
||||
name: "Stalwart".into(),
|
||||
name: types::brand!().into(),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
|
||||
+10
-59
@@ -78,9 +78,9 @@ pub use psl;
|
||||
pub static VERSION_PRIVATE: &str = env!("CARGO_PKG_VERSION");
|
||||
pub static VERSION_PUBLIC: &str = "1.0.0";
|
||||
|
||||
pub static USER_AGENT: &str = "Stalwart/1.0.0";
|
||||
pub static DAEMON_NAME: &str = concat!("Stalwart v", env!("CARGO_PKG_VERSION"),);
|
||||
pub static PROD_ID: &str = "-//Stalwart Labs LLC//Stalwart Server//EN";
|
||||
pub static USER_AGENT: &str = concat!(types::brand!(), "/1.0.0");
|
||||
pub static DAEMON_NAME: &str = concat!(types::brand!(), " v", env!("CARGO_PKG_VERSION"),);
|
||||
pub static PROD_ID: &str = types::brand_prodid!();
|
||||
|
||||
/*
|
||||
|
||||
@@ -415,59 +415,10 @@ pub struct ThrottleKeyHasher {
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ThrottleKeyHasherBuilder {}
|
||||
|
||||
pub const DEFAULT_LOGO_BASE64: &str = "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\r\n\
|
||||
AElFTkSuQmCC";
|
||||
/// The logo embedded in calendar emails when no custom logo is set: INBUXA's
|
||||
/// compact lockup at 380x80, twice its 180-pixel display width. Base64 with
|
||||
/// CRLF line breaks, ready for a base64 MIME part.
|
||||
pub const DEFAULT_LOGO_BASE64: &str = include_str!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/../../resources/branding/email-logo.png.b64"
|
||||
));
|
||||
|
||||
@@ -38,7 +38,8 @@ pub struct IpcReceivers {
|
||||
}
|
||||
|
||||
const HELP: &str = concat!(
|
||||
"Stalwart Server v",
|
||||
types::brand_server!(),
|
||||
" v",
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
r#"
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ use store::write::{AnyClass, AnyKey, BatchBuilder, ValueClass};
|
||||
use store::{Deserialize, IterateParams, SUBSPACE_INDEXES, SUBSPACE_REGISTRY_IDX, Store};
|
||||
|
||||
const HELP: &str = concat!(
|
||||
"Stalwart Server v",
|
||||
types::brand_server!(),
|
||||
" v",
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
r#" Data Store CLI
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ impl Core {
|
||||
if !conflicts.is_empty() {
|
||||
eprintln!(
|
||||
"Cannot import: the target database already contains data in the key ranges being \
|
||||
imported. This usually means Stalwart was started before the import ran, which \
|
||||
imported. This usually means the server was started before the import ran, which \
|
||||
can create duplicate entries. Import into a fresh, empty database and do not \
|
||||
start Stalwart before importing. Conflicting dumps:"
|
||||
start the server before importing. Conflicting dumps:"
|
||||
);
|
||||
for path in conflicts {
|
||||
eprintln!(" {}", path.display());
|
||||
|
||||
@@ -38,7 +38,7 @@ impl OpenIdDirectory {
|
||||
|
||||
pub async fn new(config: OidcConfig) -> Result<Self, OidcError> {
|
||||
let http = utils::http::http_client_builder(false)
|
||||
.user_agent("Stalwart/1.0")
|
||||
.user_agent("INBUXA/1.0") // types::brand!(); this crate does not depend on types
|
||||
.timeout(Duration::from_secs(30))
|
||||
.build()
|
||||
.map_err(|e| OidcError::Network(format!("HTTP client build failed: {e}")))?;
|
||||
|
||||
@@ -110,7 +110,7 @@ impl EncryptMessage for Message<'_> {
|
||||
outer_message.extend_from_slice(
|
||||
concat!(
|
||||
"\"\r\n\r\n",
|
||||
"OpenPGP/MIME message (Automatically encrypted by Stalwart)\r\n\r\n",
|
||||
concat!("OpenPGP/MIME message (Automatically encrypted by ", types::brand!(), ")\r\n\r\n"),
|
||||
"--"
|
||||
)
|
||||
.as_bytes(),
|
||||
|
||||
@@ -779,7 +779,7 @@ impl SieveScriptIngest for Server {
|
||||
fn write_received_header(buf: &mut Vec<u8>, hostname: &str, id: u64) {
|
||||
buf.extend_from_slice(b"Received: from localhost (localhost [127.0.0.1])\r\n\tby ");
|
||||
buf.extend_from_slice(hostname.as_bytes());
|
||||
buf.extend_from_slice(b" (Stalwart SMTP) with LMTP id ");
|
||||
buf.extend_from_slice(concat!(" (", types::brand!(), " SMTP) with LMTP id ").as_bytes());
|
||||
buf.extend_from_slice(format!("{id:X}").as_bytes());
|
||||
buf.extend_from_slice(b";\r\n\t");
|
||||
buf.extend_from_slice(Date::now().to_rfc822().as_bytes());
|
||||
|
||||
@@ -267,10 +267,10 @@ pub fn accept_language(req: &HttpRequest) -> &str {
|
||||
}
|
||||
|
||||
const BEARER_CHALLENGE: &str = concat!(
|
||||
"Bearer realm=\"Stalwart Server\", ",
|
||||
concat!("Bearer realm=\"", types::brand_server!(), "\", "),
|
||||
"resource_metadata=\"/.well-known/oauth-protected-resource\""
|
||||
);
|
||||
const BASIC_CHALLENGE: &str = "Basic realm=\"Stalwart Server\"";
|
||||
const BASIC_CHALLENGE: &str = concat!("Basic realm=\"", types::brand_server!(), "\"");
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AuthChallenge {
|
||||
|
||||
@@ -13,7 +13,7 @@ use imap_proto::{ResponseCode, StatusResponse, protocol::capability::Capability}
|
||||
pub mod core;
|
||||
pub mod op;
|
||||
|
||||
static SERVER_GREETING: &str = "Stalwart IMAP4rev2 at your service.";
|
||||
static SERVER_GREETING: &str = concat!(types::brand!(), " IMAP4rev2 at your service.");
|
||||
|
||||
pub(crate) static GREETING_WITH_TLS: LazyLock<Vec<u8>> =
|
||||
LazyLock::new(|| build_greeting(true, true));
|
||||
|
||||
@@ -68,8 +68,11 @@ impl<T: SessionStream> Session<T> {
|
||||
.with_tag(request.tag)
|
||||
.serialize(
|
||||
concat!(
|
||||
"* ID (\"name\" \"Stalwart\" \"version\" \"1.0.0\" \"vendor\" \"Stalwart Labs LLC\" ",
|
||||
"\"support-url\" \"https://stalw.art\")\r\n"
|
||||
"* ID (\"name\" \"",
|
||||
types::brand!(),
|
||||
"\" \"version\" \"1.0.0\" \"vendor\" \"",
|
||||
types::brand!(),
|
||||
"\")\r\n"
|
||||
)
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
|
||||
@@ -15,7 +15,7 @@ impl<T: SessionStream> Session<T> {
|
||||
let op_start = Instant::now();
|
||||
|
||||
let mut response =
|
||||
StatusResponse::bye("Stalwart IMAP4rev2 bids you farewell.".to_string()).into_bytes();
|
||||
StatusResponse::bye(concat!(types::brand!(), " IMAP4rev2 bids you farewell.").to_string()).into_bytes();
|
||||
|
||||
trc::event!(
|
||||
Imap(trc::ImapEvent::Logout),
|
||||
|
||||
@@ -407,7 +407,7 @@ impl Session {
|
||||
impl Default for SieveSessionCapabilities {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
implementation: "Stalwart v1.0.0",
|
||||
implementation: concat!(types::brand!(), " v1.0.0"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "stalwart"
|
||||
description = "Stalwart Mail and Collaboration Server"
|
||||
description = "INBUXA Mail and Collaboration Server, a fork of Stalwart"
|
||||
authors = [ "Stalwart Labs LLC <[email protected]>"]
|
||||
repository = "https://github.com/stalwartlabs/stalwart"
|
||||
homepage = "https://stalw.art"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
pub mod core;
|
||||
pub mod op;
|
||||
|
||||
static SERVER_GREETING: &str = "Stalwart ManageSieve at your service.";
|
||||
static SERVER_GREETING: &str = concat!(types::brand!(), " ManageSieve at your service.");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -14,7 +14,7 @@ impl<T: SessionStream> Session<T> {
|
||||
let op_start = Instant::now();
|
||||
|
||||
let mut response = Vec::with_capacity(128);
|
||||
response.extend_from_slice(b"\"IMPLEMENTATION\" \"Stalwart ManageSieve\"\r\n");
|
||||
response.extend_from_slice(concat!("\"IMPLEMENTATION\" \"", types::brand!(), " ManageSieve\"\r\n").as_bytes());
|
||||
response.extend_from_slice(b"\"VERSION\" \"1.0\"\r\n");
|
||||
if !self.stream.is_tls() {
|
||||
response.extend_from_slice(b"\"STARTTLS\"\r\n");
|
||||
|
||||
@@ -16,6 +16,6 @@ impl<T: AsyncRead + AsyncWrite> Session<T> {
|
||||
Elapsed = trc::Value::Duration(0)
|
||||
);
|
||||
|
||||
Ok(StatusResponse::ok("Stalwart ManageSieve bids you farewell.").into_bytes())
|
||||
Ok(StatusResponse::ok(concat!(types::brand!(), " ManageSieve bids you farewell.")).into_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ pub mod op;
|
||||
pub mod protocol;
|
||||
pub mod session;
|
||||
|
||||
static SERVER_GREETING: &str = "+OK Stalwart POP3 at your service.\r\n";
|
||||
static SERVER_GREETING: &str = concat!("+OK ", types::brand!(), " POP3 at your service.\r\n");
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Pop3SessionManager {
|
||||
|
||||
@@ -107,7 +107,8 @@ impl<T: SessionStream> Session<T> {
|
||||
}
|
||||
if not_deleted.is_empty() {
|
||||
self.write_ok(format!(
|
||||
"Stalwart POP3 bids you farewell ({num_deleted} messages deleted)."
|
||||
concat!(types::brand!(), " POP3 bids you farewell ({} messages deleted)."),
|
||||
num_deleted
|
||||
))
|
||||
.await?;
|
||||
} else {
|
||||
@@ -118,11 +119,11 @@ impl<T: SessionStream> Session<T> {
|
||||
.await?;
|
||||
}
|
||||
} else {
|
||||
self.write_ok("Stalwart POP3 bids you farewell (no messages deleted).")
|
||||
self.write_ok(concat!(types::brand!(), " POP3 bids you farewell (no messages deleted)."))
|
||||
.await?;
|
||||
}
|
||||
} else {
|
||||
self.write_ok("Stalwart POP3 bids you farewell.").await?;
|
||||
self.write_ok(concat!(types::brand!(), " POP3 bids you farewell.")).await?;
|
||||
}
|
||||
|
||||
trc::event!(
|
||||
|
||||
@@ -114,7 +114,7 @@ impl<'x, T: Display> Response<'x, T> {
|
||||
"EXPIRE NEVER",
|
||||
"UIDL",
|
||||
"UTF8",
|
||||
"IMPLEMENTATION Stalwart Server",
|
||||
concat!("IMPLEMENTATION ", types::brand_server!()),
|
||||
] {
|
||||
buf.extend_from_slice(capa.as_bytes());
|
||||
buf.extend_from_slice(b"\r\n");
|
||||
@@ -200,7 +200,7 @@ mod tests {
|
||||
"EXPIRE NEVER\r\n",
|
||||
"UIDL\r\n",
|
||||
"UTF8\r\n",
|
||||
"IMPLEMENTATION Stalwart Server\r\n.\r\n"
|
||||
concat!("IMPLEMENTATION ", types::brand_server!(), "\r\n.\r\n")
|
||||
),
|
||||
),
|
||||
(
|
||||
|
||||
@@ -730,7 +730,7 @@ impl Pickle for AddressBook {
|
||||
impl Default for AddressBook {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
default_display_name: Some("Stalwart Address Book".to_string()),
|
||||
default_display_name: Some("INBUXA Address Book".to_string()),
|
||||
default_href_name: Some("default".to_string()),
|
||||
max_v_card_size: 524288u64,
|
||||
max_address_books: Some(250u64),
|
||||
@@ -4595,7 +4595,7 @@ impl Pickle for Calendar {
|
||||
impl Default for Calendar {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
default_display_name: Some("Stalwart Calendar".to_string()),
|
||||
default_display_name: Some("INBUXA Calendar".to_string()),
|
||||
default_href_name: Some("default".to_string()),
|
||||
max_attendees: 20u64,
|
||||
max_recurrence_expansions: 3000u64,
|
||||
@@ -4732,7 +4732,7 @@ impl Default for CalendarAlarm {
|
||||
allow_external_rcpts: false,
|
||||
enable: true,
|
||||
from_email: Default::default(),
|
||||
from_name: "Stalwart Calendar".to_string(),
|
||||
from_name: "INBUXA Calendar".to_string(),
|
||||
min_trigger_interval: Duration::from_millis(3600000),
|
||||
template: Default::default(),
|
||||
}
|
||||
@@ -28308,7 +28308,7 @@ impl MtaStageConnect {
|
||||
ExpressionContext {
|
||||
expr: &self.smtp_greeting,
|
||||
default: Some(Expression {
|
||||
else_: "system('hostname') + ' Stalwart ESMTP at your service'".to_string(),
|
||||
else_: "system('hostname') + ' INBUXA ESMTP at your service'".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
property: Property::SmtpGreeting,
|
||||
@@ -28372,7 +28372,7 @@ impl Default for MtaStageConnect {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
smtp_greeting: Expression {
|
||||
else_: "system('hostname') + ' Stalwart ESMTP at your service'".to_string(),
|
||||
else_: "system('hostname') + ' INBUXA ESMTP at your service'".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
hostname: Expression {
|
||||
|
||||
@@ -130,7 +130,7 @@ impl<T: SessionStream> Session<T> {
|
||||
.await
|
||||
.filter(|g| !g.is_empty())
|
||||
.map(|g| format!("220 {}\r\n", g))
|
||||
.unwrap_or_else(|| "220 Stalwart ESMTP at your service.\r\n".to_string());
|
||||
.unwrap_or_else(|| concat!("220 ", types::brand!(), " ESMTP at your service.\r\n").to_string());
|
||||
|
||||
if self.write(greeting.as_bytes()).await.is_err() {
|
||||
return false;
|
||||
|
||||
@@ -3661,8 +3661,8 @@ impl EventType {
|
||||
EventType::Security(SecurityEvent::IpAllowExpired) => "IP allow expired",
|
||||
EventType::Security(SecurityEvent::IpUnauthorized) => "Unauthorized IP address",
|
||||
EventType::Security(SecurityEvent::Unauthorized) => "Unauthorized access",
|
||||
EventType::Server(ServerEvent::Startup) => "Starting Stalwart Server",
|
||||
EventType::Server(ServerEvent::Shutdown) => "Shutting down Stalwart Server",
|
||||
EventType::Server(ServerEvent::Startup) => "Starting INBUXA Server",
|
||||
EventType::Server(ServerEvent::Shutdown) => "Shutting down INBUXA Server",
|
||||
EventType::Server(ServerEvent::StartupError) => "Server startup error",
|
||||
EventType::Server(ServerEvent::ThreadError) => "Server thread error",
|
||||
EventType::Server(ServerEvent::Licensing) => "Server licensing event",
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 John Coffey
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
//! The product's name, in one place.
|
||||
//!
|
||||
//! Every name the server shows people (protocol greetings, the HTTP sign-in
|
||||
//! realm, the startup banner, calendar product ids, the name mail clients see
|
||||
//! during setup) comes from here. That keeps the rebrand to a single file when
|
||||
//! merging upstream releases, instead of a scattering of string edits.
|
||||
//!
|
||||
//! These are macros, not constants, so they can be joined into other string
|
||||
//! literals at compile time with `concat!`.
|
||||
|
||||
/// The product name: `INBUXA`.
|
||||
#[macro_export]
|
||||
macro_rules! brand {
|
||||
() => {
|
||||
"INBUXA"
|
||||
};
|
||||
}
|
||||
|
||||
/// The server's full name: `INBUXA Server`.
|
||||
#[macro_export]
|
||||
macro_rules! brand_server {
|
||||
() => {
|
||||
concat!($crate::brand!(), " Server")
|
||||
};
|
||||
}
|
||||
|
||||
/// The iCalendar and vCard `PRODID`.
|
||||
#[macro_export]
|
||||
macro_rules! brand_prodid {
|
||||
() => {
|
||||
concat!("-//", $crate::brand!(), "//", $crate::brand_server!(), "//EN")
|
||||
};
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
pub mod acl;
|
||||
pub mod blob;
|
||||
pub mod branding;
|
||||
pub mod blob_hash;
|
||||
pub mod collection;
|
||||
pub mod dead_property;
|
||||
|
||||
Reference in New Issue
Block a user