feat(i18n): add multi-language support (ja/ko/vi/ru/zh-TW) with system auto-detection

- Extend AppLanguage to 7 locales: zh-CN, zh-TW, en, ja, ko, vi, ru
- Auto-detect system language via navigator.languages; fallback to English
- Add BCP47 locale mapping for date formatting and sorting
- Create 50 translation JSON files (5 languages × 10 namespaces, 1137 keys each)
- Update language selector with native language names
- Extend locale key parity test to cover all 7 languages (70 assertions)
- Add VNC/RDP desktop, serial terminal, AI agent, port forwarding, and SFTP features
- Add credential encryption, host metrics, session backup crypto, and zmodem bridge
- Update Rust backend: desktop services, host metrics, SSH/SFTP enhancements
This commit is contained in:
Logan.Li committed 2026-08-12 00:07:48 +08:00
1 parent fea6d8db04
commit b0d0e3a5f3
301 files changed
+28002 -2705

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
import { describe, expect, it } from 'vitest'
import {
decryptSessionBackup,
encryptSessionBackup,
isEncryptedSessionBackup,
} from '../../src/utils/sessionBackupCrypto'
describe('sessionBackupCrypto', () => {
it('encrypts and decrypts UTF-8 session payload', async () => {
const plaintext = JSON.stringify({
version: 1,
sessions: [{ name: '生产', host: 'ops.example.com', privateKey: '-----BEGIN KEY-----\n密\n' }],
})
const encrypted = await encryptSessionBackup(plaintext, 's3cret!')
const envelope = JSON.parse(encrypted)
expect(isEncryptedSessionBackup(envelope)).toBe(true)
expect(encrypted).not.toContain('ops.example.com')
expect(encrypted).not.toContain('BEGIN KEY')
const restored = await decryptSessionBackup(envelope, 's3cret!')
expect(restored).toBe(plaintext)
})
it('rejects wrong password', async () => {
const encrypted = await encryptSessionBackup('{"sessions":[]}', 'right-password')
const envelope = JSON.parse(encrypted)
await expect(decryptSessionBackup(envelope, 'wrong-password')).rejects.toThrow(
'BACKUP_PASSWORD_INVALID'
)
})
})