Add Administration, starting with accounts

An account whose Stalwart role manages accounts now finds Administration in
the account menu. It lists, searches, creates and edits accounts -- display
name, other addresses, role, storage limit -- sets a new password, and
deletes, each offered only when the role holds the matching permission.

The server keeps the permissions list from GET /api/account, which it
already called for the edition and threw the rest away. Everything else is
JMAP x:Account, x:Domain and x:Role calls through the existing /api/jmap
proxy, so nothing new is stored and Stalwart decides every call.

Stalwart checks a grant against the caller's permissions but not a password
change or a delete, so an account that outranks the viewer is shown
read-only. Your own password is changed in Settings, which re-seals the
session; changing it here would strand it.

The mock server gains a directory behind the same permission names, with
MOCK_ROLE choosing admin, tenant-admin, helpdesk or user.

68 new strings, translated in all nine catalogues; strings falling back to
English stay at 16.
This commit is contained in:
2026-09-13 15:11:55 -07:00
parent b0564679e6
commit 82e217155b
34 changed files with 2684 additions and 22 deletions
+71
View File
@@ -43,6 +43,75 @@ import type { Catalog } from "@/lib/i18n";
*/
export const catalog: Catalog = {
strings: {
// ── Administration: accounts ───────────────────────────────────
"Change your own password in {settings}.": "Власний пароль можна змінити в розділі {settings}.",
"Administration": "Адміністрування",
"Directory": "Каталог",
"User": "Користувач",
"Administrator": "Адміністратор",
"Custom role": "Власна роль",
"New account": "Новий обліковий запис",
"The people who sign in to mail on the domains you manage.": "Люди, які входять у пошту на доменах, якими ви керуєте.",
"Search by name or address": "Пошук за іменем або адресою",
"Search accounts": "Пошук облікових записів",
"No accounts match": "Немає відповідних облікових записів",
"No accounts yet": "Облікових записів ще немає",
"Nothing on your domains matches “{query}”.": "На ваших доменах немає збігів із «{query}».",
"Open {address}": "Відкрити {address}",
"{from}{to} of {total}": "{from}{to} із {total}",
"Previous page": "Попередня сторінка",
"Next page": "Наступна сторінка",
"Storage": "Сховище",
"Groups": "Групи",
"{used} · no limit": "{used} · без обмеження",
"Profile": "Профіль",
"Domain": "Домен",
"No domains are available to create an account on.": "Немає доменів, на яких можна створити обліковий запис.",
"Sign-in": "Вхід",
"Other addresses": "Інші адреси",
"Not in any group": "Не входить до жодної групи",
"You can't change your own role.": "Ви не можете змінити власну роль.",
"Only roles whose permissions you hold yourself are offered. On an account inside a tenant, Administrator means administrator of that tenant.": "Пропонуються лише ролі, усі дозволи яких маєте ви самі. Для облікового запису всередині орендаря «Адміністратор» означає адміністратора цього орендаря.",
"Limit in GB": "Обмеження в ГБ",
"No limit": "Без обмеження",
"This account has permissions yours doesn't, so you can view it but not change it.": "Цей обліковий запис має дозволи, яких немає у вашого, тому його можна переглядати, але не змінювати.",
"Your role lets you view accounts but not change them.": "Ваша роль дозволяє переглядати облікові записи, але не змінювати їх.",
"This account has permissions yours doesn't.": "Цей обліковий запис має дозволи, яких немає у вашого.",
"You can't delete the account you're signed in with.": "Не можна видалити обліковий запис, під яким ви ввійшли.",
"Create account": "Створити обліковий запис",
"An account needs an address.": "Обліковому запису потрібна адреса.",
"Created {address}": "Обліковий запис {address} створено",
"Saved {address}": "Обліковий запис {address} збережено",
"Generate a password": "Згенерувати пароль",
"Pass it on some way other than email to this address.": "Передайте його будь-яким способом, окрім листа на цю адресу.",
"This account has no password. It may sign in through a directory or single sign-on.": "Цей обліковий запис не має пароля. Можливо, вхід виконується через каталог або єдиний вхід.",
"Set a new password…": "Задати новий пароль…",
"{name} will be signed out of every app and device using the old password.": "Для {name} буде виконано вихід у всіх застосунках і на всіх пристроях, де використовується старий пароль.",
"New password set for {address}": "Новий пароль для {address} задано",
"Set password": "Задати пароль",
"Remove {address}": "Видалити {address}",
"New address": "Нова адреса",
"another name": "інше ім'я",
"Mail to these addresses is delivered to this account. Changes apply when you save.": "Листи на ці адреси доставляються в цей обліковий запис. Зміни наберуть чинності після збереження.",
"Deletes the mailbox and everything in it.": "Видаляє поштову скриньку й усе, що в ній.",
"Delete account…": "Видалити обліковий запис…",
"Delete {address}?": "Видалити {address}?",
"This deletes the mail, calendars, contacts and files in this account. The server removes them in the background, and it can't be undone.": "Буде видалено пошту, календарі, контакти й файли цього облікового запису. Сервер видалить їх у фоновому режимі, скасувати це неможливо.",
"Type {address} to confirm": "Введіть {address} для підтвердження",
"Delete account": "Видалити обліковий запис",
"Deleted {address}": "Обліковий запис {address} видалено",
"The server did not say whether the account was created.": "Сервер не повідомив, чи створено обліковий запис.",
"The mail server refused this. Your role may not allow it.": "Поштовий сервер відхилив цю дію. Можливо, ваша роль її не дозволяє.",
"The mail server refused this: {reason}": "Поштовий сервер відхилив цю дію: {reason}",
"That address is already in use on this server, as an account, a list or an alias.": "Ця адреса вже використовується на сервері — обліковим записом, списком або псевдонімом.",
"One of the chosen domain, role or group can't be used for this account.": "Вибраний домен, роль або групу не можна використати для цього облікового запису.",
"Your organisation has reached the number of accounts it is allowed.": "Ваша організація досягла дозволеної кількості облікових записів.",
"Something still depends on this, so the server kept it.": "Від цього ще щось залежить, тому сервер це зберіг.",
"This account no longer exists. Someone may have deleted it.": "Цього облікового запису більше немає. Можливо, його хтось видалив.",
"The password was not accepted: {reason}": "Пароль не прийнято: {reason}",
"The password was not accepted.": "Пароль не прийнято.",
"The mail server rejected a value: {reason}": "Поштовий сервер відхилив значення: {reason}",
"The mail server rejected a value.": "Поштовий сервер відхилив значення.",
"Go to folder…": "Перейти до теки…",
"Set for everyone here. You cannot change this.": "Задано для всіх тут. Змінити не можна.",
"Export iCAL file": "Експортувати файл iCAL",
@@ -1344,6 +1413,8 @@ export const catalog: Catalog = {
"no address": "немає адреси",
},
plurals: {
// ── Administration ────────────────────────────────────────────────
"{n} accounts": { one: "{n} обліковий запис", few: "{n} облікові записи", many: "{n} облікових записів", other: "{n} облікового запису" },
// ── Third pass ─────────────────────────────────────────────────────
"Delete {n} items": { one: "Видалити {n} об’єкт", few: "Видалити {n} об’єкти", many: "Видалити {n} об’єктів", other: "Видалити {n} об’єкта" },
"Delete {n} items?": { one: "Видалити {n} об’єкт?", few: "Видалити {n} об’єкти?", many: "Видалити {n} об’єктів?", other: "Видалити {n} об’єкта?" },