Cybersecurity-Projects/PROJECTS/advanced/encrypted-p2p-chat/frontend
CarterPerez-dev 6fd5f3d393 fix(encrypted-p2p-chat): apply audit findings — true E2EE, session auth, spec-correct crypto
This commit applies the actionable plan from docs/plans/2026-04-29-encrypted-p2p-chat-audit-fixes.md.

Backend
- Delete server-side X3DH/Double Ratchet (`app/core/encryption/*`); the server is now an opaque relay for client-encrypted messages.
- Drop `private_key` columns from IdentityKey/SignedPrekey/OneTimePrekey; prekey-bundle endpoint serves only public material.
- Remove RatchetState and SkippedMessageKey models and the deprecated server-encryption code path in message_service.
- Fix the broken `not OneTimePrekey.is_used` SQL filter (`Column.is_(False)` instead of Python `not`); repair the silent OPK-replenish amplification by deleting the server-generated path entirely.
- Stop calling `prekey_service.initialize_user_keys` from registration/login. Server never holds private key material again.
- Add session-cookie auth: opaque token issued in Redis on register/auth complete, `current_user` dependency on every protected route, `/auth/me`, `/auth/logout`. WebSocket authenticates via the same cookie.
- Add room membership checks to WS encrypted_message + typing handlers, GET/DELETE /rooms/{id}, GET /rooms/{id}/messages. broadcast_to_room now filters by participants, not presence.
- Add slowapi rate limits to register/auth/search; per-user sliding-window cap on WS messages.
- WebAuthn: replace username with a 64-byte random `webauthn_user_handle` for `user.id`; fix `backup_eligible` to read `credential_backup_eligible`; switch UserVerificationRequirement to REQUIRED; key authentication challenges by challenge bytes (no more "discoverable" collision).
- Implement GET /rooms/{id} and DELETE /rooms/{id} (cascade delete with ownership check) and fix the N+1 in list_rooms by batching User lookups.
- Remove broken/obsolete tests; add regression tests for the OPK filter bug and session-protected endpoints (401 without cookie).
- Sanitize WebSocket error responses; correlation IDs replace stack-trace leaks.

Frontend
- X3DH: prepend the 32-byte 0xff F prefix to the HKDF input per spec section 2.2.
- Double Ratchet: switch KDF_RK to spec form (HKDF salt=root_key, IKM=dh_output) and use 0x01/0x02 byte tags for KDF_CK.
- Replace base64 helpers in `crypto/primitives.ts` with the URL-safe codec from `lib/base64.ts` (single source of truth, no spread-stack hazard).
- Update auth.service to issue a session via cookies (no more dead token store), call `/auth/me` on app boot, clear crypto state on logout. Delete unused `session.store.ts`.
- Update room.service / Chat page to drop client-supplied user_id arguments; the cookie now identifies the caller.
- Better forward-secrecy UX text for messages predating the device.
- Add Vitest with X3DH and Double Ratchet round-trip + tamper-detection tests.

Tooling
- Add `slowapi>=0.1.9` to backend deps; add `vitest` to frontend devDeps with `pnpm test` script.
- justfile: `test-frontend`, `dev-reset`.
- Adjust `.gitignore` so the Python `lib/` rules no longer hide `frontend/src/lib`.

Migration: existing dev volumes hold private-key columns and KDF-incompatible ratchet states; run `just dev-reset` and re-register before hitting the new code path.
2026-04-29 02:30:10 -04:00
..
public/assets fix(encrypted-p2p-chat): apply audit findings — true E2EE, session auth, spec-correct crypto 2026-04-29 02:30:10 -04:00
src fix(encrypted-p2p-chat): apply audit findings — true E2EE, session auth, spec-correct crypto 2026-04-29 02:30:10 -04:00
.gitignore Phase 1.1: Organize PROJECTS by difficulty level 2026-01-29 02:41:15 -05:00
.prettierignore Phase 1.1: Organize PROJECTS by difficulty level 2026-01-29 02:41:15 -05:00
.prettierrc Phase 1.1: Organize PROJECTS by difficulty level 2026-01-29 02:41:15 -05:00
README.md Phase 1.1: Organize PROJECTS by difficulty level 2026-01-29 02:41:15 -05:00
biome.json issue 77 2026-02-18 18:53:15 -05:00
eslint.config.js issue 77 2026-02-18 18:53:15 -05:00
index.html Phase 1.1: Organize PROJECTS by difficulty level 2026-01-29 02:41:15 -05:00
package.json fix(encrypted-p2p-chat): apply audit findings — true E2EE, session auth, spec-correct crypto 2026-04-29 02:30:10 -04:00
pnpm-lock.yaml fix(encrypted-p2p-chat): apply audit findings — true E2EE, session auth, spec-correct crypto 2026-04-29 02:30:10 -04:00
tsconfig.json Phase 1.1: Organize PROJECTS by difficulty level 2026-01-29 02:41:15 -05:00
vite.config.ts fix(encrypted-p2p-chat): apply audit findings — true E2EE, session auth, spec-correct crypto 2026-04-29 02:30:10 -04:00

README.md

Encrypted P2P Chat - Frontend

SolidJS frontend with Vite, TypeScript, and Tailwind CSS v4.

Requirements

  • Node.js 20.19+ or 22.12+ (required for Vite 7)

Tech Stack

  • SolidJS 1.9.10 - Fine-grained reactivity
  • TypeScript 5.9 - Type safety
  • Vite 7 - Build tool (ESM only, requires Node 20.19+)
  • Tailwind CSS v4.1 - Utility-first CSS (stable release)
  • @solidjs/router - Client-side routing
  • @tanstack/solid-query 5.90 - Data fetching and caching
  • nanostores 1.1 - State management

Development

npm install
npm run dev

Frontend runs on http://localhost:3000

Build

npm run build

Output in dist/ directory.

SolidJS Routing

Unlike React Router, SolidJS uses:

  • <A> component for navigation (not <Link>)
  • useNavigate() for programmatic navigation
  • useParams() for route parameters
  • useSearchParams() for query parameters

Environment Variables

Copy .env.example to .env and configure:

  • VITE_API_URL - Backend API URL
  • VITE_WS_URL - WebSocket URL
  • VITE_RP_ID - WebAuthn Relying Party ID