Nasaq

Mail Settings

SMTP settings with a write-only password and a test send that reports each step, plus mail domains with an SPF, DKIM and DMARC checklist, mailboxes with quota and aliases.

PreviewOpen ↗

Code

import { SmtpSettings } from "@fadymondy/nasaq/web";declare const api: { save(input: unknown): Promise<void>; test(input: unknown): Promise<{ ok: boolean; steps: { id: "connect" | "tls" | "auth" | "send"; ok: boolean; message?: string }[] }> };export function Smtp() {  return (    <SmtpSettings      value={{ host: "smtp.example.com", port: 587, encryption: "starttls", username: "mailer", fromName: "Nasaq", fromAddress: "[email protected]", passwordSet: true }}      onSave={(input) => api.save(input)}      onTest={(input) => api.test(input)}    />  );}

Server Tools · beta

Live examples and controls: Mail Settings in the lab.

Install

npx shadcn@latest add https://docs.nasaqui.com/r/mail-settings.json

Two panels for outgoing and hosted mail. There is no backend: the host sends, checks DNS and stores data.

  • SmtpSettings: host, port, encryption, username, password, From name and address. The password is write-only: pass passwordSet, and leave the field empty to keep it. Changing the encryption moves the port to the usual one unless you typed a custom port. The test card sends with the current form values and shows four steps (connect, secure, sign in, send) as passed, failed or skipped, with the server reply for a failure.
  • MailDomains: pick a domain, then read its SPF, DKIM and DMARC checklist with the expected record in a copy field and what DNS returned. Warnings appear for an open SPF (+all), more than 10 lookups and a DMARC policy of none. Below that are mailboxes with quota meters and aliases; removals ask first.

When to use

  • The mail section of an admin or hosting console.

When not to use

  • Composing or reading mail, or campaign sending.

Import

import { SmtpSettings, MailDomains } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"

Quick start

import { SmtpSettings } from "@fadymondy/nasaq/web";

declare const api: { save(input: unknown): Promise<void>; test(input: unknown): Promise<{ ok: boolean; steps: { id: "connect" | "tls" | "auth" | "send"; ok: boolean; message?: string }[] }> };

export function Smtp() {
  return (
    <SmtpSettings
      value={{ host: "smtp.example.com", port: 587, encryption: "starttls", username: "mailer", fromName: "Nasaq", fromAddress: "[email protected]", passwordSet: true }}
      onSave={(input) => api.save(input)}
      onTest={(input) => api.test(input)}
    />
  );
}

API

SmtpSettings: div props plus value: SmtpConfig, onSave(input), onTest(input) returning { ok, steps: [{ id, ok, message? }] }, defaultTestTo?, loading?, labels?. Steps after the first failing one show as skipped.

MailDomains: div props plus:

PropTypeDescription
domainsMailDomain[]{ id, name, checks, mailboxes, aliases, checkedAt? }. A check is { kind: "spf" | "dkim" | "dmarc", status: "pass" | "fail" | "missing" | "pending", name, type?, expected, found? }.
defaultDomainIdstringDomain shown first.
onRecheck(domainId)callbackRuns the DNS check again.
onAddMailbox(domainId, { local, quotaMb, password }), onRemoveMailbox(domainId, id)callbacksMailboxes.
onAddAlias(domainId, { source, destination }), onRemoveAlias(domainId, id)callbacksAliases. Source * is a catch-all.

Callbacks return Promise<void | { error?: string }>.

Accessibility

Each DNS row is a labelled section with a text status. Meters are named per mailbox. Removals use an alert dialog.

RTL and languages

English and Arabic, overridable with labels. Hosts, addresses, ports and DNS records stay left to right.

On this page