Compare commits
14
Commits
v2026.10.5.1
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b62713bb8d | ||
|
|
ef56eb33ed | ||
|
|
b64f6690f6 | ||
|
|
bf7c84bc15 | ||
|
|
b07e69b5ed | ||
|
|
ce8284df6c | ||
|
|
966241070e | ||
|
|
b25258330c | ||
|
|
db4135e481 | ||
|
|
72f8ddd5e7 | ||
|
|
88e756bc3a | ||
|
|
f77d171063 | ||
|
|
79db6c537b | ||
|
|
ca4bf75c1b |
No files matched your search
@@ -5,11 +5,6 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "cargo" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
# Enable version updates for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
# Workflow files stored in the default location of `.github/workflows`
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Close issues from non-allowed authors
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
// Users allowed to open issues directly. All other authors will have
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
sparse-checkout-cone-mode: false
|
||||
|
||||
- name: Close PRs from non-allowed authors
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Post support portal redirect
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const discussion = context.payload.discussion;
|
||||
|
||||
@@ -73,6 +73,6 @@ jobs:
|
||||
# Upload the results to GitHub's code scanning dashboard (optional).
|
||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/[email protected]7.4
|
||||
uses: github/codeql-action/[email protected]8.2
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -36,6 +36,6 @@ jobs:
|
||||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/[email protected]7.4
|
||||
uses: github/codeql-action/[email protected]8.2
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
@@ -2,6 +2,33 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.16.25] - 2026-10-05
|
||||
|
||||
If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions.
|
||||
|
||||
## Added
|
||||
|
||||
## Changed
|
||||
|
||||
## Fixed
|
||||
- JMAP: Creating a `MaskedEmail` with `emailDomain` fails with `forbidden` for every domain when the account has addresses on more than one domain.
|
||||
- Autodiscover: Requests for a response schema other than Outlook's, such as ActiveSync (`mobilesync`), are answered with the Outlook settings instead of error 601.
|
||||
- IMAP:
|
||||
- `LOGIN` and `AUTHENTICATE` with a wrong, expired or unknown app password or API key are answered with an untagged `NO`, so clients keep waiting for the command to complete until the connection times out.
|
||||
- The failed login that exceeds the maximum number of authentication failures is answered with an untagged `NO` before the connection is closed.
|
||||
- DKIM:
|
||||
- A rotation moves the active key to retiring even when its successor fails to publish or propagate, so outgoing mail is sent unsigned until a retry publishes the new key. The DNS write failure is also not logged and the task reports success.
|
||||
- Keys created while DNS management was manual, or before DKIM was added to the published records, are never rotated after DNS management becomes automatic. Domains already affected start rotating once a `DkimManagement` task is created for them.
|
||||
- After switching DNS management from automatic to manual, a due rotation activates a new key that was never published in DNS, so signatures fail verification, and retiring the old key is retried forever.
|
||||
- Spam filter:
|
||||
- Messages with no text line long enough for a Pyzor digest are checked with the digest of empty input and tagged `PYZOR`.
|
||||
- DNSBL answers with several return codes, such as a Spamhaus ZEN listing in both SBL and PBL, are scored for only the first code returned.
|
||||
- DNSBL lookups that return "not listed" are cached for 24 hours regardless of the zone's negative TTL.
|
||||
- Removing a duplicate training sample of a message reclassified on the same day clears the blob link of the sample that is kept.
|
||||
- MTA: Queue quotas with an empty `match` expression are never enforced, including the global queue quota created on first start.
|
||||
- RocksDB: The info log (`LOG`, `LOG.old.*`) grows without limit because log rotation and retention are left at RocksDB defaults.
|
||||
- WebUI: A blob store read error at startup, such as an S3 authentication failure, stops the web interface from being downloaded.
|
||||
|
||||
## [0.16.24] - 2026-09-27
|
||||
|
||||
If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions.
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ representative at an online or offline event.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
**johnellisATlinuxDOTcom**.
|
||||
**communityATcoffeylabsDOTorg**.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ Coffey Labs" line in place. New files carry:
|
||||
|
||||
```
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
Generated
+79
-69
@@ -277,9 +277,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.48"
|
||||
version = "0.4.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb61aea1a7def73ee7c350a184f0e70b32c182344e2e75bf70c9b621b83417fd"
|
||||
checksum = "ee19bd99b43e3691acbad4e840420a4881cea6c0b66a208125a824f8fd53f5a1"
|
||||
dependencies = [
|
||||
"compression-codecs",
|
||||
"compression-core",
|
||||
@@ -1292,7 +1292,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "common"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"aes-gcm-siv",
|
||||
"ahash",
|
||||
@@ -1392,9 +1392,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "compression-codecs"
|
||||
version = "0.4.43"
|
||||
version = "0.4.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef16c47ba2797aa6a909cc37d39911f3a6743811fe7408ac0b0cc0276b656e9"
|
||||
checksum = "98fc98460ba0ad5317075d3632b8dfc45d0be8c4a49347c2a38272019717614a"
|
||||
dependencies = [
|
||||
"compression-core",
|
||||
"flate2",
|
||||
@@ -1477,7 +1477,7 @@ checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
|
||||
|
||||
[[package]]
|
||||
name = "coordinator"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"async-nats",
|
||||
"futures",
|
||||
@@ -1889,7 +1889,7 @@ checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06"
|
||||
|
||||
[[package]]
|
||||
name = "dav"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"calcard",
|
||||
"chrono",
|
||||
@@ -1912,7 +1912,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dav-proto"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"calcard",
|
||||
"chrono",
|
||||
@@ -2125,7 +2125,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "directory"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"argon2 0.6.0",
|
||||
@@ -2366,7 +2366,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "email"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"aes 0.9.3",
|
||||
"aes-gcm 0.11.1",
|
||||
@@ -2406,6 +2406,16 @@ dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encodify"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "798c447647dd23f673748f2b868ef309a01dd86aaae999182559d36f06ac82f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"simdutf8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.42"
|
||||
@@ -2474,7 +2484,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "event_macro"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 3.0.6",
|
||||
@@ -3002,7 +3012,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "groupware"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"calcard",
|
||||
@@ -3289,7 +3299,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"base64 0.23.1",
|
||||
@@ -3385,7 +3395,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "http_proto"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"common",
|
||||
"compact_str",
|
||||
@@ -3872,7 +3882,7 @@ checksum = "65b27460c2c92b037f3f94c538ed9a3342f3fdf923606781629ccb35f82d042a"
|
||||
|
||||
[[package]]
|
||||
name = "imap"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"common",
|
||||
@@ -3897,7 +3907,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "imap_proto"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.23.1",
|
||||
@@ -3912,7 +3922,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "inbuxa"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"common",
|
||||
"coordinator",
|
||||
@@ -3920,7 +3930,7 @@ dependencies = [
|
||||
"directory",
|
||||
"email",
|
||||
"groupware",
|
||||
"http 0.16.24",
|
||||
"http 0.16.25",
|
||||
"http_proto",
|
||||
"imap",
|
||||
"jmap",
|
||||
@@ -4209,7 +4219,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jmap"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"base64 0.23.1",
|
||||
@@ -4258,14 +4268,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jmap-client"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4deab22e057d24e32122f0fc6e2d667a124fdd6a0d8ef3ed4f8a89923c11084f"
|
||||
checksum = "f5b5bc66252cc8e779ef1238f40ab93971d54ad00b5d7afb5c1d447a9647ed62"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"async-stream",
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"encodify",
|
||||
"futures-util",
|
||||
"maybe-async",
|
||||
"parking_lot",
|
||||
@@ -4292,7 +4302,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jmap_proto"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"calcard",
|
||||
@@ -4502,9 +4512,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb"
|
||||
dependencies = [
|
||||
"spin 0.9.9",
|
||||
]
|
||||
@@ -4798,7 +4808,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "managesieve"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"common",
|
||||
"compact_str",
|
||||
@@ -4933,7 +4943,7 @@ checksum = "c797b9d6bb23aab2fc369c65f871be49214f5c759af65bde26ffaaa2b646b492"
|
||||
|
||||
[[package]]
|
||||
name = "migration"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"common",
|
||||
"email",
|
||||
@@ -5183,7 +5193,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nlp"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"hashify",
|
||||
@@ -5503,8 +5513,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.32.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#80a14a3b6846f62f85506d68d2600c948fccc9d2"
|
||||
version = "0.33.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#ae66e97b140f70e477ab710686aafce665cc2f8b"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -5516,8 +5526,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-http"
|
||||
version = "0.32.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#80a14a3b6846f62f85506d68d2600c948fccc9d2"
|
||||
version = "0.33.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#ae66e97b140f70e477ab710686aafce665cc2f8b"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@@ -5528,8 +5538,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-otlp"
|
||||
version = "0.32.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#80a14a3b6846f62f85506d68d2600c948fccc9d2"
|
||||
version = "0.33.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#ae66e97b140f70e477ab710686aafce665cc2f8b"
|
||||
dependencies = [
|
||||
"http 1.5.0",
|
||||
"httpdate",
|
||||
@@ -5547,8 +5557,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-proto"
|
||||
version = "0.32.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#80a14a3b6846f62f85506d68d2600c948fccc9d2"
|
||||
version = "0.33.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#ae66e97b140f70e477ab710686aafce665cc2f8b"
|
||||
dependencies = [
|
||||
"opentelemetry",
|
||||
"opentelemetry_sdk",
|
||||
@@ -5559,13 +5569,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-semantic-conventions"
|
||||
version = "0.32.1"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#80a14a3b6846f62f85506d68d2600c948fccc9d2"
|
||||
version = "0.33.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#ae66e97b140f70e477ab710686aafce665cc2f8b"
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry_sdk"
|
||||
version = "0.32.1"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#80a14a3b6846f62f85506d68d2600c948fccc9d2"
|
||||
version = "0.33.0"
|
||||
source = "git+https://github.com/stalwartlabs/opentelemetry-rust#ae66e97b140f70e477ab710686aafce665cc2f8b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-executor",
|
||||
@@ -6015,7 +6025,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pop3"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"common",
|
||||
"directory",
|
||||
@@ -6385,9 +6395,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.18"
|
||||
version = "0.11.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9746dbde176634f4f2f1faf2404e30a31b2bc1e9cafb5329c95d8177a18c9fc"
|
||||
checksum = "0e750cca55fe4f0439a15d0bb529da9651e79993e8e72c61a899a36d462befbe"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"bytes",
|
||||
@@ -6410,9 +6420,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.15"
|
||||
version = "0.5.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694"
|
||||
checksum = "af66907df18639dcf4db56ca65490cabc4b27a97dbadd96f2926cca73298f016"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
@@ -6835,7 +6845,7 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
||||
|
||||
[[package]]
|
||||
name = "registry"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"hashify",
|
||||
@@ -7392,7 +7402,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "scim"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.23.1",
|
||||
@@ -7418,7 +7428,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "scim-proto"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"hashify",
|
||||
"serde",
|
||||
@@ -7672,9 +7682,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.23.0"
|
||||
version = "3.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "935177bb8c0cd8ca1a4e6d1a2ac8988bea69cab4f9d3a31311e012ad27868ea4"
|
||||
checksum = "df9adc193c780ef8f159aee8b61e2d5801aaa555e6eb0947fe45530ec506296f"
|
||||
dependencies = [
|
||||
"base64 0.23.1",
|
||||
"bs58",
|
||||
@@ -7693,9 +7703,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.23.0"
|
||||
version = "3.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d607aa01a3cb0ad757d6fd216136910db3c97b102fe686585689615a02dbcdc"
|
||||
checksum = "3e17bbc68e28663bbbb90df47e058aa7eda4fb445b89fe70457bb94fbccf6e49"
|
||||
dependencies = [
|
||||
"darling 0.24.1",
|
||||
"proc-macro2",
|
||||
@@ -7753,7 +7763,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "services"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"aes-gcm 0.11.1",
|
||||
"aho-corasick",
|
||||
@@ -8068,7 +8078,7 @@ checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e"
|
||||
|
||||
[[package]]
|
||||
name = "smtp"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.23.1",
|
||||
@@ -8107,9 +8117,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smtp-proto"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "707104487221ff447b5b796b5049e5c09cf52ff9fc1c8abba4695b89ac4b0f37"
|
||||
checksum = "142a5a642c6bd7ffd7e1b525ad6a6e9921ccef992dba4663974f8519209a00c1"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"rkyv",
|
||||
@@ -8159,7 +8169,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "spam-filter"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"common",
|
||||
"compact_str",
|
||||
@@ -8279,7 +8289,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "store"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"arc-swap",
|
||||
@@ -8539,7 +8549,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tests"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"aws-lc-rs",
|
||||
@@ -8561,7 +8571,7 @@ dependencies = [
|
||||
"form_urlencoded",
|
||||
"futures",
|
||||
"groupware",
|
||||
"http 0.16.24",
|
||||
"http 0.16.25",
|
||||
"http_proto",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
@@ -8818,9 +8828,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.5"
|
||||
version = "0.26.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67"
|
||||
checksum = "c9cc2678c2cdd569ef8215e2afd7954ada2ae20b4fdd2c5fe6139a3b02d105db"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
@@ -9154,7 +9164,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "trc"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.23.1",
|
||||
@@ -9263,7 +9273,7 @@ checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
||||
|
||||
[[package]]
|
||||
name = "types"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"blake3",
|
||||
"compact_str",
|
||||
@@ -9432,7 +9442,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "utils"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"arcstr",
|
||||
@@ -10117,9 +10127,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "xxhash-rust"
|
||||
version = "0.8.18"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6"
|
||||
checksum = "550a2b930b62486a393c52d5c3b84bff264b28aa437ed64694d31e93b1757af7"
|
||||
|
||||
[[package]]
|
||||
name = "yasna"
|
||||
@@ -10144,9 +10154,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "yoke-derive"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78"
|
||||
checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
# *****************
|
||||
# Base image for planner & builder
|
||||
# *****************
|
||||
FROM --platform=$BUILDPLATFORM rust:slim-trixie AS base
|
||||
FROM --platform=$BUILDPLATFORM rust:1.98.1-slim-trixie AS base
|
||||
|
||||
ENV DEBIAN_FRONTEND="noninteractive" \
|
||||
BINSTALL_DISABLE_TELEMETRY=true \
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ visible to everyone, including whoever would use it, before there is a fix.
|
||||
|
||||
Report it privately by email to:
|
||||
|
||||
**johnellisATlinuxDOTcom**
|
||||
**securityATcoffeylabsDOTorg**
|
||||
|
||||
Include as much as you can of:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "common"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
edition = "2024"
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -225,7 +225,7 @@ pub struct Caches {
|
||||
pub dns_ipv6: CacheWithTtl<Box<str>, RecordSet<Ipv6Addr>>,
|
||||
pub dns_tlsa: CacheWithTtl<Box<str>, Arc<Tlsa>>,
|
||||
pub dns_mta_sts: CacheWithTtl<Box<str>, Arc<Policy>>,
|
||||
pub dns_rbl: CacheWithTtl<Box<str>, Option<Arc<IpResolver>>>,
|
||||
pub dns_rbl: CacheWithTtl<Box<str>, Option<Arc<[IpResolver]>>>,
|
||||
|
||||
pub negative_cache_ttl: Duration,
|
||||
}
|
||||
|
||||
@@ -227,10 +227,22 @@ impl WebApplicationManager {
|
||||
let cached = if force_refresh {
|
||||
None
|
||||
} else {
|
||||
server
|
||||
match server
|
||||
.blob_store()
|
||||
.get_blob(self.blob_key.as_slice(), 0..usize::MAX)
|
||||
.await?
|
||||
.await
|
||||
{
|
||||
Ok(cached) => cached,
|
||||
Err(err) => {
|
||||
trc::event!(
|
||||
Resource(trc::ResourceEvent::Error),
|
||||
Reason = err,
|
||||
Url = self.url.clone(),
|
||||
Details = "Failed to read cached application bundle, downloading it again"
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
let is_cached = cached.is_some();
|
||||
let bundle = match cached {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*
|
||||
|
||||
@@ -11,7 +11,7 @@ use quick_xml::Reader;
|
||||
use quick_xml::XmlVersion;
|
||||
use quick_xml::events::Event;
|
||||
use registry::schema::{enums::ServiceProtocol, structs::Service};
|
||||
use std::fmt::Write;
|
||||
use std::{borrow::Cow, fmt::Write};
|
||||
use utils::map::vec_map::VecMap;
|
||||
|
||||
impl Server {
|
||||
@@ -20,32 +20,78 @@ impl Server {
|
||||
body: Option<Vec<u8>>,
|
||||
) -> trc::Result<Resource<Vec<u8>>> {
|
||||
// Obtain parameters
|
||||
let emailaddress = parse_autodiscover_request(body.as_deref().unwrap_or_default())
|
||||
.map_err(|err| {
|
||||
let request =
|
||||
parse_autodiscover_request(body.as_deref().unwrap_or_default()).map_err(|err| {
|
||||
trc::ResourceEvent::BadParameters
|
||||
.into_err()
|
||||
.details("Failed to parse autodiscover request")
|
||||
.ctx(trc::Key::Reason, err)
|
||||
})?;
|
||||
// inbuxa: legacy-protocols LP-7, LP-14a
|
||||
let legacy_off = match emailaddress.rsplit_once('@') {
|
||||
let legacy_off = match request.email.rsplit_once('@') {
|
||||
Some((_, domain)) => self.legacy_off_for(domain).await?,
|
||||
None => self.legacy_off_for("").await?,
|
||||
};
|
||||
|
||||
Ok(Resource::new(
|
||||
"application/xml; charset=utf-8",
|
||||
build_autodiscover_response(
|
||||
&emailaddress,
|
||||
let response = match request.response_schema {
|
||||
ResponseSchema::Outlook => build_autodiscover_response(
|
||||
&request.email,
|
||||
&self.core.network.server_name,
|
||||
&self.core.network.info.services,
|
||||
|protocol| legacy_off.service(protocol),
|
||||
)
|
||||
.into_bytes(),
|
||||
))
|
||||
ResponseSchema::Unsupported => PROVIDER_NOT_AVAILABLE_RESPONSE.as_bytes().to_vec(),
|
||||
};
|
||||
|
||||
Ok(Resource::new("application/xml; charset=utf-8", response))
|
||||
}
|
||||
}
|
||||
|
||||
const OUTLOOK_RESPONSE_SCHEMA: &str =
|
||||
"http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a";
|
||||
|
||||
const PROVIDER_NOT_AVAILABLE_RESPONSE: &str = concat!(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
|
||||
"<Autodiscover xmlns=\"http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006\">\n",
|
||||
"\t<Response>\n",
|
||||
"\t\t<Error>\n",
|
||||
"\t\t\t<ErrorCode>601</ErrorCode>\n",
|
||||
"\t\t\t<Message>Provider is not available</Message>\n",
|
||||
"\t\t\t<DebugData />\n",
|
||||
"\t\t</Error>\n",
|
||||
"\t</Response>\n",
|
||||
"</Autodiscover>\n",
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum ResponseSchema {
|
||||
Outlook,
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
impl ResponseSchema {
|
||||
fn parse(value: &str) -> Self {
|
||||
if value.trim().eq_ignore_ascii_case(OUTLOOK_RESPONSE_SCHEMA) {
|
||||
ResponseSchema::Outlook
|
||||
} else {
|
||||
ResponseSchema::Unsupported
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct AutodiscoverRequest {
|
||||
email: String,
|
||||
response_schema: ResponseSchema,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum RequestField {
|
||||
EmailAddress,
|
||||
ResponseSchema,
|
||||
}
|
||||
|
||||
fn build_autodiscover_response(
|
||||
emailaddress: &str,
|
||||
default_host: &str,
|
||||
@@ -124,7 +170,7 @@ fn build_autodiscover_response(
|
||||
config
|
||||
}
|
||||
|
||||
fn parse_autodiscover_request(bytes: &[u8]) -> Result<String, String> {
|
||||
fn parse_autodiscover_request(bytes: &[u8]) -> Result<AutodiscoverRequest, String> {
|
||||
if bytes.is_empty() {
|
||||
return Err("Empty request body".to_string());
|
||||
}
|
||||
@@ -132,8 +178,9 @@ fn parse_autodiscover_request(bytes: &[u8]) -> Result<String, String> {
|
||||
let mut reader = Reader::from_reader(bytes);
|
||||
reader.config_mut().trim_text(true);
|
||||
let mut buf = Vec::with_capacity(128);
|
||||
let mut value_buf = Vec::with_capacity(128);
|
||||
|
||||
'outer: for tag_name in ["Autodiscover", "Request", "EMailAddress"] {
|
||||
'outer: for tag_name in ["Autodiscover", "Request"] {
|
||||
loop {
|
||||
match reader.read_event_into(&mut buf) {
|
||||
Ok(Event::Start(e)) => {
|
||||
@@ -143,30 +190,6 @@ fn parse_autodiscover_request(bytes: &[u8]) -> Result<String, String> {
|
||||
.eq_ignore_ascii_case(found_tag_name.as_ref())
|
||||
{
|
||||
continue 'outer;
|
||||
} else if tag_name == "EMailAddress" {
|
||||
// Skip unsupported tags under Request, such as AcceptableResponseSchema
|
||||
let mut tag_count = 0;
|
||||
loop {
|
||||
match reader.read_event_into(&mut buf) {
|
||||
Ok(Event::End(_)) => {
|
||||
if tag_count == 0 {
|
||||
break;
|
||||
} else {
|
||||
tag_count -= 1;
|
||||
}
|
||||
}
|
||||
Ok(Event::Start(_)) => {
|
||||
tag_count += 1;
|
||||
}
|
||||
Ok(Event::Eof) => {
|
||||
return Err(format!(
|
||||
"Expected value, found unexpected EOF at position {}.",
|
||||
reader.buffer_position()
|
||||
));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Expected tag {}, found unexpected tag {} at position {}.",
|
||||
@@ -195,38 +218,172 @@ fn parse_autodiscover_request(bytes: &[u8]) -> Result<String, String> {
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(Event::Text(text)) = reader.read_event_into(&mut buf)
|
||||
&& let Ok(text) = text.xml_content(XmlVersion::Implicit1_0)
|
||||
&& text.contains('@')
|
||||
{
|
||||
return Ok(text.trim().to_lowercase());
|
||||
let mut email = None;
|
||||
let mut response_schema = ResponseSchema::Outlook;
|
||||
|
||||
loop {
|
||||
match reader.read_event_into(&mut buf) {
|
||||
Ok(Event::Start(e)) => {
|
||||
let local_name = e.local_name();
|
||||
let field = hashify::tiny_map_ignore_case!(local_name.as_ref(),
|
||||
b"EMailAddress" => RequestField::EmailAddress,
|
||||
b"AcceptableResponseSchema" => RequestField::ResponseSchema,
|
||||
);
|
||||
|
||||
let value = match reader.read_event_into(&mut value_buf) {
|
||||
Ok(Event::End(_)) => None,
|
||||
Ok(event) => {
|
||||
let value = match event {
|
||||
Event::Text(text) => text
|
||||
.xml_content(XmlVersion::Implicit1_0)
|
||||
.ok()
|
||||
.map(Cow::into_owned),
|
||||
_ => None,
|
||||
};
|
||||
reader
|
||||
.read_to_end_into(e.name(), &mut value_buf)
|
||||
.map_err(|err| {
|
||||
format!("Error at position {}: {:?}", reader.buffer_position(), err)
|
||||
})?;
|
||||
value
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(format!(
|
||||
"Error at position {}: {:?}",
|
||||
reader.buffer_position(),
|
||||
err
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
match (field, value) {
|
||||
(Some(RequestField::EmailAddress), Some(value)) => {
|
||||
email = Some(value);
|
||||
}
|
||||
(Some(RequestField::ResponseSchema), Some(value)) => {
|
||||
response_schema = ResponseSchema::parse(&value);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Ok(Event::End(_) | Event::Eof) => break,
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"Error at position {}: {:?}",
|
||||
reader.buffer_position(),
|
||||
e
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(format!(
|
||||
match email {
|
||||
Some(email) if email.contains('@') => Ok(AutodiscoverRequest {
|
||||
email: email.trim().to_lowercase(),
|
||||
response_schema,
|
||||
}),
|
||||
_ => Err(format!(
|
||||
"Expected email address, found unexpected value at position {}.",
|
||||
reader.buffer_position()
|
||||
))
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{AutodiscoverRequest, ResponseSchema, parse_autodiscover_request};
|
||||
|
||||
#[test]
|
||||
fn parse_autodiscover() {
|
||||
let r = r#"<?xml version="1.0" encoding="utf-8"?>
|
||||
const OUTLOOK: &str =
|
||||
"http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a";
|
||||
const MOBILESYNC: &str =
|
||||
"http://schemas.microsoft.com/exchange/autodiscover/mobilesync/responseschema/2006";
|
||||
|
||||
for (request, expected) in [
|
||||
(
|
||||
format!(
|
||||
r#"<?xml version="1.0" encoding="utf-8"?>
|
||||
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
|
||||
<Request>
|
||||
<EMailAddress>email@example.com</EMailAddress>
|
||||
<AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
|
||||
<EMailAddress>Email@Example.com</EMailAddress>
|
||||
<AcceptableResponseSchema>{OUTLOOK}</AcceptableResponseSchema>
|
||||
</Request>
|
||||
</Autodiscover>"#;
|
||||
|
||||
</Autodiscover>"#
|
||||
),
|
||||
ResponseSchema::Outlook,
|
||||
),
|
||||
(
|
||||
format!(
|
||||
r#"<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
|
||||
<Request>
|
||||
<AcceptableResponseSchema>{OUTLOOK}</AcceptableResponseSchema>
|
||||
<EMailAddress>[email protected]</EMailAddress>
|
||||
</Request>
|
||||
</Autodiscover>"#
|
||||
),
|
||||
ResponseSchema::Outlook,
|
||||
),
|
||||
(
|
||||
r#"<Autodiscover>
|
||||
<Request>
|
||||
<EMailAddress>[email protected]</EMailAddress>
|
||||
</Request>
|
||||
</Autodiscover>"#
|
||||
.to_string(),
|
||||
ResponseSchema::Outlook,
|
||||
),
|
||||
(
|
||||
format!(
|
||||
r#"<?xml version="1.0" encoding="utf-8"?>
|
||||
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/mobilesync/requestschema/2006">
|
||||
<Request>
|
||||
<EMailAddress>[email protected]</EMailAddress>
|
||||
<AcceptableResponseSchema>{MOBILESYNC}</AcceptableResponseSchema>
|
||||
</Request>
|
||||
</Autodiscover>"#
|
||||
),
|
||||
ResponseSchema::Unsupported,
|
||||
),
|
||||
(
|
||||
format!(
|
||||
r#"<Autodiscover>
|
||||
<Request>
|
||||
<LegacyDN>/o=Example/ou=Users/cn=email</LegacyDN>
|
||||
<Unknown><Nested>value</Nested><Empty/></Unknown>
|
||||
<AcceptableResponseSchema>{MOBILESYNC}</AcceptableResponseSchema>
|
||||
<EMailAddress>[email protected]</EMailAddress>
|
||||
</Request>
|
||||
</Autodiscover>"#
|
||||
),
|
||||
ResponseSchema::Unsupported,
|
||||
),
|
||||
] {
|
||||
assert_eq!(
|
||||
super::parse_autodiscover_request(r.as_bytes()).unwrap(),
|
||||
"[email protected]"
|
||||
parse_autodiscover_request(request.as_bytes()).expect("valid request"),
|
||||
AutodiscoverRequest {
|
||||
email: "[email protected]".to_string(),
|
||||
response_schema: expected,
|
||||
},
|
||||
"{request}"
|
||||
);
|
||||
}
|
||||
|
||||
for request in [
|
||||
"",
|
||||
"<Autodiscover><Request></Request></Autodiscover>",
|
||||
"<Autodiscover><Request><EMailAddress>no-domain</EMailAddress></Request></Autodiscover>",
|
||||
"<Autodiscover><Request><EMailAddress>[email protected]</Request></Autodiscover>",
|
||||
"<Request><EMailAddress>[email protected]</EMailAddress></Request>",
|
||||
] {
|
||||
assert!(
|
||||
parse_autodiscover_request(request.as_bytes()).is_err(),
|
||||
"{request}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn autodiscover_encryption() {
|
||||
use registry::schema::{enums::ServiceProtocol, structs::Service};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "coordinator"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "dav-proto"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "dav"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "directory"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "email"
|
||||
version = "0.16.24"
|
||||
version = "0.16.25"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@ use groupware::{
|
||||
scheduling::{ItipError, ItipMessages},
|
||||
};
|
||||
use mail_parser::{
|
||||
DateTime, Header, HeaderName, HeaderValue, Message, MessageParser, MimeHeaders, PartType,
|
||||
Header, HeaderName, HeaderValue, Message, MessageParser, MimeHeaders, PartType,
|
||||
parsers::fields::thread::thread_name,
|
||||
};
|
||||
use registry::{
|
||||
@@ -924,11 +924,7 @@ impl EmailIngest for Server {
|
||||
span_id: u64,
|
||||
) {
|
||||
if let Some(config) = &self.core.spam.classifier {
|
||||
let mut dt = DateTime::from_timestamp(now() as i64);
|
||||
dt.hour = 0;
|
||||
dt.minute = 0;
|
||||
dt.second = 0;
|
||||
let until = dt.to_timestamp() as u64 + config.hold_samples_for;
|
||||
let until = now() + config.hold_samples_for;
|
||||
|
||||
let sample = SpamTrainingSample {
|
||||
account_id: Some(Id::from(account_id)),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs LLC
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
Loaded 100 of 318 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user