Add Domains to Administration

A role that can read domains now finds a Domains section beside Accounts:
list and search with each domain's account count and whether its DNS, DKIM
and certificate are managed automatically; add a domain; edit its
description, other names, catch-all address and plus addressing; copy its
DNS records one at a time or as a zone file; see its DKIM keys and their
stage; and remove it once no accounts use it.

The records come from the zone file Stalwart computes per domain. A long
DKIM record, which the BIND serialiser splits into quoted chunks, is joined
back into the single value a DNS provider's form wants.

Removing a domain takes its DKIM keys first, in the same request, because the
server will not remove a domain its keys still name. Removal is not offered
while accounts use the domain, or when the role cannot remove the keys.

The Administration nav is now built from the sections the role can read, and
the menu appears when there is at least one. The mock gains domains, DKIM
keys and zone files.

61 new strings, translated in all nine catalogues; strings falling back to
English stay at 16.
This commit is contained in:
2026-09-13 15:39:16 -07:00
parent d279fe8f90
commit 1dafb4bc79
23 changed files with 1783 additions and 30 deletions
+64
View File
@@ -49,6 +49,63 @@ import type { Catalog } from "@/lib/i18n";
*/
export const catalog: Catalog = {
strings: {
// ── Administration: domains ────────────────────────────────────
"Domains": "Домены",
"By hand": "Вручную",
"Signing": "Подписывает",
"Published, not signing yet": "Опубликован, ещё не подписывает",
"Retiring": "Выводится из работы",
"Retired": "Выведен из работы",
"This domain no longer exists. Someone may have removed it.": "Этого домена больше нет. Возможно, его кто-то удалил.",
"That doesn't look like a domain name, such as example.com.": "Это не похоже на имя домена вроде example.com.",
"Added {name}. Its DNS records are ready to copy.": "Домен {name} добавлен. Его DNS-записи готовы к копированию.",
"Saved {name}": "Домен {name} сохранён",
"Add domain": "Добавить домен",
"Added {date}": "Добавлен {date}",
"This domain is disabled on the server.": "Этот домен отключён на сервере.",
"Your role lets you view domains but not change them.": "Ваша роль позволяет просматривать домены, но не изменять их.",
"New domains sign their mail with DKIM keys the server creates and rotates. Its DNS records appear here once it's added.": "Новые домены подписывают почту ключами DKIM, которые сервер создаёт и меняет сам. DNS-записи появятся здесь после добавления домена.",
"Other names": "Другие имена",
"Delivery": "Доставка",
"Catch-all address": "Адрес для всей почты",
"Mail to an address nobody has on this domain is delivered here. Leave it empty to refuse that mail.": "Сюда доставляются письма на адреса этого домена, которых ни у кого нет. Оставьте пустым, чтобы отклонять такие письма.",
"Plus addressing": "Адреса с «+»",
"Set by a custom rule on the server.": "Задано особым правилом на сервере.",
"Mail to name+anything@ is delivered to name@.": "Письма на имя+что-угодно@ доставляются на имя@.",
"DNS records": "DNS-записи",
"Published automatically through {provider}.": "Публикуются автоматически через {provider}.",
"Published automatically by the server.": "Публикуются сервером автоматически.",
"Add these where this domain's DNS is hosted. Mail isn't delivered or trusted until they're in place.": "Добавьте их там, где размещён DNS этого домена. Пока их нет, почта не доставляется и не считается надёжной.",
"Copy {type} record for {name}": "Скопировать запись {type} для {name}",
"Copy value": "Скопировать значение",
"Copied the zone file": "Файл зоны скопирован",
"Copy all as a zone file": "Скопировать всё как файл зоны",
"The server returned no records for this domain.": "Сервер не вернул записей для этого домена.",
"DKIM keys": "Ключи DKIM",
"The server creates and rotates these keys itself.": "Сервер создаёт и меняет эти ключи сам.",
"These keys are managed by hand on the server.": "Эти ключи управляются на сервере вручную.",
"No DKIM keys, so mail from this domain isn't signed and is more likely to be marked as spam.": "Ключей DKIM нет, поэтому почта с этого домена не подписывается и чаще попадает в спам.",
"Managed by the server": "Управляется сервером",
"Certificate": "Сертификат",
"Another name for this domain": "Другое имя для этого домена",
"Mail to the same address at any of these names reaches the same account. Changes apply when you save.": "Письма на тот же адрес под любым из этих имён попадают в ту же учётную запись. Изменения вступят в силу после сохранения.",
"Its DKIM keys have to be removed first, and your role can't remove them.": "Сначала нужно удалить его ключи DKIM, а ваша роль этого не позволяет.",
"The server stops accepting mail for this domain.": "Сервер перестанет принимать почту для этого домена.",
"Remove domain…": "Удалить домен…",
"Remove {name}?": "Удалить {name}?",
"Removed {name}": "Домен {name} удалён",
"The server kept the domain: it is still used by {things}.": "Сервер сохранил домен: его ещё используют {things}.",
"Remove domain": "Удалить домен",
"The server stops accepting mail for this domain. This can't be undone.": "Сервер перестанет принимать почту для этого домена. Отменить это нельзя.",
"Where your addresses live, and the DNS records that let mail arrive and be trusted.": "Где находятся ваши адреса и DNS-записи, благодаря которым почта доходит и вызывает доверие.",
"Search domains": "Поиск доменов",
"No domains match": "Нет подходящих доменов",
"No domains yet": "Доменов пока нет",
"DKIM": "DKIM",
"Tenant": "Арендатор",
"Disabled": "Отключён",
"also {names}": "также {names}",
"The server did not say whether the domain was created.": "Сервер не сообщил, создан ли домен.",
// ── Administration: accounts ───────────────────────────────────
"Change your own password in {settings}.": "Свой пароль можно изменить в разделе {settings}.",
"Administration": "Администрирование",
@@ -1419,6 +1476,13 @@ export const catalog: Catalog = {
"no address": "нет адреса",
},
plurals: {
// ── Administration: domains ────────────────────────────────────
"{n} accounts use this domain. Move or delete them first.": { one: "Этот домен использует {n} учётная запись. Сначала перенесите или удалите её.", few: "Этот домен используют {n} учётные записи. Сначала перенесите или удалите их.", many: "Этот домен используют {n} учётных записей. Сначала перенесите или удалите их.", other: "Этот домен используют {n} учётной записи. Сначала перенесите или удалите их." },
"The server stops accepting mail for this domain, and its {n} DKIM keys are deleted. This can't be undone.": { one: "Сервер перестанет принимать почту для этого домена, и его {n} ключ DKIM будет удалён. Отменить это нельзя.", few: "Сервер перестанет принимать почту для этого домена, и его {n} ключа DKIM будут удалены. Отменить это нельзя.", many: "Сервер перестанет принимать почту для этого домена, и его {n} ключей DKIM будут удалены. Отменить это нельзя.", other: "Сервер перестанет принимать почту для этого домена, и его {n} ключа DKIM будут удалены. Отменить это нельзя." },
"{n} domains": { one: "{n} домен", few: "{n} домена", many: "{n} доменов", other: "{n} домена" },
"{n} mailing lists": { one: "{n} список рассылки", few: "{n} списка рассылки", many: "{n} списков рассылки", other: "{n} списка рассылки" },
"{n} DKIM keys": { one: "{n} ключ DKIM", few: "{n} ключа DKIM", many: "{n} ключей DKIM", other: "{n} ключа DKIM" },
"{n} other items": { one: "{n} другой объект", few: "{n} других объекта", many: "{n} других объектов", other: "{n} другого объекта" },
// ── Administration ────────────────────────────────────────────────
"{n} accounts": { one: "{n} учётная запись", few: "{n} учётные записи", many: "{n} учётных записей", other: "{n} учётной записи" },
// ── Third pass ─────────────────────────────────────────────────────