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:
2026-09-18 10:52:34 -07:00
parent 6e73d284d8
commit 89665decfa
70 changed files with 616 additions and 442 deletions
+44 -166
View File
@@ -1,186 +1,64 @@
<p align="center">
<a href="https://stalw.art">
<img src="./img/logo-red.svg" height="150">
</a>
<img src="./img/brand/inbuxa-lockup-light.svg" alt="inbuxa" height="140">
</p>
<h3 align="center">
Secure, scalable mail & collaboration server with comprehensive protocol support 🛡️ <br/>(IMAP, JMAP, SMTP, CalDAV, CardDAV, WebDAV)
A complete mail and collaboration server, every feature included, under the AGPL
</h3>
<br>
---
<p align="center">
<a href="https://github.com/stalwartlabs/stalwart/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/stalwartlabs/stalwart/ci.yml?style=flat-square" alt="continuous integration"></a>
&nbsp;
<a href="https://www.gnu.org/licenses/agpl-3.0"><img src="https://img.shields.io/badge/License-AGPL_v3-blue.svg?label=license&style=flat-square" alt="License: AGPL v3"></a>
&nbsp;
<a href="https://stalw.art/docs/install/get-started"><img src="https://img.shields.io/badge/read_the-docs-red?style=flat-square" alt="Documentation"></a>
&nbsp;
<a href="https://github.com/stalwartlabs/stalwart/releases"><img src="https://img.shields.io/github/downloads/stalwartlabs/stalwart/total?style=flat-square" alt="downloads"></a
</p>
<p align="center">
<a href="https://mastodon.social/@stalwartlabs"><img src="https://img.shields.io/mastodon/follow/109929667531941122?style=flat-square&logo=mastodon&color=%236364ff&label=Mastodon" alt="Mastodon"></a>
&nbsp;
<a href="https://twitter.com/stalwartlabs"><img src="https://img.shields.io/twitter/follow/stalwartlabs?style=flat-square&logo=x&label=Twitter" alt="Twitter"></a>
<a href="https://discord.gg/vhqRgdhguq"><img src="https://img.shields.io/discord/923615863037390889?label=Discord&logo=discord&style=flat-square" alt="Discord"></a>
&nbsp;
<a href="https://www.reddit.com/r/stalwartlabs/"><img src="https://img.shields.io/reddit/subreddit-subscribers/stalwartlabs?label=%2Fr%2Fstalwartlabs&logo=reddit&style=flat-square" alt="Reddit"></a>
</p>
**INBUXA** is a mail and collaboration server: JMAP, IMAP, POP3, SMTP,
CalDAV, CardDAV and WebDAV, in one Rust binary, with ihasmail as its web front
end. It is a fork of [Stalwart](https://github.com/stalwartlabs/stalwart).
## Features
Stalwart ships some features only in a paid Enterprise Edition: multi-tenancy,
masked email, undelete and others. INBUXA ships everything to everybody under
the AGPL-3.0, rebuilding those features independently and without using any
of Stalwart's Enterprise code.
**Stalwart** is an open-source mail & collaboration server with JMAP, IMAP4, POP3, SMTP, CalDAV, CardDAV and WebDAV support and a wide range of modern features. It is written in Rust and designed to be secure, fast, robust and scalable.
> **Status: in development, not released.** The fork builds, passes its unit
> tests, and runs as a working mail server. The Enterprise features are being
> specified and haven't been rebuilt yet. Don't run it in production.
Key features:
## What's different from Stalwart
- **Email** server with complete protocol support:
- JMAP:
* [JMAP for Mail](https://datatracker.ietf.org/doc/html/rfc8621) server.
* [JMAP for Sieve Scripts](https://www.ietf.org/archive/id/draft-ietf-jmap-sieve-22.html).
* [WebSocket](https://datatracker.ietf.org/doc/html/rfc8887), [Blob Management](https://www.rfc-editor.org/rfc/rfc9404.html) and [Quotas](https://www.rfc-editor.org/rfc/rfc9425.html) extensions.
- IMAP:
* [IMAP4rev2](https://datatracker.ietf.org/doc/html/rfc9051) and [IMAP4rev1](https://datatracker.ietf.org/doc/html/rfc3501) server.
* [ManageSieve](https://datatracker.ietf.org/doc/html/rfc5804) server.
* Numerous [extensions](https://stalw.art/docs/development/rfcs#imap4-and-extensions) supported.
- POP3:
- [POP3](https://datatracker.ietf.org/doc/html/rfc1939) server.
- [STLS](https://datatracker.ietf.org/doc/html/rfc2595) and [SASL](https://datatracker.ietf.org/doc/html/rfc5034) support as well as other [extensions](https://datatracker.ietf.org/doc/html/rfc2449).
- SMTP:
* SMTP server with built-in [DMARC](https://datatracker.ietf.org/doc/html/rfc7489), [DKIMv2](https://datatracker.ietf.org/doc/draft-ietf-dkim-dkim2-spec/), [DKIMv1](https://datatracker.ietf.org/doc/html/rfc6376), [SPF](https://datatracker.ietf.org/doc/html/rfc7208) and [ARC](https://datatracker.ietf.org/doc/html/rfc8617) support for message authentication.
* Strong transport security through [DANE](https://datatracker.ietf.org/doc/html/rfc6698), [MTA-STS](https://datatracker.ietf.org/doc/html/rfc8461) and [SMTP TLS](https://datatracker.ietf.org/doc/html/rfc8460) reporting.
* Automated DKIM key rotation and management.
* Inbound throttling and filtering with granular configuration rules, sieve scripting, MTA hooks and milter integration.
* Distributed virtual queues with delayed delivery, priority delivery, quotas, routing rules and throttling support.
* Envelope rewriting and message modification.
- **Collaboration** server:
- Calendaring and scheduling:
- [CalDAV](https://datatracker.ietf.org/doc/html/rfc4791) and [CalDAV Scheduling](https://datatracker.ietf.org/doc/html/rfc6638) support.
- [JMAP for Calendars](https://datatracker.ietf.org/doc/html/draft-ietf-jmap-calendars-24) support.
- Contact management:
- [CardDAV](https://datatracker.ietf.org/doc/html/rfc6352) support.
- [JMAP for Contacts](https://datatracker.ietf.org/doc/html/rfc9610) support.
- File storage:
- [WebDAV](https://datatracker.ietf.org/doc/html/rfc4918) support.
- [JMAP for File Storage](https://datatracker.ietf.org/doc/html/draft-ietf-jmap-filenode-03) support.
- Sharing with fine-grained access controls:
- [WebDAV ACL](https://datatracker.ietf.org/doc/html/rfc3744) support.
- [JMAP Sharing](https://datatracker.ietf.org/doc/html/rfc9670) support.
- **Spam** and **Phishing** built-in filter:
- Comprehensive set of filtering **rules** on par with popular solutions.
- LLM-driven spam filtering and message analysis.
- Statistical **spam classifier** with collaborative filtering, automatic training capabilities and address book integration.
- DNS Blocklists (**DNSBLs**) checking of IP addresses, domains, and hashes.
- Collaborative digest-based spam filtering with **Pyzor**.
- **Phishing** protection against homographic URL attacks, sender spoofing and other techniques.
- Trusted **reply** tracking to recognize and prioritize genuine e-mail replies.
- Sender **reputation** monitoring by IP address, ASN, domain and email address.
- **Greylisting** to temporarily defer unknown senders.
- **Spam traps** to set up decoy email addresses that catch and analyze spam.
- **Flexible**:
- Pluggable storage backends with **RocksDB**, **FoundationDB**, **PostgreSQL**, **mySQL**, **SQLite**, **S3-Compatible**, **Azure** and **Redis** support.
- Full-text search available in 17 languages using the built-in search engine or via **Meilisearch**, **ElasticSearch**, **OpenSearch**, **PostgreSQL** or **mySQL** backends.
- Sieve scripting language with support for all [registered extensions](https://www.iana.org/assignments/sieve-extensions/sieve-extensions.xhtml).
- Email aliases, mailing lists, subaddressing and catch-all addresses support.
- Automated DNS management.
- Automatic account configuration and discovery with [PACC](https://datatracker.ietf.org/doc/draft-ietf-mailmaint-pacc/), [autoconfig](https://datatracker.ietf.org/doc/draft-ietf-mailmaint-autoconfig/) and [autodiscover](https://learn.microsoft.com/en-us/exchange/architecture/client-access/autodiscover?view=exchserver-2019).
- Multi-tenancy support with domain and tenant isolation.
- Disk quotas per user and tenant.
- **Secure and robust**:
- Encryption at rest with **S/MIME** or **OpenPGP**.
- Automatic TLS certificate provisioning with [ACME](https://datatracker.ietf.org/doc/html/rfc8555) using `TLS-ALPN-01`, `DNS-01`, `DNS-PERSIST-01` or `HTTP-01` challenges.
- Automated blocking of IP addresses that attack, abuse or scan the server for exploits.
- Rate limiting.
- Security audited (read the [report](https://stalw.art/blog/security-audit)).
- Memory safe (thanks to Rust).
- **Scalable and fault-tolerant**:
- Designed to handle growth seamlessly, from small setups to large-scale deployments of thousands of nodes.
- Built with **fault tolerance** and **high availability** in mind, recovers from hardware or software failures with minimal operational impact.
- Peer-to-peer cluster coordination or with **Kafka**, **Redpanda**, **NATS** or **Redis**.
- **Kubernetes**, **Apache Mesos** and **Docker Swarm** support for automated scaling and container orchestration.
- Read replicas, sharded blob storage and in-memory data stores for high performance and low latency.
- **Authentication and Authorization**:
- **OpenID Connect** authentication.
- OAuth 2.0 authorization with [authorization code](https://www.rfc-editor.org/rfc/rfc8628) and [device authorization](https://www.rfc-editor.org/rfc/rfc8628) flows.
- **LDAP**, **OIDC**, **SQL** or built-in authentication backend support.
- System for Cross-domain Identity Management ([SCIM](https://www.rfc-editor.org/info/rfc7643/)) v2 for automated provisioning.
- Two-factor authentication with Time-based One-Time Passwords (`2FA-TOTP`)
- Application passwords (App Passwords).
- Roles and permissions.
- Access Control Lists (ACLs).
- **Observability**:
- Logging and tracing with **OpenTelemetry**, journald, log files and console support.
- Metrics with **OpenTelemetry** and **Prometheus** integration.
- Webhooks for event-driven automation.
- Alerts with email and webhook notifications.
- Live tracing and metrics.
- **Web-based administration**:
- Dashboard with real-time statistics and monitoring.
- Account, domain, group and mailing list management.
- SMTP queue management for messages and outbound DMARC and TLS reports.
- Report visualization interface for received DMARC, TLS-RPT and Failure (ARF) reports.
- Configuration of every aspect of the mail server.
- Log viewer with search and filtering capabilities.
- Self-service portal for password reset and encryption-at-rest key management.
- **Every feature, one edition.** No license key, no edition checks, no
upsell. See `docs/spec/SPEC.md` §4 for the features being rebuilt, and
`docs/spec/features/` for each one's specification.
- **Webmail and administration by ihasmail,** as a separate service that can
run beside the server or elsewhere. Stalwart's own web interface is removed,
so there's no web front end on the mail host.
- **Clean-room rebuilds.** Enterprise-only code is stripped from every
upstream release before it's imported. The rebuilt features are written
from specifications that use only public sources (`docs/spec/SPEC.md` §3).
## Screenshots
## How the fork is kept
<img src="./img/demo.gif">
Upstream releases arrive as stripped snapshots, never with upstream's git
history, which contains Enterprise code. `tools/fork/strip.py` builds each
snapshot on top of upstream's own `ossify.py`, then verifies it independently.
The report for every import is in `docs/fork/strip-reports/`. See
`docs/spec/SPEC.md` §2.
## Presentation
## Building
**Want a deeper dive?** Need to explain to your boss why Stalwart is the perfect fit? Whether you're evaluating options, making a case to your team, or simply curious about how it all works under the hood, these slides walk you through the key features, architecture, and benefits of Stalwart. Browse the [slides](https://stalw.art/slides) to see what makes it stand out.
```bash
cargo build --release -p stalwart
```
## Get Started
The binary and package are still named `stalwart` while the packaging is
reworked.
Install Stalwart on your server by following the instructions for your platform:
## License and credits
- [Linux / MacOS / FreeBSD](https://stalw.art/docs/install/platform/linux)
- [Windows](https://stalw.art/docs/install/platform/windows)
- [Docker](https://stalw.art/docs/install/platform/docker)
INBUXA is free software under the [GNU Affero General Public License,
version 3](./LICENSES/AGPL-3.0-only.txt).
All documentation is available at [stalw.art/docs](https://stalw.art/docs/install/get-started).
It is a fork of Stalwart, copyright © Stalwart Labs LLC. Upstream's
copyright notices are kept on every file they cover. Stalwart's files are
dual-licensed AGPL-3.0-only or Stalwart's Enterprise License, and INBUXA takes
them under the AGPL-3.0 only. "Stalwart" is Stalwart Labs' name. INBUXA isn't
affiliated with or endorsed by Stalwart Labs.
## Support
If you are having problems running Stalwart, found a bug, or just have a question, please head to the [Stalwart Support Portal](https://support.stalw.art) at [support.stalw.art](https://support.stalw.art).
Additionally, you may purchase an [Enterprise License](https://stalw.art/enterprise) to obtain priority support from Stalwart Labs LLC, including response-time commitments and a private Priority Support area on the portal.
## Contributing
We welcome contributions, but to keep the project maintainable there are a few things to know before opening a pull request. Because of the high volume of low-quality, AI-generated submissions, pull requests are limited to a list of vouched contributors; to be added, post at [support.stalw.art](https://support.stalw.art) describing the change you would like to submit, together with a link to the proposed change. At this stage only bug fixes and translations are accepted, and new features are not, unless they involve just a few lines of code.
For the full guidelines, please read [CONTRIBUTING.md](CONTRIBUTING.md).
## Roadmap
Stalwart has reached an exciting point in its journey, its now **feature complete**. All the core functionality and open standard email and collaboration protocols that we set out to support are in place. In other words, Stalwart already does everything youd expect from a modern, standards-compliant mail and collaboration platform.
The next major milestone is all about refinement: finalizing the database schema and focusing on performance optimizations to ensure everything runs as efficiently and reliably as possible. Once thats done, well be ready to roll out version **1.0**.
Of course, development doesnt stop there. The community has contributed hundreds of great ideas for improvements and new features, everything from subtle usability tweaks to entirely new integrations. You can see the full list of proposals over on our [GitHub issues](https://github.com/stalwartlabs/stalwart/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Aenhancement). If theres something youd like to see prioritized, just give it a thumbs up as we plan to implement enhancements based on the communitys votes.
## Sponsorship
Your support is crucial in helping us continue to improve the project, add new features, and maintain the highest level of quality. By [becoming a sponsor](https://opencollective.com/stalwart), you help fund the development and future of Stalwart. As a thank-you, sponsors who contribute $5 per month or more will automatically receive a [Enterprise edition](https://stalw.art/enterprise/) license. And, sponsors who contribute $30 per month or more, also have access to [Premium Support](https://stalw.art/support) from Stalwart Labs.
## Funding
Part of the development of this project was funded through:
- [NGI0 Entrust Fund](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 101069594.
- [NGI Zero Core](https://nlnet.nl/NGI0/), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 101092990.
If you find the project useful you can help by [becoming a sponsor](https://opencollective.com/stalwart). Thank you!
## License
This project is dual-licensed under the **GNU Affero General Public License v3.0** (AGPL-3.0; as published by the Free Software Foundation) and the **Stalwart Enterprise License v2 (SELv2)**:
- The [GNU Affero General Public License v3.0](./LICENSES/AGPL-3.0-only.txt) is a free software license that ensures your freedom to use, modify, and distribute the software, with the condition that any modified versions of the software must also be distributed under the same license.
- The [Stalwart Enterprise License v2 (SELv2)](./LICENSES/LicenseRef-SEL.txt) is a proprietary license designed for commercial use. It offers additional features and greater flexibility for businesses that do not wish to comply with the AGPL-3.0 license requirements.
Each file in this project contains a license notice at the top, indicating the applicable license(s). The license notice follows the [REUSE guidelines](https://reuse.software/) to ensure clarity and consistency. The full text of each license is available in the [LICENSES](./LICENSES/) directory.
## Copyright
Copyright (C) 2020, Stalwart Labs LLC
The INBUXA mark reuses ihasmail's cat-and-envelope artwork.
@@ -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");
+1 -1
View File
@@ -190,7 +190,7 @@ impl Network {
}),
info: Info {
provider: Provider {
name: "Stalwart".into(),
name: types::brand!().into(),
..Default::default()
},
..Default::default()
+10 -59
View File
@@ -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"
));
+2 -1
View File
@@ -38,7 +38,8 @@ pub struct IpcReceivers {
}
const HELP: &str = concat!(
"Stalwart Server v",
types::brand_server!(),
" v",
env!("CARGO_PKG_VERSION"),
r#"
+2 -1
View File
@@ -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
+2 -2
View File
@@ -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());
+1 -1
View File
@@ -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}")))?;
+1 -1
View File
@@ -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(),
+1 -1
View File
@@ -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());
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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));
+5 -2
View File
@@ -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(),
+1 -1
View File
@@ -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),
+1 -1
View File
@@ -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 -1
View File
@@ -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"
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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");
+1 -1
View File
@@ -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())
}
}
+1 -1
View File
@@ -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 {
+4 -3
View File
@@ -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!(
+2 -2
View File
@@ -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")
),
),
(
+5 -5
View File
@@ -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 {
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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",
+39
View File
@@ -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")
};
}
+1
View File
@@ -6,6 +6,7 @@
pub mod acl;
pub mod blob;
pub mod branding;
pub mod blob_hash;
pub mod collection;
pub mod dead_property;
+28
View File
@@ -0,0 +1,28 @@
inbuxa logo bundle
===================
Mark: reused from ihasmail's actual cat-and-envelope artwork (ihasmail-mark.png),
unmodified. Colors sampled directly from that file:
navy outline #1C4053
cat orange #F9A34C (inner ear #F47F35)
envelope teal #46CAC3
Wordmark set in Space Grotesk (Bold for "inbuxa", Medium for the "MAIL SERVER"
tag line), rendered as true vector paths in the SVGs -- no font install needed
to view or edit them correctly in any vector app.
Files
-----
inbuxa-icon.svg / .png Mark only, square, for favicons/app icons
inbuxa-lockup-light.svg / .png Full hero lockup, white background
inbuxa-lockup-dark.svg / .png Full hero lockup, dark background
inbuxa-lockup-compact-light.svg/.png Compact lockup (icon + "inbuxa" only),
built at exactly 5x a 190x40 target
inbuxa-lockup-compact-dark.svg/.png Same, dark background
inbuxa-lockup-190x40-light.png Compact lockup pre-rendered at the literal
190x40 target size
inbuxa-lockup-190x40-dark.png Same, dark background
Dark backgrounds use #0B1720 rather than pure black -- a shade darker than the
mark's own navy outline, so the outline still reads as a lighter edge instead
of disappearing into the page.
Binary file not shown.

After

Width:  |  Height:  |  Size: 418 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 204 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

-25
View File
@@ -1,25 +0,0 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" style="enable-background:new 0 0 680.5 252.1;" xml:space="preserve" viewBox="99.5 84.68 481.62 82.75">
<style type="text/css">
.st0{fill:#100E42;}
.st1{fill:#DB2D54;}
.st2{fill:#FFFFFF;}
</style>
<g>
<g>
<path class="st1" d="M227.8,143.6c0.3,4.2,2.1,7.6,5.1,10.1c3.1,2.5,7.1,3.8,12.1,3.8c4.3,0,7.9-0.9,10.5-2.8c2.7-1.9,4-4.5,4-7.8 c0-2.4-0.7-4.3-2.2-5.7c-1.5-1.4-3.4-2.5-6-3.2c-2.5-0.7-6-1.5-10.6-2.3c-4.6-0.8-8.6-1.9-11.9-3.2c-3.3-1.3-6-3.3-8.1-6.1 c-2.1-2.7-3.1-6.3-3.1-10.7c0-4.1,1.1-7.7,3.2-10.9c2.1-3.2,5.1-5.7,9-7.4c3.8-1.8,8.2-2.6,13.2-2.6c5.1,0,9.6,1,13.7,2.9 c4,1.9,7.2,4.5,9.5,7.8c2.3,3.3,3.6,7.1,3.8,11.4h-11.5c-0.4-3.7-2-6.6-4.8-8.9c-2.8-2.2-6.3-3.4-10.6-3.4c-4.1,0-7.5,0.9-9.9,2.7 c-2.5,1.8-3.7,4.3-3.7,7.6c0,2.3,0.7,4.1,2.2,5.5c1.5,1.4,3.4,2.4,5.9,3.1c2.4,0.7,5.9,1.4,10.5,2.2c4.6,0.8,8.6,1.9,11.9,3.3 c3.3,1.4,6,3.4,8.2,6c2.1,2.6,3.2,6.1,3.2,10.5c0,4.2-1.1,8-3.4,11.3c-2.2,3.3-5.4,5.9-9.4,7.8c-4,1.9-8.6,2.8-13.7,2.8 c-5.6,0-10.6-1-14.9-3.1c-4.3-2-7.6-4.9-10-8.5c-2.4-3.6-3.7-7.8-3.7-12.5L227.8,143.6z"/>
<path class="st1" d="M278.5,102.1l11-2.1v14.6h12.6v9.7h-12.6v27.2c0,2,0.4,3.5,1.2,4.3c0.8,0.9,2.2,1.3,4.2,1.3h8.4v9.7h-10.6 c-5,0-8.6-1.2-10.8-3.5c-2.2-2.3-3.4-5.9-3.4-10.7V102.1z"/>
<path class="st1" d="M356.8,114.6v52.2h-9.7l-1.2-7.9c-1.8,2.6-4.2,4.7-7,6.2c-2.9,1.6-6.2,2.3-10,2.3c-4.8,0-9-1.1-12.7-3.2 c-3.7-2.1-6.7-5.2-8.8-9.3c-2.1-4-3.2-8.8-3.2-14.2c0-5.3,1.1-10,3.2-14c2.1-4,5.1-7.2,8.8-9.4c3.7-2.2,7.9-3.3,12.6-3.3 c3.9,0,7.2,0.7,10.1,2.2c2.9,1.5,5.2,3.5,6.9,6.1l1.3-7.6H356.8z M341.7,153.3c2.8-3.2,4.2-7.3,4.2-12.4c0-5.2-1.4-9.4-4.2-12.6 c-2.8-3.3-6.5-4.9-11-4.9c-4.6,0-8.2,1.6-11,4.8c-2.8,3.2-4.2,7.4-4.2,12.5c0,5.2,1.4,9.4,4.2,12.6c2.8,3.2,6.5,4.8,11,4.8 C335.2,158.1,338.9,156.5,341.7,153.3z"/>
<path class="st1" d="M365.5,97.5l11-2.1v71.3h-11V97.5z"/>
<path class="st1" d="M380.3,114.6h11.6l11.9,39.9l11.9-39.9h10.1l11.4,39.9l12.3-39.9h11.2l-17.3,52.2h-11.8l-11-35.5l-11.4,35.5 l-11.9,0.1L380.3,114.6z"/>
<path class="st1" d="M513.7,114.6v52.2H504l-1.2-7.9c-1.8,2.6-4.2,4.7-7,6.2c-2.9,1.6-6.2,2.3-10,2.3c-4.8,0-9-1.1-12.7-3.2 c-3.7-2.1-6.7-5.2-8.8-9.3c-2.1-4-3.2-8.8-3.2-14.2c0-5.3,1.1-10,3.2-14c2.1-4,5.1-7.2,8.8-9.4c3.7-2.2,7.9-3.3,12.6-3.3 c3.9,0,7.2,0.7,10.1,2.2c2.9,1.5,5.2,3.5,6.9,6.1l1.3-7.6H513.7z M498.6,153.3c2.8-3.2,4.2-7.3,4.2-12.4c0-5.2-1.4-9.4-4.2-12.6 c-2.8-3.3-6.5-4.9-11-4.9c-4.6,0-8.2,1.6-11,4.8c-2.8,3.2-4.2,7.4-4.2,12.5c0,5.2,1.4,9.4,4.2,12.6c2.8,3.2,6.5,4.8,11,4.8 C492.2,158.1,495.8,156.5,498.6,153.3z"/>
<path class="st1" d="M551.3,114.6v10.3h-4.9c-4.6,0-7.8,1.5-9.9,4.4c-2,3-3.1,6.7-3.1,11.3v26.2h-11v-52.2h9.8l1.2,7.8 c1.5-2.4,3.4-4.4,5.8-5.8c2.4-1.4,5.6-2.1,9.6-2.1H551.3z"/>
<path class="st1" d="M556.3,102.1l11-2.1v14.6h12.6v9.7h-12.6v27.2c0,2,0.4,3.5,1.2,4.3c0.8,0.9,2.2,1.3,4.2,1.3h8.4v9.7h-10.6 c-5,0-8.6-1.2-10.8-3.5s-3.4-5.9-3.4-10.7V102.1z"/>
</g>
<g>
<path class="st1" d="M149.1,84.7h-4.8l-44.8,25.9v8.3l44.8,25.9h4.8l44.8-25.9v-8.3L149.1,84.7z M182,114.7h-35.3V94.4L182,114.7z M146.7,135.1l-35.3-20.4l27-15.6v15.6v4.1v0.5l6.3,3.6h22.9L146.7,135.1z"/>
<polygon class="st1" points="99.5,129.9 99.5,140.9 144.3,166.8 149.1,166.8 193.9,140.9 193.9,129.9 146.7,157.2 "/>
<polygon class="st1" points="187.3,166.8 193.9,163 193.9,152 168.2,166.8 "/>
<polygon class="st1" points="99.5,163 106.1,166.8 125.2,166.8 99.5,152 "/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+218
View File
@@ -0,0 +1,218 @@
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
SUVORK5CYII=
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 35 KiB

+2 -2
View File
@@ -50,7 +50,7 @@
}
a {
color: #185fa5;
color: #0f766e;
}
@media only screen and (max-width:600px) {
@@ -143,7 +143,7 @@
{{key}}</div>
<div
style="font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:15px;line-height:1.5;color:#1a1a18;padding-top:3px;word-break:break-word;">
{{#if link}}<a href="{{link}}" target="_blank" style="color:#185fa5;text-decoration:underline;">{{/if link}}{{value}}{{#if link}}</a>{{/if link}}</div>
{{#if link}}<a href="{{link}}" target="_blank" style="color:#0f766e;text-decoration:underline;">{{/if link}}{{value}}{{#if link}}</a>{{/if link}}</div>
</td>
</tr>
{{/each event_details}}
File diff suppressed because one or more lines are too long
@@ -50,7 +50,7 @@
}
a {
color: #185fa5;
color: #0f766e;
}
.bar-info {
@@ -192,7 +192,7 @@
{{old_value}}</div>{{/if old_value}}
<div
style="font-family:-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;font-size:15px;line-height:1.5;color:#1a1a18;padding-top:3px;word-break:break-word;">
{{#if link}}<a href="{{link}}" target="_blank" style="color:#185fa5;text-decoration:underline;">{{/if link}}{{value}}{{#if link}}</a>{{/if link}}</div>
{{#if link}}<a href="{{link}}" target="_blank" style="color:#0f766e;text-decoration:underline;">{{/if link}}{{value}}{{#if link}}</a>{{/if link}}</div>
</td>
</tr>
{{/each event_details}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
+3 -3
View File
@@ -61,7 +61,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Weekly, until: None, count:
summary.summary: Text("Meet me maybe")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
X-MICROSOFT-CDO-OWNERAPPTID:299828133
@@ -176,7 +176,7 @@ summary.summary: Text("Meet me maybe")
~summary.description: Text("This is the event description")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
X-MICROSOFT-CDO-OWNERAPPTID:299828133
@@ -224,7 +224,7 @@ END:VCALENDAR
# Make sure the original alarms are preserved
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
X-MICROSOFT-CDO-OWNERAPPTID:299828133
+2 -2
View File
@@ -64,7 +64,7 @@ summary.location: Text("Conference Room A")
summary.summary: Text("Review Accounts")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:Conference Room A
@@ -114,7 +114,7 @@ summary.location: Text("Conference Room A")
summary.summary: Text("Review Accounts")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:Conference Room A
+3 -3
View File
@@ -146,7 +146,7 @@ summary.dtstart: Time(ItipTime { start: 867787200, tz_id: 32768 })
summary.summary: Text("Conference")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -402,7 +402,7 @@ summary.dtstart: Time(ItipTime { start: 867787200, tz_id: 32768 })
summary.summary: Text("Conference")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -450,7 +450,7 @@ summary.dtstart: Time(ItipTime { start: 867787200, tz_id: 32768 })
summary.summary: Text("Conference")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -37,7 +37,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: Some(Partia
summary.summary: Text("IETF Calendaring Working Group Meeting")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
CLASS:PUBLIC
@@ -117,7 +117,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: Some(Partia
summary.summary: Text("IETF Calendaring Working Group Meeting")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
CLASS:PUBLIC
@@ -207,7 +207,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: Some(Partia
summary.summary: Text("IETF Calendaring Working Group Meeting")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CANCELLED
@@ -226,7 +226,7 @@ END:VCALENDAR
# Make sure B has the cancelled event
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
CLASS:PUBLIC
@@ -358,7 +358,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: Some(Partia
summary.summary: Text("IETF Calendaring Working Group Meeting")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
CLASS:PUBLIC
@@ -386,7 +386,7 @@ END:VCALENDAR
# Make sure B has the complete event including all updates
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
CLASS:PUBLIC
@@ -538,7 +538,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: Some(Partia
summary.summary: Text("IETF Calendaring Working Group Meeting")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
DESCRIPTION:IETF-C&S Conference Call
@@ -564,7 +564,7 @@ END:VCALENDAR
# Make sure all instances in B were deleted
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
CLASS:PUBLIC
@@ -677,7 +677,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Weekly, until: None, count:
summary.summary: Text("Review Accounts")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:The White Room
@@ -742,7 +742,7 @@ summary.summary: Text("Review Accounts")
~summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Weekly, until: None, count: None, interval: None, bysecond: [], byminute: [], byhour: [], byday: [ICalendarDay { ordwk: None, weekday: Tuesday }], bymonthday: [], byyearday: [], byweekno: [], bymonth: [], bysetpos: [], wkst: Some(Sunday), rscale: None, skip: None })
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:The White Room
@@ -770,7 +770,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Weekly, until: None, count:
summary.summary: Text("Review Accounts")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:The Red Room
@@ -791,7 +791,7 @@ END:VCALENDAR
# Make sure B has the updated event
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:The White Room
@@ -812,7 +812,7 @@ END:VCALENDAR
# Make sure C has the updated event
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:The Red Room
@@ -853,7 +853,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Weekly, until: None, count:
summary.summary: Text("Review Accounts")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Review Accounts
@@ -919,7 +919,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Weekly, until: None, count:
summary.summary: Text("Weekly Sync")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Weekly Sync
@@ -967,7 +967,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Weekly, until: None, count:
summary.summary: Text("Weekly Sync")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Weekly Sync
+20 -20
View File
@@ -32,7 +32,7 @@ summary.dtstart: Time(ItipTime { start: 867787200, tz_id: 32768 })
summary.summary: Text("Conference")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -61,7 +61,7 @@ END:VCALENDAR
# Make sure B receives the request
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -88,7 +88,7 @@ END:VCALENDAR
> put [email protected] [email protected]
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
BEGIN:VEVENT
DTSTAMP:19970701T200000Z
SEQUENCE:1
@@ -119,7 +119,7 @@ summary.dtstart: Time(ItipTime { start: 867787200, tz_id: 32768 })
summary.summary: Text("Conference")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Conference
@@ -198,7 +198,7 @@ summary.summary: Text("Phone Conference")
~summary.summary: Text("Conference")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -228,7 +228,7 @@ END:VCALENDAR
# Make sure C receives the request
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -256,7 +256,7 @@ END:VCALENDAR
> put [email protected] [email protected]
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
BEGIN:VEVENT
DTSTAMP:19970701T180000Z
UID:[email protected]
@@ -287,7 +287,7 @@ summary.dtstart: Time(ItipTime { start: 867780000, tz_id: 32768 })
summary.summary: Text("Phone Conference")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Phone Conference
@@ -313,7 +313,7 @@ summary.dtstart: Time(ItipTime { start: 867780000, tz_id: 32768 })
summary.summary: Text("Phone Conference")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -343,7 +343,7 @@ END:VCALENDAR
# Make sure E receives the request
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -398,7 +398,7 @@ END:VCALENDAR
> put [email protected] [email protected]
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
BEGIN:VEVENT
DTSTAMP:19970701T180000Z
SEQUENCE:2
@@ -430,7 +430,7 @@ summary.dtstart: Time(ItipTime { start: 867780000, tz_id: 32768 })
summary.summary: Text("Phone Conference")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Phone Conference
@@ -479,7 +479,7 @@ END:VCALENDAR
# Make sure C receives the reply
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -508,7 +508,7 @@ END:VCALENDAR
> put [email protected] [email protected]
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
BEGIN:VEVENT
DTSTAMP:19970701T180000Z
SEQUENCE:2
@@ -540,7 +540,7 @@ summary.dtstart: Time(ItipTime { start: 867780000, tz_id: 32768 })
summary.summary: Text("Phone Conference")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Phone Conference
@@ -564,7 +564,7 @@ END:VCALENDAR
# Make sure C receives the reply
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -650,7 +650,7 @@ summary.summary: Text("Phone Conference")
~summary.attendee: Participants([ItipParticipant { email: "[email protected]", name: None, is_organizer: true }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }, ItipParticipant { email: "[email protected]", name: Some("Hal"), is_organizer: false }, ItipParticipant { email: "[email protected]", name: None, is_organizer: false }])
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CONFIRMED
@@ -681,7 +681,7 @@ summary.dtstart: Time(ItipTime { start: 867780000, tz_id: 32768 })
summary.summary: Text("Phone Conference")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CANCELLED
@@ -702,7 +702,7 @@ END:VCALENDAR
# Make sure B receives the cancelation
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CANCELLED
@@ -727,7 +727,7 @@ summary.dtstart: Time(ItipTime { start: 867780000, tz_id: 32768 })
summary.summary: Text("Phone Conference")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CANCELLED
+9 -9
View File
@@ -32,7 +32,7 @@ summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
summary.summary: Text("Create the requirements document")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
@@ -57,7 +57,7 @@ END:VCALENDAR
# Make sure B received the todo
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
@@ -103,7 +103,7 @@ summary.attendee: Participants([ItipParticipant { email: "[email protected]", name:
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
STATUS:IN-PROCESS
@@ -172,7 +172,7 @@ summary.attendee: Participants([ItipParticipant { email: "[email protected]", name:
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
PERCENT-COMPLETE:75
@@ -241,7 +241,7 @@ summary.attendee: Participants([ItipParticipant { email: "[email protected]", name:
summary.dtstart: Time(ItipTime { start: 867776400, tz_id: 32768 })
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
DUE:19970722T170000Z
@@ -317,7 +317,7 @@ summary.summary: Text("Send Status Reports to Area Managers")
~summary.summary: Text("Create the requirements document")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
@@ -347,7 +347,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: None, count
summary.summary: Text("Create the requirements document")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
STATUS:CANCELLED
@@ -367,7 +367,7 @@ END:VCALENDAR
# Make sure "C" received the cancel request
> get [email protected] [email protected]
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
PRIORITY:1
@@ -451,7 +451,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Monthly, until: None, count
summary.summary: Text("Send Status Reports to Area Managers")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VTODO
PERCENT-COMPLETE:75
+4 -4
View File
@@ -47,7 +47,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Daily, until: None, count:
summary.summary: Text("Review Internet-Draft")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Review Internet-Draft
@@ -89,7 +89,7 @@ END:VCALENDAR
# Make sure the participant receives the event
> get [email protected] 9263504FD3AD
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Review Internet-Draft
@@ -185,7 +185,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Daily, until: None, count:
summary.summary: Text("Review Internet-Draft")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Review Internet-Draft
@@ -343,7 +343,7 @@ summary.rrule: Rrule(ICalendarRecurrenceRule { freq: Daily, until: None, count:
summary.summary: Text("Review Internet-Draft")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Review Internet-Draft
+3 -3
View File
@@ -30,7 +30,7 @@ summary.dtstart: Time(ItipTime { start: 1243958400, tz_id: 32768 })
summary.summary: Text("Lunch")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Lunch
@@ -83,7 +83,7 @@ END:VCALENDAR
# Make sure the message was received by the attendees
> get [email protected] 9263504FD3AD
BEGIN:VCALENDAR
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Lunch
@@ -170,7 +170,7 @@ summary.dtstart: Time(ItipTime { start: 1243958400, tz_id: 32768 })
summary.summary: Text("Lunch")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Lunch
+4 -4
View File
@@ -26,7 +26,7 @@ summary.dtstart: Time(ItipTime { start: 1794322800, tz_id: 433 })
summary.summary: Text("Berlin meeting")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Berlin meeting
@@ -92,7 +92,7 @@ summary.dtstart: Time(ItipTime { start: 1794322800, tz_id: 433 })
summary.summary: Text("Berlin meeting")
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Berlin meeting
@@ -144,7 +144,7 @@ summary.dtstart: Time(ItipTime { start: 1794322800, tz_id: 433 })
summary.summary: Text("Berlin meeting")
BEGIN:VCALENDAR
METHOD:CANCEL
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
STATUS:CANCELLED
@@ -228,7 +228,7 @@ summary.dtstart: Time(ItipTime { start: 1794322800, tz_id: 433 })
summary.summary: Text("Berlin meeting")
BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Berlin meeting
+1 -1
View File
@@ -45,7 +45,7 @@ pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) {
imap.send("ID").await;
imap.assert_read(Type::Tagged, ResponseType::Ok)
.await
.assert_contains("* ID (\"name\" \"Stalwart\" \"version\" ");
.assert_contains("* ID (\"name\" \"INBUXA\" \"version\" ");
// Login should be disabled
imap.send("LOGIN [email protected] secret").await;
+2 -2
View File
@@ -43,7 +43,7 @@ pub async fn test(test: &TestServer) {
list[0],
json!({
"id": default_calendar_id,
"name": "Stalwart Calendar ([email protected])",
"name": "INBUXA Calendar ([email protected])",
"description": null,
"sortOrder": 0,
"isSubscribed": true,
@@ -308,7 +308,7 @@ pub async fn test(test: &TestServer) {
}));
response.list()[1].assert_is_equal(json!({
"id": default_calendar_id,
"name": "Stalwart Calendar ([email protected])",
"name": "INBUXA Calendar ([email protected])",
"description": (),
"sortOrder": 0,
"isSubscribed": true,
+2 -2
View File
@@ -36,7 +36,7 @@ pub async fn test(test: &TestServer) {
assert_eq!(
list[0],
json!({
"name": "Stalwart Address Book ([email protected])",
"name": "INBUXA Address Book ([email protected])",
"description": (),
"sortOrder": 0,
"isSubscribed": true,
@@ -146,7 +146,7 @@ pub async fn test(test: &TestServer) {
"id": addressbook_id,
}),
json!({
"name": "Stalwart Address Book ([email protected])",
"name": "INBUXA Address Book ([email protected])",
"description": (),
"sortOrder": 0,
"isSubscribed": true,
+1 -1
View File
@@ -54,7 +54,7 @@ pub async fn test(test: &TestServer) {
"urn:ietf:params:jmap:submission": {},
"urn:ietf:params:jmap:vacationresponse": {},
"urn:ietf:params:jmap:sieve": {
"implementation": "Stalwart v1.0.0"
"implementation": "INBUXA v1.0.0"
},
"urn:ietf:params:jmap:blob": {},
"urn:ietf:params:jmap:quota": {},
+2 -2
View File
@@ -905,7 +905,7 @@ const REPORT_10: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
const REPORT_10_RESPONSE: &str = r#"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
BEGIN:VFREEBUSY
DTSTART:20060104T140000Z
DTEND:20060105T220000Z
@@ -926,7 +926,7 @@ const REPORT_11: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
const REPORT_11_RESPONSE: &str = r#"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Stalwart Labs LLC//Stalwart Server//EN
PRODID:-//INBUXA//INBUXA Server//EN
BEGIN:VFREEBUSY
DTSTART:20060101T000000Z
DTEND:20060104T140000Z