Skip to main content

cloudillo_email/
settings.rs

1//! Email settings registration
2//!
3//! Registers global SMTP and email configuration settings.
4
5use crate::prelude::*;
6use cloudillo_core::settings::{
7	PermissionLevel, SettingDefinition, SettingScope, SettingValue, SettingsRegistry,
8};
9
10/// Register all email settings
11pub fn register_settings(registry: &mut SettingsRegistry) -> ClResult<()> {
12	// Email enabled flag
13	registry.register(
14		SettingDefinition::builder("email.enabled")
15			.description("Enable email sending (disable for testing)")
16			.default(SettingValue::Bool(false))
17			.scope(SettingScope::Global)
18			.permission(PermissionLevel::Admin)
19			.build()?,
20	)?;
21
22	// SMTP host
23	registry.register(
24		SettingDefinition::builder("email.smtp.host")
25			.description("SMTP server hostname (e.g., smtp.gmail.com). If not set, emails will be silently skipped.")
26			.scope(SettingScope::Global)
27			.permission(PermissionLevel::Admin)
28			.optional(true)
29			.build()?, // No default - optional, silently skip if not configured
30	)?;
31
32	// SMTP port
33	registry.register(
34		SettingDefinition::builder("email.smtp.port")
35			.description("SMTP server port (typically 25, 465, or 587)")
36			.default(SettingValue::Int(587))
37			.scope(SettingScope::Global)
38			.permission(PermissionLevel::Admin)
39			.validator(|v| {
40				if let SettingValue::Int(port) = v {
41					if *port > 0 && *port < 65536 {
42						return Ok(());
43					}
44				}
45				Err(Error::ValidationError("Port must be between 1 and 65535".into()))
46			})
47			.build()?,
48	)?;
49
50	// SMTP username
51	registry.register(
52		SettingDefinition::builder("email.smtp.username")
53			.description("SMTP authentication username")
54			.scope(SettingScope::Global)
55			.permission(PermissionLevel::Admin)
56			.optional(true)
57			.build()?, // No default - optional
58	)?;
59
60	// SMTP password
61	registry.register(
62		SettingDefinition::builder("email.smtp.password")
63			.description("SMTP authentication password")
64			.scope(SettingScope::Global)
65			.permission(PermissionLevel::Admin)
66			.optional(true)
67			.build()?, // No default - optional
68	)?;
69
70	// From address
71	registry.register(
72		SettingDefinition::builder("email.from.address")
73			.description("Email sender address (e.g., noreply@example.com)")
74			.scope(SettingScope::Global)
75			.permission(PermissionLevel::Admin)
76			.optional(true)
77			.validator(|v| {
78				if let SettingValue::String(email) = v {
79					// Basic email validation
80					if email.contains('@') && email.contains('.') {
81						return Ok(());
82					}
83				}
84				Err(Error::ValidationError("Invalid email address format".into()))
85			})
86			.build()?, // No default - required
87	)?;
88
89	// From name
90	registry.register(
91		SettingDefinition::builder("email.from.name")
92			.description("Email sender display name")
93			.default(SettingValue::String("Cloudillo".into()))
94			.scope(SettingScope::Global)
95			.permission(PermissionLevel::Admin)
96			.build()?,
97	)?;
98
99	// TLS mode
100	registry.register(
101		SettingDefinition::builder("email.smtp.tls_mode")
102			.description(
103				"TLS mode: none, starttls, or tls (StartTLS on port 587, TLS/SSL on port 465)",
104			)
105			.default(SettingValue::String("starttls".into()))
106			.scope(SettingScope::Global)
107			.permission(PermissionLevel::Admin)
108			.validator(|v| {
109				if let SettingValue::String(mode) = v {
110					if ["none", "starttls", "tls"].contains(&mode.as_str()) {
111						return Ok(());
112					}
113				}
114				Err(Error::ValidationError("TLS mode must be: none, starttls, or tls".into()))
115			})
116			.build()?,
117	)?;
118
119	// Connection timeout
120	registry.register(
121		SettingDefinition::builder("email.smtp.timeout_seconds")
122			.description("SMTP connection timeout in seconds")
123			.default(SettingValue::Int(30))
124			.scope(SettingScope::Global)
125			.permission(PermissionLevel::Admin)
126			.build()?,
127	)?;
128
129	// Template directory (read-only, can only be set in config file)
130	registry.register(
131		SettingDefinition::builder("email.template_dir")
132			.description("Path to email templates directory")
133			.default(SettingValue::String("./templates/email".into()))
134			.scope(SettingScope::System)
135			.permission(PermissionLevel::System)
136			.build()?,
137	)?;
138
139	// Retry attempts
140	registry.register(
141		SettingDefinition::builder("email.retry_attempts")
142			.description("Number of retry attempts for failed emails")
143			.default(SettingValue::Int(3))
144			.scope(SettingScope::Global)
145			.permission(PermissionLevel::Admin)
146			.build()?,
147	)?;
148
149	Ok(())
150}
151
152// vim: ts=4