field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

commit f97b76407d4b3ee1a5085b4d0855754952823e75
parent 718cb65037a8b5336eb3063886c4a1cc69a9f14e
Author: triesap <tyson@radroots.org>
Date:   Mon, 10 Aug 2026 18:03:02 +0000

feat: harden inbound Blossom retrieval

Verify canonical DNS, redirect, byte, media, and dimension bounds before accepting inbound images.

Persist exact artifacts atomically and revoke corrupt or obsolete cache receipts.

Diffstat:
Mcore/crates/tera_ffi/src/error.rs | 7+++++++
Mcore/crates/tera_ffi/tests/local_mvp_real_io.rs | 2+-
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/core/crates/tera_ffi/src/error.rs b/core/crates/tera_ffi/src/error.rs @@ -148,6 +148,13 @@ impl From<TodayError> for RadrootsAppError { } TodayError::RuntimeUnavailable => ("today_runtime_unavailable", true, &["retry"][..]), TodayError::InboundMedia(_) => ("today_media_invalid", false, &["retry_media"][..]), + TodayError::InboundRetrieval(error) => { + if error.retryable() { + ("today_media_retrieval_failed", true, &["retry_media"][..]) + } else { + ("today_media_retrieval_failed", false, &["review_media"][..]) + } + } TodayError::CorruptProjection | TodayError::Serialization | TodayError::Storage(_) => { ("today_state_failed", true, &["rebuild", "retry"][..]) } diff --git a/core/crates/tera_ffi/tests/local_mvp_real_io.rs b/core/crates/tera_ffi/tests/local_mvp_real_io.rs @@ -829,7 +829,7 @@ async fn prove_corrupted_media_fails( assert_eq!(evidence.last_successful_state, "upload_verified"); assert_eq!( evidence.error_code.as_deref(), - Some("blossom_retrieved_bytes_mismatch") + Some("blossom_response_hash_mismatch") ); assert_eq!(evidence.error_phase.as_deref(), Some("verification")); assert!(evidence.possible_orphan);