1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! Mailbox preview UI for development.
//!
//! Provides a web UI that displays emails stored in `MemoryStorage`.
//!
//! ## Features
//!
//! - CSP nonce support for Content Security Policy compliance
//! - Full JSON API with private/provider_options/headers
//! - Path-based attachment lazy loading
//! - RFC 5322 compliant recipient rendering
//!
//! # Standalone Server (Recommended)
//!
//! The simplest way to preview emails during development. No framework required.
//!
//! ```rust,ignore
//! use missive::providers::LocalMailer;
//! use missive::preview::serve;
//!
//! let mailer = LocalMailer::new();
//!
//! // Blocking - runs until error
//! serve("127.0.0.1:3025", mailer.storage())?;
//! ```
//!
//! For background execution:
//!
//! ```rust,ignore
//! use missive::preview::PreviewServer;
//!
//! let server = PreviewServer::new("127.0.0.1:3025", mailer.storage())?;
//! let handle = server.spawn();
//!
//! // ... your app runs ...
//!
//! handle.shutdown();
//! ```
//!
//! # Axum Integration
//!
//! Embed the preview UI into an existing Axum application.
//!
//! ```rust,ignore
//! use missive::providers::LocalMailer;
//! use missive::preview::mailbox_router;
//! use axum::Router;
//!
//! let mailer = LocalMailer::new();
//! let storage = mailer.storage();
//!
//! let app = Router::new()
//! .nest("/dev/mailbox", mailbox_router(storage));
//! ```
//!
//! # Actix Integration
//!
//! Embed the preview UI into an existing Actix application.
//!
//! ```rust,ignore
//! use missive::providers::LocalMailer;
//! use missive::preview::{actix_configure, ActixAppState, PreviewConfig};
//! use actix_web::{App, web};
//!
//! let mailer = LocalMailer::new();
//! let storage = mailer.storage();
//! let state = ActixAppState { storage, config: PreviewConfig::default() };
//!
//! let app = App::new()
//! .service(web::scope("/dev/mailbox").configure(|cfg| actix_configure(cfg, state)));
//! ```
use Arc;
use crateMemoryStorage;
// Re-export configuration type
pub use PreviewConfig;
// ============================================================================
// Standalone Server
// ============================================================================
pub use ;
// ============================================================================
// Axum Support
// ============================================================================
pub use Router;
/// Re-exports for testing (Axum).
/// Create an Axum router for the mailbox preview UI.
///
/// Mount this at a development route (e.g., `/dev/mailbox`).
///
/// ## Routes
///
/// | Method | Path | Description |
/// |--------|------|-------------|
/// | GET | `/` | HTML UI listing all emails |
/// | GET | `/json` | JSON API |
/// | GET | `/:id` | View single email as JSON |
/// | GET | `/:id/html` | Raw HTML body (for iframe) |
/// | GET | `/:id/attachments/:idx` | Download attachment |
/// | POST | `/clear` | Delete all emails |
/// Create a mailbox router with CSP nonce configuration.
// ============================================================================
// Actix Support
// ============================================================================
pub use AppState as ActixAppState;
/// Configure Actix routes on a scope.
///
/// ## Example
///
/// ```rust,ignore
/// use missive::preview::{actix_configure, ActixAppState, PreviewConfig};
/// use actix_web::{App, web};
///
/// let state = ActixAppState {
/// storage: mailer.storage(),
/// config: PreviewConfig::default(),
/// };
///
/// App::new()
/// .service(web::scope("/mailbox").configure(|cfg| actix_configure(cfg, state)));
/// ```