|
| 1 | +# Báo cáo nâng cấp — v3.1.0 (Encrypted Backup & Theme) |
| 2 | + |
| 3 | +Tài liệu này tổng hợp các thay đổi của bản **v3.1.0**: bổ sung **Import/Export & sao lưu dữ liệu có mã hóa** và **hệ thống Theme Sáng/Tối**. Bản nâng cấp giữ nguyên toàn bộ chức năng hiện có và tương thích ngược với dữ liệu cũ. |
| 4 | + |
| 5 | +> Bản này được xây dựng tiếp nối trên v3.0.0 (UX & Interface Upgrade). |
| 6 | +
|
| 7 | +--- |
| 8 | + |
| 9 | +## 1. Danh sách file đã sửa / thêm mới |
| 10 | + |
| 11 | +### Thêm mới |
| 12 | +| File | Mục đích | |
| 13 | +|------|----------| |
| 14 | +| `app-tauri/src/lib/backup.ts` | Lõi mã hóa/giải mã backup (AES-256-GCM + PBKDF2) + định dạng envelope, lỗi có phân loại. | |
| 15 | +| `app-tauri/src/dialogs/BackupDialog.tsx` | Luồng UI Export/Import nhiều bước (mật khẩu, chọn file, xác nhận ghi đè, báo lỗi). | |
| 16 | +| `app-tauri/src/theme/ThemeContext.tsx` | Context quản lý Theme (light/dark/system), lưu lựa chọn, theo dõi thay đổi OS. | |
| 17 | +| `REPORT_v3.1.0.md` | Báo cáo này. | |
| 18 | + |
| 19 | +### Đã chỉnh sửa |
| 20 | +| File | Thay đổi chính | |
| 21 | +|------|----------------| |
| 22 | +| `app-tauri/src-tauri/src/commands.rs` | Thêm command `replace_accounts`, `read_text_file`, `write_text_file`. | |
| 23 | +| `app-tauri/src-tauri/src/lib.rs` | Đăng ký 3 command mới vào `invoke_handler`. | |
| 24 | +| `app-tauri/src-tauri/capabilities/default.json` | Bổ sung quyền `dialog:allow-save` (lưu file backup). | |
| 25 | +| `app-tauri/src/lib/api.ts` | Thêm `replaceAccounts`, `saveTextFile`, `pickAndReadTextFile` (đa nền tảng Tauri/web). | |
| 26 | +| `app-tauri/src/lib/mock-store.ts` | Thêm `replaceAccounts` cho chế độ web preview. | |
| 27 | +| `app-tauri/src/dialogs/SettingsDialog.tsx` | Thêm khu vực **Giao diện** (segmented Light/Dark/System) và **Sao lưu & Khôi phục** (Export/Import). | |
| 28 | +| `app-tauri/src/App.tsx` | Nút chuyển nhanh Sáng/Tối ở header; state `backupMode`; render `BackupDialog`; refresh sau import. | |
| 29 | +| `app-tauri/src/main.tsx` | Bọc ứng dụng trong `ThemeProvider`. | |
| 30 | +| `app-tauri/index.html` | Script áp dụng theme trước first paint (tránh nhấp nháy/FOUC). | |
| 31 | +| `app-tauri/src/styles.css` | Bảng biến cho dark theme, chuyển màu hardcode sang biến, transition mượt, style cho theme/backup. | |
| 32 | +| `app-tauri/src/i18n/strings.ts` | Bổ sung chuỗi cho Theme & Backup (vi + en). | |
| 33 | +| `app-tauri/src/dialogs/AboutDialog.tsx` | Cập nhật version 3.0.0 → 3.1.0. | |
| 34 | +| `package.json`, `app-tauri/package.json`, `Cargo.toml`, `Cargo.lock`, lock files, `tauri.conf.json` | Bump version 3.1.0. | |
| 35 | +| `README.md` | Bổ sung tính năng, cập nhật Roadmap (đánh dấu hoàn thành) và Changelog v3.1.0. | |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## 2. Các thay đổi chính |
| 40 | + |
| 41 | +- **Export có mã hóa:** xuất toàn bộ dữ liệu (accounts + settings + đường dẫn Riot) ra file `.backup`, mã hóa bằng mật khẩu người dùng. Bắt buộc nhập **mật khẩu + xác nhận**; nếu không khớp sẽ không cho xuất. |
| 42 | +- **Import có kiểm tra:** chọn file → nhập mật khẩu → giải mã → kiểm tra hợp lệ → **xác nhận ghi đè** rồi mới áp dụng. Báo lỗi rõ ràng cho từng trường hợp (sai mật khẩu, file hỏng, sai định dạng, phiên bản mới hơn). |
| 43 | +- **Tương thích & versioning:** envelope chứa `formatVersion` + `dataVersion` + `createdAt`, cho phép phát hiện và từ chối an toàn file từ phiên bản mới hơn; không làm crash ứng dụng. |
| 44 | +- **Theme đầy đủ:** Light / Dark / System; chuyển đổi tức thì không reload; ghi nhớ qua `localStorage`; áp dụng sớm để tránh nhấp nháy. |
| 45 | +- **Không phá vỡ dữ liệu cũ:** không thay đổi cấu trúc lưu trữ tài khoản hiện có; chỉ thêm command ghi-đè-toàn-bộ phục vụ khôi phục. |
| 46 | + |
| 47 | +--- |
| 48 | + |
| 49 | +## 3. Kiến trúc giải pháp |
| 50 | + |
| 51 | +``` |
| 52 | + ┌────────────────────────── Frontend (React/TS) ──────────────────────────┐ |
| 53 | + │ SettingsDialog ──(Export/Import)──► App.backupMode ──► BackupDialog │ |
| 54 | + │ │ │ |
| 55 | + │ lib/backup.ts (Web Crypto) │ │ |
| 56 | + │ encryptBackup() / decryptBackup() ◄─────────┘ │ |
| 57 | + │ │ │ |
| 58 | + │ lib/api.ts (platform abstraction) │ |
| 59 | + │ saveTextFile / pickAndReadTextFile / replaceAccounts / get/set... │ |
| 60 | + └───────────────┬───────────────────────────────────┬─────────────────────┘ |
| 61 | + │ isTauri() │ web preview |
| 62 | + ▼ ▼ |
| 63 | + Rust commands (read/write_text_file, mock-store + Blob download / |
| 64 | + replace_accounts) + plugin-dialog <input type=file> + localStorage |
| 65 | + │ |
| 66 | + ▼ |
| 67 | + ram-core::store (lưu trữ mã hóa cục bộ - giữ nguyên) |
| 68 | +``` |
| 69 | + |
| 70 | +- **Mã hóa nằm hoàn toàn ở frontend** bằng **Web Crypto API**, đúng định hướng của stack; backend chỉ đọc/ghi bytes thô. |
| 71 | +- **`ThemeProvider`** đặt ngoài cùng cây React, gán `data-theme` lên `<html>`; CSS dùng biến `--*` để đổi màu tức thì. |
| 72 | + |
| 73 | +## 4. Cách hoạt động của Import/Export |
| 74 | + |
| 75 | +### Định dạng file `.backup` |
| 76 | +```jsonc |
| 77 | +{ |
| 78 | + "app": "RiotAccountManager", |
| 79 | + "type": "backup", |
| 80 | + "formatVersion": 1, // phiên bản cấu trúc envelope |
| 81 | + "dataVersion": 1, // phiên bản schema payload |
| 82 | + "createdAt": "2026-06-12T...Z", |
| 83 | + "kdf": { "name": "PBKDF2", "hash": "SHA-256", "iterations": 210000, "salt": "<base64>" }, |
| 84 | + "cipher":{ "name": "AES-GCM", "iv": "<base64>" }, |
| 85 | + "data": "<base64 ciphertext>" // JSON {accounts, settings, riotPath} đã mã hóa |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +### Export |
| 90 | +1. Người dùng nhập mật khẩu + xác nhận (không khớp ⇒ dừng). |
| 91 | +2. Sinh `salt` (16 byte) + `iv` (12 byte) ngẫu nhiên; PBKDF2-SHA256 (210k vòng) ⇒ khóa AES-256. |
| 92 | +3. AES-GCM mã hóa payload ⇒ ghi envelope ra file (`.backup`). Mật khẩu **không** được lưu. |
| 93 | + |
| 94 | +### Import |
| 95 | +1. Chọn file ⇒ đọc text ⇒ parse envelope (kiểm tra `app/type/formatVersion`). |
| 96 | +2. Nhập mật khẩu ⇒ derive khóa từ `salt` lưu trong file ⇒ AES-GCM decrypt. |
| 97 | +3. AES-GCM tự xác thực: sai mật khẩu / dữ liệu bị sửa ⇒ ném lỗi ⇒ thông báo "sai mật khẩu hoặc file hỏng". |
| 98 | +4. Kiểm tra payload hợp lệ ⇒ hiển thị xác nhận ghi đè ⇒ áp dụng (`replaceAccounts`, `setSettings`, `setRiotPath`) ⇒ refresh UI. |
| 99 | + |
| 100 | +### Các luồng đã kiểm thử |
| 101 | +| Luồng | Kết quả | |
| 102 | +|-------|---------| |
| 103 | +| Export thành công | ✅ (roundtrip verify qua Web Crypto) | |
| 104 | +| Import thành công | ✅ | |
| 105 | +| Import sai mật khẩu | ✅ bị từ chối, báo lỗi rõ ràng | |
| 106 | +| Import file lỗi/hỏng | ✅ bị từ chối | |
| 107 | + |
| 108 | +## 5. Cách hoạt động của Theme |
| 109 | + |
| 110 | +- `ThemeContext` đọc `localStorage["ram.theme"]` (`light`/`dark`/`system`, mặc định `system`). |
| 111 | +- Theme được "resolve" thành `light|dark` và gán `data-theme` lên `<html>`. Toàn bộ màu dùng biến CSS nên đổi **ngay lập tức, không reload**. |
| 112 | +- Khi chọn `system`, lắng nghe `matchMedia("(prefers-color-scheme: dark)")` để tự đổi theo OS. |
| 113 | +- `index.html` áp dụng theme trước khi React mount ⇒ không nhấp nháy lúc khởi động. |
| 114 | +- Hai điểm điều khiển: nút ☀/🌙 ở header (đổi nhanh) và bộ chọn 3 lựa chọn trong Cài đặt. |
| 115 | + |
| 116 | +| Luồng | Kết quả | |
| 117 | +|-------|---------| |
| 118 | +| Chuyển Light Mode | ✅ | |
| 119 | +| Chuyển Dark Mode | ✅ | |
| 120 | +| Theo Hệ thống (System) | ✅ | |
| 121 | +| Ghi nhớ theme sau khởi động lại | ✅ (localStorage + apply sớm) | |
| 122 | + |
| 123 | +## 6. Những điểm cần lưu ý |
| 124 | + |
| 125 | +- **Mật khẩu backup không thể khôi phục:** nếu quên mật khẩu sẽ không giải mã được file (đây là chủ đích bảo mật). |
| 126 | +- **Import là ghi đè toàn bộ** danh sách tài khoản hiện tại (sau xác nhận). Backend `ram-core` vẫn tự tạo bản sao lưu nội bộ khi ghi (`accounts.bak`). |
| 127 | +- **Web preview** dùng tải/đọc file qua trình duyệt và `localStorage`; bản desktop dùng dialog gốc + lệnh Rust. |
| 128 | +- **Phụ thuộc hệ thống khi build desktop:** cần GTK/WebKit (`libgtk-3-dev`, `libwebkit2gtk-4.1-dev`, …) để `cargo check`/`tauri build` chạy trên Linux. |
| 129 | + |
| 130 | +## 7. Kiểm tra cuối cùng |
| 131 | + |
| 132 | +| Hạng mục | Lệnh | Kết quả | |
| 133 | +|----------|------|---------| |
| 134 | +| TypeScript + build web | `npm run build` | ✅ | |
| 135 | +| Kiểm tra lõi Rust | `cargo check -p ram-core` | ✅ | |
| 136 | +| Unit test lõi Rust | `cargo test -p ram-core` | ✅ 8 passed | |
| 137 | +| Build crate Tauri (sau khi cài GTK/WebKit) | `cargo check -p riot-account-manager` | ✅ | |
| 138 | +| Mã hóa backup (roundtrip / sai mật khẩu / file hỏng) | Web Crypto verify | ✅ | |
| 139 | + |
| 140 | +## 8. Đề xuất cải tiến trong tương lai |
| 141 | + |
| 142 | +- Tự động sao lưu định kỳ (scheduled backup) ra thư mục do người dùng chọn. |
| 143 | +- Cho phép **merge** khi import thay vì chỉ ghi đè. |
| 144 | +- Thêm các theme/màu nhấn tùy biến và độ tương phản cao (accessibility). |
| 145 | +- Thêm thanh đo độ mạnh mật khẩu khi đặt mật khẩu backup. |
| 146 | +- Đồng bộ ngôn ngữ khi import (hiện chỉ lưu vào config, không đổi UI tức thì). |
| 147 | + |
| 148 | +--- |
| 149 | + |
| 150 | +*Báo cáo cho phiên bản v3.1.0 — Encrypted Backup & Theme.* |
0 commit comments