fix: accept inbox published timestamps without timezone

Signed-off-by: Marcus Fihlon <marcus@fihlon.swiss>
This commit is contained in:
Marcus Fihlon 2026-05-02 20:13:49 +02:00
parent 55265c991c
commit f5dd624016
Signed by: McPringle
GPG key ID: C6B7F469EE363E1F

View file

@ -21,6 +21,11 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
import java.util.Map;
import java.util.UUID;
@ -411,7 +416,7 @@ public class InboxProcessor {
// Parse published timestamp
String publishedStr = (String) noteObject.get("published");
Instant publishedAt = publishedStr != null ? Instant.parse(publishedStr) : Instant.now();
Instant publishedAt = parsePublishedAt(publishedStr);
// Build RemoteActivity entity
RemoteActivity remoteActivity = RemoteActivity.builder()
@ -824,6 +829,44 @@ public class InboxProcessor {
}
}
/**
* Parse ActivityPub published timestamps.
*
* <p>Preferred input is a full ISO-8601 instant with timezone/offset. Some
* remote implementations still send zoneless timestamps, so we accept those
* as a compatibility fallback and interpret them as UTC.
*/
private Instant parsePublishedAt(String publishedStr) {
if (publishedStr == null || publishedStr.isBlank()) {
return Instant.now();
}
try {
return Instant.parse(publishedStr);
} catch (DateTimeParseException ignored) {
// Fall through to compatibility parsers below.
}
try {
return OffsetDateTime.parse(publishedStr).toInstant();
} catch (DateTimeParseException ignored) {
// Fall through to compatibility parsers below.
}
try {
return ZonedDateTime.parse(publishedStr).toInstant();
} catch (DateTimeParseException ignored) {
// Fall through to compatibility parsers below.
}
try {
return LocalDateTime.parse(publishedStr).atOffset(ZoneOffset.UTC).toInstant();
} catch (DateTimeParseException e) {
log.warn("Failed to parse published timestamp: {}", publishedStr, e);
return Instant.now();
}
}
/**
* Serialize object to JSON string.
*/