Allow Email DNS updates with RSA-only DKIM paste.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
c344ddefdc
commit
8630465d34
@@ -24,6 +24,12 @@ function keyReady(paste: string, selector: string) {
|
|||||||
return pasteIncludesDomainkey(trimmed) || Boolean(selector.trim())
|
return pasteIncludesDomainkey(trimmed) || Boolean(selector.trim())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Empty = skip Ed25519; otherwise same rules as RSA. */
|
||||||
|
function optionalKeyReady(paste: string, selector: string) {
|
||||||
|
if (!paste.trim()) return true
|
||||||
|
return keyReady(paste, selector)
|
||||||
|
}
|
||||||
|
|
||||||
export function EmailDnsModal({ domain, onClose }: EmailDnsModalProps) {
|
export function EmailDnsModal({ domain, onClose }: EmailDnsModalProps) {
|
||||||
const { showToast } = useToast()
|
const { showToast } = useToast()
|
||||||
const [dnsProvider, setDnsProvider] = useState<ParkedDnsProvider>('arvan')
|
const [dnsProvider, setDnsProvider] = useState<ParkedDnsProvider>('arvan')
|
||||||
@@ -48,17 +54,19 @@ export function EmailDnsModal({ domain, onClose }: EmailDnsModalProps) {
|
|||||||
if (!domain) return null
|
if (!domain) return null
|
||||||
const target = domain
|
const target = domain
|
||||||
const canSubmit =
|
const canSubmit =
|
||||||
keyReady(ed25519Key, ed25519Selector) && keyReady(rsaKey, rsaSelector)
|
keyReady(rsaKey, rsaSelector) &&
|
||||||
|
optionalKeyReady(ed25519Key, ed25519Selector)
|
||||||
|
|
||||||
async function submit() {
|
async function submit() {
|
||||||
setSubmitting(true)
|
setSubmitting(true)
|
||||||
setError('')
|
setError('')
|
||||||
try {
|
try {
|
||||||
|
const ed25519Paste = ed25519Key.trim()
|
||||||
const result = await applyMailDns(target.id, {
|
const result = await applyMailDns(target.id, {
|
||||||
dnsProvider,
|
dnsProvider,
|
||||||
ed25519Key,
|
|
||||||
rsaKey,
|
rsaKey,
|
||||||
...(ed25519Selector.trim()
|
...(ed25519Paste ? { ed25519Key: ed25519Paste } : {}),
|
||||||
|
...(ed25519Paste && ed25519Selector.trim()
|
||||||
? { ed25519Selector: ed25519Selector.trim() }
|
? { ed25519Selector: ed25519Selector.trim() }
|
||||||
: {}),
|
: {}),
|
||||||
...(rsaSelector.trim() ? { rsaSelector: rsaSelector.trim() } : {}),
|
...(rsaSelector.trim() ? { rsaSelector: rsaSelector.trim() } : {}),
|
||||||
@@ -85,14 +93,16 @@ export function EmailDnsModal({ domain, onClose }: EmailDnsModalProps) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p className={parkedStyles.hint}>
|
<p className={parkedStyles.hint}>
|
||||||
Paste each DKIM <strong>TXT value</strong> (<code>v=DKIM1; …</code>) from
|
Paste the RSA DKIM <strong>TXT value</strong> (<code>v=DKIM1; …</code>) from
|
||||||
Stalwart, or the full zone line. For value-only pastes, fill the selector
|
Stalwart, or the full zone line. Ed25519 is optional — leave it empty to
|
||||||
(for example <code>v1-ed25519-20260901</code>). We upsert common mail
|
skip. For value-only pastes, fill the selector (for example{' '}
|
||||||
records on {dnsProvider === 'cloudflare' ? 'Cloudflare' : 'Arvan'}{' '}
|
<code>v1-rsa-20260901</code>). We upsert common mail records on{' '}
|
||||||
(DNS-only / not proxied): <strong>mail</strong> A → 185.214.101.41, MX →
|
{dnsProvider === 'cloudflare' ? 'Cloudflare' : 'Arvan'} (DNS-only / not
|
||||||
mail.meshkee.com (priority 10), SPF <code>v=spf1 mx -all</code>, both
|
proxied): <strong>mail</strong> A → 185.214.101.41, MX → mail.meshkee.com
|
||||||
DKIM keys, autoconfig / autodiscover → mail.meshkee.com. Extra MX,{' '}
|
(priority 10), SPF <code>v=spf1 mx -all</code>, DKIM (RSA required,
|
||||||
<strong>dkim._domainkey</strong>, and <strong>_dmarc</strong> are removed.
|
Ed25519 if provided), autoconfig / autodiscover → mail.meshkee.com. Extra
|
||||||
|
MX, <strong>dkim._domainkey</strong>, and <strong>_dmarc</strong> are
|
||||||
|
removed.
|
||||||
</p>
|
</p>
|
||||||
{error ? (
|
{error ? (
|
||||||
<p className={tableStyles.alertError} role="alert">
|
<p className={tableStyles.alertError} role="alert">
|
||||||
@@ -115,7 +125,9 @@ export function EmailDnsModal({ domain, onClose }: EmailDnsModalProps) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={tableStyles.field}>
|
<div className={tableStyles.field}>
|
||||||
<label htmlFor="mail-dkim-ed25519-selector">Ed25519 selector</label>
|
<label htmlFor="mail-dkim-ed25519-selector">
|
||||||
|
Ed25519 selector <span className={tableStyles.helperText}>(optional)</span>
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
id="mail-dkim-ed25519-selector"
|
id="mail-dkim-ed25519-selector"
|
||||||
className={styles.selectorInput}
|
className={styles.selectorInput}
|
||||||
@@ -129,18 +141,20 @@ export function EmailDnsModal({ domain, onClose }: EmailDnsModalProps) {
|
|||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
<p className={tableStyles.helperText}>
|
<p className={tableStyles.helperText}>
|
||||||
Needed when pasting only the TXT value. Optional if the paste includes{' '}
|
Only needed with an Ed25519 paste that has no <code>…._domainkey</code>.
|
||||||
<code>…._domainkey</code>.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={tableStyles.field}>
|
<div className={tableStyles.field}>
|
||||||
<label htmlFor="mail-dkim-ed25519">Ed25519 domain key</label>
|
<label htmlFor="mail-dkim-ed25519">
|
||||||
|
Ed25519 domain key{' '}
|
||||||
|
<span className={tableStyles.helperText}>(optional)</span>
|
||||||
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="mail-dkim-ed25519"
|
id="mail-dkim-ed25519"
|
||||||
className={styles.textarea}
|
className={styles.textarea}
|
||||||
value={ed25519Key}
|
value={ed25519Key}
|
||||||
onChange={(e) => setEd25519Key(e.target.value)}
|
onChange={(e) => setEd25519Key(e.target.value)}
|
||||||
placeholder='v=DKIM1; k=ed25519; h=sha256; p=…'
|
placeholder="Leave empty to skip — or paste v=DKIM1; k=ed25519; …"
|
||||||
disabled={submitting}
|
disabled={submitting}
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
dir="ltr"
|
dir="ltr"
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ export async function applyMailDns(
|
|||||||
domainId: number | string,
|
domainId: number | string,
|
||||||
payload: {
|
payload: {
|
||||||
dnsProvider: 'arvan' | 'cloudflare'
|
dnsProvider: 'arvan' | 'cloudflare'
|
||||||
ed25519Key: string
|
|
||||||
rsaKey: string
|
rsaKey: string
|
||||||
|
ed25519Key?: string
|
||||||
ed25519Selector?: string
|
ed25519Selector?: string
|
||||||
rsaSelector?: string
|
rsaSelector?: string
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user