diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/domains/diagnostics/SRVTabContent.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/domains/diagnostics/SRVTabContent.component.tsx index 9d256a0302ee..1cf2d16271fa 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/domains/diagnostics/SRVTabContent.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/domains/diagnostics/SRVTabContent.component.tsx @@ -1,3 +1,5 @@ +import { useMemo } from 'react'; + import { Trans, useTranslation } from 'react-i18next'; import { ODS_MESSAGE_COLOR, ODS_TEXT_PRESET } from '@ovhcloud/ods-components'; @@ -15,6 +17,7 @@ import { import { GUIDES_LIST, Guide } from '@/guides.constants'; import { AUTO_CONFIGURE_DOMAIN } from '@/tracking.constants'; import { DnsRecordType } from '@/utils/dnsconfig.constants'; +import { parseSRVRecord } from '@/utils/domains'; import StatusBadge from './StatusBadge.component'; @@ -35,6 +38,11 @@ const SRVTabContent = ({ }) => { const { t } = useTranslation('domains/diagnostic'); const { trackClick } = useOvhTracking(); + const { subdomain, priority, weight, port, target } = useMemo(() => { + if (expectedDNSConfig?.autodiscover) { + return parseSRVRecord(expectedDNSConfig?.autodiscover); + } + }, [expectedDNSConfig?.autodiscover]); if (!diagnostic) { return ( @@ -98,10 +106,38 @@ const SRVTabContent = ({ - + + + {t('zimbra_domain_diagnostic_field_subdomain')} + + + + + + + + {t('zimbra_domain_diagnostic_field_priority')} + + + + + + + {t('zimbra_domain_diagnostic_field_weight')} + + + + + + {t('zimbra_domain_diagnostic_field_port')} + + + + + {t('zimbra_domain_diagnostic_field_target')} - + diff --git a/packages/manager/apps/zimbra/src/utils/domains.spec.ts b/packages/manager/apps/zimbra/src/utils/domains.spec.ts new file mode 100644 index 000000000000..9d9e10f93881 --- /dev/null +++ b/packages/manager/apps/zimbra/src/utils/domains.spec.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from 'vitest'; + +import { parseSRVRecord } from './domains'; + +describe('parseSRVRecord', () => { + it('parses a minimal SRV record (no TTL, domain)', () => { + const record = '_autodiscover._tcp IN SRV 0 0 443 zimbra1.mail.ovh.net.'; + const result = parseSRVRecord(record); + + expect(result).toEqual({ + subdomain: '_autodiscover._tcp', + priority: 0, + weight: 0, + port: 443, + target: 'zimbra1.mail.ovh.net', + }); + }); + + it('throws an error if SRV keyword is missing', () => { + const record = '_autodiscover._tcp IN TXT 0 0 443 mail.example.com.'; + expect(() => parseSRVRecord(record)).toThrowError('Invalid SRV record format'); + }); + + it('throws an error if there are not enough fields after SRV', () => { + const record = '_autodiscover._tcp IN SRV 0 0'; + expect(() => parseSRVRecord(record)).toThrowError('Invalid SRV record format'); + }); +}); diff --git a/packages/manager/apps/zimbra/src/utils/domains.ts b/packages/manager/apps/zimbra/src/utils/domains.ts new file mode 100644 index 000000000000..5da64bae7217 --- /dev/null +++ b/packages/manager/apps/zimbra/src/utils/domains.ts @@ -0,0 +1,16 @@ +export const parseSRVRecord = (record: string) => { + const parts = record.trim().split(/\s+/); + + const srvIndex = parts.findIndex((p) => p.toUpperCase() === 'SRV'); + if (srvIndex === -1 || parts.length < srvIndex + 4) { + throw new Error('Invalid SRV record format'); + } + + const subdomain = parts[0]; // e.g. "_autodiscover._tcp" + const priority = parseInt(parts[srvIndex + 1], 10); + const weight = parseInt(parts[srvIndex + 2], 10); + const port = parseInt(parts[srvIndex + 3], 10); + const target = parts[srvIndex + 4]?.replace(/\.$/, ''); // remove trailing dot + + return { subdomain, priority, weight, port, target }; +};