🐛 fix(desktop): add auth required modal and improve error handling (#11574)

* 🐛 fix(desktop): add auth required modal and improve error handling

- Add AuthRequiredModal component to handle authentication expiration
- Improve backend proxy protocol error handling for auth errors
- Add updater manager authentication header support
- Add i18n strings for auth error messages

* 🔧 fix(desktop): update UpdaterManager to leave channel unset for GitHub prerelease matching

- Modify UpdaterManager to leave the channel unset, allowing GitHub to use version tags for prerelease matching.
- Update logging to reflect the new behavior when the channel is unset or kept as is.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix(desktop): clarify UpdaterManager behavior for GitHub provider

- Update comments and logging in UpdaterManager to clarify that the channel is left unset for beta/nightly, allowing GitHub to use version tags for prerelease matching.
- Ensure logging accurately reflects the new behavior when the channel is unset.

Signed-off-by: Innei <tukon479@gmail.com>

*  feat(desktop): add desktop build channel script and update documentation

- Introduced a new script for building desktop applications for specific release channels (stable, beta, nightly).
- Updated package.json to include a new npm command for the build channel.
- Enhanced README documentation to guide users on simulating CI channel builds and retaining changes.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix(desktop): streamline NODE_ENV usage in logger and config

- Removed redundant process.env.NODE_ENV definition from electron.vite.config.ts.
- Simplified logger implementation by directly using process.env.NODE_ENV for environment checks.
- Improved readability and maintainability of logging behavior based on the environment.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix(desktop): enhance logging configuration to support debug mode

- Updated logger configuration to allow for debug level logging when DEBUG environment variable is set.
- Simplified the logic for console logging levels based on the environment, improving clarity and maintainability.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix(desktop): enhance version generation and logging in UpdaterManager

- Updated version generation logic in manual-build-desktop.yml to handle channel suffixes more effectively.
- Added inferredChannel logging in UpdaterManager to improve clarity on the current update channel being used.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix(desktop): update localization files and set default entry locale to English

- Changed default entry locale from Chinese (zh-CN) to English (en) in .i18nrc.js.
- Added full disk access messages in multiple languages (Arabic, Bulgarian, German, Spanish, French, Italian, Japanese, Korean, Dutch, Polish, Portuguese, Russian, Turkish, Vietnamese, Traditional Chinese).
- Enhanced menu localization with new settings and permissions options across various languages.

Signed-off-by: Innei <tukon479@gmail.com>

---------

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2026-01-18 18:55:18 +08:00
committed by GitHub
parent dd4cbcce7a
commit 4e5a516865
51 changed files with 864 additions and 45 deletions

View File

@@ -73,7 +73,17 @@ jobs:
echo "📦 Using provided version: ${version} (base: ${base_version})"
else
ci_build_number="${{ github.run_number }}"
version="0.0.0-${CHANNEL}.manual.${ci_build_number}"
if [ "$CHANNEL" = "beta" ]; then
channel_suffix="next"
else
channel_suffix="$CHANNEL"
fi
if [[ "$base_version" == *"-${channel_suffix}"* ]]; then
version="${base_version}.manual.${ci_build_number}"
else
version="${base_version}-${channel_suffix}.manual.${ci_build_number}"
fi
echo "📦 Generated version: ${version} (base: ${base_version})"
fi

View File

@@ -1,14 +1,14 @@
const { defineConfig } = require('@lobehub/i18n-cli');
module.exports = defineConfig({
entry: 'resources/locales/zh-CN',
entryLocale: 'zh-CN',
entry: 'resources/locales/en',
entryLocale: 'en',
output: 'resources/locales',
outputLocales: [
'ar',
'bg-BG',
'zh-TW',
'en',
'zh-CN',
'ru-RU',
'ja-JP',
'ko-KR',

View File

@@ -22,9 +22,7 @@ export default defineConfig({
sourcemap: isDev ? 'inline' : false,
},
define: {
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.UPDATE_CHANNEL': JSON.stringify(process.env.UPDATE_CHANNEL),
'process.env.UPDATE_SERVER_URL': JSON.stringify(process.env.UPDATE_SERVER_URL),
},

View File

@@ -11,6 +11,10 @@
"error.detail": "حدث خطأ أثناء العملية، يرجى المحاولة لاحقًا",
"error.message": "حدث خطأ",
"error.title": "خطأ",
"fullDiskAccess.message": "يحتاج LobeHub إلى الوصول الكامل إلى القرص لقراءة الملفات وتمكين ميزات قاعدة المعرفة. يرجى منح الوصول في إعدادات النظام.",
"fullDiskAccess.openSettings": "افتح الإعدادات",
"fullDiskAccess.skip": "لاحقًا",
"fullDiskAccess.title": "مطلوب الوصول الكامل إلى القرص",
"update.downloadAndInstall": "تنزيل وتثبيت",
"update.downloadComplete": "اكتمل التنزيل",
"update.downloadCompleteMessage": "تم تنزيل حزمة التحديث، هل ترغب في التثبيت الآن؟",
@@ -20,4 +24,4 @@
"update.newVersion": "تم اكتشاف إصدار جديد",
"update.newVersionAvailable": "تم اكتشاف إصدار جديد: {{version}}",
"update.skipThisVersion": "تخطي هذا الإصدار"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "لوحة المطور",
"dev.devTools": "أدوات المطور",
"dev.forceReload": "إعادة تحميل قسري",
"dev.openSettingsFile": "فتح ملف الإعدادات",
"dev.openStore": "فتح ملف التخزين",
"dev.openUpdaterCacheDir": "فتح ذاكرة التخزين المؤقت للمحدث",
"dev.openUserDataDir": "فتح بيانات المستخدم",
"dev.permissions.accessibility.request": "طلب إذن الوصول",
"dev.permissions.fullDisk.open": "فتح إعدادات الوصول الكامل إلى القرص",
"dev.permissions.fullDisk.request": "طلب إذن الوصول الكامل إلى القرص",
"dev.permissions.microphone.request": "طلب إذن الميكروفون",
"dev.permissions.notification.request": "طلب إذن الإشعارات",
"dev.permissions.screen.request": "طلب إذن تسجيل الشاشة",
"dev.permissions.title": "الأذونات",
"dev.refreshMenu": "تحديث القائمة",
"dev.reload": "إعادة تحميل",
"dev.simulateAutoDownload": "محاكاة التنزيل التلقائي (3 ثوانٍ)",
"dev.simulateDownloadComplete": "محاكاة اكتمال التنزيل",
"dev.simulateDownloadProgress": "محاكاة تقدم التنزيل",
"dev.title": "تطوير",
"dev.updaterSimulation": "محاكاة المحدث",
"edit.copy": "نسخ",
"edit.cut": "قص",
"edit.delete": "حذف",
@@ -23,6 +37,8 @@
"file.title": "ملف",
"help.about": "حول",
"help.githubRepo": "مستودع GitHub",
"help.openConfigDir": "فتح دليل الإعدادات",
"help.openLogsDir": "فتح دليل السجلات",
"help.reportIssue": "الإبلاغ عن مشكلة",
"help.title": "مساعدة",
"help.visitWebsite": "زيارة الموقع الرسمي",

View File

@@ -11,6 +11,10 @@
"error.detail": "Възникна грешка по време на операцията, моля опитайте отново по-късно",
"error.message": "Възникна грешка",
"error.title": "Грешка",
"fullDiskAccess.message": "LobeHub се нуждае от пълен достъп до диска, за да чете файлове и да активира функциите на базата знания. Моля, предоставете достъп в Системните настройки.",
"fullDiskAccess.openSettings": "Отвори настройки",
"fullDiskAccess.skip": "По-късно",
"fullDiskAccess.title": "Изисква се пълен достъп до диска",
"update.downloadAndInstall": "Изтегли и инсталирай",
"update.downloadComplete": "Изтеглянето е завършено",
"update.downloadCompleteMessage": "Актуализационният пакет е изтеглен, желаете ли да го инсталирате веднага?",
@@ -20,4 +24,4 @@
"update.newVersion": "Открита нова версия",
"update.newVersionAvailable": "Открита нова версия: {{version}}",
"update.skipThisVersion": "Пропусни тази версия"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Панел на разработчика",
"dev.devTools": "Инструменти за разработчици",
"dev.forceReload": "Принудително презареждане",
"dev.openSettingsFile": "Отвори файл с настройки",
"dev.openStore": "Отворете файла за съхранение",
"dev.openUpdaterCacheDir": "Отвори кеш на актуализации",
"dev.openUserDataDir": "Отвори потребителски данни",
"dev.permissions.accessibility.request": "Заяви разрешение за достъпност",
"dev.permissions.fullDisk.open": "Отвори настройки за пълен достъп до диска",
"dev.permissions.fullDisk.request": "Заяви разрешение за пълен достъп до диска",
"dev.permissions.microphone.request": "Заяви разрешение за микрофон",
"dev.permissions.notification.request": "Заяви разрешение за известия",
"dev.permissions.screen.request": "Заяви разрешение за запис на екрана",
"dev.permissions.title": "Разрешения",
"dev.refreshMenu": "Освежаване на менюто",
"dev.reload": "Презареждане",
"dev.simulateAutoDownload": "Симулирай автоматично изтегляне (3с)",
"dev.simulateDownloadComplete": "Симулирай завършване на изтегляне",
"dev.simulateDownloadProgress": "Симулирай напредък на изтегляне",
"dev.title": "Разработка",
"dev.updaterSimulation": "Симулация на актуализатор",
"edit.copy": "Копиране",
"edit.cut": "Изрязване",
"edit.delete": "Изтрий",
@@ -23,6 +37,8 @@
"file.title": "Файл",
"help.about": "За",
"help.githubRepo": "GitHub хранилище",
"help.openConfigDir": "Отвори директория с конфигурации",
"help.openLogsDir": "Отвори директория с логове",
"help.reportIssue": "Докладвай проблем",
"help.title": "Помощ",
"help.visitWebsite": "Посети уебсайта",

View File

@@ -11,6 +11,10 @@
"error.detail": "Während der Operation ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut",
"error.message": "Ein Fehler ist aufgetreten",
"error.title": "Fehler",
"fullDiskAccess.message": "LobeHub benötigt vollen Festplattenzugriff, um Dateien zu lesen und Funktionen der Wissensdatenbank zu aktivieren. Bitte gewähren Sie den Zugriff in den Systemeinstellungen.",
"fullDiskAccess.openSettings": "Einstellungen öffnen",
"fullDiskAccess.skip": "Später",
"fullDiskAccess.title": "Voller Festplattenzugriff erforderlich",
"update.downloadAndInstall": "Herunterladen und installieren",
"update.downloadComplete": "Download abgeschlossen",
"update.downloadCompleteMessage": "Das Update-Paket wurde heruntergeladen, möchten Sie es jetzt installieren?",
@@ -20,4 +24,4 @@
"update.newVersion": "Neue Version gefunden",
"update.newVersionAvailable": "Neue Version verfügbar: {{version}}",
"update.skipThisVersion": "Diese Version überspringen"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Entwicklerpanel",
"dev.devTools": "Entwicklerwerkzeuge",
"dev.forceReload": "Erzwinge Neuladen",
"dev.openSettingsFile": "Einstellungsdatei öffnen",
"dev.openStore": "Speicherdatei öffnen",
"dev.openUpdaterCacheDir": "Updater-Cache öffnen",
"dev.openUserDataDir": "Benutzerdaten öffnen",
"dev.permissions.accessibility.request": "Zugriffsberechtigung anfordern",
"dev.permissions.fullDisk.open": "Einstellungen für vollen Festplattenzugriff öffnen",
"dev.permissions.fullDisk.request": "Berechtigung für vollen Festplattenzugriff anfordern",
"dev.permissions.microphone.request": "Mikrofonberechtigung anfordern",
"dev.permissions.notification.request": "Benachrichtigungsberechtigung anfordern",
"dev.permissions.screen.request": "Bildschirmaufnahmeberechtigung anfordern",
"dev.permissions.title": "Berechtigungen",
"dev.refreshMenu": "Menü aktualisieren",
"dev.reload": "Neuladen",
"dev.simulateAutoDownload": "Automatischen Download simulieren (3s)",
"dev.simulateDownloadComplete": "Download abgeschlossen simulieren",
"dev.simulateDownloadProgress": "Downloadfortschritt simulieren",
"dev.title": "Entwicklung",
"dev.updaterSimulation": "Updater-Simulation",
"edit.copy": "Kopieren",
"edit.cut": "Ausschneiden",
"edit.delete": "Löschen",
@@ -23,6 +37,8 @@
"file.title": "Datei",
"help.about": "Über",
"help.githubRepo": "GitHub-Repository",
"help.openConfigDir": "Konfigurationsverzeichnis öffnen",
"help.openLogsDir": "Protokollverzeichnis öffnen",
"help.reportIssue": "Problem melden",
"help.title": "Hilfe",
"help.visitWebsite": "Besuche die Website",

View File

@@ -0,0 +1,26 @@
{
"actions.add": "Add",
"actions.back": "Back",
"actions.cancel": "Cancel",
"actions.close": "Close",
"actions.confirm": "Confirm",
"actions.delete": "Delete",
"actions.edit": "Edit",
"actions.more": "More",
"actions.next": "Next",
"actions.ok": "OK",
"actions.previous": "Previous",
"actions.refresh": "Refresh",
"actions.remove": "Remove",
"actions.retry": "Retry",
"actions.save": "Save",
"actions.search": "Search",
"actions.submit": "Submit",
"app.description": "Where Agents Collaborate",
"app.name": "LobeHub",
"status.error": "Error",
"status.info": "Information",
"status.loading": "Loading",
"status.success": "Success",
"status.warning": "Warning"
}

View File

@@ -0,0 +1,27 @@
{
"about.button": "OK",
"about.detail": "An LLM-powered chat app",
"about.message": "{{appName}} {{appVersion}}",
"about.title": "About",
"confirm.cancel": "Cancel",
"confirm.no": "Cancel",
"confirm.title": "Please confirm",
"confirm.yes": "Continue",
"error.button": "OK",
"error.detail": "Couldn't complete the action. Retry or try again later.",
"error.message": "An error occurred",
"error.title": "Error",
"fullDiskAccess.message": "LobeHub needs Full Disk Access to read files and enable knowledge base features. Please grant access in System Settings.",
"fullDiskAccess.openSettings": "Open Settings",
"fullDiskAccess.skip": "Later",
"fullDiskAccess.title": "Full Disk Access Required",
"update.downloadAndInstall": "Download and Install",
"update.downloadComplete": "Download Complete",
"update.downloadCompleteMessage": "Update downloaded. Install now?",
"update.installLater": "Install Later",
"update.installNow": "Install Now",
"update.later": "Remind Me Later",
"update.newVersion": "New Version Found",
"update.newVersionAvailable": "New version: {{version}}",
"update.skipThisVersion": "Skip This Version"
}

View File

@@ -0,0 +1,73 @@
{
"common.checkUpdates": "Check for updates...",
"dev.devPanel": "Developer Panel",
"dev.devTools": "Developer Tools",
"dev.forceReload": "Force Reload",
"dev.openSettingsFile": "Open Settings File",
"dev.openStore": "Open Data Folder",
"dev.openUpdaterCacheDir": "Open Updater Cache",
"dev.openUserDataDir": "Open User Data",
"dev.permissions.accessibility.request": "Request Accessibility Permission",
"dev.permissions.fullDisk.open": "Open Full Disk Access Settings",
"dev.permissions.fullDisk.request": "Request Full Disk Access Permission",
"dev.permissions.microphone.request": "Request Microphone Permission",
"dev.permissions.notification.request": "Request Notification Permission",
"dev.permissions.screen.request": "Request Screen Recording Permission",
"dev.permissions.title": "Permissions",
"dev.refreshMenu": "Refresh Menu",
"dev.reload": "Reload",
"dev.simulateAutoDownload": "Simulate Auto Download (3s)",
"dev.simulateDownloadComplete": "Simulate Download Complete",
"dev.simulateDownloadProgress": "Simulate Download Progress",
"dev.title": "Development",
"dev.updaterSimulation": "Updater Simulation",
"edit.copy": "Copy",
"edit.cut": "Cut",
"edit.delete": "Delete",
"edit.paste": "Paste",
"edit.redo": "Redo",
"edit.selectAll": "Select All",
"edit.speech": "Speech",
"edit.startSpeaking": "Start Speaking",
"edit.stopSpeaking": "Stop Speaking",
"edit.title": "Edit",
"edit.undo": "Undo",
"file.preferences": "Preferences",
"file.quit": "Quit",
"file.title": "File",
"help.about": "About",
"help.githubRepo": "GitHub Repository",
"help.openConfigDir": "Open Config Directory",
"help.openLogsDir": "Open Logs Directory",
"help.reportIssue": "Send Feedback",
"help.title": "Help",
"help.visitWebsite": "Open Website",
"history.back": "Back",
"history.forward": "Forward",
"history.home": "Home",
"history.title": "Go",
"macOS.about": "About {{appName}}",
"macOS.devTools": "LobeHub Developer Tools",
"macOS.hide": "Hide {{appName}}",
"macOS.hideOthers": "Hide Others",
"macOS.preferences": "Preferences...",
"macOS.services": "Services",
"macOS.unhide": "Show All",
"tray.open": "Open {{appName}}",
"tray.quit": "Quit",
"tray.show": "Show {{appName}}",
"view.forceReload": "Force Reload",
"view.reload": "Reload",
"view.resetZoom": "Reset Zoom",
"view.title": "View",
"view.toggleFullscreen": "Toggle Fullscreen",
"view.zoomIn": "Zoom In",
"view.zoomOut": "Zoom Out",
"window.bringAllToFront": "Bring All Windows to Front",
"window.close": "Close",
"window.front": "Bring All Windows to Front",
"window.minimize": "Minimize",
"window.title": "Window",
"window.toggleFullscreen": "Toggle Fullscreen",
"window.zoom": "Zoom"
}

View File

@@ -11,6 +11,10 @@
"error.detail": "Se produjo un error durante la operación, por favor intente de nuevo más tarde",
"error.message": "Se produjo un error",
"error.title": "Error",
"fullDiskAccess.message": "LobeHub necesita acceso completo al disco para leer archivos y habilitar las funciones de la base de conocimientos. Por favor, concede acceso en la Configuración del Sistema.",
"fullDiskAccess.openSettings": "Abrir Configuración",
"fullDiskAccess.skip": "Más tarde",
"fullDiskAccess.title": "Se requiere acceso completo al disco",
"update.downloadAndInstall": "Descargar e instalar",
"update.downloadComplete": "Descarga completada",
"update.downloadCompleteMessage": "El paquete de actualización se ha descargado, ¿desea instalarlo ahora?",
@@ -20,4 +24,4 @@
"update.newVersion": "Nueva versión disponible",
"update.newVersionAvailable": "Nueva versión encontrada: {{version}}",
"update.skipThisVersion": "Saltar esta versión"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Panel de desarrollador",
"dev.devTools": "Herramientas de desarrollador",
"dev.forceReload": "Recargar forzosamente",
"dev.openSettingsFile": "Abrir archivo de configuración",
"dev.openStore": "Abrir archivo de almacenamiento",
"dev.openUpdaterCacheDir": "Abrir caché del actualizador",
"dev.openUserDataDir": "Abrir datos de usuario",
"dev.permissions.accessibility.request": "Solicitar permiso de accesibilidad",
"dev.permissions.fullDisk.open": "Abrir configuración de acceso completo al disco",
"dev.permissions.fullDisk.request": "Solicitar permiso de acceso completo al disco",
"dev.permissions.microphone.request": "Solicitar permiso de micrófono",
"dev.permissions.notification.request": "Solicitar permiso de notificaciones",
"dev.permissions.screen.request": "Solicitar permiso para grabar pantalla",
"dev.permissions.title": "Permisos",
"dev.refreshMenu": "Actualizar menú",
"dev.reload": "Recargar",
"dev.simulateAutoDownload": "Simular descarga automática (3s)",
"dev.simulateDownloadComplete": "Simular descarga completada",
"dev.simulateDownloadProgress": "Simular progreso de descarga",
"dev.title": "Desarrollo",
"dev.updaterSimulation": "Simulación del actualizador",
"edit.copy": "Copiar",
"edit.cut": "Cortar",
"edit.delete": "Eliminar",
@@ -23,6 +37,8 @@
"file.title": "Archivo",
"help.about": "Acerca de",
"help.githubRepo": "Repositorio de GitHub",
"help.openConfigDir": "Abrir directorio de configuración",
"help.openLogsDir": "Abrir directorio de registros",
"help.reportIssue": "Reportar un problema",
"help.title": "Ayuda",
"help.visitWebsite": "Visitar el sitio web",

View File

@@ -11,6 +11,10 @@
"error.detail": "در حین انجام عملیات خطایی رخ داده است، لطفاً بعداً دوباره تلاش کنید",
"error.message": "خطا رخ داده است",
"error.title": "خطا",
"fullDiskAccess.message": "LobeHub برای خواندن فایل‌ها و فعال‌سازی ویژگی‌های پایگاه دانش به دسترسی کامل به دیسک نیاز دارد. لطفاً در تنظیمات سیستم دسترسی را اعطا کنید.",
"fullDiskAccess.openSettings": "باز کردن تنظیمات",
"fullDiskAccess.skip": "بعداً",
"fullDiskAccess.title": "دسترسی کامل به دیسک مورد نیاز است",
"update.downloadAndInstall": "دانلود و نصب",
"update.downloadComplete": "دانلود کامل شد",
"update.downloadCompleteMessage": "بسته به‌روزرسانی دانلود شده است، آیا می‌خواهید بلافاصله نصب کنید؟",
@@ -20,4 +24,4 @@
"update.newVersion": "نسخه جدیدی پیدا شد",
"update.newVersionAvailable": "نسخه جدید پیدا شد: {{version}}",
"update.skipThisVersion": "این نسخه را نادیده بگیرید"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "پنل توسعه‌دهنده",
"dev.devTools": "ابزارهای توسعه‌دهنده",
"dev.forceReload": "بارگذاری اجباری",
"dev.openSettingsFile": "باز کردن فایل تنظیمات",
"dev.openStore": "باز کردن فایل‌های ذخیره شده",
"dev.openUpdaterCacheDir": "باز کردن کش به‌روزرسان",
"dev.openUserDataDir": "باز کردن داده‌های کاربر",
"dev.permissions.accessibility.request": "درخواست دسترسی به قابلیت‌های دسترسی",
"dev.permissions.fullDisk.open": "باز کردن تنظیمات دسترسی کامل به دیسک",
"dev.permissions.fullDisk.request": "درخواست دسترسی کامل به دیسک",
"dev.permissions.microphone.request": "درخواست دسترسی به میکروفون",
"dev.permissions.notification.request": "درخواست دسترسی به اعلان‌ها",
"dev.permissions.screen.request": "درخواست دسترسی به ضبط صفحه",
"dev.permissions.title": "مجوزها",
"dev.refreshMenu": "به‌روزرسانی منو",
"dev.reload": "بارگذاری مجدد",
"dev.simulateAutoDownload": "شبیه‌سازی دانلود خودکار (۳ ثانیه)",
"dev.simulateDownloadComplete": "شبیه‌سازی اتمام دانلود",
"dev.simulateDownloadProgress": "شبیه‌سازی پیشرفت دانلود",
"dev.title": "توسعه",
"dev.updaterSimulation": "شبیه‌سازی به‌روزرسان",
"edit.copy": "کپی",
"edit.cut": "برش",
"edit.delete": "حذف",
@@ -23,6 +37,8 @@
"file.title": "فایل",
"help.about": "درباره",
"help.githubRepo": "مخزن GitHub",
"help.openConfigDir": "باز کردن پوشه تنظیمات",
"help.openLogsDir": "باز کردن پوشه گزارش‌ها",
"help.reportIssue": "گزارش مشکل",
"help.title": "کمک",
"help.visitWebsite": "بازدید از وب‌سایت",

View File

@@ -11,6 +11,10 @@
"error.detail": "Une erreur s'est produite lors de l'opération, veuillez réessayer plus tard",
"error.message": "Une erreur s'est produite",
"error.title": "Erreur",
"fullDiskAccess.message": "LobeHub nécessite un accès complet au disque pour lire les fichiers et activer les fonctionnalités de la base de connaissances. Veuillez accorder l'accès dans les paramètres système.",
"fullDiskAccess.openSettings": "Ouvrir les paramètres",
"fullDiskAccess.skip": "Plus tard",
"fullDiskAccess.title": "Accès complet au disque requis",
"update.downloadAndInstall": "Télécharger et installer",
"update.downloadComplete": "Téléchargement terminé",
"update.downloadCompleteMessage": "Le paquet de mise à jour a été téléchargé, souhaitez-vous l'installer maintenant ?",
@@ -20,4 +24,4 @@
"update.newVersion": "Nouvelle version détectée",
"update.newVersionAvailable": "Nouvelle version disponible : {{version}}",
"update.skipThisVersion": "Ignorer cette version"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Panneau de développement",
"dev.devTools": "Outils de développement",
"dev.forceReload": "Recharger de force",
"dev.openSettingsFile": "Ouvrir le fichier de configuration",
"dev.openStore": "Ouvrir le fichier de stockage",
"dev.openUpdaterCacheDir": "Ouvrir le cache de mise à jour",
"dev.openUserDataDir": "Ouvrir les données utilisateur",
"dev.permissions.accessibility.request": "Demander l'autorisation d'accessibilité",
"dev.permissions.fullDisk.open": "Ouvrir les paramètres d'accès complet au disque",
"dev.permissions.fullDisk.request": "Demander l'autorisation d'accès complet au disque",
"dev.permissions.microphone.request": "Demander l'autorisation du microphone",
"dev.permissions.notification.request": "Demander l'autorisation de notification",
"dev.permissions.screen.request": "Demander l'autorisation d'enregistrement d'écran",
"dev.permissions.title": "Autorisations",
"dev.refreshMenu": "Rafraîchir le menu",
"dev.reload": "Recharger",
"dev.simulateAutoDownload": "Simuler le téléchargement automatique (3s)",
"dev.simulateDownloadComplete": "Simuler le téléchargement terminé",
"dev.simulateDownloadProgress": "Simuler la progression du téléchargement",
"dev.title": "Développement",
"dev.updaterSimulation": "Simulation de mise à jour",
"edit.copy": "Copier",
"edit.cut": "Couper",
"edit.delete": "Supprimer",
@@ -23,6 +37,8 @@
"file.title": "Fichier",
"help.about": "À propos",
"help.githubRepo": "Dépôt GitHub",
"help.openConfigDir": "Ouvrir le répertoire de configuration",
"help.openLogsDir": "Ouvrir le répertoire des journaux",
"help.reportIssue": "Signaler un problème",
"help.title": "Aide",
"help.visitWebsite": "Visiter le site officiel",

View File

@@ -11,6 +11,10 @@
"error.detail": "Si è verificato un errore durante l'operazione, riprovare più tardi",
"error.message": "Si è verificato un errore",
"error.title": "Errore",
"fullDiskAccess.message": "LobeHub necessita dell'accesso completo al disco per leggere i file e abilitare le funzionalità della base di conoscenza. Si prega di concedere l'accesso nelle Impostazioni di Sistema.",
"fullDiskAccess.openSettings": "Apri Impostazioni",
"fullDiskAccess.skip": "Più tardi",
"fullDiskAccess.title": "Accesso Completo al Disco Richiesto",
"update.downloadAndInstall": "Scarica e installa",
"update.downloadComplete": "Download completato",
"update.downloadCompleteMessage": "Il pacchetto di aggiornamento è stato scaricato, vuoi installarlo subito?",
@@ -20,4 +24,4 @@
"update.newVersion": "Nuova versione disponibile",
"update.newVersionAvailable": "Nuova versione trovata: {{version}}",
"update.skipThisVersion": "Salta questa versione"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Pannello sviluppatore",
"dev.devTools": "Strumenti per sviluppatori",
"dev.forceReload": "Ricarica forzata",
"dev.openSettingsFile": "Apri file impostazioni",
"dev.openStore": "Apri il file di archiviazione",
"dev.openUpdaterCacheDir": "Apri cache aggiornamenti",
"dev.openUserDataDir": "Apri dati utente",
"dev.permissions.accessibility.request": "Richiedi permesso di accessibilità",
"dev.permissions.fullDisk.open": "Apri impostazioni accesso completo al disco",
"dev.permissions.fullDisk.request": "Richiedi permesso di accesso completo al disco",
"dev.permissions.microphone.request": "Richiedi permesso microfono",
"dev.permissions.notification.request": "Richiedi permesso notifiche",
"dev.permissions.screen.request": "Richiedi permesso registrazione schermo",
"dev.permissions.title": "Permessi",
"dev.refreshMenu": "Aggiorna menu",
"dev.reload": "Ricarica",
"dev.simulateAutoDownload": "Simula download automatico (3s)",
"dev.simulateDownloadComplete": "Simula completamento download",
"dev.simulateDownloadProgress": "Simula progresso download",
"dev.title": "Sviluppo",
"dev.updaterSimulation": "Simulazione aggiornamento",
"edit.copy": "Copia",
"edit.cut": "Taglia",
"edit.delete": "Elimina",
@@ -23,6 +37,8 @@
"file.title": "File",
"help.about": "Informazioni",
"help.githubRepo": "Repository GitHub",
"help.openConfigDir": "Apri directory configurazione",
"help.openLogsDir": "Apri directory log",
"help.reportIssue": "Segnala un problema",
"help.title": "Aiuto",
"help.visitWebsite": "Visita il sito ufficiale",

View File

@@ -11,6 +11,10 @@
"error.detail": "操作中にエラーが発生しました。後で再試行してください。",
"error.message": "エラーが発生しました",
"error.title": "エラー",
"fullDiskAccess.message": "LobeHubはファイルを読み取り、ナレッジベース機能を有効にするためにフルディスクアクセスが必要です。システム設定でアクセスを許可してください。",
"fullDiskAccess.openSettings": "設定を開く",
"fullDiskAccess.skip": "後で",
"fullDiskAccess.title": "フルディスクアクセスが必要です",
"update.downloadAndInstall": "ダウンロードしてインストール",
"update.downloadComplete": "ダウンロード完了",
"update.downloadCompleteMessage": "更新パッケージのダウンロードが完了しました。今すぐインストールしますか?",
@@ -20,4 +24,4 @@
"update.newVersion": "新しいバージョンが見つかりました",
"update.newVersionAvailable": "新しいバージョンが見つかりました: {{version}}",
"update.skipThisVersion": "このバージョンをスキップ"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "開発者パネル",
"dev.devTools": "開発者ツール",
"dev.forceReload": "強制再読み込み",
"dev.openSettingsFile": "設定ファイルを開く",
"dev.openStore": "ストレージファイルを開く",
"dev.openUpdaterCacheDir": "アップデーターキャッシュを開く",
"dev.openUserDataDir": "ユーザーデータを開く",
"dev.permissions.accessibility.request": "アクセシビリティ権限をリクエスト",
"dev.permissions.fullDisk.open": "フルディスクアクセス設定を開く",
"dev.permissions.fullDisk.request": "フルディスクアクセス権限をリクエスト",
"dev.permissions.microphone.request": "マイク権限をリクエスト",
"dev.permissions.notification.request": "通知権限をリクエスト",
"dev.permissions.screen.request": "画面録画権限をリクエスト",
"dev.permissions.title": "権限",
"dev.refreshMenu": "メニューを更新",
"dev.reload": "再読み込み",
"dev.simulateAutoDownload": "自動ダウンロードをシミュレート3秒",
"dev.simulateDownloadComplete": "ダウンロード完了をシミュレート",
"dev.simulateDownloadProgress": "ダウンロード進行をシミュレート",
"dev.title": "開発",
"dev.updaterSimulation": "アップデーターシミュレーション",
"edit.copy": "コピー",
"edit.cut": "切り取り",
"edit.delete": "削除",
@@ -23,6 +37,8 @@
"file.title": "ファイル",
"help.about": "について",
"help.githubRepo": "GitHub リポジトリ",
"help.openConfigDir": "設定ディレクトリを開く",
"help.openLogsDir": "ログディレクトリを開く",
"help.reportIssue": "問題を報告",
"help.title": "ヘルプ",
"help.visitWebsite": "公式ウェブサイトを訪問",

View File

@@ -11,6 +11,10 @@
"error.detail": "작업 중 오류가 발생했습니다. 나중에 다시 시도해 주세요.",
"error.message": "오류 발생",
"error.title": "오류",
"fullDiskAccess.message": "LobeHub는 파일을 읽고 지식 기반 기능을 활성화하기 위해 전체 디스크 접근 권한이 필요합니다. 시스템 설정에서 접근 권한을 부여해 주세요.",
"fullDiskAccess.openSettings": "설정 열기",
"fullDiskAccess.skip": "나중에",
"fullDiskAccess.title": "전체 디스크 접근 권한 필요",
"update.downloadAndInstall": "다운로드 및 설치",
"update.downloadComplete": "다운로드 완료",
"update.downloadCompleteMessage": "업데이트 패키지가 다운로드 완료되었습니다. 지금 설치하시겠습니까?",
@@ -20,4 +24,4 @@
"update.newVersion": "새 버전 발견",
"update.newVersionAvailable": "새 버전 발견: {{version}}",
"update.skipThisVersion": "이 버전 건너뛰기"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "개발자 패널",
"dev.devTools": "개발자 도구",
"dev.forceReload": "강제 새로 고침",
"dev.openSettingsFile": "설정 파일 열기",
"dev.openStore": "저장 파일 열기",
"dev.openUpdaterCacheDir": "업데이터 캐시 열기",
"dev.openUserDataDir": "사용자 데이터 열기",
"dev.permissions.accessibility.request": "접근성 권한 요청",
"dev.permissions.fullDisk.open": "전체 디스크 접근 설정 열기",
"dev.permissions.fullDisk.request": "전체 디스크 접근 권한 요청",
"dev.permissions.microphone.request": "마이크 권한 요청",
"dev.permissions.notification.request": "알림 권한 요청",
"dev.permissions.screen.request": "화면 녹화 권한 요청",
"dev.permissions.title": "권한",
"dev.refreshMenu": "메뉴 새로 고침",
"dev.reload": "새로 고침",
"dev.simulateAutoDownload": "자동 다운로드 시뮬레이션 (3초)",
"dev.simulateDownloadComplete": "다운로드 완료 시뮬레이션",
"dev.simulateDownloadProgress": "다운로드 진행 시뮬레이션",
"dev.title": "개발",
"dev.updaterSimulation": "업데이터 시뮬레이션",
"edit.copy": "복사",
"edit.cut": "잘라내기",
"edit.delete": "삭제",
@@ -23,6 +37,8 @@
"file.title": "파일",
"help.about": "정보",
"help.githubRepo": "GitHub 저장소",
"help.openConfigDir": "설정 디렉터리 열기",
"help.openLogsDir": "로그 디렉터리 열기",
"help.reportIssue": "문제 보고",
"help.title": "도움말",
"help.visitWebsite": "웹사이트 방문",

View File

@@ -11,6 +11,10 @@
"error.detail": "Er is een fout opgetreden tijdens de operatie, probeer het later opnieuw",
"error.message": "Er is een fout opgetreden",
"error.title": "Fout",
"fullDiskAccess.message": "LobeHub heeft volledige schijf toegang nodig om bestanden te lezen en functies van de kennisbank mogelijk te maken. Geef toegang via de Systeeminstellingen.",
"fullDiskAccess.openSettings": "Instellingen openen",
"fullDiskAccess.skip": "Later",
"fullDiskAccess.title": "Volledige schijf toegang vereist",
"update.downloadAndInstall": "Downloaden en installeren",
"update.downloadComplete": "Download voltooid",
"update.downloadCompleteMessage": "Het updatepakket is gedownload, wilt u het nu installeren?",
@@ -20,4 +24,4 @@
"update.newVersion": "Nieuwe versie gevonden",
"update.newVersionAvailable": "Nieuwe versie beschikbaar: {{version}}",
"update.skipThisVersion": "Deze versie overslaan"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Ontwikkelaarspaneel",
"dev.devTools": "Ontwikkelaarstools",
"dev.forceReload": "Forceer herladen",
"dev.openSettingsFile": "Instellingenbestand openen",
"dev.openStore": "Open opslagbestand",
"dev.openUpdaterCacheDir": "Updater-cache openen",
"dev.openUserDataDir": "Gebruikersgegevens openen",
"dev.permissions.accessibility.request": "Toegankelijkheidsmachtiging aanvragen",
"dev.permissions.fullDisk.open": "Instellingen voor volledige schijf toegang openen",
"dev.permissions.fullDisk.request": "Machtiging voor volledige schijf toegang aanvragen",
"dev.permissions.microphone.request": "Microfoonmachtiging aanvragen",
"dev.permissions.notification.request": "Machtiging voor meldingen aanvragen",
"dev.permissions.screen.request": "Machtiging voor schermopname aanvragen",
"dev.permissions.title": "Machtigingen",
"dev.refreshMenu": "Menu verversen",
"dev.reload": "Herladen",
"dev.simulateAutoDownload": "Automatisch downloaden simuleren (3s)",
"dev.simulateDownloadComplete": "Download voltooid simuleren",
"dev.simulateDownloadProgress": "Downloadvoortgang simuleren",
"dev.title": "Ontwikkeling",
"dev.updaterSimulation": "Updater-simulatie",
"edit.copy": "Kopiëren",
"edit.cut": "Knippen",
"edit.delete": "Verwijderen",
@@ -23,6 +37,8 @@
"file.title": "Bestand",
"help.about": "Over",
"help.githubRepo": "GitHub-repo",
"help.openConfigDir": "Configuratiemap openen",
"help.openLogsDir": "Logmap openen",
"help.reportIssue": "Probleem melden",
"help.title": "Hulp",
"help.visitWebsite": "Bezoek de website",

View File

@@ -11,6 +11,10 @@
"error.detail": "Wystąpił błąd podczas operacji, spróbuj ponownie później",
"error.message": "Wystąpił błąd",
"error.title": "Błąd",
"fullDiskAccess.message": "LobeHub wymaga pełnego dostępu do dysku, aby odczytywać pliki i umożliwić funkcje bazy wiedzy. Proszę przyznać dostęp w ustawieniach systemowych.",
"fullDiskAccess.openSettings": "Otwórz ustawienia",
"fullDiskAccess.skip": "Później",
"fullDiskAccess.title": "Wymagany pełny dostęp do dysku",
"update.downloadAndInstall": "Pobierz i zainstaluj",
"update.downloadComplete": "Pobieranie zakończone",
"update.downloadCompleteMessage": "Pakiet aktualizacji został pobrany, czy chcesz go teraz zainstalować?",
@@ -20,4 +24,4 @@
"update.newVersion": "Nowa wersja dostępna",
"update.newVersionAvailable": "Znaleziono nową wersję: {{version}}",
"update.skipThisVersion": "Pomiń tę wersję"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Panel dewelopera",
"dev.devTools": "Narzędzia dewelopera",
"dev.forceReload": "Wymuś ponowne załadowanie",
"dev.openSettingsFile": "Otwórz plik ustawień",
"dev.openStore": "Otwórz plik magazynu",
"dev.openUpdaterCacheDir": "Otwórz pamięć podręczną aktualizatora",
"dev.openUserDataDir": "Otwórz dane użytkownika",
"dev.permissions.accessibility.request": "Poproś o uprawnienia dostępu",
"dev.permissions.fullDisk.open": "Otwórz ustawienia pełnego dostępu do dysku",
"dev.permissions.fullDisk.request": "Poproś o pełny dostęp do dysku",
"dev.permissions.microphone.request": "Poproś o dostęp do mikrofonu",
"dev.permissions.notification.request": "Poproś o pozwolenie na powiadomienia",
"dev.permissions.screen.request": "Poproś o pozwolenie na nagrywanie ekranu",
"dev.permissions.title": "Uprawnienia",
"dev.refreshMenu": "Odśwież menu",
"dev.reload": "Przeładuj",
"dev.simulateAutoDownload": "Symuluj automatyczne pobieranie (3s)",
"dev.simulateDownloadComplete": "Symuluj zakończenie pobierania",
"dev.simulateDownloadProgress": "Symuluj postęp pobierania",
"dev.title": "Rozwój",
"dev.updaterSimulation": "Symulacja aktualizatora",
"edit.copy": "Kopiuj",
"edit.cut": "Wytnij",
"edit.delete": "Usuń",
@@ -23,6 +37,8 @@
"file.title": "Plik",
"help.about": "O",
"help.githubRepo": "Repozytorium GitHub",
"help.openConfigDir": "Otwórz katalog konfiguracji",
"help.openLogsDir": "Otwórz katalog logów",
"help.reportIssue": "Zgłoś problem",
"help.title": "Pomoc",
"help.visitWebsite": "Odwiedź stronę internetową",

View File

@@ -11,6 +11,10 @@
"error.detail": "Ocorreu um erro durante a operação, por favor tente novamente mais tarde",
"error.message": "Ocorreu um erro",
"error.title": "Erro",
"fullDiskAccess.message": "O LobeHub precisa de Acesso Completo ao Disco para ler arquivos e ativar os recursos da base de conhecimento. Por favor, conceda acesso nas Configurações do Sistema.",
"fullDiskAccess.openSettings": "Abrir Configurações",
"fullDiskAccess.skip": "Depois",
"fullDiskAccess.title": "Acesso Completo ao Disco Necessário",
"update.downloadAndInstall": "Baixar e instalar",
"update.downloadComplete": "Download completo",
"update.downloadCompleteMessage": "O pacote de atualização foi baixado com sucesso, deseja instalá-lo agora?",
@@ -20,4 +24,4 @@
"update.newVersion": "Nova versão disponível",
"update.newVersionAvailable": "Nova versão encontrada: {{version}}",
"update.skipThisVersion": "Ignorar esta versão"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Painel do Desenvolvedor",
"dev.devTools": "Ferramentas do Desenvolvedor",
"dev.forceReload": "Recarregar Forçadamente",
"dev.openSettingsFile": "Abrir arquivo de configurações",
"dev.openStore": "Abrir arquivo de armazenamento",
"dev.openUpdaterCacheDir": "Abrir cache do atualizador",
"dev.openUserDataDir": "Abrir dados do usuário",
"dev.permissions.accessibility.request": "Solicitar permissão de acessibilidade",
"dev.permissions.fullDisk.open": "Abrir configurações de acesso total ao disco",
"dev.permissions.fullDisk.request": "Solicitar permissão de acesso total ao disco",
"dev.permissions.microphone.request": "Solicitar permissão para microfone",
"dev.permissions.notification.request": "Solicitar permissão para notificações",
"dev.permissions.screen.request": "Solicitar permissão para gravação de tela",
"dev.permissions.title": "Permissões",
"dev.refreshMenu": "Atualizar menu",
"dev.reload": "Recarregar",
"dev.simulateAutoDownload": "Simular download automático (3s)",
"dev.simulateDownloadComplete": "Simular download concluído",
"dev.simulateDownloadProgress": "Simular progresso do download",
"dev.title": "Desenvolvimento",
"dev.updaterSimulation": "Simulação do atualizador",
"edit.copy": "Copiar",
"edit.cut": "Cortar",
"edit.delete": "Excluir",
@@ -23,6 +37,8 @@
"file.title": "Arquivo",
"help.about": "Sobre",
"help.githubRepo": "Repositório do GitHub",
"help.openConfigDir": "Abrir diretório de configuração",
"help.openLogsDir": "Abrir diretório de logs",
"help.reportIssue": "Reportar Problema",
"help.title": "Ajuda",
"help.visitWebsite": "Visitar o Site",

View File

@@ -11,6 +11,10 @@
"error.detail": "Произошла ошибка во время операции, пожалуйста, попробуйте позже",
"error.message": "Произошла ошибка",
"error.title": "Ошибка",
"fullDiskAccess.message": "LobeHub требует полный доступ к диску для чтения файлов и активации функций базы знаний. Пожалуйста, предоставьте доступ в системных настройках.",
"fullDiskAccess.openSettings": "Открыть настройки",
"fullDiskAccess.skip": "Позже",
"fullDiskAccess.title": "Требуется полный доступ к диску",
"update.downloadAndInstall": "Скачать и установить",
"update.downloadComplete": "Скачивание завершено",
"update.downloadCompleteMessage": "Обновление загружено, хотите установить сейчас?",
@@ -20,4 +24,4 @@
"update.newVersion": "Обнаружена новая версия",
"update.newVersionAvailable": "Обнаружена новая версия: {{version}}",
"update.skipThisVersion": "Пропустить эту версию"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Панель разработчика",
"dev.devTools": "Инструменты разработчика",
"dev.forceReload": "Принудительная перезагрузка",
"dev.openSettingsFile": "Открыть файл настроек",
"dev.openStore": "Открыть файл хранилища",
"dev.openUpdaterCacheDir": "Открыть кэш обновлений",
"dev.openUserDataDir": "Открыть данные пользователя",
"dev.permissions.accessibility.request": "Запросить разрешение на доступность",
"dev.permissions.fullDisk.open": "Открыть настройки полного доступа к диску",
"dev.permissions.fullDisk.request": "Запросить разрешение на полный доступ к диску",
"dev.permissions.microphone.request": "Запросить разрешение на использование микрофона",
"dev.permissions.notification.request": "Запросить разрешение на уведомления",
"dev.permissions.screen.request": "Запросить разрешение на запись экрана",
"dev.permissions.title": "Разрешения",
"dev.refreshMenu": "Обновить меню",
"dev.reload": "Перезагрузить",
"dev.simulateAutoDownload": "Симуляция автозагрузки (3 с)",
"dev.simulateDownloadComplete": "Симуляция завершения загрузки",
"dev.simulateDownloadProgress": "Симуляция прогресса загрузки",
"dev.title": "Разработка",
"dev.updaterSimulation": "Симуляция обновления",
"edit.copy": "Копировать",
"edit.cut": "Вырезать",
"edit.delete": "Удалить",
@@ -23,6 +37,8 @@
"file.title": "Файл",
"help.about": "О программе",
"help.githubRepo": "Репозиторий GitHub",
"help.openConfigDir": "Открыть каталог конфигурации",
"help.openLogsDir": "Открыть каталог журналов",
"help.reportIssue": "Сообщить о проблеме",
"help.title": "Помощь",
"help.visitWebsite": "Посетить сайт",

View File

@@ -11,6 +11,10 @@
"error.detail": "İşlem sırasında bir hata oluştu, lütfen daha sonra tekrar deneyin",
"error.message": "Hata oluştu",
"error.title": "Hata",
"fullDiskAccess.message": "LobeHub, dosyaları okuyabilmek ve bilgi tabanı özelliklerini etkinleştirebilmek için Tam Disk Erişimi gerektirir. Lütfen Sistem Ayarları'ndan erişim izni verin.",
"fullDiskAccess.openSettings": "Ayarları Aç",
"fullDiskAccess.skip": "Daha Sonra",
"fullDiskAccess.title": "Tam Disk Erişimi Gerekiyor",
"update.downloadAndInstall": "İndir ve Yükle",
"update.downloadComplete": "İndirme tamamlandı",
"update.downloadCompleteMessage": "Güncelleme paketi indirildi, hemen yüklemek ister misiniz?",
@@ -20,4 +24,4 @@
"update.newVersion": "Yeni sürüm bulundu",
"update.newVersionAvailable": "Yeni sürüm bulundu: {{version}}",
"update.skipThisVersion": "Bu sürümü atla"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Geliştirici Paneli",
"dev.devTools": "Geliştirici Araçları",
"dev.forceReload": "Zorla Yenile",
"dev.openSettingsFile": "Ayarlar Dosyasını Aç",
"dev.openStore": "Depolama dosyasını aç",
"dev.openUpdaterCacheDir": "Güncelleyici Önbelleğini Aç",
"dev.openUserDataDir": "Kullanıcı Verilerini Aç",
"dev.permissions.accessibility.request": "Erişilebilirlik İzni İste",
"dev.permissions.fullDisk.open": "Tam Disk Erişimi Ayarlarını Aç",
"dev.permissions.fullDisk.request": "Tam Disk Erişimi İzni İste",
"dev.permissions.microphone.request": "Mikrofon İzni İste",
"dev.permissions.notification.request": "Bildirim İzni İste",
"dev.permissions.screen.request": "Ekran Kaydı İzni İste",
"dev.permissions.title": "İzinler",
"dev.refreshMenu": "Menüyü yenile",
"dev.reload": "Yenile",
"dev.simulateAutoDownload": "Otomatik İndirmeyi Simüle Et (3s)",
"dev.simulateDownloadComplete": "İndirme Tamamlanmasını Simüle Et",
"dev.simulateDownloadProgress": "İndirme İlerlemesini Simüle Et",
"dev.title": "Geliştir",
"dev.updaterSimulation": "Güncelleyici Simülasyonu",
"edit.copy": "Kopyala",
"edit.cut": "Kes",
"edit.delete": "Sil",
@@ -23,6 +37,8 @@
"file.title": "Dosya",
"help.about": "Hakkında",
"help.githubRepo": "GitHub Deposu",
"help.openConfigDir": "Yapılandırma Dizini Aç",
"help.openLogsDir": "Kayıtlar Dizini Aç",
"help.reportIssue": "Sorun Bildir",
"help.title": "Yardım",
"help.visitWebsite": "Resmi Web Sitesini Ziyaret Et",

View File

@@ -11,6 +11,10 @@
"error.detail": "Đã xảy ra lỗi trong quá trình thực hiện, vui lòng thử lại sau",
"error.message": "Đã xảy ra lỗi",
"error.title": "Lỗi",
"fullDiskAccess.message": "LobeHub cần quyền truy cập toàn bộ đĩa để đọc tệp và kích hoạt các tính năng cơ sở tri thức. Vui lòng cấp quyền truy cập trong Cài đặt Hệ thống.",
"fullDiskAccess.openSettings": "Mở Cài đặt",
"fullDiskAccess.skip": "Để sau",
"fullDiskAccess.title": "Yêu cầu quyền truy cập toàn bộ đĩa",
"update.downloadAndInstall": "Tải xuống và cài đặt",
"update.downloadComplete": "Tải xuống hoàn tất",
"update.downloadCompleteMessage": "Gói cập nhật đã tải xuống hoàn tất, có muốn cài đặt ngay không?",
@@ -20,4 +24,4 @@
"update.newVersion": "Phát hiện phiên bản mới",
"update.newVersionAvailable": "Phát hiện phiên bản mới: {{version}}",
"update.skipThisVersion": "Bỏ qua phiên bản này"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "Bảng điều khiển nhà phát triển",
"dev.devTools": "Công cụ phát triển",
"dev.forceReload": "Tải lại cưỡng bức",
"dev.openSettingsFile": "Mở Tệp Cài Đặt",
"dev.openStore": "Mở tệp lưu trữ",
"dev.openUpdaterCacheDir": "Mở Bộ Nhớ Đệm Cập Nhật",
"dev.openUserDataDir": "Mở Thư Mục Dữ Liệu Người Dùng",
"dev.permissions.accessibility.request": "Yêu Cầu Quyền Truy Cập Trợ Năng",
"dev.permissions.fullDisk.open": "Mở Cài Đặt Truy Cập Ổ Đĩa Toàn Bộ",
"dev.permissions.fullDisk.request": "Yêu Cầu Quyền Truy Cập Ổ Đĩa Toàn Bộ",
"dev.permissions.microphone.request": "Yêu Cầu Quyền Sử Dụng Micro",
"dev.permissions.notification.request": "Yêu Cầu Quyền Thông Báo",
"dev.permissions.screen.request": "Yêu Cầu Quyền Ghi Màn Hình",
"dev.permissions.title": "Quyền Truy Cập",
"dev.refreshMenu": "Làm mới menu",
"dev.reload": "Tải lại",
"dev.simulateAutoDownload": "Mô Phỏng Tải Tự Động (3 giây)",
"dev.simulateDownloadComplete": "Mô Phỏng Hoàn Thành Tải",
"dev.simulateDownloadProgress": "Mô Phỏng Tiến Trình Tải",
"dev.title": "Phát triển",
"dev.updaterSimulation": "Mô Phỏng Trình Cập Nhật",
"edit.copy": "Sao chép",
"edit.cut": "Cắt",
"edit.delete": "Xóa",
@@ -23,6 +37,8 @@
"file.title": "Tập tin",
"help.about": "Về",
"help.githubRepo": "Kho lưu trữ GitHub",
"help.openConfigDir": "Mở Thư Mục Cấu Hình",
"help.openLogsDir": "Mở Thư Mục Nhật Ký",
"help.reportIssue": "Báo cáo sự cố",
"help.title": "Trợ giúp",
"help.visitWebsite": "Truy cập trang web",

View File

@@ -11,6 +11,10 @@
"error.detail": "操作過程中發生錯誤,請稍後重試",
"error.message": "發生錯誤",
"error.title": "錯誤",
"fullDiskAccess.message": "LobeHub 需要完整磁碟存取權限以讀取檔案並啟用知識庫功能。請在系統設定中授予存取權限。",
"fullDiskAccess.openSettings": "開啟設定",
"fullDiskAccess.skip": "稍後",
"fullDiskAccess.title": "需要完整磁碟存取權限",
"update.downloadAndInstall": "下載並安裝",
"update.downloadComplete": "下載完成",
"update.downloadCompleteMessage": "更新包已下載完成,是否立即安裝?",
@@ -20,4 +24,4 @@
"update.newVersion": "發現新版本",
"update.newVersionAvailable": "發現新版本: {{version}}",
"update.skipThisVersion": "跳過此版本"
}
}

View File

@@ -3,10 +3,24 @@
"dev.devPanel": "開發者面板",
"dev.devTools": "開發者工具",
"dev.forceReload": "強制重新載入",
"dev.openSettingsFile": "開啟設定檔案",
"dev.openStore": "打開儲存檔案",
"dev.openUpdaterCacheDir": "開啟更新快取資料夾",
"dev.openUserDataDir": "開啟使用者資料夾",
"dev.permissions.accessibility.request": "請求輔助功能權限",
"dev.permissions.fullDisk.open": "開啟完整磁碟存取設定",
"dev.permissions.fullDisk.request": "請求完整磁碟存取權限",
"dev.permissions.microphone.request": "請求麥克風權限",
"dev.permissions.notification.request": "請求通知權限",
"dev.permissions.screen.request": "請求螢幕錄製權限",
"dev.permissions.title": "權限",
"dev.refreshMenu": "刷新選單",
"dev.reload": "重新載入",
"dev.simulateAutoDownload": "模擬自動下載3秒",
"dev.simulateDownloadComplete": "模擬下載完成",
"dev.simulateDownloadProgress": "模擬下載進度",
"dev.title": "開發",
"dev.updaterSimulation": "更新模擬",
"edit.copy": "複製",
"edit.cut": "剪下",
"edit.delete": "刪除",
@@ -23,6 +37,8 @@
"file.title": "檔案",
"help.about": "關於",
"help.githubRepo": "GitHub 倉庫",
"help.openConfigDir": "開啟設定目錄",
"help.openLogsDir": "開啟日誌目錄",
"help.reportIssue": "報告問題",
"help.title": "幫助",
"help.visitWebsite": "訪問網站",

View File

@@ -45,6 +45,21 @@ bun run build
bun run build-local
```
如果需要模拟 CI 的渠道构建Nightly / Beta / Stable可以使用根目录脚本
```bash
# 回到仓库根目录
cd ../../..
# 指定渠道与版本号
npm run desktop:build-channel -- nightly 2.1.0-nightly.1
npm run desktop:build-channel -- beta 2.1.0-beta.1
npm run desktop:build-channel -- stable 2.1.0
# 保留 package.json 与 icon 变更
npm run desktop:build-channel -- stable 2.1.0 --keep-changes
```
### 3. 生成更新文件
```bash

View File

@@ -163,13 +163,14 @@ export class BackendProxyProtocolManager {
responseHeaders.set('Access-Control-Allow-Headers', '*');
responseHeaders.set('X-Src-Url', rewrittenUrl);
// Handle 401 Unauthorized: notify authorization required regardless of token presence
// This covers cases where:
// 1. No token exists
// 2. Token has expired
// 3. Token has been revoked server-side
// Handle 401 Unauthorized: only notify authorization required for real auth failures
// The server sets X-Auth-Required header for real authentication failures (e.g., token expired)
// Other 401 errors (e.g., invalid API keys) should not trigger re-authentication
if (upstreamResponse.status === 401) {
this.notifyAuthorizationRequired();
const authRequired = upstreamResponse.headers.get('X-Auth-Required') === 'true';
if (authRequired) {
this.notifyAuthorizationRequired();
}
}
return new Response(upstreamResponse.body, {

View File

@@ -113,6 +113,26 @@ export class UpdaterManager {
logger.info(`${manual ? 'Manually checking' : 'Auto checking'} for updates...`);
// Log detailed updater configuration for debugging
const inferredChannel =
autoUpdater.channel ||
(autoUpdater.currentVersion?.prerelease?.[0]
? String(autoUpdater.currentVersion.prerelease[0])
: null);
logger.info('[Updater Config] Channel:', autoUpdater.channel);
logger.info('[Updater Config] inferredChannel:', inferredChannel);
logger.info('[Updater Config] allowPrerelease:', autoUpdater.allowPrerelease);
logger.info('[Updater Config] currentVersion:', autoUpdater.currentVersion?.version);
logger.info('[Updater Config] allowDowngrade:', autoUpdater.allowDowngrade);
logger.info('[Updater Config] autoDownload:', autoUpdater.autoDownload);
logger.info('[Updater Config] forceDevUpdateConfig:', autoUpdater.forceDevUpdateConfig);
logger.info('[Updater Config] Build channel from config:', channel);
logger.info('[Updater Config] isStableChannel:', isStableChannel);
logger.info('[Updater Config] UPDATE_SERVER_URL:', UPDATE_SERVER_URL || '(not set)');
logger.info('[Updater Config] usingFallbackProvider:', this.usingFallbackProvider);
logger.info('[Updater Config] GitHub config:', JSON.stringify(githubConfig));
// If manual check, notify renderer process about check start
if (manual) {
this.mainWindow.broadcast('manualUpdateCheckStart');
@@ -322,7 +342,7 @@ export class UpdaterManager {
/**
* Configure update provider based on channel
* - Stable channel + UPDATE_SERVER_URL: Use generic HTTP provider (S3) as primary, channel=stable
* - Other channels (beta/nightly) or no S3: Use GitHub provider, channel=latest
* - Other channels (beta/nightly) or no S3: Use GitHub provider, channel unset (defaults to latest)
*
* Important: S3 has stable-mac.yml, GitHub has latest-mac.yml
*/
@@ -340,12 +360,15 @@ export class UpdaterManager {
url: UPDATE_SERVER_URL,
});
} else {
// Beta/nightly channels use GitHub, or fallback to GitHub if UPDATE_SERVER_URL not configured
// GitHub releases have latest-mac.yml, so we use default channel (latest)
autoUpdater.channel = 'latest';
// GitHub provider:
// - stable: use default latest-mac.yml (GitHub uploads latest* only)
// - beta/nightly: leave channel unset so prerelease matching uses tag (e.g. next)
const reason = this.usingFallbackProvider ? '(fallback from S3)' : '';
logger.info(`Configuring GitHub provider for ${channel} channel ${reason}`);
logger.info(`Channel set to: latest (will look for latest-mac.yml)`);
if (autoUpdater.channel !== null) {
autoUpdater.channel = null;
}
logger.info('Channel left unset (defaults to latest-mac.yml for GitHub)');
// For beta/nightly channels, we need prerelease versions
const needPrerelease = channel !== 'stable';
@@ -406,6 +429,8 @@ export class UpdaterManager {
autoUpdater.on('checking-for-update', () => {
logger.info('[Updater] Checking for update...');
logger.info('[Updater] Current channel:', autoUpdater.channel);
logger.info('[Updater] Current allowPrerelease:', autoUpdater.allowPrerelease);
});
autoUpdater.on('update-available', (info) => {
@@ -437,6 +462,14 @@ export class UpdaterManager {
autoUpdater.on('error', async (err) => {
logger.error('Error in auto-updater:', err);
// Log configuration state when error occurs for debugging
logger.error('[Updater Error Context] Channel:', autoUpdater.channel);
logger.error('[Updater Error Context] allowPrerelease:', autoUpdater.allowPrerelease);
logger.error('[Updater Error Context] Build channel from config:', channel);
logger.error('[Updater Error Context] isStableChannel:', isStableChannel);
logger.error('[Updater Error Context] UPDATE_SERVER_URL:', UPDATE_SERVER_URL || '(not set)');
logger.error('[Updater Error Context] usingFallbackProvider:', this.usingFallbackProvider);
logger.error('[Updater Error Context] GitHub config:', JSON.stringify(githubConfig));
// Try fallback to GitHub if S3 failed
if (!this.usingFallbackProvider && isStableChannel && UPDATE_SERVER_URL) {

View File

@@ -7,8 +7,8 @@ import { getDesktopEnv } from '@/env';
electronLog.transports.file.level = 'info'; // Log info level and above in production
electronLog.transports.console.level =
getDesktopEnv().NODE_ENV === 'development'
? 'debug' // Show more logs in development
: 'warn'; // Only show warnings and errors in production
? 'debug' // 开发环境显示更多日志
: 'info'; // 生产环境显示 info 及以上级别
// Create namespaced debugger
export const createLogger = (namespace: string) => {

View File

@@ -28,6 +28,11 @@
"apikey.list.columns.status": "Enabled Status",
"apikey.list.title": "API Key List",
"apikey.validation.required": "This field cannot be empty",
"authModal.description": "Your login session has expired. Please sign in again to continue using cloud sync features.",
"authModal.later": "Later",
"authModal.signIn": "Sign In Again",
"authModal.signingIn": "Signing in...",
"authModal.title": "Session Expired",
"betterAuth.errors.confirmPasswordRequired": "Please confirm your password",
"betterAuth.errors.emailExists": "This email is already registered. Please sign in instead",
"betterAuth.errors.emailInvalid": "Please enter a valid email address or username",

View File

@@ -28,6 +28,11 @@
"apikey.list.columns.status": "启用状态",
"apikey.list.title": "API Key 列表",
"apikey.validation.required": "内容不得为空",
"authModal.description": "您的登录会话已过期,请重新登录以继续使用云同步功能。",
"authModal.later": "稍后",
"authModal.signIn": "重新登录",
"authModal.signingIn": "登录中...",
"authModal.title": "登录已过期",
"betterAuth.errors.confirmPasswordRequired": "请确认密码",
"betterAuth.errors.emailExists": "该邮箱已注册,请直接登录",
"betterAuth.errors.emailInvalid": "请输入有效的邮箱地址或用户名",

View File

@@ -47,6 +47,7 @@
"db:studio": "drizzle-kit studio",
"db:visualize": "dbdocs build docs/development/database-schema.dbml --project lobe-chat",
"desktop:build": "npm run desktop:build-next && npm run desktop:prepare-dist && npm run desktop:build-electron",
"desktop:build-channel": "tsx scripts/electronWorkflow/buildDesktopChannel.ts",
"desktop:build-electron": "tsx scripts/electronWorkflow/buildElectron.ts",
"desktop:build-local": "npm run desktop:build-next && npm run desktop:prepare-dist && npm run build-local --prefix=./apps/desktop",
"desktop:build-next": "npm run build:electron",

View File

@@ -0,0 +1,135 @@
/* eslint-disable unicorn/no-process-exit */
import fs from 'fs-extra';
import { execSync } from 'node:child_process';
import path from 'node:path';
type ReleaseChannel = 'stable' | 'beta' | 'nightly';
const rootDir = path.resolve(__dirname, '../..');
const desktopDir = path.join(rootDir, 'apps/desktop');
const desktopPackageJsonPath = path.join(desktopDir, 'package.json');
const buildDir = path.join(desktopDir, 'build');
const iconTargets = ['icon.png', 'Icon.icns', 'icon.ico'];
const isFlag = (value: string) => value.startsWith('-');
const parseArgs = (args: string[]) => {
let channel = '';
let version = '';
let keepChanges = false;
for (let i = 0; i < args.length; i += 1) {
const arg = args[i];
if (arg === '--channel' || arg === '-c') {
channel = args[i + 1] ?? '';
i += 1;
continue;
}
if (arg === '--version' || arg === '-v') {
version = args[i + 1] ?? '';
i += 1;
continue;
}
if (arg === '--keep-changes') {
keepChanges = true;
continue;
}
if (!isFlag(arg)) {
if (!channel) {
channel = arg;
continue;
}
if (!version) {
version = arg;
}
}
}
return { channel, keepChanges, version };
};
const resolveDefaultVersion = () => {
const rootPackageJsonPath = path.join(rootDir, 'package.json');
const rootPackageJson = fs.readJsonSync(rootPackageJsonPath);
return rootPackageJson.version as string | undefined;
};
const backupFile = async (filePath: string) => {
try {
return await fs.readFile(filePath);
} catch {
return undefined;
}
};
const restoreFile = async (filePath: string, content?: Buffer) => {
if (!content) return;
await fs.writeFile(filePath, content);
};
const validateChannel = (channel: string): channel is ReleaseChannel =>
channel === 'stable' || channel === 'beta' || channel === 'nightly';
const runCommand = (command: string, env?: Record<string, string | undefined>) => {
execSync(command, {
cwd: rootDir,
env: { ...process.env, ...env },
stdio: 'inherit',
});
};
const main = async () => {
const { channel, version: rawVersion, keepChanges } = parseArgs(process.argv.slice(2));
if (!validateChannel(channel)) {
console.error(
'Missing or invalid channel. Usage: npm run desktop:build-channel -- <stable|beta|nightly> [version] [--keep-changes]',
);
process.exit(1);
}
const version = rawVersion || resolveDefaultVersion();
if (!version) {
console.error('Missing version. Provide it or ensure root package.json has a version.');
process.exit(1);
}
const packageJsonBackup = await backupFile(desktopPackageJsonPath);
const iconBackups = await Promise.all(
iconTargets.map(async (fileName) => ({
content: await backupFile(path.join(buildDir, fileName)),
fileName,
})),
);
console.log(`🚦 CI-style build channel: ${channel}`);
console.log(`🏷️ Desktop version: ${version}`);
console.log(`🧩 Keep local changes: ${keepChanges ? 'yes' : 'no'}`);
try {
runCommand(`npm run workflow:set-desktop-version ${version} ${channel}`);
runCommand('npm run desktop:build', { UPDATE_CHANNEL: channel });
} catch (error) {
console.error('❌ Build failed:', error);
process.exit(1);
} finally {
if (!keepChanges) {
await restoreFile(desktopPackageJsonPath, packageJsonBackup);
await Promise.all(
iconBackups.map(({ fileName, content }) =>
restoreFile(path.join(buildDir, fileName), content),
),
);
console.log('🧹 Restored local desktop package metadata and icons.');
}
}
};
main();

View File

@@ -12,6 +12,7 @@ import Loading from '@/components/Loading/BrandTextLoading';
import { isDesktop } from '@/const/version';
import { BANNER_HEIGHT } from '@/features/AlertBanner/CloudBanner';
import DesktopNavigationBridge from '@/features/DesktopNavigationBridge';
import AuthRequiredModal from '@/features/Electron/AuthRequiredModal';
import TitleBar from '@/features/Electron/titlebar/TitleBar';
import HotkeyHelperPanel from '@/features/HotkeyHelperPanel';
import NavPanel from '@/features/NavPanel';
@@ -45,6 +46,7 @@ const Layout: FC = () => {
{isDesktop && <TitleBar />}
{isDesktop && <DesktopAutoOidcOnFirstOpen />}
{isDesktop && <DesktopNavigationBridge />}
{isDesktop && <AuthRequiredModal />}
{showCloudPromotion && <CloudBanner />}
</Suspense>
<DndContextWrapper>

View File

@@ -4,8 +4,6 @@ import { useWatchBroadcast } from '@lobechat/electron-client-ipc';
import { memo, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { clearDesktopOnboardingCompleted } from '@/app/[variants]/(desktop)/desktop-onboarding/storage';
const DesktopNavigationBridge = memo(() => {
const navigate = useNavigate();
@@ -19,13 +17,6 @@ const DesktopNavigationBridge = memo(() => {
useWatchBroadcast('navigate', handleNavigate);
const handleAuthorizationRequired = useCallback(() => {
clearDesktopOnboardingCompleted();
navigate('/desktop-onboarding#5', { replace: true });
}, [navigate]);
useWatchBroadcast('authorizationRequired', handleAuthorizationRequired);
return null;
});

View File

@@ -0,0 +1,151 @@
'use client';
import { useWatchBroadcast } from '@lobechat/electron-client-ipc';
import { Button, Flexbox, Icon, type ModalInstance, createModal } from '@lobehub/ui';
import { AlertCircle, LogIn } from 'lucide-react';
import { type ReactNode, memo, useCallback, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useElectronStore } from '@/store/electron';
interface ModalUpdateOptions {
closable?: boolean;
keyboard?: boolean;
maskClosable?: boolean;
title?: ReactNode;
}
interface AuthRequiredModalContentProps {
onClose: () => void;
setModalProps: (props: ModalUpdateOptions) => void;
}
const AuthRequiredModalContent = memo<AuthRequiredModalContentProps>(
({ onClose, setModalProps }) => {
const { t } = useTranslation('auth');
const [isSigningIn, setIsSigningIn] = useState(false);
const isClosingRef = useRef(false);
const [dataSyncConfig, connectRemoteServer, refreshServerConfig, clearRemoteServerSyncError] =
useElectronStore((s) => [
s.dataSyncConfig,
s.connectRemoteServer,
s.refreshServerConfig,
s.clearRemoteServerSyncError,
]);
// Update modal props based on signing in state
setModalProps({
closable: !isSigningIn,
keyboard: !isSigningIn,
maskClosable: !isSigningIn,
title: (
<Flexbox align="center" gap={8} horizontal>
<Icon icon={AlertCircle} />
{t('authModal.title')}
</Flexbox>
),
});
// Listen for successful authorization to close the modal
useWatchBroadcast('authorizationSuccessful', async () => {
if (isClosingRef.current) return;
isClosingRef.current = true;
setIsSigningIn(false);
onClose();
await refreshServerConfig();
});
// Listen for authorization failure
useWatchBroadcast('authorizationFailed', () => {
setIsSigningIn(false);
});
const handleSignIn = useCallback(async () => {
setIsSigningIn(true);
clearRemoteServerSyncError();
await connectRemoteServer({
remoteServerUrl: dataSyncConfig?.remoteServerUrl,
storageMode: dataSyncConfig?.storageMode || 'cloud',
});
}, [clearRemoteServerSyncError, connectRemoteServer, dataSyncConfig]);
const handleLater = useCallback(() => {
if (isClosingRef.current) return;
isClosingRef.current = true;
onClose();
}, [onClose]);
return (
<Flexbox gap={16} style={{ padding: 16 }}>
<p style={{ margin: 0 }}>{t('authModal.description')}</p>
<Flexbox gap={8} horizontal justify="flex-end">
<Button disabled={isSigningIn} onClick={handleLater}>
{t('authModal.later')}
</Button>
<Button
icon={<Icon icon={LogIn} />}
loading={isSigningIn}
onClick={handleSignIn}
type="primary"
>
{isSigningIn ? t('authModal.signingIn') : t('authModal.signIn')}
</Button>
</Flexbox>
</Flexbox>
);
},
);
AuthRequiredModalContent.displayName = 'AuthRequiredModalContent';
/**
* Hook to create and manage the auth required modal
*/
export const useAuthRequiredModal = () => {
const instanceRef = useRef<ModalInstance | null>(null);
const open = useCallback(() => {
// Don't open multiple modals
if (instanceRef.current) return;
const setModalProps = (nextProps: ModalUpdateOptions) => {
instanceRef.current?.update?.(nextProps);
};
const handleClose = () => {
instanceRef.current?.close();
instanceRef.current = null;
};
instanceRef.current = createModal({
children: <AuthRequiredModalContent onClose={handleClose} setModalProps={setModalProps} />,
closable: false,
footer: null,
keyboard: false,
maskClosable: false,
title: '',
});
}, []);
return { open };
};
/**
* Component that listens for authorizationRequired IPC events and opens the modal
*/
const AuthRequiredModal = memo(() => {
const { open } = useAuthRequiredModal();
// Listen for IPC event to open the modal
useWatchBroadcast('authorizationRequired', () => {
open();
});
return null;
});
AuthRequiredModal.displayName = 'AuthRequiredModal';
export default AuthRequiredModal;

View File

@@ -28,6 +28,12 @@ export default {
'apikey.list.columns.status': 'Enabled Status',
'apikey.list.title': 'API Key List',
'apikey.validation.required': 'This field cannot be empty',
'authModal.description':
'Your login session has expired. Please sign in again to continue using cloud sync features.',
'authModal.later': 'Later',
'authModal.signIn': 'Sign In Again',
'authModal.signingIn': 'Signing in...',
'authModal.title': 'Session Expired',
'betterAuth.errors.confirmPasswordRequired': 'Please confirm your password',
'betterAuth.errors.emailExists': 'This email is already registered. Please sign in instead',
'betterAuth.errors.emailInvalid': 'Please enter a valid email address or username',

View File

@@ -1,6 +1,16 @@
import { AgentRuntimeErrorType, type ILobeAgentRuntimeErrorType } from '@lobechat/model-runtime';
import { ChatErrorType, type ErrorResponse, type ErrorType } from '@lobechat/types';
/**
* Error types that indicate a real authentication failure.
* When these errors occur, the response will include X-Auth-Required header
* to signal the client that re-authentication is needed.
*/
const AUTH_REQUIRED_ERROR_TYPES = new Set<ErrorType>([
ChatErrorType.Unauthorized,
ChatErrorType.InvalidClerkUser,
]);
const getStatus = (errorType: ILobeAgentRuntimeErrorType | ErrorType) => {
// InvalidAccessCode / InvalidAzureAPIKey / InvalidOpenAIAPIKey / InvalidZhipuAPIKey ....
if (errorType.toString().includes('Invalid')) return 401;
@@ -71,5 +81,15 @@ export const createErrorResponse = (
);
}
return new Response(JSON.stringify(data), { status: statusCode });
const headers: Record<string, string> = {
'Content-Type': 'application/json',
};
// Add X-Auth-Required header for real authentication failures
// This allows the client to distinguish between auth failures and other 401 errors (e.g., invalid API keys)
if (AUTH_REQUIRED_ERROR_TYPES.has(errorType as ErrorType)) {
headers['X-Auth-Required'] = 'true';
}
return new Response(JSON.stringify(data), { headers, status: statusCode });
};