Fix JMAP: EmailSubmission/set must return sendAt and undoStatus in the created response

This commit is contained in:
Maurus Decimus
2026-06-18 16:34:49 +02:00
parent 4e9b4c1651
commit 63284599d7
2 changed files with 32 additions and 4 deletions

View File

@@ -15,13 +15,14 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If
## Changed ## Changed
## Fixed ## Fixed
- JMAP: - JMAP conformance (pass the [jmap-test-suite](https://github.com/jmapio/jmap-test-suite) tests):
- Default calendars and address books are not subscribed by default. - Default calendars and address books are not subscribed by default.
- Unchanged immutable `id` property is rejected on `/set`. - Unchanged immutable `id` property is rejected on `/set`.
- `filter: null` rejected as `notRequest` on `/query` and `/queryChanges`. - `filter: null` rejected as `notRequest` on `/query` and `/queryChanges`.
- `Email/query` total miscount when `collapseThreads` is enabled. - `Email/query` total miscount when `collapseThreads` is enabled.
- `SearchSnippet/get` response structure. - `SearchSnippet/get` response structure.
- `VacationResponse` singleton handling. - `VacationResponse` singleton handling.
- `EmailSubmission/set` must return `sendAt` and `undoStatus` in the created response.
- OIDC: Add default domain name to groups that are not email addresses. - OIDC: Add default domain name to groups that are not email addresses.
- RocksDB: Enable blob garbage collection to reclaim disk space from deleted blobs. - RocksDB: Enable blob garbage collection to reclaim disk space from deleted blobs.

View File

@@ -25,9 +25,9 @@ use jmap_proto::{
method::{MethodFunction, MethodName, MethodObject}, method::{MethodFunction, MethodName, MethodObject},
reference::{MaybeIdReference, MaybeResultReference}, reference::{MaybeIdReference, MaybeResultReference},
}, },
types::state::State, types::{date::UTCDate, state::State},
}; };
use jmap_tools::{Key, Value}; use jmap_tools::{Key, Map, Value};
use smtp::{ use smtp::{
core::{Session, SessionData}, core::{Session, SessionData},
queue::spool::SmtpSpool, queue::spool::SmtpSpool,
@@ -88,6 +88,13 @@ impl EmailSubmissionSet for Server {
Id::from_parts(submission.thread_id, submission.email_id), Id::from_parts(submission.thread_id, submission.email_id),
); );
let send_at = submission.send_at;
let undo_status = match submission.undo_status {
UndoStatus::Pending => email_submission::UndoStatus::Pending,
UndoStatus::Final => email_submission::UndoStatus::Final,
UndoStatus::Canceled => email_submission::UndoStatus::Canceled,
};
// Insert record // Insert record
let document_id = self let document_id = self
.store() .store()
@@ -101,7 +108,27 @@ impl EmailSubmissionSet for Server {
.custom(ObjectIndexBuilder::<(), _>::new().with_changes(submission)) .custom(ObjectIndexBuilder::<(), _>::new().with_changes(submission))
.caused_by(trc::location!())? .caused_by(trc::location!())?
.commit_point(); .commit_point();
response.created(id, document_id);
response.created.insert(
id,
Value::Object(
Map::with_capacity(3)
.with_key_value(
EmailSubmissionProperty::Id,
Value::Element(Id::from(document_id).into()),
)
.with_key_value(
EmailSubmissionProperty::SendAt,
Value::Element(EmailSubmissionValue::Date(
UTCDate::from_timestamp(send_at as i64),
)),
)
.with_key_value(
EmailSubmissionProperty::UndoStatus,
Value::Element(EmailSubmissionValue::UndoStatus(undo_status)),
),
),
);
} }
Err(err) => { Err(err) => {
response.not_created.append(id, err); response.not_created.append(id, err);