diff --git a/README.md b/README.md index 1fe4842..8e83740 100644 --- a/README.md +++ b/README.md @@ -1,186 +1,64 @@

- - - + inbuxa

- Secure, scalable mail & collaboration server with comprehensive protocol support 🛡️
(IMAP, JMAP, SMTP, CalDAV, CardDAV, WebDAV) + A complete mail and collaboration server, every feature included, under the AGPL

-
+--- -

- continuous integration -   - License: AGPL v3 -   - Documentation -   - downloads -

- Mastodon -   - Twitter - Discord -   - Reddit -

+**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 - +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, it’s 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 you’d 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 that’s done, we’ll be ready to roll out version **1.0**. - -Of course, development doesn’t 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 there’s something you’d like to see prioritized, just give it a thumbs up as we plan to implement enhancements based on the community’s 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. diff --git a/crates/common/src/config/mailstore/scripts.rs b/crates/common/src/config/mailstore/scripts.rs index 212ea0a..f46b5aa 100644 --- a/crates/common/src/config/mailstore/scripts.rs +++ b/crates/common/src/config/mailstore/scripts.rs @@ -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"); diff --git a/crates/common/src/config/network.rs b/crates/common/src/config/network.rs index be4d848..0cb4036 100644 --- a/crates/common/src/config/network.rs +++ b/crates/common/src/config/network.rs @@ -190,7 +190,7 @@ impl Network { }), info: Info { provider: Provider { - name: "Stalwart".into(), + name: types::brand!().into(), ..Default::default() }, ..Default::default() diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 68b35b3..1caa1f0 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -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 = "iVBORw0KGgoAAAANSUhEUgAAAMgAAAAnCAMAAAB9lPf7AAABOFBMVEUAAAAAADoAAEkPDkIPDkIQ\r\n\ - DkIQDkLcLVTYMVTbLVTbLVQPDkLWM2YQDkIPD0IODEHaJlPbLVQWDT8MC0IQDkIQDkIPDkIODkEQ\r\n\ - D0ITDEAQDkIPDkIODkIPDkIPDkIRDUIQDkIQDUIPDkLcLVQQDkIQDkIQDkIQDULbLVQQDUIPDkIQ\r\n\ - EEIPDkIPD0EPDkHcLlUPDkLbLFQPDULbLFPbLVQQDkLbLFPcK1TbLVTbLVQQDUIPDkIPDkIPDULc\r\n\ - LVTcLVQQDkLbLFTcLFTbLFQPDkIQDkIQDULbLVUSEkPcLVTbLVQQDULbLFTcLVTbLVTbLVPbLFQP\r\n\ - DUHbLVMPDkPbLVTdLFXbLFQNDULcLVTcLlMRD0cQDkIQDkXpMFnrMFrtMFvlL1jjLlfdLVThLlYS\r\n\ - EErnL1gRD0n0Ml2YjG1wAAAAWnRSTlMABAb59/379wr7/lMF9HgoBvQJF/BtZSQwGu7JNulAO95x\r\n\ - WD3TsF1M3b6kH5MRiRe5saujyH9oHezk4tjGmn9fwkc1vrVqYA8N19DPqnFQkYh1V0a4LSITmSiJ\r\n\ - LN30AAAKZUlEQVRYw91ZCVvbRhCVrcuWD7AxYLANtrEx5opDIBCOQBLO5qTQ0uyubyD//x/0za4O\r\n\ - RIG0/dLvazu0tbTaWc3bOd6sqv2PJen9/LcF9o++fnf58r8OBcb/vNBttzvrc0Ck/VcFMN6+a/fs\r\n\ - uG23+x9+fcopkUiE/ks/35ew2j8ucMCz3wbteNwZtIcZp2O/jj3mlWjo+t8nHzNdx3ac/sLrTDee\r\n\ - GXRf7cMpD+OYnF9dO6zvnc/gOuLv93dBRScTkz/KWrwu+mBUfTrrwhHtod1b0J696N/E7T5S5UEo\r\n\ - xbrBlIidyp90CvCO1cu56you/jFBAP1y2evZdq/z4suwv3CiaXPr7X7Gbg9fbP4xvtKccSNlGEYq\r\n\ - ZQpWG3GRTM2ki49biUkjgpks8aOAZCcT6ZX7ME4+Izkyw85Pn7T9m+FCjMb2X3UHSJXM62TIKxFt\r\n\ - lXHdEPAG/jUNnelFQjJVM8T1BK4e98hIiqd+DBCskcgZjE/dW+zlFiVHd+sjXfcICEnsS7wTtwfd\r\n\ - hZ8DJFBsMNPirLxabSQqTSFMQ5RWyErBDTH/NBCdGz8MyPm1wUtjocXe/NQZZuLtwednMN4FkpSO\r\n\ - +vqhh1Tp3bx7qwXyXuhcLLsLNHJAwvZg/6TBLRYGEoE8AOTplAqrPx6nR8wQ01N3Fht90evF4+2b\r\n\ - y1+k7QEQLTkqQfbt+M3wi29NUZgWO8RSJLg1ucVTY6hj5j0geCh//pZHAvX7s+nNtOr4fSCbw0Hc\r\n\ - cdbd8ElKIIESMf3AsftbSW8nJphusqqWdTMOGQNgVRdINUQvkZWrLP24Ix6Q74qn46kHEtwqIKda\r\n\ - IJtbDgQ4YpoLxMk89+Xy+W/rAyc+OPOBpBki6wIX7v2s4CZblUBMXjtstgoNLYK/6PxarVQqt8Zh\r\n\ - zEThEKMKSCPaah4WKporK/Vm6yCP+SqDC61ma0paW10k9SYVpirUq3Jqcw23F8tr0K8wg+sHrSbN\r\n\ - l/LMadvxwfDyKyKL/vn4DQSipNdG19XtO3G7+8rf6Ap5pKJlPZ9H8/l8ccoFQrXsukIoG2Vcco6R\r\n\ - UkNrXfPrI83zSA135YhXOm6hseHt8yEe1Wh4puapT89rixjdQF3kGFvKHtA7FskOeow/RbGKCG2n\r\n\ - 7Xw5kdG1+bzXaUvp9uIkjiRGH0iCWSafzitmDUhdATFNpP4RZm0wYRm6EFTKxHxBpMSEC6QKE1I6\r\n\ - B+NItWWWMsSupmRsmudok7QjqoaGVOdsoiVS7Fw+tfhx4dpI5cSyAoL3cWPyTmvScWx0JC9din+h\r\n\ - 5POH+MBx4rJVCWTKgLrQV4tZt7QADWxSQCAWgCCATcsSorxbKDGMUUELgOQt/KSBltR3hMW5vuRG\r\n\ - Fowz84glMJUl2PbuLtRNqOssDSA5WJ7CdeAREssDEqNmcQg+7Ldp42PJoCwPHLgq/iWG0WDrl29T\r\n\ - WJzx7cONxEjUTz9KdpFeQqCNaXm80WKFGWBdmS8JHdABxE/2XWGwA68GcuBgx4CFu0WWYvDOEqw1\r\n\ - We0C6qeJMtR9ILRVopmeqMxQsvPczCTeB9UACrXvGftGNu8xd6SD0PJHAokc3ILPLcoHxsuL1RUM\r\n\ - uUC8klRnusXqXryUsekhIGkGnyxBi0JQJycuyiWy20JavMcMizW9TgS8FQJSfaRqPfuEFB+VB6qB\r\n\ - HVfNu+sjGz3LG8DA0093XBJdRIaZOgmhKW1g0OeRLHEjDBZlTJSGSP+EgOTJdtXN7FJkmWI7S+l3\r\n\ - IWBoXpvKcZ26haxSh39MH4iOZEFqRh7ikcE7UGGMjrh2x3Gb949bXVx2tl5iGI/mzohHgkI+u1gS\r\n\ - sqpYhoFYLqxo0YAQI0Q1iJagQi8y/S6QCJoDg61pEQlZ7BSELmaI5pZhW0GT5QSGZz31VWZ5QHRA\r\n\ - VlXCAxIJPJLpqOYEmF4M2zZS5d16Fz1Lx/l8Iod//TDsnmlhOb3YqO+kBMBYpkFxfRfIHkuJ3NSd\r\n\ - 7iwMJIuAMtSWTyApNiZuU2yV7N4RBhm8qlI+YKogRwwZhA8D2cygXfS3fl12JNTQ954rR8Veo3V0\r\n\ - FkbvdkBu2V1qrL5HncTy46EW5RDm1QLQ8lEABFPyVPgasL3ODFacFJbYpcTnkBGNHCi2Tz0TI1R2\r\n\ - fY/IaveYR7po4LuUDKNu827b6j6WdJv5+Dd4JCwemEZJwKhCCMgBgBz4M5UFodBCbKXYsqZdlbjY\r\n\ - jmo1IclgA2oEqA4gO8GLqAYEQMYfBYIjleuBrzBdNu/tNjX0SSpdOF5RMcPxypVssUgFNjhrFok/\r\n\ - SlfaiOUDacKiwl3qSYWBRMhmUctqDYHOmWLJYMdIfKhRaqwBSPlOr3la+nNAvENuB9wuoXzd3/dy\r\n\ - BgfeTMDrpL9kCo5AjfqOgdk6zy3dBbIGM8ungQ5VqRAQFUVFmd3owWYo92kB1CwA2aMFx4LQWjL4\r\n\ - nwIympSfHRS3K0dIGMnX7uA+BZ3vEbCCKAdNaJQ2kE+PBUAitMMwM+h6j8LJTuM12XXsCF46pTW5\r\n\ - KMnEL+BGcrZoBMleFeb3gYS5XW1+LBaTvNIhN4V5XUWwicYp6582doCshhxxgeCv4R22ICojrDCQ\r\n\ - qIymwxGhUxWKkg9EHrROqeyeeOq4UrUFLrceBxINkv1jUkv63N6TTC7v+rbP9JgUC5pGHXVqlq6j\r\n\ - tEqF9mtZJrvOqpIQT7cFtfowEUJJbPH7QGaJBfdAIChiWFMYYrEMXlJFt0bq85qm1I+Y+Vho5a5k\r\n\ - BCjZ7C/c5/ZRfKgL8fp+JqP5sssMU5jpK1WQVgU3qWhSJFOkS0lLsG6/soGyFgaimkWTQ6ZX5KFk\r\n\ - mq5l8dMUoeLhsVI/4vxBIJjExXHoYNXuXXqUobh94VWY19fbnbNk0K8bwtA5m24try63cozrqrhH\r\n\ - y7SP7+v11h7CDWC5aI03EukaQ3m4D4RYXPaCa3QXkXkWkIR2INUPKonEeUFA/SEgM7Q/VrNeb07g\r\n\ - joDEbfrwcBJwu90P83q/ZzuvRoMzbDHHcFjgjISncIHAIj6/zYFRmLgFM0xOM90wGROMERuDskNA\r\n\ - lB2cYlG1vccEhCIroihwG+oW1AWDZr0mjHtAVIeZMjm19Mtq6GSBPgXJ7deSHrcrXh9VTsInoW/v\r\n\ - 7n7AWGoJOjfRNzpYnhpXWzRVuuVwj8Fr5Lb3DCwH0QXbI4aUQAw/tKQDLaqyEBmXpi4K/hvGcAz0\r\n\ - 1NdQX1J+izLu15AqY1DSU2LVHXr22ekPB+1vZ59wI7m815M8j7uXW996g2Evg5Y4EKhdrJWE8sjO\r\n\ - xpRf79emucAmluWU8RqXE94nNDqr3tJRlwt+W/WOhtecX9e9NZu3uEsH3KEdF6S62DnWaOo1AdGh\r\n\ - XgnqVKNg4H3c8wjk69zc3Nu3b+ZG3c+Oc3SVJG+9efP2LR5u/vFDxkqxOn5+lMhTwPujK/nZ2dmZ\r\n\ - vDslX61U5vMS4szsDPY+S0+vvL7lAoNeZ4kZeHQaesNIYvz8uCg7AzUzWpwNNJRWkVZceur/vSUf\r\n\ - GAtDCZrI0KAvoeG/Lt9Xx5MfIhFiicj9QSmhGd649zg098nPik+rB+/T/k/yO9A7bEvKcQkCAAAA\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" +)); diff --git a/crates/common/src/manager/boot.rs b/crates/common/src/manager/boot.rs index 5f7f501..bc00361 100644 --- a/crates/common/src/manager/boot.rs +++ b/crates/common/src/manager/boot.rs @@ -38,7 +38,8 @@ pub struct IpcReceivers { } const HELP: &str = concat!( - "Stalwart Server v", + types::brand_server!(), + " v", env!("CARGO_PKG_VERSION"), r#" diff --git a/crates/common/src/manager/console.rs b/crates/common/src/manager/console.rs index 470f697..4dd1fd8 100644 --- a/crates/common/src/manager/console.rs +++ b/crates/common/src/manager/console.rs @@ -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 diff --git a/crates/common/src/manager/restore.rs b/crates/common/src/manager/restore.rs index cfdb084..c15e2c6 100644 --- a/crates/common/src/manager/restore.rs +++ b/crates/common/src/manager/restore.rs @@ -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()); diff --git a/crates/directory/src/backend/oidc/config.rs b/crates/directory/src/backend/oidc/config.rs index 5fdadb1..36b30b2 100644 --- a/crates/directory/src/backend/oidc/config.rs +++ b/crates/directory/src/backend/oidc/config.rs @@ -38,7 +38,7 @@ impl OpenIdDirectory { pub async fn new(config: OidcConfig) -> Result { 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}")))?; diff --git a/crates/email/src/message/crypto.rs b/crates/email/src/message/crypto.rs index fd0b95e..5a30b1e 100644 --- a/crates/email/src/message/crypto.rs +++ b/crates/email/src/message/crypto.rs @@ -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(), diff --git a/crates/email/src/sieve/ingest.rs b/crates/email/src/sieve/ingest.rs index e3e966a..5f27b9b 100644 --- a/crates/email/src/sieve/ingest.rs +++ b/crates/email/src/sieve/ingest.rs @@ -779,7 +779,7 @@ impl SieveScriptIngest for Server { fn write_received_header(buf: &mut Vec, 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()); diff --git a/crates/http/src/api/mod.rs b/crates/http/src/api/mod.rs index 5185d38..f1f1c4a 100644 --- a/crates/http/src/api/mod.rs +++ b/crates/http/src/api/mod.rs @@ -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 { diff --git a/crates/imap/src/lib.rs b/crates/imap/src/lib.rs index 3a08b97..c3e0a02 100644 --- a/crates/imap/src/lib.rs +++ b/crates/imap/src/lib.rs @@ -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> = LazyLock::new(|| build_greeting(true, true)); diff --git a/crates/imap/src/op/capability.rs b/crates/imap/src/op/capability.rs index bc4a32e..f16d6b4 100644 --- a/crates/imap/src/op/capability.rs +++ b/crates/imap/src/op/capability.rs @@ -68,8 +68,11 @@ impl Session { .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(), diff --git a/crates/imap/src/op/logout.rs b/crates/imap/src/op/logout.rs index 44b9c7f..97cc3a5 100644 --- a/crates/imap/src/op/logout.rs +++ b/crates/imap/src/op/logout.rs @@ -15,7 +15,7 @@ impl Session { 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), diff --git a/crates/jmap-proto/src/request/capability.rs b/crates/jmap-proto/src/request/capability.rs index 147ae3e..39a9f8d 100644 --- a/crates/jmap-proto/src/request/capability.rs +++ b/crates/jmap-proto/src/request/capability.rs @@ -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"), } } } diff --git a/crates/main/Cargo.toml b/crates/main/Cargo.toml index 66e1175..394cd2f 100644 --- a/crates/main/Cargo.toml +++ b/crates/main/Cargo.toml @@ -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 "] repository = "https://github.com/stalwartlabs/stalwart" homepage = "https://stalw.art" diff --git a/crates/managesieve/src/lib.rs b/crates/managesieve/src/lib.rs index 0237a69..2d809aa 100644 --- a/crates/managesieve/src/lib.rs +++ b/crates/managesieve/src/lib.rs @@ -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 { diff --git a/crates/managesieve/src/op/capability.rs b/crates/managesieve/src/op/capability.rs index c0ceff6..ba8ae68 100644 --- a/crates/managesieve/src/op/capability.rs +++ b/crates/managesieve/src/op/capability.rs @@ -14,7 +14,7 @@ impl Session { 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"); diff --git a/crates/managesieve/src/op/logout.rs b/crates/managesieve/src/op/logout.rs index e32240f..72488a1 100644 --- a/crates/managesieve/src/op/logout.rs +++ b/crates/managesieve/src/op/logout.rs @@ -16,6 +16,6 @@ impl Session { 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()) } } diff --git a/crates/pop3/src/lib.rs b/crates/pop3/src/lib.rs index d800fd7..aeee3a7 100644 --- a/crates/pop3/src/lib.rs +++ b/crates/pop3/src/lib.rs @@ -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 { diff --git a/crates/pop3/src/op/delete.rs b/crates/pop3/src/op/delete.rs index 20ddc83..8b53b25 100644 --- a/crates/pop3/src/op/delete.rs +++ b/crates/pop3/src/op/delete.rs @@ -107,7 +107,8 @@ impl Session { } 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 Session { .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!( diff --git a/crates/pop3/src/protocol/response.rs b/crates/pop3/src/protocol/response.rs index 007594b..899b30a 100644 --- a/crates/pop3/src/protocol/response.rs +++ b/crates/pop3/src/protocol/response.rs @@ -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") ), ), ( diff --git a/crates/registry/src/schema/structs_impl.rs b/crates/registry/src/schema/structs_impl.rs index 2596655..1d65d22 100644 --- a/crates/registry/src/schema/structs_impl.rs +++ b/crates/registry/src/schema/structs_impl.rs @@ -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 { diff --git a/crates/smtp/src/inbound/spawn.rs b/crates/smtp/src/inbound/spawn.rs index 7849224..0ec38ab 100644 --- a/crates/smtp/src/inbound/spawn.rs +++ b/crates/smtp/src/inbound/spawn.rs @@ -130,7 +130,7 @@ impl Session { .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; diff --git a/crates/trc/src/event/enums_impl.rs b/crates/trc/src/event/enums_impl.rs index e84c5ab..e7d8cc6 100644 --- a/crates/trc/src/event/enums_impl.rs +++ b/crates/trc/src/event/enums_impl.rs @@ -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", diff --git a/crates/types/src/branding.rs b/crates/types/src/branding.rs new file mode 100644 index 0000000..049c98a --- /dev/null +++ b/crates/types/src/branding.rs @@ -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") + }; +} diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 422c41a..475c9d8 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -6,6 +6,7 @@ pub mod acl; pub mod blob; +pub mod branding; pub mod blob_hash; pub mod collection; pub mod dead_property; diff --git a/img/brand/README.txt b/img/brand/README.txt new file mode 100644 index 0000000..b23028e --- /dev/null +++ b/img/brand/README.txt @@ -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. diff --git a/img/brand/inbuxa-icon.png b/img/brand/inbuxa-icon.png new file mode 100644 index 0000000..afa38ac Binary files /dev/null and b/img/brand/inbuxa-icon.png differ diff --git a/img/brand/inbuxa-icon.svg b/img/brand/inbuxa-icon.svg new file mode 100644 index 0000000..53f217b --- /dev/null +++ b/img/brand/inbuxa-icon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/img/brand/inbuxa-lockup-190x40-dark.png b/img/brand/inbuxa-lockup-190x40-dark.png new file mode 100644 index 0000000..3e11e36 Binary files /dev/null and b/img/brand/inbuxa-lockup-190x40-dark.png differ diff --git a/img/brand/inbuxa-lockup-190x40-light.png b/img/brand/inbuxa-lockup-190x40-light.png new file mode 100644 index 0000000..da9c002 Binary files /dev/null and b/img/brand/inbuxa-lockup-190x40-light.png differ diff --git a/img/brand/inbuxa-lockup-compact-dark.png b/img/brand/inbuxa-lockup-compact-dark.png new file mode 100644 index 0000000..991739a Binary files /dev/null and b/img/brand/inbuxa-lockup-compact-dark.png differ diff --git a/img/brand/inbuxa-lockup-compact-dark.svg b/img/brand/inbuxa-lockup-compact-dark.svg new file mode 100644 index 0000000..2554409 --- /dev/null +++ b/img/brand/inbuxa-lockup-compact-dark.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/brand/inbuxa-lockup-compact-light.png b/img/brand/inbuxa-lockup-compact-light.png new file mode 100644 index 0000000..2b59cae Binary files /dev/null and b/img/brand/inbuxa-lockup-compact-light.png differ diff --git a/img/brand/inbuxa-lockup-compact-light.svg b/img/brand/inbuxa-lockup-compact-light.svg new file mode 100644 index 0000000..88f9c14 --- /dev/null +++ b/img/brand/inbuxa-lockup-compact-light.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/brand/inbuxa-lockup-dark.png b/img/brand/inbuxa-lockup-dark.png new file mode 100644 index 0000000..e0d772d Binary files /dev/null and b/img/brand/inbuxa-lockup-dark.png differ diff --git a/img/brand/inbuxa-lockup-dark.svg b/img/brand/inbuxa-lockup-dark.svg new file mode 100644 index 0000000..40117f7 --- /dev/null +++ b/img/brand/inbuxa-lockup-dark.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/brand/inbuxa-lockup-light.png b/img/brand/inbuxa-lockup-light.png new file mode 100644 index 0000000..1d3da43 Binary files /dev/null and b/img/brand/inbuxa-lockup-light.png differ diff --git a/img/brand/inbuxa-lockup-light.svg b/img/brand/inbuxa-lockup-light.svg new file mode 100644 index 0000000..f9f4940 --- /dev/null +++ b/img/brand/inbuxa-lockup-light.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/demo.gif b/img/demo.gif deleted file mode 100644 index 861577e..0000000 Binary files a/img/demo.gif and /dev/null differ diff --git a/img/logo-red.svg b/img/logo-red.svg deleted file mode 100644 index eb8888a..0000000 --- a/img/logo-red.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/resources/branding/email-logo.png b/resources/branding/email-logo.png new file mode 100644 index 0000000..cafac13 Binary files /dev/null and b/resources/branding/email-logo.png differ diff --git a/resources/branding/email-logo.png.b64 b/resources/branding/email-logo.png.b64 new file mode 100644 index 0000000..01d99e3 --- /dev/null +++ b/resources/branding/email-logo.png.b64 @@ -0,0 +1,218 @@ +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 +SUVORK5CYII= \ No newline at end of file diff --git a/resources/branding/favicon-64.png b/resources/branding/favicon-64.png new file mode 100644 index 0000000..87db9b9 Binary files /dev/null and b/resources/branding/favicon-64.png differ diff --git a/resources/branding/inbuxa-logo-web.svg b/resources/branding/inbuxa-logo-web.svg new file mode 100644 index 0000000..0665906 --- /dev/null +++ b/resources/branding/inbuxa-logo-web.svg @@ -0,0 +1,4 @@ + diff --git a/resources/html-templates/calendar-alarm.html b/resources/html-templates/calendar-alarm.html index 01438f2..f648a2a 100644 --- a/resources/html-templates/calendar-alarm.html +++ b/resources/html-templates/calendar-alarm.html @@ -50,7 +50,7 @@ } a { - color: #185fa5; + color: #0f766e; } @media only screen and (max-width:600px) { @@ -143,7 +143,7 @@ {{key}}
- {{#if link}}{{/if link}}{{value}}{{#if link}}{{/if link}}
+ {{#if link}}{{/if link}}{{value}}{{#if link}}{{/if link}} {{/each event_details}} diff --git a/resources/html-templates/calendar-alarm.html.min b/resources/html-templates/calendar-alarm.html.min index 22896e3..fb8d81d 100644 --- a/resources/html-templates/calendar-alarm.html.min +++ b/resources/html-templates/calendar-alarm.html.min @@ -2,4 +2,4 @@
{{page_title}}
{{#if header}} {{/if header}} {{#if event_title}} {{/if event_title}} {{#if event_description}} {{/if event_description}} {{#if event_details}} {{/if event_details}} {{#if attendees}} {{/if attendees}} {{#if footer}} {{/if footer}}
\ No newline at end of file +
{{page_title}}
{{#if header}} {{/if header}} {{#if event_title}} {{/if event_title}} {{#if event_description}} {{/if event_description}} {{#if event_details}} {{/if event_details}} {{#if attendees}} {{/if attendees}} {{#if footer}} {{/if footer}}
\ No newline at end of file diff --git a/resources/html-templates/calendar-invite.html b/resources/html-templates/calendar-invite.html index c231faf..2199f76 100644 --- a/resources/html-templates/calendar-invite.html +++ b/resources/html-templates/calendar-invite.html @@ -50,7 +50,7 @@ } a { - color: #185fa5; + color: #0f766e; } .bar-info { @@ -192,7 +192,7 @@ {{old_value}}{{/if old_value}}
- {{#if link}}{{/if link}}{{value}}{{#if link}}{{/if link}}
+ {{#if link}}{{/if link}}{{value}}{{#if link}}{{/if link}} {{/each event_details}} diff --git a/resources/html-templates/calendar-invite.html.min b/resources/html-templates/calendar-invite.html.min index 3566d57..cdbe1fa 100644 --- a/resources/html-templates/calendar-invite.html.min +++ b/resources/html-templates/calendar-invite.html.min @@ -2,4 +2,4 @@
{{page_title}}
{{#if header}} {{/if header}} {{#if event_title}} {{/if event_title}} {{#if event_description}} {{/if event_description}} {{#if event_details}} {{/if event_details}} {{#if attendees}} {{/if attendees}} {{#if rsvp}} {{/if rsvp}} {{#if footer}} {{#each footer}} {{/each footer}} {{/if footer}}
\ No newline at end of file +
{{page_title}}
{{#if header}} {{/if header}} {{#if event_title}} {{/if event_title}} {{#if event_description}} {{/if event_description}} {{#if event_details}} {{/if event_details}} {{#if attendees}} {{/if attendees}} {{#if rsvp}} {{/if rsvp}} {{#if footer}} {{#each footer}} {{/each footer}} {{/if footer}}
\ No newline at end of file diff --git a/resources/html-templates/calendar-rsvp.html b/resources/html-templates/calendar-rsvp.html index 430dc15..896c450 100644 --- a/resources/html-templates/calendar-rsvp.html +++ b/resources/html-templates/calendar-rsvp.html @@ -6,7 +6,8 @@ - Respond to invitation + Respond to invitation · INBUXA +
\ No newline at end of file + Respond to invitation · INBUXA
\ No newline at end of file diff --git a/resources/html-templates/calendar-rsvp.html.min.gz b/resources/html-templates/calendar-rsvp.html.min.gz index a76d480..40c18d3 100644 Binary files a/resources/html-templates/calendar-rsvp.html.min.gz and b/resources/html-templates/calendar-rsvp.html.min.gz differ diff --git a/resources/html-templates/login.html b/resources/html-templates/login.html index f0d1fad..c6cb824 100644 --- a/resources/html-templates/login.html +++ b/resources/html-templates/login.html @@ -5,7 +5,8 @@ - Sign in + Sign in · INBUXA +

Sign in

Enter your credentials to continue

\ No newline at end of file + Sign in · INBUXA

Sign in

Enter your credentials to continue

\ No newline at end of file diff --git a/resources/html-templates/login.html.min.gz b/resources/html-templates/login.html.min.gz index 80d26e8..475be43 100644 Binary files a/resources/html-templates/login.html.min.gz and b/resources/html-templates/login.html.min.gz differ diff --git a/tests/resources/itip/google_calendar.txt b/tests/resources/itip/google_calendar.txt index e1a75d2..3cfee45 100644 --- a/tests/resources/itip/google_calendar.txt +++ b/tests/resources/itip/google_calendar.txt @@ -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 b@gmail.com 1qnf39p0m9h6n1cm9qa9d8mocv@google.com BEGIN:VCALENDAR -PRODID:-//Stalwart Labs LLC//Stalwart Server//EN +PRODID:-//INBUXA//INBUXA Server//EN VERSION:2.0 BEGIN:VEVENT X-MICROSOFT-CDO-OWNERAPPTID:299828133 diff --git a/tests/resources/itip/itip_incoming.txt b/tests/resources/itip/itip_incoming.txt index 9033373..e0dc9d9 100644 --- a/tests/resources/itip/itip_incoming.txt +++ b/tests/resources/itip/itip_incoming.txt @@ -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 diff --git a/tests/resources/itip/put_validation.txt b/tests/resources/itip/put_validation.txt index fbe268c..61c645b 100644 --- a/tests/resources/itip/put_validation.txt +++ b/tests/resources/itip/put_validation.txt @@ -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 diff --git a/tests/resources/itip/rfc5546_event_recurring.txt b/tests/resources/itip/rfc5546_event_recurring.txt index bb69530..b356ff8 100644 --- a/tests/resources/itip/rfc5546_event_recurring.txt +++ b/tests/resources/itip/rfc5546_event_recurring.txt @@ -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 b@example.com guid-1@example.com 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 b@example.com guid-1@example.com 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 b@example.com guid-1@example.com 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 b@example.com 123456789@example.com 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 c@example.com 123456789@example.com 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 diff --git a/tests/resources/itip/rfc5546_event_single.txt b/tests/resources/itip/rfc5546_event_single.txt index 278e279..3df323e 100644 --- a/tests/resources/itip/rfc5546_event_single.txt +++ b/tests/resources/itip/rfc5546_event_single.txt @@ -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 b@example.com calsrv.example.com-873970198738777@example.com 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 b@example.com calsrv.example.com-873970198738777@example.com 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 c@example.com calsrv.example.com-873970198738777@example.com 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 c@example.com calsrv.example.com-873970198738777@example.com BEGIN:VCALENDAR VERSION:2.0 -PRODID:-//Stalwart Labs LLC//Stalwart Server//EN +PRODID:-//INBUXA//INBUXA Server//EN BEGIN:VEVENT DTSTAMP:19970701T180000Z UID:calsrv.example.com-873970198738777@example.com @@ -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 e@example.com calsrv.example.com-873970198738777@example.com 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 e@example.com calsrv.example.com-873970198738777@example.com 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 c@example.com calsrv.example.com-873970198738777@example.com 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 e@example.com calsrv.example.com-873970198738777@example.com 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 c@example.com calsrv.example.com-873970198738777@example.com 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: "a@example.com", name: None, is_organizer: true }, ItipParticipant { email: "b@example.com", name: None, is_organizer: false }, ItipParticipant { email: "c@example.com", name: None, is_organizer: false }, ItipParticipant { email: "conf@example.com", name: None, is_organizer: false }, ItipParticipant { email: "d@example.com", name: Some("Hal"), is_organizer: false }, ItipParticipant { email: "e@example.com", 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 b@example.com calsrv.example.com-873970198738777@example.com 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 diff --git a/tests/resources/itip/rfc5546_todo.txt b/tests/resources/itip/rfc5546_todo.txt index 5efa11a..01a0aec 100644 --- a/tests/resources/itip/rfc5546_todo.txt +++ b/tests/resources/itip/rfc5546_todo.txt @@ -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 b@example.com calsrv.example.com-873970198738777-00@example.com 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: "a@example.com", 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: "a@example.com", 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: "a@example.com", 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 c@example.com calsrv.example.com-873970198738777-00@example.com 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 diff --git a/tests/resources/itip/rfc6638_recurring.txt b/tests/resources/itip/rfc6638_recurring.txt index e619597..70bd46b 100644 --- a/tests/resources/itip/rfc6638_recurring.txt +++ b/tests/resources/itip/rfc6638_recurring.txt @@ -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 bernard@example.net 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 diff --git a/tests/resources/itip/rfc6638_single.txt b/tests/resources/itip/rfc6638_single.txt index 312c3ae..b6554c2 100644 --- a/tests/resources/itip/rfc6638_single.txt +++ b/tests/resources/itip/rfc6638_single.txt @@ -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 wilfredo@example.com 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 diff --git a/tests/resources/itip/vtimezone.txt b/tests/resources/itip/vtimezone.txt index 0edd9fd..d90562c 100644 --- a/tests/resources/itip/vtimezone.txt +++ b/tests/resources/itip/vtimezone.txt @@ -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 diff --git a/tests/src/imap/basic.rs b/tests/src/imap/basic.rs index 60eed8c..21efaff 100644 --- a/tests/src/imap/basic.rs +++ b/tests/src/imap/basic.rs @@ -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 jdoe@example.com secret").await; diff --git a/tests/src/jmap/calendar/calendars.rs b/tests/src/jmap/calendar/calendars.rs index 9ca9a8e..af72eaf 100644 --- a/tests/src/jmap/calendar/calendars.rs +++ b/tests/src/jmap/calendar/calendars.rs @@ -43,7 +43,7 @@ pub async fn test(test: &TestServer) { list[0], json!({ "id": default_calendar_id, - "name": "Stalwart Calendar (jdoe@example.com)", + "name": "INBUXA Calendar (jdoe@example.com)", "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 (jdoe@example.com)", + "name": "INBUXA Calendar (jdoe@example.com)", "description": (), "sortOrder": 0, "isSubscribed": true, diff --git a/tests/src/jmap/contacts/addressbook.rs b/tests/src/jmap/contacts/addressbook.rs index 4a4bad8..fa253c9 100644 --- a/tests/src/jmap/contacts/addressbook.rs +++ b/tests/src/jmap/contacts/addressbook.rs @@ -36,7 +36,7 @@ pub async fn test(test: &TestServer) { assert_eq!( list[0], json!({ - "name": "Stalwart Address Book (jdoe@example.com)", + "name": "INBUXA Address Book (jdoe@example.com)", "description": (), "sortOrder": 0, "isSubscribed": true, @@ -146,7 +146,7 @@ pub async fn test(test: &TestServer) { "id": addressbook_id, }), json!({ - "name": "Stalwart Address Book (jdoe@example.com)", + "name": "INBUXA Address Book (jdoe@example.com)", "description": (), "sortOrder": 0, "isSubscribed": true, diff --git a/tests/src/jmap/principal/get.rs b/tests/src/jmap/principal/get.rs index a739c60..3be7f5d 100644 --- a/tests/src/jmap/principal/get.rs +++ b/tests/src/jmap/principal/get.rs @@ -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": {}, diff --git a/tests/src/webdav/cal_query.rs b/tests/src/webdav/cal_query.rs index 8c34904..f1ff0ef 100644 --- a/tests/src/webdav/cal_query.rs +++ b/tests/src/webdav/cal_query.rs @@ -905,7 +905,7 @@ const REPORT_10: &str = r#" 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#" 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