Skip to main content

cloudillo_email/
settings.rs

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