Skip to main content

arminius_lib_events/
lib.rs

1// SPDX-FileCopyrightText: 2025 BWI GmbH
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! Event lifecycle management for Matrix room events.
6//!
7//! This crate provides a type-safe implementation of the complete Matrix room
8//! event lifecycle, from initial draft to verified persistence. The
9//! implementation follows the ADR "ESIG-RDAC" and uses the type system to
10//! enforce correct state transitions.
11//!
12//! # Architecture
13//!
14//! Events progress through four distinct states, each represented by a
15//! different type:
16//!
17//! - **[`RoomEvent<Draft>`]**: Raw user intent (content + type only)
18//! - **[`RoomEvent<Contextualized>`]**: Contextualized in the DAG with auth/prev events
19//! - **[`RoomEvent<Signed>`]**: Signed with event ID and signatures
20//! - **[`RoomEvent<Verified>`]**: Verified signatures and authorization
21//!
22//! State transitions are enforced at compile-time, preventing common errors
23//! like attempting to verify an event which has not been signed yet or storing
24//! an unverified event.
25//!
26//! # Lifecycle Flow
27//!
28//! The typical lifecycle flows are:
29//!
30//! **Local Event Creation (Client → Database)**:
31//! 1. Client Request → [`Draft`] (via `new()`)
32//! 2. [`Draft`] → [`Contextualized`] (via `contextualize()`)
33//! 3. [`Contextualized`] → [`Verified`] (via `sign()` - Signatures are trivially valid, auth rules
34//!    are checked)
35//! 4. [`Verified`] → Database
36//!
37//! **Federation Event Reception (Federation → Database)**:
38//! 1. Federation Input → [`Signed`]
39//! 2. [`Signed`] → [`Verified`] (via `verify()` - explicitly verified)
40//! 3. [`Verified`] → Database
41//!
42//! **Event Distribution (Database → Clients/Federation)**:
43//! 1. Database → [`Verified`]
44//! 2. [`Verified`] → PDU (via `to_pdu()` for federation)
45//! 3. [`Verified`] → Client Event (via `to_client_event()` for client API)
46//!
47//! # Room Version Support
48//!
49//! This crate supports multiple Matrix room versions (V1, V3-V11, V12+) with
50//! version-specific handling of:
51//!
52//! - Event ID format (included in PDU vs. computed from reference hash)
53//! - Event reference format (hashed vs. plain)
54//! - Authorization rules
55//! - Field requirements (e.g., `room_id` in `m.room.create` events)
56//!
57//! Room version rules are configurable via
58//! [`ruma::room_version_rules::RoomVersionRules`].
59//!
60//! ## Verifying an event from federation
61//!
62//! ```no_run
63//! use std::collections::HashMap;
64//!
65//! use arminius_lib_events::{RoomEvent, Signed, Verified, VerifiedFields as _};
66//! use arminius_lib_events::errors::ValidationError;
67//! use ruma::{events::StateEventType, signatures::PublicKeyMap};
68//!
69//! # fn example(
70//! #     signed: RoomEvent<Signed>,
71//! #     previous_state: HashMap<(StateEventType, String), RoomEvent<Verified>>,
72//! #     auth_events: HashMap<(StateEventType, String), RoomEvent<Verified>>,
73//! #     current_state: HashMap<(StateEventType, String), RoomEvent<Verified>>,
74//! #     required_verify_keys: PublicKeyMap,
75//! # ) -> Result<(), ValidationError> {
76//! // Verify signatures and authorization against room state
77//! let verified = signed.verify(
78//!     &previous_state,
79//!     &auth_events,
80//!     &current_state,
81//!     &required_verify_keys,
82//! )?;
83//!
84//! // Check if the event was soft-failed
85//! if verified.soft_failed() {
86//!     // Event passed auth against its own auth_events and previous_state
87//!     // but failed against current room state. Persist it, but don't add
88//!     // to leaf events or relay to clients.
89//! }
90//!
91//! # Ok(())
92//! # }
93//! ```
94//!
95//! # Error Handling
96//!
97//! The crate provides specific error types for different failure modes:
98//!
99//! - [`errors::SigningError`]: Canonicalization, signing, or event ID generation failures
100//! - [`errors::ValidationError`]: Signature verification, authorization, or key fetch failures
101//! - [`errors::EventConversionError`]: PDU/client event serialization failures
102
103// Module declarations
104pub(crate) mod conversions;
105pub mod errors;
106mod event_id;
107mod fields;
108mod pdu;
109pub(crate) mod redaction;
110mod states;
111mod traits;
112mod transitions;
113mod types;
114
115pub use event_id::event_id_from_pdu;
116pub use fields::{ContextualizedFields, DraftFields, SignedFields, VerifiedFields};
117pub use pdu::{ClientEvent, Pdu, PduCommon, V1Pdu, V3Pdu, V12Pdu};
118pub use states::{Contextualized, Draft, Signed, Verified};
119pub use traits::Redactable;
120pub use transitions::RoomEvent;
121pub use types::{
122	ClientContext, EventFormatOptions, EventHash, EventRefs, HashedEventRef, KnownRoomVersionId,
123	PartsVerified, SUPPORTED_ROOM_VERSIONS, VerificationMetadata,
124};