diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ed623ef..de003a6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,13 +15,14 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If ## Changed ## 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. - Unchanged immutable `id` property is rejected on `/set`. - `filter: null` rejected as `notRequest` on `/query` and `/queryChanges`. - `Email/query` total miscount when `collapseThreads` is enabled. - `SearchSnippet/get` response structure. - `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. - RocksDB: Enable blob garbage collection to reclaim disk space from deleted blobs. diff --git a/crates/jmap/src/submission/set.rs b/crates/jmap/src/submission/set.rs index 7b24b247..eab2fa18 100644 --- a/crates/jmap/src/submission/set.rs +++ b/crates/jmap/src/submission/set.rs @@ -25,9 +25,9 @@ use jmap_proto::{ method::{MethodFunction, MethodName, MethodObject}, reference::{MaybeIdReference, MaybeResultReference}, }, - types::state::State, + types::{date::UTCDate, state::State}, }; -use jmap_tools::{Key, Value}; +use jmap_tools::{Key, Map, Value}; use smtp::{ core::{Session, SessionData}, queue::spool::SmtpSpool, @@ -88,6 +88,13 @@ impl EmailSubmissionSet for Server { 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 let document_id = self .store() @@ -101,7 +108,27 @@ impl EmailSubmissionSet for Server { .custom(ObjectIndexBuilder::<(), _>::new().with_changes(submission)) .caused_by(trc::location!())? .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) => { response.not_created.append(id, err);