mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 15:15:24 +00:00
* fix(sso): send the PKCE verifier for GitHub login (#1534) * fix(remote-desktop): clip cursor overflow without disabling zoom (#1535) * test(remote-desktop): preserve sessions beyond one hour (#1536) * fix(hosts): expose controls for overflowing editor tabs (#1537) * fix(hosts): expose controls for overflowing editor tabs * test(hosts): mock resize observation in admin panel tests * fix(status): skip TCP probes while host sessions are active (#1538) * fix(database): batch session activity persistence (#1539) * docs(api): describe cookie and API key authentication (#1540) * fix(snippets): repair missing note column on SQLite upgrades (#1541) * fix(docker): retain stored SSH credential association (#1543) * fix(file-manager): render transfer toasts without plugin hooks (#1546) * feat(hosts): keep compact row actions inline (#1547) * fix(auth): allow retrying unavailable second-factor interfaces (#1549) * fix(auth): reject unresolved legacy identity provisioning (#1550) * fix(desktop): ship the plugin SDK inside Mac App Store builds (#1551) * fix(tmux): pass full session info to the terminal's session picker (#1552) The tmux.sessions service reduced detected sessions to bare names, but the picker reads session.name, so every entry rendered blank and selecting one sent an empty name, which created a new session instead of attaching. * fix(ssh): read force keyboard-interactive as a boolean when resolving hosts (#1553) The column holds the text "true"/"false", and the resolver passed it through as-is. The string "false" is truthy, so the password provider treated every saved host as forced keyboard-interactive and left the password out. Jump hops are built straight from the resolved host, so a password hop whose server doesn't offer keyboard-interactive failed with "All configured authentication methods failed". * fix(database): batch database saves for bulk host writes (#1554) * fix(database): yield to the event loop between database saves Each SQLite save serializes and encrypts the whole database into new buffers, which V8 only releases once the event loop turns. Boot migrations and bulk host import write plugin settings per host and per key in an awaited loop, so hundreds of full copies piled up and the container ran out of memory. * fix(database): save once per bulk host write instead of once per row On SQLite every repository write force-saves the whole database. Boot plugin data migrations, host defaults materialization and the bulk host routes write one row per host per setting, so they serialized and encrypted the full database hundreds of times in a row. DatabaseSaveTrigger.batched wraps a function so force saves made while it runs collapse into a single save when it finishes. Nested scopes fold into the outer one, and work that outlives its scope saves normally. * feat(hosts): add instance-wide predefined tag suggestions (#1548) * feat(hosts): add shared predefined tag suggestions * style(hosts): format tag catalog routes * test(database): advance fake timers past the save yield (#1555) * fix(i18n): complete Simplified Chinese core and plugin translations (#1542) * fix(i18n): complete Chinese onboarding and navigation labels * fix(i18n): translate remaining Chinese core and plugin interfaces * fix(i18n): translate host editor tab overflow controls * fix(i18n): use consistent Chinese fleet terminology * fix(i18n): localize hardcoded controls and plugin views * fix(i18n): translate built-in homepage widget catalog * test(homepage): follow translated timezone placeholder * fix(i18n): translate plugin-provided homepage widgets * fix(i18n): localize feature settings section titles * fix: 2.8 oidc accounts unable to sign in after upgrading (#1381) * fix: plugins losing the saved ssh login when copying a host (#1391) * fix: fleets, proxmox and automations not getting the host sudo password * fix: host imports running a defaults pass and metrics restart per host (#1384) * fix: high cpu from status probes and full database saves on every sample (#1300) * fix: user data export freezing the server (#1393) * fix: op:// secret references rejected as ssh keys on credentials (#1394) * fix: slow file deletes from the trash lookups on every delete (#1390) * fix: add openapi docs and error handling to host tag routes * test: compare download stream buffers directly so it stops timing out * chore: drop em dash from host row comment * chore: update release notes for 2.9.1 * fix: restore space to add host tags and redesign predefined tags editor * fix: host key silently accepted when the host is missing from the database (#1397) * fix: clearer host login failed status label and fix its translations (#1396) * chore: add host key and status label fixes to release notes * fix: sso and ldap provider dialogs overflowing the screen and using mismatched toggles * chore: increment ver * fix(audit): store plugin entries with no acting user as a null user_id (#1556) Plugin audit entries written outside a request used the literal "system" as user_id. That column references users.id, so the insert was refused (Postgres logs it as an FK violation) and the entry was silently dropped. Write null instead and keep "system" / plugin:<id> in username. * chore: add sso/ldap dialog and audit log fixes to release notes * fix: tunnels and host settings missing from shared hosts on desktop * fix: remote desktop logins missing from shared hosts on desktop * fix: simplify host status to online/offline and keep it live without a refresh * chore: sync Crowdin translations for 2.9.1 --------- Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com>
190 lines
10 KiB
JSON
190 lines
10 KiB
JSON
{
|
|
"sessionSharing": {
|
|
"guestView": {
|
|
"loading": "Đang kết nối đến phiên chia sẻ...",
|
|
"linkInvalid": "Liên kết chia sẻ này không hợp lệ, đã hết hạn hoặc đã bị thu hồi.",
|
|
"rateLimited": "Đã thử quá nhiều lần, vui lòng thử lại sau.",
|
|
"sessionEnded": "Phiên này đã kết thúc",
|
|
"readOnlyBadge": "Chỉ xem",
|
|
"ownerLabel": "Chủ nhà"
|
|
},
|
|
"modalTitle": "Chia sẻ phiên họp",
|
|
"shareButton": "Chia sẻ",
|
|
"notReadyToShare": "Buổi học chưa sẵn sàng để chia sẻ.",
|
|
"modeTab": {
|
|
"link": "Liên kết",
|
|
"user": "Người dùng"
|
|
},
|
|
"linkModeDescription": "Bất kỳ ai có liên kết này đều có thể tham gia, không cần tài khoản.",
|
|
"userModeDescription": "Chia sẻ với một người dùng cụ thể đã có quyền truy cập vào máy chủ này. Nếu họ chưa có quyền truy cập, hãy chia sẻ máy chủ với họ trước hoặc sử dụng liên kết thay thế. Sau khi chia sẻ, phiên làm việc sẽ xuất hiện trong tab Kết nối của họ.",
|
|
"permissionLevel": {
|
|
"label": "Cấp độ quyền",
|
|
"readOnly": "Chỉ đọc",
|
|
"readOnlyDescription": "Có thể xem phiên trực tiếp nhưng không thể gõ chữ hoặc tương tác.",
|
|
"readWrite": "Đọc-viết",
|
|
"readWriteDescription": "Có thể nhập liệu và tương tác với phiên làm việc giống như chủ sở hữu."
|
|
},
|
|
"expiryLabel": "Liên kết hết hạn",
|
|
"createLinkButton": "Tạo liên kết",
|
|
"createShareButton": "Chia sẻ với người dùng",
|
|
"searchUsersPlaceholder": "Tìm kiếm người dùng...",
|
|
"noUsersFound": "Không tìm thấy người dùng nào",
|
|
"linkCreated": "Đã tạo liên kết chia sẻ",
|
|
"linkNeedsServer": "Liên kết chia sẻ chỉ hoạt động cho các phiên trên máy chủ Termix. Kết nối máy chủ này thông qua máy chủ được liên kết của bạn để chia sẻ nó bằng liên kết.",
|
|
"linkCopied": "Liên kết đã được sao chép vào clipboard",
|
|
"copyLink": "Sao chép liên kết",
|
|
"shareCreated": "Phiên họp đã được chia sẻ. Nó sẽ xuất hiện trong tab Kết nối của họ.",
|
|
"shareFailed": "Không thể tạo chia sẻ",
|
|
"userLacksHostAccess": "Người dùng đó chưa có quyền truy cập vào máy chủ này. Hãy chia sẻ thông tin máy chủ với họ trước, hoặc sử dụng liên kết thay thế.",
|
|
"activeShares": "Cổ phiếu tích cực",
|
|
"noActiveShares": "Hiện không có cổ phiếu nào đang được giao dịch trong phiên này.",
|
|
"revoke": "Thu hồi",
|
|
"revokeConfirmTitle": "Thu hồi cổ phần này?",
|
|
"revokeConfirmDescription": "Bất kỳ ai sử dụng thư mục chia sẻ này sẽ mất quyền truy cập ngay lập tức.",
|
|
"revoked": "Cổ phần đã bị thu hồi",
|
|
"revokeFailed": "Không thể thu hồi cổ phần",
|
|
"joinCount": "{{count}} tham gia",
|
|
"joinCount_other": "{{count}} tham gia",
|
|
"expiresAt": "Hết hạn {{date}}",
|
|
"linkShareBadge": "Liên kết",
|
|
"userShareBadge": "Người dùng: {{username}}",
|
|
"loadSharesFailed": "Không thể tải các chia sẻ đang hoạt động",
|
|
"remoteDisplayUnavailable": "Hiện tại, tính năng truy cập máy tính từ xa không khả dụng.",
|
|
"sharedWithMe": "Các buổi chia sẻ với tôi",
|
|
"customHoursPlaceholder": "Số giờ cho đến khi hết hạn truy cập"
|
|
},
|
|
"collab": {
|
|
"createRoom": "Phòng mới",
|
|
"roomName": "Tên phòng",
|
|
"persistentRoom": "Phòng bền vững",
|
|
"persistentRoomHint": "Các phòng họp được lưu lại sẽ vẫn hiển thị sau khi cuộc họp kết thúc và có thể được sử dụng lại.",
|
|
"noRooms": "Chưa có phòng nào. Hãy tạo một phòng để bắt đầu cuộc họp.",
|
|
"openRoom": "Mở",
|
|
"endRoom": "Kết thúc cuộc họp",
|
|
"leaveRoom": "Rời khỏi",
|
|
"deleteMember": "Xóa",
|
|
"removeMember": "Xóa {{name}}",
|
|
"removeMemberTitle": "Xóa thành viên này?",
|
|
"removeMemberDescription": "{{name}} sẽ mất quyền truy cập vào phòng này ngay lập tức. Bất kỳ trình xem SSH nào đang hoạt động sẽ bị ngắt kết nối.",
|
|
"invite": "Mời",
|
|
"inviteTitle": "Mời thành viên",
|
|
"members": "Thành viên",
|
|
"membersPanel": "Thành viên phòng và yêu cầu kiểm soát",
|
|
"membersWithCount": "Thành viên ({{count}})",
|
|
"guestsWithCount": "Khách ({{count}})",
|
|
"removeGuests": "Đuổi khách",
|
|
"anonymousGuest": "Khách mời",
|
|
"online": "trực tuyến",
|
|
"offline": "ngoại tuyến",
|
|
"you": "(Bạn)",
|
|
"hostBadge": "Máy chủ",
|
|
"presenterBadge": "Giới thiệu",
|
|
"present": "Hiện tại",
|
|
"presentTitle": "Hãy lên sân khấu",
|
|
"presentHost": "Máy chủ",
|
|
"searchHosts": "Tìm kiếm máy chủ",
|
|
"noHostsFound": "Không tìm thấy máy chủ nào khả dụng.",
|
|
"presentProtocol": "Giao thức",
|
|
"stopPresenting": "Dừng thuyết trình",
|
|
"takeOver": "Tiếp quản",
|
|
"takeOverConfirmTitle": "Bạn muốn thay thế bài thuyết trình hiện tại?",
|
|
"takeOverDescription": "{{name}} đang trình bày. Việc tiếp quản sẽ ngắt kết nối mọi người khỏi sân khấu đó.",
|
|
"emptyStage": "Hiện chưa có ai thuyết trình. Hãy lên sân khấu để chia sẻ một phiên thảo luận.",
|
|
"stageLoading": "Kết nối với sân khấu...",
|
|
"stageEnded": "Buổi thuyết trình kết thúc.",
|
|
"roomEnded": "Cuộc họp này đã kết thúc.",
|
|
"presenterLabel": "{{name}} đang trình bày",
|
|
"guestLink": "Liên kết khách",
|
|
"guestLinkOn": "Link dành cho khách đã được bật. Bất cứ ai có link đều có thể xem chương trình.",
|
|
"guestLinkOff": "Liên kết khách đã bị tắt.",
|
|
"copyLink": "Sao chép liên kết",
|
|
"rotateLink": "Xoay liên kết",
|
|
"disableLink": "Vô hiệu hóa liên kết",
|
|
"rotateLinkConfirmTitle": "Xoay liên kết khách?",
|
|
"rotateLinkDescription": "Kết nối hiện tại sẽ ngừng hoạt động ngay lập tức. Các máy khách SSH đang kết nối sẽ bị ngắt kết nối.",
|
|
"disableLinkConfirmTitle": "Vô hiệu hóa liên kết khách?",
|
|
"disableLinkDescription": "Những người xem SSH ẩn danh sẽ bị ngắt kết nối ngay lập tức và liên kết hiện tại sẽ ngừng hoạt động.",
|
|
"linkCopied": "Đã sao chép liên kết",
|
|
"roles": "Vai trò",
|
|
"users": "Người dùng",
|
|
"searchUsers": "Tìm kiếm người dùng",
|
|
"endConfirmTitle": "Kết thúc cuộc họp này?",
|
|
"endDescription": "{{name}} sẽ kết thúc đối với tất cả mọi người và không thể mở lại.",
|
|
"endPersistentDescription": "Buổi thuyết trình đang diễn ra tại {{name}} sẽ dừng lại. Phòng vẫn có thể được sử dụng lại.",
|
|
"deleteRoom": "Xóa phòng",
|
|
"deleteConfirmTitle": "Xóa phòng này?",
|
|
"deleteDescription": "{{name}} sẽ bị xóa vĩnh viễn đối với tất cả mọi người và không thể hoàn tác.",
|
|
"invitedTo": "Bạn được mời đến \"{{name}}\"",
|
|
"guest": {
|
|
"title": "Cuộc họp",
|
|
"waiting": "Đang chờ người dẫn chương trình...",
|
|
"linkInvalid": "Liên kết dành cho khách này không hợp lệ hoặc cuộc họp đã kết thúc."
|
|
},
|
|
"reopenFromPanel": "Tab cuộc họp này đã hết hạn. Vui lòng mở lại phòng từ mục Cuộc họp.",
|
|
"retry": "Thử lại",
|
|
"requestControl": "Yêu cầu kiểm soát",
|
|
"cancelControlRequest": "Yêu cầu hủy bỏ",
|
|
"controlQueue": "Yêu cầu kiểm soát",
|
|
"noControlRequests": "Không có yêu cầu nào đang chờ xử lý.",
|
|
"grantControlTo": "Trao quyền điều khiển cho {{name}}",
|
|
"dismissControlRequest": "Bỏ qua yêu cầu điều khiển của {{name}}",
|
|
"releaseControl": "Kiểm soát giải phóng",
|
|
"grantControl": "Trao quyền kiểm soát",
|
|
"revokeControl": "Giành lại quyền kiểm soát",
|
|
"controlRequestedBy": "{{name}} yêu cầu quyền điều khiển",
|
|
"grant": "Khoản trợ cấp",
|
|
"controlBadge": "Trong tầm kiểm soát",
|
|
"youArePresenting": "Bạn đang thuyết trình ở một tab khác. Hãy dừng thuyết trình để nhường sân khấu.",
|
|
"created": "Phòng được tạo",
|
|
"invited": "Các thành viên được mời",
|
|
"roomTab": "Cuộc họp",
|
|
"serverChanged": "Máy chủ cuộc họp đã thay đổi. Vui lòng mở lại cuộc họp này từ mục Cuộc họp.",
|
|
"hostNotSynced": "Hãy đồng bộ hóa máy chủ này với máy chủ cuộc họp trước khi trình bày.",
|
|
"linkRequiresServer": "Kết nối máy tính để bàn này với máy chủ Termix và tạo cuộc họp ở đó để chia sẻ liên kết web."
|
|
},
|
|
"nav": {
|
|
"collab": "Các cuộc họp"
|
|
},
|
|
"settings": {
|
|
"admin": {
|
|
"globallyEnabled": {
|
|
"label": "Cho phép chia sẻ phiên",
|
|
"description": "Cho phép chia sẻ các phiên terminal trực tiếp, RDP, VNC và Telnet trên toàn bộ máy chủ. Khi bị vô hiệu hóa, tùy chọn này sẽ ghi đè lên mọi tùy chọn chia sẻ trên từng máy chủ riêng lẻ."
|
|
}
|
|
},
|
|
"host": {
|
|
"allowSessionSharing": {
|
|
"label": "Cho phép chia sẻ phiên",
|
|
"description": "Cho phép chia sẻ các phiên trực tiếp trên máy chủ này qua liên kết hoặc với những người dùng khác."
|
|
}
|
|
}
|
|
},
|
|
"permissions": {
|
|
"use": {
|
|
"title": "Chia sẻ phiên họp và tham gia phòng họp",
|
|
"description": "Chia sẻ các phiên trực tiếp qua liên kết hoặc với người dùng khác, tạo và tham gia các phòng cộng tác."
|
|
}
|
|
},
|
|
"hosts": {
|
|
"sharing": {
|
|
"expiry": {
|
|
"never": "Không bao giờ",
|
|
"oneHour": "1 giờ",
|
|
"oneDay": "24 giờ",
|
|
"sevenDays": "7 ngày",
|
|
"thirtyDays": "30 ngày",
|
|
"custom": "Tùy chỉnh"
|
|
}
|
|
}
|
|
},
|
|
"connections": {
|
|
"sectionSharedWithMe": "Đã chia sẻ với tôi",
|
|
"sharedBy": "Được chia sẻ bởi {{username}}",
|
|
"join": "Tham gia",
|
|
"sharedSessionLabel": "{{hostName}} (được chia sẻ)"
|
|
},
|
|
"plugin": {
|
|
"name": "Session Sharing"
|
|
}
|
|
}
|