Accept value-only DKIM TXT pastes for Email DNS
Allow v=DKIM1… pastes without a zone name by taking an optional selector hint so Arvan/Cloudflare still get the right _domainkey record.
This commit is contained in:
@@ -11,13 +11,29 @@ export type MailDkimKey = {
|
||||
text: string;
|
||||
};
|
||||
|
||||
/** Bare selector, or `name._domainkey` / `name._domainkey.example.com.` */
|
||||
export function normalizeDkimSelector(raw: string | undefined | null): string | null {
|
||||
if (raw == null) return null;
|
||||
let input = raw.trim().replace(/^"+|"+$/g, '').trim();
|
||||
if (!input) return null;
|
||||
|
||||
const hostMatch = input.match(/^([a-z0-9][a-z0-9-]*)\._domainkey(?:\.|$)/i);
|
||||
if (hostMatch) return hostMatch[1].toLowerCase();
|
||||
|
||||
if (/^[a-z0-9][a-z0-9-]*$/i.test(input)) return input.toLowerCase();
|
||||
return null;
|
||||
}
|
||||
|
||||
export function parseDkimPaste(
|
||||
raw: string,
|
||||
expectedKind: 'ed25519' | 'rsa',
|
||||
selectorHint?: string,
|
||||
): MailDkimKey {
|
||||
const input = raw.trim();
|
||||
if (!input) {
|
||||
throw new Error(`Paste the ${expectedKind} DKIM line from Stalwart.`);
|
||||
throw new Error(
|
||||
`Paste the ${expectedKind} DKIM TXT value (v=DKIM1; …) or the full Stalwart zone line.`,
|
||||
);
|
||||
}
|
||||
|
||||
const quoted = [...input.matchAll(/"([^"]*)"/g)].map((match) => match[1]).join('');
|
||||
@@ -29,7 +45,7 @@ export function parseDkimPaste(
|
||||
text = text.replace(/^"+|"+$/g, '').replace(/\s+/g, ' ').replace(/[.\s]+$/g, '').trim();
|
||||
if (!/^v=DKIM1/i.test(text)) {
|
||||
throw new Error(
|
||||
`Could not find a v=DKIM1 value in the ${expectedKind} field. Paste the Stalwart zone line.`,
|
||||
`Could not find a v=DKIM1 value in the ${expectedKind} field. Paste the TXT value or Stalwart zone line.`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,14 +61,16 @@ export function parseDkimPaste(
|
||||
}
|
||||
|
||||
const nameMatch = compact.match(/([a-z0-9][a-z0-9-]*)\._domainkey/i);
|
||||
if (!nameMatch) {
|
||||
const selector =
|
||||
(nameMatch ? nameMatch[1].toLowerCase() : null) || normalizeDkimSelector(selectorHint);
|
||||
if (!selector) {
|
||||
throw new Error(
|
||||
'Include the selector name (for example v1-ed25519-20260831._domainkey) from the Stalwart zone file.',
|
||||
'Could not find a DKIM selector. Enter the selector (for example v1-ed25519-20260901), or paste a zone line that includes …._domainkey.',
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
selector: nameMatch[1].toLowerCase(),
|
||||
selector,
|
||||
text,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user