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
@@ -50,6 +50,75 @@ import type { Catalog } from "@/lib/i18n";
*/
export const catalog: Catalog = {
strings: {
// ── Administration: accounts ───────────────────────────────────
"Change your own password in {settings}.": "Altere sua própria senha em {settings}.",
"Administration": "Administração",
"Directory": "Diretório",
"User": "Usuário",
"Administrator": "Administrador",
"Custom role": "Função personalizada",
"New account": "Nova conta",
"The people who sign in to mail on the domains you manage.": "As pessoas que entram no e-mail nos domínios que você administra.",
"Search by name or address": "Pesquisar por nome ou endereço",
"Search accounts": "Pesquisar contas",
"No accounts match": "Nenhuma conta corresponde",
"No accounts yet": "Ainda não há contas",
"Nothing on your domains matches “{query}”.": "Nada nos seus domínios corresponde a “{query}”.",
"Open {address}": "Abrir {address}",
"{from}{to} of {total}": "{from}{to} de {total}",
"Previous page": "Página anterior",
"Next page": "Próxima página",
"Storage": "Armazenamento",
"Groups": "Grupos",
"{used} · no limit": "{used} · sem limite",
"Profile": "Perfil",
"Domain": "Domínio",
"No domains are available to create an account on.": "Não há nenhum domínio disponível para criar uma conta.",
"Sign-in": "Acesso",
"Other addresses": "Outros endereços",
"Not in any group": "Não está em nenhum grupo",
"You can't change your own role.": "Você não pode alterar sua própria função.",
"Only roles whose permissions you hold yourself are offered. On an account inside a tenant, Administrator means administrator of that tenant.": "Só são oferecidas as funções cujas permissões você mesmo tem. Em uma conta dentro de um locatário, Administrador significa administrador desse locatário.",
"Limit in GB": "Limite em GB",
"No limit": "Sem limite",
"This account has permissions yours doesn't, so you can view it but not change it.": "Esta conta tem permissões que a sua não tem, então você pode vê-la, mas não alterá-la.",
"Your role lets you view accounts but not change them.": "Sua função permite ver as contas, mas não alterá-las.",
"This account has permissions yours doesn't.": "Esta conta tem permissões que a sua não tem.",
"You can't delete the account you're signed in with.": "Você não pode excluir a conta com a qual está conectado.",
"Create account": "Criar conta",
"An account needs an address.": "Uma conta precisa de um endereço.",
"Created {address}": "{address} criada",
"Saved {address}": "{address} salva",
"Generate a password": "Gerar uma senha",
"Pass it on some way other than email to this address.": "Repasse-a por outro meio que não seja um e-mail para este endereço.",
"This account has no password. It may sign in through a directory or single sign-on.": "Esta conta não tem senha. Ela pode entrar por meio de um diretório ou de login único.",
"Set a new password…": "Definir nova senha…",
"{name} will be signed out of every app and device using the old password.": "{name} será desconectado de todos os apps e dispositivos que usam a senha antiga.",
"New password set for {address}": "Nova senha definida para {address}",
"Set password": "Definir senha",
"Remove {address}": "Remover {address}",
"New address": "Novo endereço",
"another name": "outro nome",
"Mail to these addresses is delivered to this account. Changes apply when you save.": "Os e-mails enviados a estes endereços são entregues nesta conta. As alterações valem ao salvar.",
"Deletes the mailbox and everything in it.": "Exclui a caixa de correio e tudo o que há nela.",
"Delete account…": "Excluir conta…",
"Delete {address}?": "Excluir {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.": "Isto exclui os e-mails, agendas, contatos e arquivos desta conta. O servidor os remove em segundo plano, e não é possível desfazer.",
"Type {address} to confirm": "Digite {address} para confirmar",
"Delete account": "Excluir conta",
"Deleted {address}": "{address} excluída",
"The server did not say whether the account was created.": "O servidor não informou se a conta foi criada.",
"The mail server refused this. Your role may not allow it.": "O servidor de e-mail recusou. Talvez sua função não permita.",
"The mail server refused this: {reason}": "O servidor de e-mail recusou: {reason}",
"That address is already in use on this server, as an account, a list or an alias.": "Esse endereço já está em uso neste servidor, como conta, lista ou alias.",
"One of the chosen domain, role or group can't be used for this account.": "O domínio, a função ou o grupo escolhido não pode ser usado nesta conta.",
"Your organisation has reached the number of accounts it is allowed.": "Sua organização atingiu o número de contas permitido.",
"Something still depends on this, so the server kept it.": "Algo ainda depende disto, então o servidor o manteve.",
"This account no longer exists. Someone may have deleted it.": "Esta conta não existe mais. Talvez alguém a tenha excluído.",
"The password was not accepted: {reason}": "A senha não foi aceita: {reason}",
"The password was not accepted.": "A senha não foi aceita.",
"The mail server rejected a value: {reason}": "O servidor de e-mail recusou um valor: {reason}",
"The mail server rejected a value.": "O servidor de e-mail recusou um valor.",
"Go to folder…": "Ir para a pasta…",
"Set for everyone here. You cannot change this.": "Definido para todos aqui. Você não pode alterar isto.",
"Export iCAL file": "Exportar arquivo iCAL",
@@ -1351,6 +1420,8 @@ export const catalog: Catalog = {
"no address": "nenhum endereço",
},
plurals: {
// ── Administration ────────────────────────────────────────────────
"{n} accounts": { one: "{n} conta", other: "{n} contas" },
// ── Third pass ─────────────────────────────────────────────────────
"Delete {n} items": { one: "Excluir {n} item", other: "Excluir {n} itens" },
"Delete {n} items?": { one: "Excluir {n} item?", other: "Excluir {n} itens?" },