JMAP/changes: Update newState with last changeId if an invalid fromChangeId is provided

This commit is contained in:
mdecimus
2026-01-19 07:53:29 -03:00
parent 1fbc7c04bf
commit 4b661d5d1f
2 changed files with 33 additions and 38 deletions

View File

@@ -199,7 +199,6 @@ fn validate_identity_value(
identity: &mut ParticipantIdentity,
allowed_emails: &AHashSet<String>,
) -> Result<(), SetError<ParticipantIdentityProperty>> {
let mut changed_address = None;
for (property, value) in update.into_expanded_object() {
let Key::Property(property) = property else {
return Err(SetError::invalid_properties()
@@ -213,7 +212,27 @@ fn validate_identity_value(
}
(ParticipantIdentityProperty::CalendarAddress, Value::Str(value)) => {
if identity.calendar_address != value {
changed_address = Some(value);
let email = if let Some(email) = value.strip_prefix("mailto:") {
sanitize_email(email)
} else {
sanitize_email(&value)
};
if let Some(email) = email {
if allowed_emails.iter().any(|e| e == &email) {
identity.calendar_address = format!("mailto:{email}");
} else {
return Err(SetError::invalid_properties()
.with_property(ParticipantIdentityProperty::CalendarAddress)
.with_description(
"Calendar address not configured for this account.".to_string(),
));
}
} else {
return Err(SetError::invalid_properties()
.with_property(ParticipantIdentityProperty::CalendarAddress)
.with_description("Invalid or missing calendar address.".to_string()));
}
}
}
(property, _) => {
@@ -223,34 +242,10 @@ fn validate_identity_value(
}
}
}
// Validate email address
if !identity.calendar_address.is_empty() {
if let Some(new_address) = changed_address {
let email = if let Some(email) = new_address.strip_prefix("mailto:") {
sanitize_email(email)
} else {
sanitize_email(&new_address)
};
if let Some(email) = email {
if allowed_emails.iter().any(|e| e == &email) {
identity.calendar_address = format!("mailto:{email}");
Ok(())
} else {
Err(SetError::invalid_properties()
.with_property(ParticipantIdentityProperty::CalendarAddress)
.with_description(
"Calendar address not configured for this account.".to_string(),
))
}
} else {
Err(SetError::invalid_properties()
.with_property(ParticipantIdentityProperty::CalendarAddress)
.with_description("Invalid or missing calendar address.".to_string()))
}
} else {
Ok(())
}
Ok(())
} else {
Err(SetError::invalid_properties()
.with_property(ParticipantIdentityProperty::CalendarAddress)

View File

@@ -63,14 +63,14 @@ impl Store {
pub async fn changes(
&self,
account_id: u32,
collection: LogCollection,
collection_: LogCollection,
query: Query,
) -> trc::Result<Changes> {
let is_share_log = matches!(
collection,
collection_,
LogCollection::Sync(SyncCollection::ShareNotification)
);
let collection = u8::from(collection);
let collection = u8::from(collection_);
let (is_inclusive, from_change_id, to_change_id) = match query {
Query::All => (true, 0, u64::MAX),
@@ -127,13 +127,13 @@ impl Store {
.await
.caused_by(trc::location!())?;
if changelog.changes.is_empty() {
changelog.from_change_id = from_change_id;
changelog.to_change_id = if to_change_id != u64::MAX {
to_change_id
} else {
from_change_id
};
// A non-existing change id was requested, return the last change id
if changelog.changes.is_empty() && from_change_id != 0 && changelog.from_change_id == 0 {
changelog.from_change_id = self
.get_last_change_id(account_id, collection_)
.await?
.unwrap_or_default();
changelog.to_change_id = changelog.from_change_id;
}
Ok(changelog)