refactor(frontend): unify mailbox terminology

Closes #1129
This commit is contained in:
Dream Hunter
2026-08-31 22:36:08 +08:00
committed by GitHub
parent 70206c61ef
commit 5fd181d9c0
24 changed files with 319 additions and 272 deletions
+1
View File
@@ -23,6 +23,7 @@
### Improvements
- fix: |Frontend| 统一邮箱、邮箱地址、用户账号与管理后台的核心界面术语,并补齐附加语言缺失的邮件状态与远程图片文案(issue #1129
- feat: |发信页面| 优化用户和 Admin 发信页面的信息层级与响应式布局,增加正文格式工具栏、草稿状态、底部发送操作区及隔离的 HTML 预览
### Testing
+1
View File
@@ -23,6 +23,7 @@
### Improvements
- fix: |Frontend| Unify core mailbox, email-address, user-account, and Admin Console terminology, and fill missing additional-locale strings for mail status and remote images (issue #1129)
- feat: |Send Mail| Improve the information hierarchy and responsive layout of the user and Admin composers, with a content-format toolbar, draft status, bottom send-action area, and isolated HTML preview
### Testing
+2 -2
View File
@@ -6,7 +6,7 @@ test('create an address with a custom subdomain from the UI', async ({ page, req
try {
await page.goto(`${FRONTEND_URL}/en/`);
await page.getByRole('button', { name: 'Create New Email' }).click();
await page.getByRole('button', { name: 'Create Email Address' }).click();
const name = `subui${Date.now()}`;
const createForm = page.locator('.n-tab-pane:visible form');
@@ -36,7 +36,7 @@ test('create an address with a custom subdomain from the UI', async ({ page, req
await createForm.getByText('Use Custom Subdomain', { exact: true }).click();
await createForm.locator('.n-input-group:visible .n-input input').last().fill('team');
await createForm.getByRole('button', { name: 'Create New Email' }).click();
await createForm.getByRole('button', { name: 'Create Email Address' }).click();
const domain = `team.${TEST_DOMAIN}`;
const address = `tmp${name}@${domain}`;
@@ -100,7 +100,7 @@ test.describe('User address pagination browser flow', () => {
return url.pathname === '/user_api/bind_address'
&& url.searchParams.get('limit') === '100';
});
await page.getByText('Mail Box', { exact: true }).click();
await page.getByText('Inbox', { exact: true }).click();
const initialMailboxResponse = await initialMailboxAddressesResponse;
expect(initialMailboxResponse.ok()).toBe(true);
const mailboxAddressSelect = page.locator('.n-input-group .n-select').first();
+2 -2
View File
@@ -153,7 +153,7 @@ const refreshAddressOptions = async () => {
if (userJwt.value) {
const userChildren = await buildUserOptions();
if (userChildren.length > 0) {
groups.push({ type: 'group', label: t('userAddresses'), children: userChildren });
groups.push({ type: 'group', label: t('linkedMailboxes'), children: userChildren });
}
const userAddressSet = new Set(userChildren.map((item) => item.address));
const localChildren = buildLocalOptions(userAddressSet);
@@ -215,7 +215,7 @@ watch([userJwt, isTelegram, () => settings.value.address], async () => {
<template>
<n-flex class="address-row" align="center" justify="center" :wrap="true">
<n-select v-model:value="addressValue" :options="addressOptions" :size="size" filterable
:loading="addressLoading" :placeholder="t('address')" @update:value="onAddressChange"
:loading="addressLoading" :placeholder="t('selectMailbox')" @update:value="onAddressChange"
class="address-select" />
<slot name="actions" />
<n-button v-if="showCopy" class="address-copy" @click="copy" :size="size" tertiary type="primary">
+30 -21
View File
@@ -33,10 +33,12 @@ export const deMessages = {
"views.Index.about": "Über",
"views.Admin.about": "Über",
"views.Header.accessHeader": "Zugangspasswort",
"views.Admin.account": "Konto",
"views.Index.accountSettings": "E-Mail-Einstellungen",
"views.Admin.account_settings": "Kontoeinstellungen",
"views.index.SimpleIndex.accountSettings": "E-Mail-Einstellungen",
"views.Header.admin": "Admin-Konsole",
"views.Admin.mailbox_management": "Postfachverwaltung",
"views.Admin.mailbox_list": "Postfächer",
"views.Index.mailboxSettings": "Postfacheinstellungen",
"views.Admin.mailbox_settings": "Globale Postfacheinstellungen",
"views.index.SimpleIndex.mailboxSettings": "Postfacheinstellungen",
"views.index.Attachment.action": "Aktion",
"views.admin.SenderAccess.action": "Aktion",
"views.user.UserSettings.actions": "Aktionen",
@@ -50,7 +52,7 @@ export const deMessages = {
"views.admin.Maintenance.customSqlTip": "Füge benutzerdefinierte DELETE-SQL-Anweisungen für die geplante Bereinigung hinzu. Pro Eintrag ist nur eine DELETE-Anweisung erlaubt.",
"views.admin.Maintenance.addCustomSql": "Benutzerdefinierte SQL hinzufügen",
"views.admin.UserOauth2Settings.addOauth2": "Oauth2 hinzufügen",
"components.AddressSelect.address": "Adresse",
"components.AddressSelect.selectMailbox": "Postfach auswählen",
"views.user.AddressManagement.address": "Adresse",
"views.index.TelegramAddress.address": "Adresse",
"views.admin.SenderAccess.address": "Adresse",
@@ -86,7 +88,7 @@ export const deMessages = {
"views.admin.Account.clearSentItemsTip": "Möchtest du wirklich die gesendeten Elemente dieser E-Mail-Adresse leeren?",
"views.admin.Account.multiDeleteTip": "Möchtest du wirklich die ausgewählten Adressen löschen?",
"views.index.Attachment.deleteConfirm": "Möchtest du wirklich diesen Anhang löschen?",
"views.admin.Account.deleteTip": "Möchtest du wirklich diese E-Mail löschen?",
"views.admin.Account.deleteTip": "Möchtest du wirklich dieses Postfach löschen?",
"views.admin.SenderAccess.deleteTip": "Möchtest du dies wirklich löschen?",
"views.index.AccountSettings.deleteAccountConfirm": "Möchtest du diese E-Mail-Adresse und alle zugehörigen E-Mails wirklich löschen? Dein Benutzerkonto wird dabei nicht gelöscht.",
"views.index.AccountSettings.logoutConfirm": "Möchtest du dich wirklich von der aktuellen E-Mail-Adresse abmelden?",
@@ -123,7 +125,7 @@ export const deMessages = {
"views.admin.AccountSettings.cancel": "Abbrechen",
"components.MailBox.cancelMultiAction": "Mehrfachaktion abbrechen",
"components.SendBox.cancelMultiAction": "Mehrfachaktion abbrechen",
"views.user.AddressManagement.changeMailAddress": "Adresse wechseln",
"views.user.AddressManagement.openMailbox": "Postfach öffnen",
"views.index.TelegramAddress.changeMailAddress": "Mailadresse ändern",
"views.index.LocalAddress.changeMailAddress": "Mailadresse ändern",
"views.index.AccountSettings.changePassword": "Adresspasswort ändern",
@@ -162,8 +164,8 @@ export const deMessages = {
"views.index.SimpleIndex.copyAddress": "Kopieren",
"components.AiExtractInfo.copyFailed": "Kopieren fehlgeschlagen",
"views.Footer.copyright": "Urheberrecht",
"views.Admin.account_create": "Konto erstellen",
"views.admin.CreateAccount.creatNewEmail": "Neue E-Mail erstellen",
"views.Admin.mailbox_create": "E-Mail-Adresse erstellen",
"views.admin.CreateAccount.createEmailAddress": "E-Mail-Adresse erstellen",
"views.common.Login.getNewEmail": "Neue E-Mail erstellen",
"views.user.AddressManagement.create_or_bind": "Erstellen oder verknüpfen",
"views.index.LocalAddress.create_or_bind": "Erstellen oder verknüpfen",
@@ -198,8 +200,8 @@ export const deMessages = {
"views.admin.UserManagement.delete": "Löschen",
"views.admin.AccountSettings.delete_rule": "Löschen",
"views.admin.Maintenance.deleteCustomSql": "Löschen",
"views.index.AccountSettings.deleteAccount": "E-Mail-Adresse löschen",
"views.admin.Account.deleteAccount": "Konto löschen",
"views.index.AccountSettings.deleteMailbox": "Postfach löschen",
"views.admin.Account.deleteMailbox": "Postfach löschen",
"views.user.UserSettings.deletePasskey": "Passkey löschen",
"views.admin.AccountSettings.delete_success": "Erfolgreich gelöscht",
"views.admin.UserManagement.deleteUser": "Benutzer löschen",
@@ -270,7 +272,7 @@ export const deMessages = {
"views.admin.Telegram.globalMailPushList": "Globale Mail-Push-Chat-ID-Liste",
"views.common.Appearance.globalTabplacement": "Globale Tab-Position",
"views.common.Login.help": "Hilfe",
"views.Header.home": "Startseite",
"views.Header.mailbox": "Postfach",
"views.index.SendMail.html": "HTML",
"views.admin.SendMail.html": "HTML",
"views.admin.UserOauth2Settings.icon": "Icon (SVG, bitte nur aus vertrauenswürdiger Quelle)",
@@ -319,7 +321,7 @@ export const deMessages = {
"views.admin.Account.addressCredential": "E-Mail-Adresszugangsdaten",
"views.admin.CreateAccount.addressCredential": "E-Mail-Adresszugangsdaten",
"views.index.AddressBar.fetchAddressError": "Die E-Mail-Zugangsdaten sind ungültig oder das Konto existiert nicht. Es kann auch ein Netzwerkproblem sein. Bitte später erneut versuchen.",
"views.Index.mailbox": "Posteingang",
"views.Index.inbox": "Posteingang",
"views.User.user_mail_box_tab": "Posteingang",
"views.user.AddressManagement.mail_count": "E-Mail-Anzahl",
"views.admin.Account.mail_count": "E-Mail-Anzahl",
@@ -349,11 +351,11 @@ export const deMessages = {
"views.admin.Account.multiClearInbox": "Mehrere Posteingänge leeren",
"views.admin.Account.multiClearSentItems": "Mehrere gesendete Elemente leeren",
"views.admin.Account.multiDelete": "Mehrfach löschen",
"views.user.AddressManagement.name": "Name",
"views.user.AddressManagement.emailAddress": "E-Mail-Adresse",
"views.index.AutoReply.name": "Name",
"views.admin.Account.name": "Name",
"views.admin.Account.emailAddress": "E-Mail-Adresse",
"views.admin.UserOauth2Settings.name": "Name",
"views.admin.UserAddressManagement.name": "Name",
"views.admin.UserAddressManagement.emailAddress": "E-Mail-Adresse",
"views.admin.Maintenance.sqlName": "Name",
"views.index.AccountSettings.newPassword": "Neues Passwort",
"views.admin.Account.newPassword": "Neues Passwort",
@@ -585,13 +587,13 @@ export const deMessages = {
"views.admin.UserOauth2Settings.userEmailFormatTip": "Regex verwenden, um die E-Mail umzuwandeln. Beispiel: ^(.+)@old\\.com$ mit $1@new.com",
"views.common.Appearance.useSimpleIndex": "Einfachen Index verwenden",
"views.common.Appearance.useUTCDate": "UTC-Datum verwenden",
"views.Header.user": "Benutzer",
"views.Header.userCenter": "Benutzerbereich",
"views.Admin.user": "Benutzer",
"components.AddressSelect.userAddresses": "Benutzeradressen",
"views.Admin.loginViaUserAdmin": "Benutzer-Admin-Berechtigung",
"components.AddressSelect.linkedMailboxes": "Verknüpfte Postfächer",
"views.Admin.loginViaUserAdmin": "Benutzerkonto (Administratorrolle)",
"views.admin.Statistics.userCount": "Benutzeranzahl",
"views.admin.UserManagement.user_email": "Benutzer-E-Mail",
"views.index.AddressBar.userLogin": "Benutzeranmeldung",
"views.index.AddressBar.userCenter": "Benutzerbereich",
"views.Admin.user_management": "Benutzerverwaltung",
"views.Admin.user_settings": "Benutzereinstellungen",
"views.User.user_settings": "Benutzereinstellungen",
@@ -654,5 +656,12 @@ export const deMessages = {
"components.AddressCredentialModal.username": "Benutzername",
"views.User.send_mail": "E-Mail senden",
"views.user.UserSendBox.noAddress": "Wähle eine verknüpfte E-Mail-Adresse aus",
"views.user.UserSendBox.sendbox": "Gesendet"
"views.user.UserSendBox.sendbox": "Gesendet",
"components.MailContentRenderer.markAsRead": "Als gelesen markieren",
"components.MailContentRenderer.markAsUnread": "Als ungelesen markieren",
"components.MailContentRenderer.loadRemoteImages": "Bilder laden",
"components.MailContentRenderer.remoteImagesBlocked": "{count} externe Ressourcen wurden zum Schutz deiner Privatsphäre blockiert",
"views.user.AddressManagement.itemCount": "Gesamt",
"views.index.SimpleIndex.readStatusUpdated": "Lesestatus aktualisiert",
"views.common.Appearance.autoLoadRemoteImages": "Externe Bilder im E-Mail-Inhalt automatisch laden"
}
+30 -21
View File
@@ -33,10 +33,12 @@ export const esMessages = {
"views.Index.about": "Acerca de",
"views.Admin.about": "Acerca de",
"views.Header.accessHeader": "Contraseña de acceso",
"views.Admin.account": "Cuenta",
"views.Index.accountSettings": "Configuración del correo",
"views.Admin.account_settings": "Configuración de la cuenta",
"views.index.SimpleIndex.accountSettings": "Configuración del correo",
"views.Header.admin": "Consola de administración",
"views.Admin.mailbox_management": "Gestión de buzones",
"views.Admin.mailbox_list": "Buzones",
"views.Index.mailboxSettings": "Configuración del buzón",
"views.Admin.mailbox_settings": "Configuración global de buzones",
"views.index.SimpleIndex.mailboxSettings": "Configuración del buzón",
"views.index.Attachment.action": "Acción",
"views.admin.SenderAccess.action": "Acción",
"views.user.UserSettings.actions": "Acciones",
@@ -50,7 +52,7 @@ export const esMessages = {
"views.admin.Maintenance.customSqlTip": "Añade sentencias SQL DELETE personalizadas para la limpieza programada. Solo se permite una sentencia DELETE por entrada.",
"views.admin.Maintenance.addCustomSql": "Añadir SQL personalizada",
"views.admin.UserOauth2Settings.addOauth2": "Añadir OAuth2",
"components.AddressSelect.address": "Dirección",
"components.AddressSelect.selectMailbox": "Seleccionar buzón",
"views.user.AddressManagement.address": "Dirección",
"views.index.TelegramAddress.address": "Dirección",
"views.admin.SenderAccess.address": "Dirección",
@@ -86,7 +88,7 @@ export const esMessages = {
"views.admin.Account.clearSentItemsTip": "¿Seguro que quieres vaciar los enviados de este correo?",
"views.admin.Account.multiDeleteTip": "¿Seguro que quieres eliminar las direcciones seleccionadas?",
"views.index.Attachment.deleteConfirm": "¿Seguro que quieres eliminar este adjunto?",
"views.admin.Account.deleteTip": "¿Seguro que quieres eliminar este correo?",
"views.admin.Account.deleteTip": "¿Seguro que quieres eliminar este buzón?",
"views.admin.SenderAccess.deleteTip": "¿Seguro que quieres eliminar esto?",
"views.index.AccountSettings.deleteAccountConfirm": "¿Seguro que quieres eliminar esta dirección de correo y todos sus correos? Esto no elimina tu cuenta de usuario.",
"views.index.AccountSettings.logoutConfirm": "¿Seguro que quieres cerrar la sesión de la dirección de correo actual?",
@@ -123,7 +125,7 @@ export const esMessages = {
"views.admin.AccountSettings.cancel": "Cancelar",
"components.MailBox.cancelMultiAction": "Cancelar selección múltiple",
"components.SendBox.cancelMultiAction": "Cancelar selección múltiple",
"views.user.AddressManagement.changeMailAddress": "Cambiar dirección",
"views.user.AddressManagement.openMailbox": "Abrir buzón",
"views.index.TelegramAddress.changeMailAddress": "Cambiar dirección de correo",
"views.index.LocalAddress.changeMailAddress": "Cambiar dirección de correo",
"views.index.AccountSettings.changePassword": "Cambiar contraseña de la dirección",
@@ -162,8 +164,8 @@ export const esMessages = {
"views.index.SimpleIndex.copyAddress": "Copiar",
"components.AiExtractInfo.copyFailed": "Error al copiar",
"views.Footer.copyright": "Derechos de autor",
"views.Admin.account_create": "Crear cuenta",
"views.admin.CreateAccount.creatNewEmail": "Crear nuevo correo",
"views.Admin.mailbox_create": "Crear dirección de correo",
"views.admin.CreateAccount.createEmailAddress": "Crear dirección de correo",
"views.common.Login.getNewEmail": "Crear nuevo correo",
"views.user.AddressManagement.create_or_bind": "Crear o vincular",
"views.index.LocalAddress.create_or_bind": "Crear o vincular",
@@ -198,8 +200,8 @@ export const esMessages = {
"views.admin.UserManagement.delete": "Eliminar",
"views.admin.AccountSettings.delete_rule": "Eliminar",
"views.admin.Maintenance.deleteCustomSql": "Eliminar",
"views.index.AccountSettings.deleteAccount": "Eliminar dirección de correo",
"views.admin.Account.deleteAccount": "Eliminar cuenta",
"views.index.AccountSettings.deleteMailbox": "Eliminar buzón",
"views.admin.Account.deleteMailbox": "Eliminar buzón",
"views.user.UserSettings.deletePasskey": "Eliminar passkey",
"views.admin.AccountSettings.delete_success": "Eliminado correctamente",
"views.admin.UserManagement.deleteUser": "Eliminar usuario",
@@ -270,7 +272,7 @@ export const esMessages = {
"views.admin.Telegram.globalMailPushList": "Lista global de chat ID para envío de correos",
"views.common.Appearance.globalTabplacement": "Posición global de pestañas",
"views.common.Login.help": "Ayuda",
"views.Header.home": "Inicio",
"views.Header.mailbox": "Buzón",
"views.index.SendMail.html": "HTML",
"views.admin.SendMail.html": "HTML",
"views.admin.UserOauth2Settings.icon": "Icono (SVG, asegúrate de que la fuente sea fiable)",
@@ -319,7 +321,7 @@ export const esMessages = {
"views.admin.Account.addressCredential": "Credencial de dirección de correo",
"views.admin.CreateAccount.addressCredential": "Credencial de dirección de correo",
"views.index.AddressBar.fetchAddressError": "La credencial del correo no es válida o la cuenta no existe; también puede ser un problema de red. Inténtalo más tarde.",
"views.Index.mailbox": "Bandeja de entrada",
"views.Index.inbox": "Bandeja de entrada",
"views.User.user_mail_box_tab": "Bandeja de entrada",
"views.user.AddressManagement.mail_count": "Cantidad de correos",
"views.admin.Account.mail_count": "Cantidad de correos",
@@ -349,11 +351,11 @@ export const esMessages = {
"views.admin.Account.multiClearInbox": "Vaciar varias bandejas",
"views.admin.Account.multiClearSentItems": "Vaciar varios enviados",
"views.admin.Account.multiDelete": "Eliminar en lote",
"views.user.AddressManagement.name": "Nombre",
"views.user.AddressManagement.emailAddress": "Dirección de correo",
"views.index.AutoReply.name": "Nombre",
"views.admin.Account.name": "Nombre",
"views.admin.Account.emailAddress": "Dirección de correo",
"views.admin.UserOauth2Settings.name": "Nombre",
"views.admin.UserAddressManagement.name": "Nombre",
"views.admin.UserAddressManagement.emailAddress": "Dirección de correo",
"views.admin.Maintenance.sqlName": "Nombre",
"views.index.AccountSettings.newPassword": "Nueva contraseña",
"views.admin.Account.newPassword": "Nueva contraseña",
@@ -585,13 +587,13 @@ export const esMessages = {
"views.admin.UserOauth2Settings.userEmailFormatTip": "Usa regex para transformar el correo. Ejemplo: ^(.+)@old\\.com$ con $1@new.com",
"views.common.Appearance.useSimpleIndex": "Usar índice simple",
"views.common.Appearance.useUTCDate": "Usar fecha UTC",
"views.Header.user": "Usuario",
"views.Header.userCenter": "Centro de usuario",
"views.Admin.user": "Usuario",
"components.AddressSelect.userAddresses": "Direcciones del usuario",
"views.Admin.loginViaUserAdmin": "Permiso de administrador del usuario",
"components.AddressSelect.linkedMailboxes": "Buzones vinculados",
"views.Admin.loginViaUserAdmin": "Cuenta de usuario (rol de administrador)",
"views.admin.Statistics.userCount": "Cantidad de usuarios",
"views.admin.UserManagement.user_email": "Correo del usuario",
"views.index.AddressBar.userLogin": "Inicio de sesión de usuario",
"views.index.AddressBar.userCenter": "Centro de usuario",
"views.Admin.user_management": "Gestión de usuarios",
"views.Admin.user_settings": "Configuración de usuario",
"views.User.user_settings": "Configuración de usuario",
@@ -654,5 +656,12 @@ export const esMessages = {
"components.AddressCredentialModal.username": "Usuario",
"views.User.send_mail": "Enviar correo",
"views.user.UserSendBox.noAddress": "Selecciona una dirección de correo vinculada",
"views.user.UserSendBox.sendbox": "Enviados"
"views.user.UserSendBox.sendbox": "Enviados",
"components.MailContentRenderer.markAsRead": "Marcar como leído",
"components.MailContentRenderer.markAsUnread": "Marcar como no leído",
"components.MailContentRenderer.loadRemoteImages": "Cargar imágenes",
"components.MailContentRenderer.remoteImagesBlocked": "Se bloquearon {count} recursos remotos para proteger tu privacidad",
"views.user.AddressManagement.itemCount": "Total",
"views.index.SimpleIndex.readStatusUpdated": "Estado de lectura actualizado",
"views.common.Appearance.autoLoadRemoteImages": "Cargar automáticamente las imágenes externas del correo"
}
+30 -21
View File
@@ -33,10 +33,12 @@ export const jaMessages = {
"views.Index.about": "概要",
"views.Admin.about": "概要",
"views.Header.accessHeader": "アクセス用パスワード",
"views.Admin.account": "アカウント",
"views.Index.accountSettings": "メール設定",
"views.Admin.account_settings": "アカウント設定",
"views.index.SimpleIndex.accountSettings": "メール設定",
"views.Header.admin": "管理画面",
"views.Admin.mailbox_management": "メールボックス管理",
"views.Admin.mailbox_list": "メールボックス一覧",
"views.Index.mailboxSettings": "メールボックス設定",
"views.Admin.mailbox_settings": "メールボックスのグローバル設定",
"views.index.SimpleIndex.mailboxSettings": "メールボックス設定",
"views.index.Attachment.action": "操作",
"views.admin.SenderAccess.action": "操作",
"views.user.UserSettings.actions": "操作",
@@ -50,7 +52,7 @@ export const jaMessages = {
"views.admin.Maintenance.customSqlTip": "定期クリーンアップ用にカスタム DELETE SQL を追加します。各項目には 1 つの DELETE 文のみ使用できます。",
"views.admin.Maintenance.addCustomSql": "カスタム SQL を追加",
"views.admin.UserOauth2Settings.addOauth2": "Oauth2 を追加",
"components.AddressSelect.address": "アドレス",
"components.AddressSelect.selectMailbox": "メールボックスを選択",
"views.user.AddressManagement.address": "アドレス",
"views.index.TelegramAddress.address": "アドレス",
"views.admin.SenderAccess.address": "アドレス",
@@ -86,7 +88,7 @@ export const jaMessages = {
"views.admin.Account.clearSentItemsTip": "このメールアドレスの送信済みを削除してもよろしいですか?",
"views.admin.Account.multiDeleteTip": "選択したアドレスを削除してもよろしいですか?",
"views.index.Attachment.deleteConfirm": "この添付ファイルを削除してもよろしいですか?",
"views.admin.Account.deleteTip": "このメールを削除してもよろしいですか?",
"views.admin.Account.deleteTip": "このメールボックスを削除してもよろしいですか?",
"views.admin.SenderAccess.deleteTip": "これを削除してもよろしいですか?",
"views.index.AccountSettings.deleteAccountConfirm": "このメールアドレスと関連するすべてのメールを削除しますか?ユーザーアカウントは削除されません。",
"views.index.AccountSettings.logoutConfirm": "現在のメールアドレスからログアウトしますか?",
@@ -123,7 +125,7 @@ export const jaMessages = {
"views.admin.AccountSettings.cancel": "キャンセル",
"components.MailBox.cancelMultiAction": "複数選択をキャンセル",
"components.SendBox.cancelMultiAction": "複数選択をキャンセル",
"views.user.AddressManagement.changeMailAddress": "アドレスを変更",
"views.user.AddressManagement.openMailbox": "メールボックスを開く",
"views.index.TelegramAddress.changeMailAddress": "メールアドレスを変更",
"views.index.LocalAddress.changeMailAddress": "メールアドレスを変更",
"views.index.AccountSettings.changePassword": "アドレスパスワードを変更",
@@ -162,8 +164,8 @@ export const jaMessages = {
"views.index.SimpleIndex.copyAddress": "コピー",
"components.AiExtractInfo.copyFailed": "コピーに失敗しました",
"views.Footer.copyright": "著作権",
"views.Admin.account_create": "アカウントを作成",
"views.admin.CreateAccount.creatNewEmail": "新しいメールを作成",
"views.Admin.mailbox_create": "メールアドレスを作成",
"views.admin.CreateAccount.createEmailAddress": "メールアドレスを作成",
"views.common.Login.getNewEmail": "新しいメールを作成",
"views.user.AddressManagement.create_or_bind": "作成または紐付け",
"views.index.LocalAddress.create_or_bind": "作成または紐付け",
@@ -198,8 +200,8 @@ export const jaMessages = {
"views.admin.UserManagement.delete": "削除",
"views.admin.AccountSettings.delete_rule": "削除",
"views.admin.Maintenance.deleteCustomSql": "削除",
"views.index.AccountSettings.deleteAccount": "メールアドレスを削除",
"views.admin.Account.deleteAccount": "アカウントを削除",
"views.index.AccountSettings.deleteMailbox": "メールボックスを削除",
"views.admin.Account.deleteMailbox": "メールボックスを削除",
"views.user.UserSettings.deletePasskey": "Passkeyを削除",
"views.admin.AccountSettings.delete_success": "削除しました",
"views.admin.UserManagement.deleteUser": "ユーザーを削除",
@@ -270,7 +272,7 @@ export const jaMessages = {
"views.admin.Telegram.globalMailPushList": "グローバルメール通知 Chat ID 一覧",
"views.common.Appearance.globalTabplacement": "全体タブ位置",
"views.common.Login.help": "ヘルプ",
"views.Header.home": "ホーム",
"views.Header.mailbox": "メールボックス",
"views.index.SendMail.html": "HTML",
"views.admin.SendMail.html": "HTML",
"views.admin.UserOauth2Settings.icon": "アイコン (SVG、信頼できるソースのみ使用してください)",
@@ -319,7 +321,7 @@ export const jaMessages = {
"views.admin.Account.addressCredential": "メールアドレス資格情報",
"views.admin.CreateAccount.addressCredential": "メールアドレス資格情報",
"views.index.AddressBar.fetchAddressError": "メール資格情報が無効かアカウントが存在しません。ネットワークの問題の可能性もあります。後でもう一度お試しください。",
"views.Index.mailbox": "受信箱",
"views.Index.inbox": "受信箱",
"views.User.user_mail_box_tab": "受信箱",
"views.user.AddressManagement.mail_count": "メール数",
"views.admin.Account.mail_count": "メール数",
@@ -349,11 +351,11 @@ export const jaMessages = {
"views.admin.Account.multiClearInbox": "受信箱を一括削除",
"views.admin.Account.multiClearSentItems": "送信済みを一括削除",
"views.admin.Account.multiDelete": "一括削除",
"views.user.AddressManagement.name": "名前",
"views.user.AddressManagement.emailAddress": "メールアドレス",
"views.index.AutoReply.name": "名前",
"views.admin.Account.name": "名前",
"views.admin.Account.emailAddress": "メールアドレス",
"views.admin.UserOauth2Settings.name": "名前",
"views.admin.UserAddressManagement.name": "名前",
"views.admin.UserAddressManagement.emailAddress": "メールアドレス",
"views.admin.Maintenance.sqlName": "名前",
"views.index.AccountSettings.newPassword": "新しいパスワード",
"views.admin.Account.newPassword": "新しいパスワード",
@@ -585,13 +587,13 @@ export const jaMessages = {
"views.admin.UserOauth2Settings.userEmailFormatTip": "正規表現でメールを変換します。例: ^(.+)@old\\.com$ と $1@new.com",
"views.common.Appearance.useSimpleIndex": "シンプルインデックスを使う",
"views.common.Appearance.useUTCDate": "UTC 日時を使う",
"views.Header.user": "ユーザー",
"views.Header.userCenter": "ユーザーセンター",
"views.Admin.user": "ユーザー",
"components.AddressSelect.userAddresses": "ユーザーのアドレス",
"views.Admin.loginViaUserAdmin": "ユーザー管理者権限",
"components.AddressSelect.linkedMailboxes": "連携済みメールボックス",
"views.Admin.loginViaUserAdmin": "ユーザーアカウント(管理者ロール)",
"views.admin.Statistics.userCount": "ユーザー数",
"views.admin.UserManagement.user_email": "ユーザーメール",
"views.index.AddressBar.userLogin": "ユーザーログイン",
"views.index.AddressBar.userCenter": "ユーザーセンター",
"views.Admin.user_management": "ユーザー管理",
"views.Admin.user_settings": "ユーザー設定",
"views.User.user_settings": "ユーザー設定",
@@ -654,5 +656,12 @@ export const jaMessages = {
"components.AddressCredentialModal.username": "ユーザー名",
"views.User.send_mail": "メール送信",
"views.user.UserSendBox.noAddress": "紐付け済みのメールアドレスを選択してください",
"views.user.UserSendBox.sendbox": "送信済み"
"views.user.UserSendBox.sendbox": "送信済み",
"components.MailContentRenderer.markAsRead": "既読にする",
"components.MailContentRenderer.markAsUnread": "未読にする",
"components.MailContentRenderer.loadRemoteImages": "画像を読み込む",
"components.MailContentRenderer.remoteImagesBlocked": "プライバシー保護のため、{count} 件の外部リソースをブロックしました",
"views.user.AddressManagement.itemCount": "合計",
"views.index.SimpleIndex.readStatusUpdated": "既読状態を更新しました",
"views.common.Appearance.autoLoadRemoteImages": "メール本文の外部画像を自動的に読み込む"
}
+30 -21
View File
@@ -33,10 +33,12 @@ export const ptBRMessages = {
"views.Index.about": "Sobre",
"views.Admin.about": "Sobre",
"views.Header.accessHeader": "Senha de acesso",
"views.Admin.account": "Conta",
"views.Index.accountSettings": "Configurações de e-mail",
"views.Admin.account_settings": "Configurações da conta",
"views.index.SimpleIndex.accountSettings": "Configurações de e-mail",
"views.Header.admin": "Painel administrativo",
"views.Admin.mailbox_management": "Gerenciamento de caixas de correio",
"views.Admin.mailbox_list": "Caixas de correio",
"views.Index.mailboxSettings": "Configurações da caixa de correio",
"views.Admin.mailbox_settings": "Configurações globais de caixas de correio",
"views.index.SimpleIndex.mailboxSettings": "Configurações da caixa de correio",
"views.index.Attachment.action": "Ação",
"views.admin.SenderAccess.action": "Ação",
"views.user.UserSettings.actions": "Ações",
@@ -50,7 +52,7 @@ export const ptBRMessages = {
"views.admin.Maintenance.customSqlTip": "Adicione instruções SQL DELETE personalizadas para a limpeza agendada. Apenas uma instrução DELETE é permitida por item.",
"views.admin.Maintenance.addCustomSql": "Adicionar SQL personalizada",
"views.admin.UserOauth2Settings.addOauth2": "Adicionar OAuth2",
"components.AddressSelect.address": "Endereço",
"components.AddressSelect.selectMailbox": "Selecionar caixa de correio",
"views.user.AddressManagement.address": "Endereço",
"views.index.TelegramAddress.address": "Endereço",
"views.admin.SenderAccess.address": "Endereço",
@@ -86,7 +88,7 @@ export const ptBRMessages = {
"views.admin.Account.clearSentItemsTip": "Tem certeza de que deseja limpar os itens enviados deste e-mail?",
"views.admin.Account.multiDeleteTip": "Tem certeza de que deseja excluir os endereços selecionados?",
"views.index.Attachment.deleteConfirm": "Tem certeza de que deseja excluir este anexo?",
"views.admin.Account.deleteTip": "Tem certeza de que deseja excluir este e-mail?",
"views.admin.Account.deleteTip": "Tem certeza de que deseja excluir esta caixa de correio?",
"views.admin.SenderAccess.deleteTip": "Tem certeza de que deseja excluir isto?",
"views.index.AccountSettings.deleteAccountConfirm": "Tem certeza de que deseja excluir este endereço de e-mail e todas as mensagens dele? Isso não exclui sua conta de usuário.",
"views.index.AccountSettings.logoutConfirm": "Tem certeza de que deseja sair do endereço de e-mail atual?",
@@ -123,7 +125,7 @@ export const ptBRMessages = {
"views.admin.AccountSettings.cancel": "Cancelar",
"components.MailBox.cancelMultiAction": "Cancelar múltipla seleção",
"components.SendBox.cancelMultiAction": "Cancelar múltipla seleção",
"views.user.AddressManagement.changeMailAddress": "Alterar endereço",
"views.user.AddressManagement.openMailbox": "Abrir caixa de correio",
"views.index.TelegramAddress.changeMailAddress": "Alterar endereço de e-mail",
"views.index.LocalAddress.changeMailAddress": "Alterar endereço de e-mail",
"views.index.AccountSettings.changePassword": "Alterar senha do endereço",
@@ -162,8 +164,8 @@ export const ptBRMessages = {
"views.index.SimpleIndex.copyAddress": "Copiar",
"components.AiExtractInfo.copyFailed": "Falha ao copiar",
"views.Footer.copyright": "Direitos autorais",
"views.Admin.account_create": "Criar conta",
"views.admin.CreateAccount.creatNewEmail": "Criar novo e-mail",
"views.Admin.mailbox_create": "Criar endereço de e-mail",
"views.admin.CreateAccount.createEmailAddress": "Criar endereço de e-mail",
"views.common.Login.getNewEmail": "Criar novo e-mail",
"views.user.AddressManagement.create_or_bind": "Criar ou vincular",
"views.index.LocalAddress.create_or_bind": "Criar ou vincular",
@@ -198,8 +200,8 @@ export const ptBRMessages = {
"views.admin.UserManagement.delete": "Excluir",
"views.admin.AccountSettings.delete_rule": "Excluir",
"views.admin.Maintenance.deleteCustomSql": "Excluir",
"views.index.AccountSettings.deleteAccount": "Excluir endereço de e-mail",
"views.admin.Account.deleteAccount": "Excluir conta",
"views.index.AccountSettings.deleteMailbox": "Excluir caixa de correio",
"views.admin.Account.deleteMailbox": "Excluir caixa de correio",
"views.user.UserSettings.deletePasskey": "Excluir passkey",
"views.admin.AccountSettings.delete_success": "Excluído com sucesso",
"views.admin.UserManagement.deleteUser": "Excluir usuário",
@@ -270,7 +272,7 @@ export const ptBRMessages = {
"views.admin.Telegram.globalMailPushList": "Lista global de chat ID para envio de e-mails",
"views.common.Appearance.globalTabplacement": "Posição global das abas",
"views.common.Login.help": "Ajuda",
"views.Header.home": "Início",
"views.Header.mailbox": "Caixa de correio",
"views.index.SendMail.html": "HTML",
"views.admin.SendMail.html": "HTML",
"views.admin.UserOauth2Settings.icon": "Ícone (SVG, use apenas fonte confiável)",
@@ -319,7 +321,7 @@ export const ptBRMessages = {
"views.admin.Account.addressCredential": "Credencial do endereço de e-mail",
"views.admin.CreateAccount.addressCredential": "Credencial do endereço de e-mail",
"views.index.AddressBar.fetchAddressError": "A credencial do e-mail é inválida ou a conta não existe; também pode ser um problema de rede. Tente novamente mais tarde.",
"views.Index.mailbox": "Caixa de entrada",
"views.Index.inbox": "Caixa de entrada",
"views.User.user_mail_box_tab": "Caixa de entrada",
"views.user.AddressManagement.mail_count": "Quantidade de e-mails",
"views.admin.Account.mail_count": "Quantidade de e-mails",
@@ -349,11 +351,11 @@ export const ptBRMessages = {
"views.admin.Account.multiClearInbox": "Limpar várias caixas de entrada",
"views.admin.Account.multiClearSentItems": "Limpar vários itens enviados",
"views.admin.Account.multiDelete": "Excluir em lote",
"views.user.AddressManagement.name": "Nome",
"views.user.AddressManagement.emailAddress": "Endereço de e-mail",
"views.index.AutoReply.name": "Nome",
"views.admin.Account.name": "Nome",
"views.admin.Account.emailAddress": "Endereço de e-mail",
"views.admin.UserOauth2Settings.name": "Nome",
"views.admin.UserAddressManagement.name": "Nome",
"views.admin.UserAddressManagement.emailAddress": "Endereço de e-mail",
"views.admin.Maintenance.sqlName": "Nome",
"views.index.AccountSettings.newPassword": "Nova senha",
"views.admin.Account.newPassword": "Nova senha",
@@ -585,13 +587,13 @@ export const ptBRMessages = {
"views.admin.UserOauth2Settings.userEmailFormatTip": "Use regex para transformar o e-mail. Exemplo: ^(.+)@old\\.com$ com $1@new.com",
"views.common.Appearance.useSimpleIndex": "Usar índice simples",
"views.common.Appearance.useUTCDate": "Usar data UTC",
"views.Header.user": "Usuário",
"views.Header.userCenter": "Central do usuário",
"views.Admin.user": "Usuário",
"components.AddressSelect.userAddresses": "Endereços do usuário",
"views.Admin.loginViaUserAdmin": "Permissão de administrador do usuário",
"components.AddressSelect.linkedMailboxes": "Caixas de correio vinculadas",
"views.Admin.loginViaUserAdmin": "Conta de usuário (função de administrador)",
"views.admin.Statistics.userCount": "Quantidade de usuários",
"views.admin.UserManagement.user_email": "E-mail do usuário",
"views.index.AddressBar.userLogin": "Login do usuário",
"views.index.AddressBar.userCenter": "Central do usuário",
"views.Admin.user_management": "Gerenciamento de usuários",
"views.Admin.user_settings": "Configurações do usuário",
"views.User.user_settings": "Configurações do usuário",
@@ -654,5 +656,12 @@ export const ptBRMessages = {
"components.AddressCredentialModal.username": "Nome de usuário",
"views.User.send_mail": "Enviar e-mail",
"views.user.UserSendBox.noAddress": "Selecione um endereço de e-mail vinculado",
"views.user.UserSendBox.sendbox": "Enviados"
"views.user.UserSendBox.sendbox": "Enviados",
"components.MailContentRenderer.markAsRead": "Marcar como lido",
"components.MailContentRenderer.markAsUnread": "Marcar como não lido",
"components.MailContentRenderer.loadRemoteImages": "Carregar imagens",
"components.MailContentRenderer.remoteImagesBlocked": "{count} recursos externos foram bloqueados para proteger sua privacidade",
"views.user.AddressManagement.itemCount": "Total",
"views.index.SimpleIndex.readStatusUpdated": "Status de leitura atualizado",
"views.common.Appearance.autoLoadRemoteImages": "Carregar automaticamente imagens externas no corpo do e-mail"
}
+132 -124
View File
@@ -280,9 +280,9 @@ export const MESSAGE_REGISTRY = {
}
},
"components.AddressSelect": {
"address": {
"en": "Address",
"zh": "地址"
"selectMailbox": {
"en": "Select Mailbox",
"zh": "选择邮箱"
},
"copied": {
"en": "Copied",
@@ -293,12 +293,12 @@ export const MESSAGE_REGISTRY = {
"zh": "复制"
},
"localAddresses": {
"en": "Local Addresses",
"zh": "本地地址"
"en": "Local Email Addresses",
"zh": "本地邮箱地址"
},
"userAddresses": {
"en": "User Addresses",
"zh": "用户地址"
"linkedMailboxes": {
"en": "Linked Mailboxes",
"zh": "已绑定邮箱"
}
},
"components.AddressCredentialModal": {
@@ -311,8 +311,8 @@ export const MESSAGE_REGISTRY = {
"zh": "Address JWT"
},
"addressPassword": {
"en": "Address Password",
"zh": "地址密码"
"en": "Mailbox Password",
"zh": "邮箱密码"
},
"agentAccess": {
"en": "AI Agent",
@@ -351,8 +351,8 @@ export const MESSAGE_REGISTRY = {
"zh": "已复制"
},
"currentAddress": {
"en": "Current address",
"zh": "当前邮箱"
"en": "Current Email Address",
"zh": "当前邮箱地址"
},
"docs": {
"en": "Docs",
@@ -387,8 +387,8 @@ export const MESSAGE_REGISTRY = {
"zh": "SMTP / IMAP"
},
"smtpImapTip": {
"en": "Use these values in mail clients after the administrator configures the SMTP/IMAP proxy. The password can be the Address JWT shown here, or the address password when you have it.",
"zh": "管理员配置 SMTP/IMAP 代理后,可在邮件客户端中使用这些信息。密码可使用这里展示的 Address JWT,也可使用你持有的地址密码。"
"en": "Use these values in mail clients after the administrator configures the SMTP/IMAP proxy. The password can be the Address JWT shown here, or the mailbox password when you have it.",
"zh": "管理员配置 SMTP/IMAP 代理后,可在邮件客户端中使用这些信息。密码可使用这里展示的 Address JWT,也可使用你持有的邮箱密码。"
},
"smtpPort": {
"en": "SMTP port",
@@ -426,8 +426,8 @@ export const MESSAGE_REGISTRY = {
"en": "About",
"zh": "关于"
},
"accountSettings": {
"en": "Email Settings",
"mailboxSettings": {
"en": "Mailbox Settings",
"zh": "邮箱设置"
},
"appearance": {
@@ -442,8 +442,8 @@ export const MESSAGE_REGISTRY = {
"en": "Simple Mode",
"zh": "极简模式"
},
"mailbox": {
"en": "Mail Box",
"inbox": {
"en": "Inbox",
"zh": "收件箱"
},
"query": {
@@ -459,7 +459,7 @@ export const MESSAGE_REGISTRY = {
"zh": "保存到s3成功"
},
"sendbox": {
"en": "Send Box",
"en": "Sent",
"zh": "发件箱"
},
"sendmail": {
@@ -536,6 +536,10 @@ export const MESSAGE_REGISTRY = {
}
},
"views.Header": {
"admin": {
"en": "Admin Console",
"zh": "管理后台"
},
"accessHeader": {
"en": "Access Password",
"zh": "访问密码"
@@ -546,15 +550,15 @@ export const MESSAGE_REGISTRY = {
},
"dark": {
"en": "Dark",
"zh": "色"
"zh": "色"
},
"home": {
"en": "Home",
"zh": "主页"
"mailbox": {
"en": "Mailbox",
"zh": "邮箱"
},
"light": {
"en": "Light",
"zh": "色"
"zh": "色"
},
"menu": {
"en": "Menu",
@@ -572,9 +576,9 @@ export const MESSAGE_REGISTRY = {
"en": "Cloudflare Temp Email",
"zh": "Cloudflare 临时邮件"
},
"user": {
"en": "User",
"zh": "用户"
"userCenter": {
"en": "User Center",
"zh": "用户中心"
}
},
"views.user.BindAddress": {
@@ -590,23 +594,27 @@ export const MESSAGE_REGISTRY = {
},
"accessHeader": {
"en": "Admin Password",
"zh": "Admin 密码"
"zh": "管理员密码"
},
"accessTip": {
"en": "Please enter the admin password",
"zh": "请输入 Admin 密码"
"zh": "请输入管理员密码"
},
"account": {
"en": "Account",
"zh": "账号"
"mailbox_management": {
"en": "Mailbox Management",
"zh": "邮箱管理"
},
"account_create": {
"en": "Create Account",
"zh": "创建账号"
"mailbox_list": {
"en": "Mailboxes",
"zh": "邮箱列表"
},
"account_settings": {
"en": "Account Settings",
"zh": "账号设置"
"mailbox_create": {
"en": "Create Email Address",
"zh": "创建邮箱"
},
"mailbox_settings": {
"en": "Global Mailbox Settings",
"zh": "全局邮箱设置"
},
"adminAccount": {
"en": "Admin",
@@ -642,19 +650,19 @@ export const MESSAGE_REGISTRY = {
},
"loginViaPassword": {
"en": "Admin Password Login",
"zh": "Admin 密码登录"
"zh": "管理员密码登录"
},
"loginViaUserAdmin": {
"en": "User Admin Permission",
"zh": "用户管理员权限"
"en": "User Account (Admin Role)",
"zh": "用户账号(管理员权限"
},
"logout": {
"en": "Logout",
"zh": "退出登录"
},
"logoutConfirmContent": {
"en": "Are you sure you want to logout from admin panel?",
"zh": "确定要退出管理员面板吗?"
"en": "Are you sure you want to log out of the admin console?",
"zh": "确定要退出管理后台吗?"
},
"logoutConfirmTitle": {
"en": "Confirm Logout",
@@ -689,7 +697,7 @@ export const MESSAGE_REGISTRY = {
"zh": "角色地址配置"
},
"sendBox": {
"en": "Send Box",
"en": "Sent",
"zh": "发件箱"
},
"sendMail": {
@@ -739,11 +747,11 @@ export const MESSAGE_REGISTRY = {
},
"views.User": {
"address_management": {
"en": "Address Management",
"zh": "地址管理"
"en": "Mailbox Management",
"zh": "邮箱管理"
},
"bind_address": {
"en": "Bind Mail Address",
"en": "Link Email Address",
"zh": "绑定邮箱地址"
},
"send_mail": {
@@ -751,7 +759,7 @@ export const MESSAGE_REGISTRY = {
"zh": "发送邮件"
},
"user_mail_box_tab": {
"en": "Mail Box",
"en": "Inbox",
"zh": "收件箱"
},
"user_settings": {
@@ -775,8 +783,8 @@ export const MESSAGE_REGISTRY = {
"zh": "未开启邮箱验证或未开启注册功能,无法重置密码,请联系管理员"
},
"email": {
"en": "Email",
"zh": "邮箱"
"en": "Account Email",
"zh": "用户邮箱"
},
"forgotPassword": {
"en": "Forgot Password",
@@ -803,16 +811,16 @@ export const MESSAGE_REGISTRY = {
"zh": "请完成人机验证"
},
"pleaseInput": {
"en": "Please input email and password",
"zh": "请输入邮箱和密码"
"en": "Please enter the account email and password",
"zh": "请输入用户邮箱和密码"
},
"pleaseInputCode": {
"en": "Please input code",
"zh": "请输入验证码"
},
"pleaseInputEmail": {
"en": "Please input email",
"zh": "请输入邮箱"
"en": "Please enter the account email",
"zh": "请输入用户邮箱"
},
"pleaseLogin": {
"en": "Please login",
@@ -845,8 +853,8 @@ export const MESSAGE_REGISTRY = {
},
"views.user.UserBar": {
"currentUser": {
"en": "Current Login User",
"zh": "当前登录用户"
"en": "Current User",
"zh": "当前用户"
},
"fetchUserSettingsError": {
"en": "Login password is invalid or account not exist, it may be network connection issue, please try again later.",
@@ -859,16 +867,16 @@ export const MESSAGE_REGISTRY = {
"zh": "操作"
},
"address": {
"en": "Address",
"zh": "地址"
"en": "Mailboxes",
"zh": "邮箱列表"
},
"changeMailAddress": {
"en": "Change Address",
"zh": "切换地址"
"openMailbox": {
"en": "Open Mailbox",
"zh": "进入邮箱"
},
"create_or_bind": {
"en": "Create or Bind",
"zh": "创建或绑定"
"en": "Add Mailbox",
"zh": "添加邮箱"
},
"mail_count": {
"en": "Mail Count",
@@ -878,9 +886,9 @@ export const MESSAGE_REGISTRY = {
"en": "Total",
"zh": "总数"
},
"name": {
"en": "Name",
"zh": "名称"
"emailAddress": {
"en": "Email Address",
"zh": "邮箱地址"
},
"send_count": {
"en": "Send Count",
@@ -895,16 +903,16 @@ export const MESSAGE_REGISTRY = {
"zh": "目标用户邮箱"
},
"transferAddress": {
"en": "Transfer Address",
"zh": "转移地址"
"en": "Transfer Mailbox",
"zh": "转移邮箱"
},
"transferAddressTip": {
"en": "Transfer address to another user will remove the address from your account and transfer it to another user. Are you sure to transfer the address?",
"zh": "转移地址到其他用户将会从你的账户中移除此地址并转移给其他用户。确定要转移地址吗?"
},
"unbindAddress": {
"en": "Unbind Address",
"zh": "解绑地址"
"en": "Unlink Mailbox",
"zh": "解绑邮箱"
},
"unbindAddressTip": {
"en": "Before unbinding, please switch to this email address and save the email address credential.",
@@ -913,8 +921,8 @@ export const MESSAGE_REGISTRY = {
},
"views.index.AccountSettings": {
"changePassword": {
"en": "Change Address Password",
"zh": "修改地址密码"
"en": "Change Mailbox Password",
"zh": "修改邮箱密码"
},
"clearInbox": {
"en": "Clear Inbox",
@@ -936,17 +944,17 @@ export const MESSAGE_REGISTRY = {
"en": "Confirm Password",
"zh": "确认密码"
},
"deleteAccount": {
"en": "Delete Email Address",
"zh": "删除邮箱地址"
"deleteMailbox": {
"en": "Delete Mailbox",
"zh": "删除邮箱"
},
"deleteAccountConfirm": {
"en": "Are you sure you want to delete this email address and all of its emails? This does not delete your user account.",
"zh": "确定要删除当前邮箱地址及其中的所有邮件吗?此操作不会删除你的用户账号。"
},
"logout": {
"en": "Log Out of Address",
"zh": "退出地址登录"
"en": "Log Out of Mailbox",
"zh": "退出邮箱登录"
},
"logoutConfirm": {
"en": "Are you sure you want to log out of the current email address?",
@@ -1162,8 +1170,8 @@ export const MESSAGE_REGISTRY = {
}
},
"views.index.SimpleIndex": {
"accountSettings": {
"en": "Email Settings",
"mailboxSettings": {
"en": "Mailbox Settings",
"zh": "邮箱设置"
},
"addressCopied": {
@@ -1263,12 +1271,12 @@ export const MESSAGE_REGISTRY = {
"zh": "请复制邮箱地址凭证,你可以使用它登录你的邮箱。"
},
"addressManage": {
"en": "Manage",
"zh": "地址管理"
"en": "Mailbox Management",
"zh": "邮箱管理"
},
"addressPassword": {
"en": "Address Password",
"zh": "地址密码"
"en": "Mailbox Password",
"zh": "邮箱密码"
},
"fetchAddressError": {
"en": "Mail address credential is invalid or account not exist, it may be network connection issue, please try again later.",
@@ -1282,9 +1290,9 @@ export const MESSAGE_REGISTRY = {
"en": "OK",
"zh": "确定"
},
"userLogin": {
"en": "User Login",
"zh": "用户登录"
"userCenter": {
"en": "User Center",
"zh": "用户中心"
}
},
"views.admin.SendBox": {
@@ -1451,8 +1459,8 @@ export const MESSAGE_REGISTRY = {
"zh": "请复制邮箱地址凭证,你可以使用它登录你的邮箱。"
},
"addressQueryTip": {
"en": "Leave blank to query all addresses",
"zh": "留空查询所有地址"
"en": "Leave blank to query all email addresses",
"zh": "留空查询所有邮箱地址"
},
"clearInbox": {
"en": "Clear Inbox",
@@ -1478,12 +1486,12 @@ export const MESSAGE_REGISTRY = {
"en": "Delete",
"zh": "删除"
},
"deleteAccount": {
"en": "Delete Account",
"deleteMailbox": {
"en": "Delete Mailbox",
"zh": "删除邮箱"
},
"deleteTip": {
"en": "Are you sure to delete this email?",
"en": "Are you sure you want to delete this mailbox?",
"zh": "确定要删除这个邮箱吗?"
},
"itemCount": {
@@ -1518,9 +1526,9 @@ export const MESSAGE_REGISTRY = {
"en": "Are you sure to delete selected addresses?",
"zh": "确定要删除选中的邮箱吗?"
},
"name": {
"en": "Name",
"zh": "名称"
"emailAddress": {
"en": "Email Address",
"zh": "邮箱地址"
},
"newPassword": {
"en": "New Password",
@@ -1531,8 +1539,8 @@ export const MESSAGE_REGISTRY = {
"zh": "密码重置成功"
},
"pleaseSelectAddress": {
"en": "Please select address",
"zh": "请选择地址"
"en": "Please select a mailbox",
"zh": "请选择邮箱"
},
"query": {
"en": "Query",
@@ -1685,8 +1693,8 @@ export const MESSAGE_REGISTRY = {
"zh": "操作"
},
"address": {
"en": "Address",
"zh": "地址"
"en": "Email Address",
"zh": "邮箱地址"
},
"balance": {
"en": "Balance",
@@ -1972,9 +1980,9 @@ export const MESSAGE_REGISTRY = {
"en": "Mail Count",
"zh": "邮件数量"
},
"name": {
"en": "Name",
"zh": "名称"
"emailAddress": {
"en": "Email Address",
"zh": "邮箱地址"
},
"send_count": {
"en": "Send Count",
@@ -1991,8 +1999,8 @@ export const MESSAGE_REGISTRY = {
"zh": "操作"
},
"address_count": {
"en": "Address Count",
"zh": "地址数量"
"en": "Mailbox Count",
"zh": "邮箱数量"
},
"changeRole": {
"en": "Change Role",
@@ -2023,8 +2031,8 @@ export const MESSAGE_REGISTRY = {
"zh": "域名"
},
"email": {
"en": "Email",
"zh": "邮箱"
"en": "Account Email",
"zh": "用户邮箱"
},
"itemCount": {
"en": "itemCount",
@@ -2063,8 +2071,8 @@ export const MESSAGE_REGISTRY = {
"zh": "成功"
},
"userAddressManagement": {
"en": "Address Management",
"zh": "地址管理"
"en": "Mailbox Management",
"zh": "邮箱管理"
},
"user_email": {
"en": "User Email",
@@ -2123,8 +2131,8 @@ export const MESSAGE_REGISTRY = {
},
"views.admin.CreateAccount": {
"address": {
"en": "Address",
"zh": "地址"
"en": "Email Address",
"zh": "邮箱地址"
},
"addressCredential": {
"en": "Mail Address Credential",
@@ -2135,12 +2143,12 @@ export const MESSAGE_REGISTRY = {
"zh": "请复制邮箱地址凭证,你可以使用它登录你的邮箱。"
},
"addressPassword": {
"en": "Address Password",
"zh": "地址密码"
"en": "Mailbox Password",
"zh": "邮箱密码"
},
"creatNewEmail": {
"en": "Create New Email",
"zh": "创建邮箱"
"createEmailAddress": {
"en": "Create Email Address",
"zh": "创建邮箱"
},
"enableCustomSubdomain": {
"en": "Use Custom Subdomain",
@@ -2649,12 +2657,12 @@ export const MESSAGE_REGISTRY = {
"zh": "凭据登录"
},
"email": {
"en": "Email",
"zh": "邮箱"
"en": "Email Address",
"zh": "邮箱地址"
},
"emailPasswordRequired": {
"en": "Email and password are required",
"zh": "邮箱密码不能为空"
"en": "Email address and mailbox password are required",
"zh": "邮箱地址和邮箱密码不能为空"
},
"enableRandomSubdomain": {
"en": "Use Random Subdomain",
@@ -2669,8 +2677,8 @@ export const MESSAGE_REGISTRY = {
"zh": "生成随机名字"
},
"getNewEmail": {
"en": "Create New Email",
"zh": "创建邮箱"
"en": "Create Email Address",
"zh": "创建邮箱"
},
"normalSubdomain": {
"en": "Normal Domain",
@@ -2693,8 +2701,8 @@ export const MESSAGE_REGISTRY = {
"zh": "帮助"
},
"login": {
"en": "Login",
"zh": "登录"
"en": "Log In to Mailbox",
"zh": "登录邮箱"
},
"loginAndBind": {
"en": "Login and Bind",
@@ -2705,8 +2713,8 @@ export const MESSAGE_REGISTRY = {
"zh": "确定"
},
"password": {
"en": "Password",
"zh": "密码"
"en": "Mailbox Password",
"zh": "邮箱密码"
},
"passwordLogin": {
"en": "Password Login",
+5 -5
View File
@@ -124,7 +124,7 @@ onMounted(async () => {
<n-tab-pane name="database" :tab="t('database')">
<DatabaseManager />
</n-tab-pane>
<n-tab-pane name="account_settings" :tab="t('account_settings')">
<n-tab-pane name="account_settings" :tab="t('mailbox_settings')">
<AccountSettings />
</n-tab-pane>
<n-tab-pane name="user_settings" :tab="t('user_settings')">
@@ -135,15 +135,15 @@ onMounted(async () => {
</n-tab-pane>
</n-tabs>
</n-tab-pane>
<n-tab-pane name="account" :tab="t('account')">
<n-tab-pane name="account" :tab="t('mailbox_management')">
<n-tabs key="account-tabs" type="bar" justify-content="center" animated>
<n-tab-pane name="account" :tab="t('account')">
<n-tab-pane name="account" :tab="t('mailbox_list')">
<Account />
</n-tab-pane>
<n-tab-pane name="account_create" :tab="t('account_create')">
<n-tab-pane name="account_create" :tab="t('mailbox_create')">
<CreateAccount />
</n-tab-pane>
<n-tab-pane name="account_settings" :tab="t('account_settings')">
<n-tab-pane name="account_settings" :tab="t('mailbox_settings')">
<AccountSettings />
</n-tab-pane>
<n-tab-pane name="senderAccess" :tab="t('senderAccess')">
+5 -5
View File
@@ -9,7 +9,7 @@ import {
AdminPanelSettingsFilled, MonitorHeartFilled,
KeyboardArrowDownOutlined, OpenInNewOutlined
} from '@vicons/material'
import { GithubAlt, Language, User, Home } from '@vicons/fa'
import { Envelope, GithubAlt, Language, User } from '@vicons/fa'
import { useGlobalState } from '../store'
import { api } from '../api'
@@ -123,8 +123,8 @@ const menuOptions = computed(() => [
}
},
{
default: () => t('home'),
icon: () => h(NIcon, { component: Home })
default: () => t('mailbox'),
icon: () => h(NIcon, { component: Envelope })
}),
key: "home"
},
@@ -142,7 +142,7 @@ const menuOptions = computed(() => [
}
},
{
default: () => t('user'),
default: () => t('userCenter'),
icon: () => h(NIcon, { component: User }),
}
),
@@ -165,7 +165,7 @@ const menuOptions = computed(() => [
}
},
{
default: () => "Admin",
default: () => t('admin'),
icon: () => h(NIcon, { component: AdminPanelSettingsFilled }),
}
),
+2 -2
View File
@@ -124,7 +124,7 @@ onMounted(() => {
{{ t('enterSimpleMode') }}
</n-button>
</template>
<n-tab-pane name="mailbox" :tab="t('mailbox')">
<n-tab-pane name="mailbox" :tab="t('inbox')">
<div v-if="showMailIdQuery" style="margin-bottom: 10px;">
<n-input-group>
<n-input v-model:value="mailIdQuery" />
@@ -145,7 +145,7 @@ onMounted(() => {
<n-tab-pane v-if="openSettings.enableSendMail" name="sendmail" :tab="t('sendmail')">
<SendMail />
</n-tab-pane>
<n-tab-pane name="accountSettings" :tab="t('accountSettings')">
<n-tab-pane name="accountSettings" :tab="t('mailboxSettings')">
<AccountSettings />
</n-tab-pane>
<n-tab-pane name="appearance" :tab="t('appearance')">
+3 -3
View File
@@ -265,7 +265,7 @@ const columns = computed(() => [
sortOrder: sortBy.value === 'id' ? sortOrder.value : false
},
{
title: t('name'),
title: t('emailAddress'),
key: "name",
sorter: true,
sortOrder: sortBy.value === 'name' ? sortOrder.value : false
@@ -479,11 +479,11 @@ onMounted(async () => {
<div style="margin-top: 10px;">
<AddressCredentialModal v-model:show="showEmailCredential" :address="curEmailAddress"
:jwt="curEmailCredential" />
<n-modal v-model:show="showDeleteAccount" preset="dialog" :title="t('deleteAccount')">
<n-modal v-model:show="showDeleteAccount" preset="dialog" :title="t('deleteMailbox')">
<p>{{ t('deleteTip') }}</p>
<template #action>
<n-button :loading="loading" @click="deleteEmail" size="small" tertiary type="error">
{{ t('deleteAccount') }}
{{ t('deleteMailbox') }}
</n-button>
</template>
</n-modal>
+1 -1
View File
@@ -152,7 +152,7 @@ onMounted(async () => {
</n-form-item-row>
<n-button @click="newEmail" type="primary" block :loading="loading"
:disabled="subdomainMode === 'custom' && !customSubdomain.trim()">
{{ t('creatNewEmail') }}
{{ t('createEmailAddress') }}
</n-button>
</n-card>
</div>
@@ -32,7 +32,7 @@ const fetchData = async () => {
const columns = [
{
title: t('name'),
title: t('emailAddress'),
key: "name"
},
{
+3 -3
View File
@@ -113,7 +113,7 @@ const changePassword = async () => {
<n-divider v-if="openSettings.enableUserDeleteEmail" />
<n-button v-if="openSettings.enableUserDeleteEmail" @click="showDeleteAccount = true" type="error" secondary
block strong>
{{ t('deleteAccount') }}
{{ t('deleteMailbox') }}
</n-button>
</n-card>
@@ -125,11 +125,11 @@ const changePassword = async () => {
</n-button>
</template>
</n-modal>
<n-modal v-model:show="showDeleteAccount" preset="dialog" :title="t('deleteAccount')">
<n-modal v-model:show="showDeleteAccount" preset="dialog" :title="t('deleteMailbox')">
<p>{{ t('deleteAccountConfirm') }}</p>
<template #action>
<n-button :loading="loading" @click="deleteAccount" size="small" tertiary type="error">
{{ t('deleteAccount') }}
{{ t('deleteMailbox') }}
</n-button>
</template>
</n-modal>
+1 -1
View File
@@ -71,7 +71,7 @@ onMounted(async () => {
<template #icon>
<n-icon :component="User" />
</template>
{{ t('userLogin') }}
{{ t('userCenter') }}
</n-button>
</n-card>
</div>
+2 -2
View File
@@ -188,7 +188,7 @@ onBeforeUnmount(() => {
<SettingsFilled />
</n-icon>
</template>
{{ t('accountSettings') }}
{{ t('mailboxSettings') }}
</n-button>
</n-flex>
<div v-if="isFirstPage" style="text-align: center; margin-top: 12px;">
@@ -200,7 +200,7 @@ onBeforeUnmount(() => {
<!-- 账户设置卡片 -->
<n-card v-if="showAccountSettingsCard" :bordered="false" embedded closable
@close="showAccountSettingsCard = false" :title="t('accountSettings')">
@close="showAccountSettingsCard = false" :title="t('mailboxSettings')">
<AccountSettings />
</n-card>
@@ -44,7 +44,6 @@ const showCredential = async (row) => {
const changeMailAddress = async (address_id) => {
try {
const res = await api.fetch(`/user_api/bind_address_jwt/${address_id}`);
message.success(t('changeMailAddress') + " " + t('success'));
if (!res.jwt) {
message.error("jwt not found");
return;
@@ -130,7 +129,7 @@ const fetchData = async () => {
const columns = [
{
title: t('name'),
title: t('emailAddress'),
key: "name"
},
{
@@ -180,9 +179,9 @@ const columns = [
tertiary: true,
type: "primary",
},
{ default: () => t('changeMailAddress') }
{ default: () => t('openMailbox') }
),
default: () => `${t('changeMailAddress')}?`
default: () => `${t('openMailbox')}?`
}
),
h(NButton,
@@ -150,19 +150,20 @@ cd worker
wrangler secret put SMTP_CONFIG
```
## User Accounts, Email Addresses, and Send Permission
## User Accounts, Mailboxes, Email Addresses, and Send Permission
These concepts are related, but they identify different objects:
| Concept | Description |
|---------|-------------|
| User account | Signs in to the user center and can bind and manage multiple email addresses. The user account's login email is not automatically a sending or receiving address |
| Email address | The identity that actually receives and sends mail, such as `name@example.com`. The address currently selected on the frontend home page is authenticated by its Address JWT |
| User account | Signs in to the user center and can link and manage multiple mailboxes. The account email is not automatically a sending or receiving address |
| Mailbox | The user-facing object that contains an inbox, sent mail, sending capability, and mailbox settings |
| Email address | The concrete value that identifies a mailbox, such as `name@example.com`. The current mailbox is authenticated by its Address JWT |
| Send permission and balance | Permission and balance records in `address_sender` are managed independently **per email address**; user roles configured by `NO_LIMIT_SEND_ROLE` can bypass address balance checks |
Multiple email addresses bound to the same user account therefore do not share send permission or balance. To request permission for an address:
1. Switch to the email address that needs to send mail
1. Switch to the mailbox that needs to send mail
2. Open the **Send Mail** page
3. Click **Request Access**
@@ -4,31 +4,31 @@
> You need to configure `ADMIN_PASSWORDS` or `ADMIN_USER_ROLE` to access the admin console
> Admin role configuration: if the user role equals ADMIN_USER_ROLE, they can access the admin console
After deploying the frontend application, click the upper-left logo 5 times or visit the `/admin` path to enter the management console.
After deploying the frontend application, click the upper-left logo 5 times or visit the `/admin` path to enter the Admin Console.
You need to configure `ADMIN_PASSWORDS` in the backend or ensure the current user role is `ADMIN_USER_ROLE`, otherwise access to the console will be denied.
## Admin Passwords vs User Accounts
`ADMIN_PASSWORDS` is the management password for the Admin console. It is not a site user account
and does not correspond to any mailbox address. Logging in with an admin password grants access to
`ADMIN_PASSWORDS` is the password for the Admin Console. It is not a site user account
and does not correspond to any mailbox. Logging in with an admin password grants access to
the console, but that login itself cannot receive mail.
Site user accounts are stored in the `users` table and use the user login flow. Whether a user can
receive mail depends on whether they created or bound a mailbox address. Creating a normal user
whose email looks like `admin@example.com` does not automatically grant admin permissions.
receive mail depends on whether they created or bound a mailbox. Creating a normal user
whose account email is `admin@example.com` does not automatically grant admin permissions.
If you want a user account to access the Admin console, configure `ADMIN_USER_ROLE` and assign the
same role to that user in user management.
![admin](/feature/admin.png)
## Account List Sorting
## Mailbox List Sorting
The Accounts tab in the admin console supports column sorting. Click the column header to toggle ascending/descending order for:
**Admin Console → Mailbox Management → Mailboxes** supports column sorting. Click a column header to toggle ascending/descending order for:
- ID
- Name
- Email Address
- Created At
- Updated At
- Mail Count
@@ -150,19 +150,20 @@ cd worker
wrangler secret put SMTP_CONFIG
```
## 用户账号、邮箱地址与发信权限
## 用户账号、邮箱、邮箱地址与发信权限
三个概念相互关联,但不是同一个对象:
概念相互关联,但不是同一个对象:
| 概念 | 说明 |
|------|------|
| 用户账号 | 用于登录用户中心,可绑定和管理多个邮箱地址;用户账号的登录邮箱本身不等于用于收发信的邮箱地址 |
| 邮箱地址 | 实际收信和发信的身份,例如 `name@example.com`;前端首页当前选中的地址由该地址的凭证(Address JWT)认证 |
| 用户账号 | 用于登录用户中心,可绑定和管理多个邮箱;用户账号的用户邮箱本身不等于用于收发信的邮箱地址 |
| 邮箱 | 包含收件箱、发件箱、发信能力和邮箱设置的业务对象 |
| 邮箱地址 | 标识邮箱的具体值,例如 `name@example.com`;当前邮箱由该地址的 Address JWT 认证 |
| 发信权限与额度 | `address_sender` 中的权限和额度以**邮箱地址**为单位独立管理;`NO_LIMIT_SEND_ROLE` 配置的用户角色可以绕过地址额度检查 |
因此,同一用户账号绑定的多个邮箱地址不会共享发信权限或余额。为某个地址申请发信权限时:
1. 先在前端切换到需要发信的邮箱地址
1. 先在前端切换到需要发信的邮箱
2. 打开「发送邮件」页
3. 点击「申请权限」
@@ -175,7 +176,7 @@ wrangler secret put SMTP_CONFIG
1. **自动初始化默认额度**:当 `DEFAULT_SEND_BALANCE > 0` 时,用户打开前端发信页或第一次调用发信接口时,系统会自动为该地址初始化默认额度
2. **手动申请**:如果 `DEFAULT_SEND_BALANCE = 0`,使用者可以在前端切换到目标邮箱地址并点击「申请权限」,为当前地址创建待管理员处理的发信权限记录
3. **无限制发送**:以下方式可以跳过余额检查:
- admin 后台将地址加入「无限制发送地址列表」
-管理后台将邮箱地址加入「无限制发送地址列表」
- 配置 `NO_LIMIT_SEND_ROLE` 环境变量,指定可以无限发送的用户角色
> [!NOTE]
@@ -193,4 +194,4 @@ wrangler secret put SMTP_CONFIG
适合未完成 Email Routing onboarding 的域名,或 Workers 免费版。
只有收件人在 admin 后台的 `已验证地址列表` 中时,才会通过 `SEND_MAIL` binding 发信。
只有收件人在管理后台的 `已验证地址列表` 中时,才会通过 `SEND_MAIL` binding 发信。
+13 -13
View File
@@ -1,29 +1,29 @@
# Admin 控制
# 管理后
> [!NOTE]
> 需要配置 `ADMIN_PASSWORDS` 或者 `ADMIN_USER_ROLE` 才可以访问 admin 控制
> admin 角色配置, 如果用户角色等于 ADMIN_USER_ROLE 则可以访问 admin 控制
> 需要配置 `ADMIN_PASSWORDS` 或者 `ADMIN_USER_ROLE` 才可以访问管理后
> 管理员角色配置如果用户角色等于 `ADMIN_USER_ROLE`则可以访问管理后
部署前端应用之后,点击 左上角 logo 5 次 或者访问 `/admin` 路径即可进入管理控制台。
部署前端应用之后,点击左上角 logo 5 次访问 `/admin` 路径即可进入管理台。
需要在后端配置 `ADMIN_PASSWORDS` 或者当前用户角色为 `ADMIN_USER_ROLE`,否则不允许访问控制台。
需要在后端配置 `ADMIN_PASSWORDS` 或者当前用户角色为 `ADMIN_USER_ROLE`,否则不允许访问管理后台。
## 管理口令和用户账号的区别
## 管理员密码和用户账号的区别
`ADMIN_PASSWORDS` Admin 控制台的管理口令,不是站点用户账号,也不对应某个邮箱地址。使用管理口令登录后可以进入后台,但它本身不能收信。
`ADMIN_PASSWORDS`管理后台的管理员密码,不是站点用户账号,也不对应某个邮箱地址。使用管理员密码登录后可以进入后台,但它本身不能收信。
站点用户账号存储在 `users` 表中,需要通过用户登录体系进入;用户是否能收信取决于是否创建或绑定了邮箱地址。即使你创建了一个邮箱为 `admin@example.com` 或用户名看起来像 `admin` 的普通用户,它也不会自动获得后台权限。
站点用户账号存储在 `users` 表中,需要通过用户登录体系进入;用户是否能收信取决于是否创建或绑定了邮箱。即使你创建了一个用户邮箱为 `admin@example.com` 或用户名看起来像 `admin` 的普通用户,它也不会自动获得后台权限。
如果希望某个用户也能进入 Admin 控制台,请配置 `ADMIN_USER_ROLE`,并在用户管理中给该用户设置相同的角色。
如果希望某个用户也能进入管理后台,请配置 `ADMIN_USER_ROLE`,并在用户管理中给该用户设置相同的角色。
![admin](/feature/admin.png)
## 账号列表排序
## 邮箱列表排序
管理后台的账号标签页支持按列排序,可点击表头对以下列进行升序/降序排列:
管理后台的「邮箱管理 → 邮箱列表」支持按列排序,可点击表头进行升序/降序排列:
- ID
- 名称
- 邮箱地址
- 创建时间
- 更新时间
- 邮件数量
@@ -37,7 +37,7 @@
## IP 黑名单 / 白名单
Admin 控制台 → **IP 黑名单设置** 页面可配置访问控制,作用于以下接口:创建邮箱地址、发送邮件、外部发送邮件 API、用户注册、验证码校验。
管理后台的 **IP 黑名单设置** 页面可配置访问控制,作用于以下接口:创建邮箱地址、发送邮件、外部发送邮件 API、用户注册、验证码校验。
### IP 白名单(严格模式)