ali-ahnaf / ali-ahnaf/pocket_pixel

Add client-side encryption/decryption for Expense and Tag fields (zero-knowledge, frontend)

Đang mở
#181 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
blocked frontend
Ngôn ngữ chính
TypeScript
Star
14
Fork
91
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

## 🔒 Context / background
Companion to backend issue #180 — **blocked by it**, since it needs the new API contracts and endpoints for encrypted expenses/tags before any of this can be wired up. Once the backend accepts/returns `{ nonce, encryptedData }` instead of plaintext `title`/`amount` (expenses) and `name` (tags), the UI needs to do all the actual encryption and decryption — the server never sees plaintext.

## 🎯 Problem / goal
Encrypt an expense's `title`+`amount` and a tag's `name` in the browser before sending to the API, and decrypt them in the browser after fetching, so the DB/backups never contain plaintext.

## 🛠 Suggested approach
1. Add `libsodium-wrappers` to `packages/ui`.
2. Add a crypto helper module (e.g. `packages/ui/src/lib/crypto/`):
- `encryptExpenseFields(dek, { title, amount })` / `decryptExpenseFields(dek, nonce, encryptedData)` using `crypto_secretbox_easy` / `crypto_secretbox_open_easy`.
- `encryptTagName(dek, name)` / `decryptTagName(dek, nonce, encryptedData)`, same pattern.
- **Generate a fresh random nonce per encryption call** — never reuse a nonce with the same DEK.
3. Derive/unwrap the user's DEK on login (depends on whatever #180 lands for wrapped-DEK storage — likely a client-side KDF over the password, then unwrap the DEK fetched from the backend). Keep the DEK in memory only — the repo currently uses `localStorage` for `auth_token`/`pocket_pixel_profile`; do not add the DEK there.
4. Update transaction create/update (`packages/ui/src/components/LogResourceModal.tsx`) to encrypt `title`+`amount` before calling the API.
5. Update tag create/update (`packages/ui/src/components/AddTagModal.tsx`) to encrypt `name` before calling the API.
6. Update every place that renders/aggregates these fields to decrypt first:
- `packages/ui/src/app/page.tsx` (~lines 34-53 tag/vault display, ~168-177 `totalIncome`/`totalExpenses`/budget % — these become post-decrypt client reduces)
- `packages/ui/src/app/stats/page.tsx` (~lines 136-149 income/expense totals, monthly net, cumulative)
- `packages/ui/src/components/LogResourceModal.tsx` (~line 44 tag autocomplete — filter on decrypted names)
7. Tag names/expense titles are no longer server-sortable; sort/filter the decrypted list client-side after fetch (lists are small — no need for IndexedDB unless that changes later).
8. Add the one-time migration flow: on login, if the backend flags the user as having un-migrated legacy rows, fetch plaintext rows, encrypt client-side, and call the backend's migration-write endpoint (added in #180) before showing the dashboard.

## ✅ Acceptance criteria
- [ ] New expenses/tags are created via the UI with encrypted fields; no plaintext `title`/`amount`/`name` is ever sent in a create/update request body
- [ ] Dashboard (`page.tsx`) and stats (`stats/page.tsx`) correctly decrypt and render titles, amounts, and tag names
- [ ] Totals/sums/budget-progress on both pages are computed client-side after decryption
- [ ] Tag autocomplete (`LogResourceModal.tsx`) filters against decrypted names
- [ ] Existing users are walked through the one-time migration on next login without data loss
- [ ] DEK is held in memory only, never written to `localStorage`/`IndexedDB` in plaintext
- [ ] Playwright e2e coverage added/updated for create → reload → verify decrypted display

## Notes
- Depends entirely on the contracts/endpoints landing in #180 first — don't start API-call changes until those contracts exist in `packages/shared`.
- Related files: `packages/ui/src/app/page.tsx`, `packages/ui/src/app/stats/page.tsx`, `packages/ui/src/components/LogResourceModal.tsx`, `packages/ui/src/components/AddTagModal.tsx`, `packages/ui/src/hooks/useAuth.ts`, `packages/ui/src/lib/api/ApiClient.ts`.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.