fix: unblock tenant SMTP saves in admin

This commit is contained in:
Martin Porwoll 2026-02-17 08:58:21 +00:00
parent 4386ac5d8d
commit 5f45cc820d
2 changed files with 28 additions and 29 deletions

View file

@ -1,15 +1,12 @@
import type { CollectionConfig, FieldHook } from 'payload' import type { CollectionConfig, FieldHook } from 'payload'
import { invalidateEmailCacheHook } from '../hooks/invalidateEmailCache' import { invalidateEmailCacheHook } from '../hooks/invalidateEmailCache'
import { auditTenantAfterChange, auditTenantAfterDelete } from '../hooks/auditTenantChanges' import { auditTenantAfterChange, auditTenantAfterDelete } from '../hooks/auditTenantChanges'
import { neverReadable } from '../lib/access'
/** /**
* Validiert SMTP Host Format * Validiert SMTP Host Format
*/ */
const validateSmtpHost: FieldHook = ({ value, siblingData }) => { const validateSmtpHost: FieldHook = ({ value }) => {
// Nur validieren wenn useCustomSmtp aktiv ist und ein Wert vorhanden // Nur validieren, wenn ein Wert gesetzt ist
const emailData = siblingData as { useCustomSmtp?: boolean }
if (!emailData?.useCustomSmtp) return value
if (!value) return value if (!value) return value
// Basis-Validierung: Keine Protokoll-Präfixe erlaubt // Basis-Validierung: Keine Protokoll-Präfixe erlaubt
@ -23,9 +20,8 @@ const validateSmtpHost: FieldHook = ({ value, siblingData }) => {
/** /**
* Validiert SMTP Port * Validiert SMTP Port
*/ */
const validateSmtpPort: FieldHook = ({ value, siblingData }) => { const validateSmtpPort: FieldHook = ({ value }) => {
const emailData = siblingData as { useCustomSmtp?: boolean } if (!value) return value
if (!emailData?.useCustomSmtp) return value
const port = Number(value) const port = Number(value)
if (port && (port < 1 || port > 65535)) { if (port && (port < 1 || port > 65535)) {
@ -138,6 +134,22 @@ export const Tenants: CollectionConfig = {
description: description:
'Hinweis: Stellen Sie sicher, dass SPF- und DKIM-Einträge für Ihre Domain konfiguriert sind, um eine optimale E-Mail-Zustellung zu gewährleisten.', 'Hinweis: Stellen Sie sicher, dass SPF- und DKIM-Einträge für Ihre Domain konfiguriert sind, um eine optimale E-Mail-Zustellung zu gewährleisten.',
}, },
validate: (value, { siblingData }) => {
const emailData = siblingData as { useCustomSmtp?: boolean }
if (!emailData?.useCustomSmtp) return true
const smtpData = (value || {}) as { host?: string; user?: string }
if (!smtpData.host?.trim()) {
return 'SMTP Host ist erforderlich'
}
if (!smtpData.user?.trim()) {
return 'SMTP Benutzername ist erforderlich'
}
return true
},
fields: [ fields: [
{ {
type: 'row', type: 'row',
@ -146,7 +158,6 @@ export const Tenants: CollectionConfig = {
name: 'host', name: 'host',
type: 'text', type: 'text',
label: 'SMTP Host', label: 'SMTP Host',
required: true,
admin: { admin: {
placeholder: 'smtp.example.com', placeholder: 'smtp.example.com',
width: '50%', width: '50%',
@ -155,13 +166,6 @@ export const Tenants: CollectionConfig = {
hooks: { hooks: {
beforeValidate: [validateSmtpHost], beforeValidate: [validateSmtpHost],
}, },
validate: (value: string | undefined | null, { siblingData }: { siblingData: Record<string, unknown> }) => {
const emailData = siblingData as { useCustomSmtp?: boolean }
if (emailData?.useCustomSmtp && !value) {
return 'SMTP Host ist erforderlich'
}
return true
},
}, },
{ {
name: 'port', name: 'port',
@ -197,19 +201,10 @@ export const Tenants: CollectionConfig = {
name: 'user', name: 'user',
type: 'text', type: 'text',
label: 'SMTP Benutzername', label: 'SMTP Benutzername',
required: true,
admin: { admin: {
width: '50%', width: '50%',
description: 'Meist die E-Mail-Adresse', description: 'Meist die E-Mail-Adresse',
}, },
validate: (value: string | undefined | null, { siblingData }: { siblingData: Record<string, unknown> }) => {
const smtpData = siblingData as { host?: string }
// Nur validieren wenn host gesetzt ist (d.h. SMTP aktiv)
if (smtpData?.host && !value) {
return 'SMTP Benutzername ist erforderlich'
}
return true
},
}, },
{ {
name: 'pass', name: 'pass',

View file

@ -46,7 +46,7 @@ export const auditTenantAfterChange: CollectionAfterChangeHook = async ({
if (!user) return doc if (!user) return doc
await logTenantChange( logTenantChange(
req.payload, req.payload,
doc.id, doc.id,
operation, operation,
@ -55,7 +55,9 @@ export const auditTenantAfterChange: CollectionAfterChangeHook = async ({
sanitizeTenantDoc(previousDoc), sanitizeTenantDoc(previousDoc),
sanitizeTenantDoc(doc), sanitizeTenantDoc(doc),
req, req,
) ).catch((error) => {
console.error('[AuditHook] Error logging tenant change:', error)
})
return doc return doc
} }
@ -70,7 +72,7 @@ export const auditTenantAfterDelete: CollectionAfterDeleteHook = async ({ doc, r
if (!user) return doc if (!user) return doc
// WICHTIG: Auch bei Löschung das Dokument sanitizen! // WICHTIG: Auch bei Löschung das Dokument sanitizen!
await logTenantChange( logTenantChange(
req.payload, req.payload,
doc.id, doc.id,
'delete', 'delete',
@ -79,7 +81,9 @@ export const auditTenantAfterDelete: CollectionAfterDeleteHook = async ({ doc, r
sanitizeTenantDoc(doc), sanitizeTenantDoc(doc),
undefined, undefined,
req, req,
) ).catch((error) => {
console.error('[AuditHook] Error logging tenant delete:', error)
})
return doc return doc
} }