fix: improve SMTP configuration and error handling
- Change default use_tls from True to False to match typical STARTTLS setup - Add MailDeliveryError exception for mail delivery failures - Wrap send_mail calls in try-catch blocks to handle errors gracefully - Return 502 status code with error details when mail delivery fails - Add SMTP security mode selector in frontend (STARTTLS/TLS/None) - Add test mail form to admin panel - Handle empty SMTP credentials properly in update_mail_settings - Catch
This commit is contained in:
@@ -61,6 +61,10 @@ export const dictionaries: Record<Language, Record<string, string>> = {
|
||||
smtpPort: 'SMTP Port',
|
||||
smtpUser: 'SMTP User',
|
||||
smtpPassword: 'SMTP Passwort',
|
||||
smtpSecurity: 'SMTP Sicherheit',
|
||||
smtpStarttls: 'STARTTLS (typisch Port 587)',
|
||||
smtpTls: 'TLS/SSL (typisch Port 465)',
|
||||
smtpNone: 'Keine Verschlüsselung',
|
||||
senderAddress: 'Absender-Adresse',
|
||||
senderName: 'Absender-Name',
|
||||
testMail: 'Testmail senden',
|
||||
@@ -128,6 +132,10 @@ export const dictionaries: Record<Language, Record<string, string>> = {
|
||||
smtpPort: 'SMTP port',
|
||||
smtpUser: 'SMTP user',
|
||||
smtpPassword: 'SMTP password',
|
||||
smtpSecurity: 'SMTP security',
|
||||
smtpStarttls: 'STARTTLS (usually port 587)',
|
||||
smtpTls: 'TLS/SSL (usually port 465)',
|
||||
smtpNone: 'No encryption',
|
||||
senderAddress: 'Sender address',
|
||||
senderName: 'Sender name',
|
||||
testMail: 'Send test mail',
|
||||
|
||||
@@ -61,8 +61,15 @@ function AdminUsers() {
|
||||
|
||||
function AdminMail() {
|
||||
const { t } = useI18n();
|
||||
const [form, setForm] = useState({ smtp_host: '', smtp_port: 587, smtp_user: '', smtp_password: '', sender_address: '', sender_name: 'NexaPantry', use_tls: true, use_starttls: true });
|
||||
const [form, setForm] = useState({ smtp_host: '', smtp_port: 587, smtp_user: '', smtp_password: '', sender_address: '', sender_name: 'NexaPantry', use_tls: false, use_starttls: true });
|
||||
const [testTo, setTestTo] = useState('');
|
||||
const set = (key: string, value: string | number | boolean) => setForm((current) => ({ ...current, [key]: value }));
|
||||
const security = form.use_starttls ? 'starttls' : form.use_tls ? 'tls' : 'none';
|
||||
const setSecurity = (value: string) => setForm((current) => ({
|
||||
...current,
|
||||
use_starttls: value === 'starttls',
|
||||
use_tls: value === 'tls'
|
||||
}));
|
||||
useEffect(() => { void api<Record<string, string | number | boolean | null>>('/admin/mail').then((data) => setForm((current) => ({ ...current, ...data, smtp_password: '' }))); }, []);
|
||||
return (
|
||||
<Panel title={t('mail')}>
|
||||
@@ -71,10 +78,19 @@ function AdminMail() {
|
||||
<Field label={t('smtpPort')} type="number" value={form.smtp_port} onChange={(e) => set('smtp_port', Number(e.target.value))} />
|
||||
<Field label={t('smtpUser')} value={form.smtp_user} onChange={(e) => set('smtp_user', e.target.value)} />
|
||||
<Field label={t('smtpPassword')} type="password" value={form.smtp_password} onChange={(e) => set('smtp_password', e.target.value)} />
|
||||
<SelectField label={t('smtpSecurity')} value={security} onChange={(e) => setSecurity(e.target.value)}>
|
||||
<option value="starttls">{t('smtpStarttls')}</option>
|
||||
<option value="tls">{t('smtpTls')}</option>
|
||||
<option value="none">{t('smtpNone')}</option>
|
||||
</SelectField>
|
||||
<Field label={t('senderAddress')} type="email" value={form.sender_address} onChange={(e) => set('sender_address', e.target.value)} />
|
||||
<Field label={t('senderName')} value={form.sender_name} onChange={(e) => set('sender_name', e.target.value)} />
|
||||
<Button>{t('save')}</Button>
|
||||
</form>
|
||||
<form className="mt-4 flex flex-col gap-3 sm:flex-row" onSubmit={async (event) => { event.preventDefault(); await api('/admin/mail/test', { method: 'POST', body: JSON.stringify({ to: testTo }) }); }}>
|
||||
<Field className="sm:min-w-80" label={t('email')} type="email" required value={testTo} onChange={(e) => setTestTo(e.target.value)} />
|
||||
<Button className="self-end" variant="secondary">{t('testMail')}</Button>
|
||||
</form>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user