Skip to content

Commit e5720d1

Browse files
chat interface and improve authentication flow (#50)
* downloading messages * unlock view for re-deriving private key after page reload * polling for new messages in the inbox view so user dont need to refresh * extend JWT expiry to 1 hr * Chat interface to look like whatsapp - Updated index.html to include new CSS files for authentication, chat, and verification styles. - Removed the compose button from the navbar and adjusted the inbox view to reflect new chat terminology. - Refactored app.js to remove the compose view and streamline navigation. - Enhanced the inbox view in views.js to support conversation grouping and improved message rendering. - Updated message retrieval logic in routes.py to handle both sent and received messages in a single query. - Introduced new CSS styles for authentication, chat, and verification views to improve UI consistency and aesthetics. * tweaked the frontend * fix revoke and delete, allows revoked messages still to be forwarded * password creation checks * Implement TOFU key pinning and enhance password validation feedback * username validation and password confirmation * rabbit fixes * split views.js cuz it was rlly big * rabbit nitpick * web-client readme * confirm password match * rabbit * :P * readme * rabbit
1 parent f4f918f commit e5720d1

18 files changed

Lines changed: 1923 additions & 794 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ client-cpp/build/
55
__pycache__/
66
.vscode/settings.json
77
docs/transcript_sreejita.md
8+
client-cpp/whatsas_pins.txt

client-cpp/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ The client loads this cert at startup (`loadPinnedCert` in `tls_connect.cpp`) an
5959

6060
```powershell
6161
# Must be run from the client-cpp\ directory so certs/server.crt resolves correctly
62+
63+
$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
64+
6265
.\build\sas-client.exe
6366
```
6467

client-web/README.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# WhatSaS — Web Client
2+
3+
A secure end-to-end encrypted messaging web client built with vanilla JavaScript and the Web Crypto API. All encryption and decryption happens entirely in the browser — the server only ever sees ciphertext.
4+
5+
---
6+
7+
## Prerequisites
8+
9+
Before setting up the web client, ensure you have:
10+
11+
- **Node.js** v18 or later — [download here](https://nodejs.org)
12+
- **npm** (comes with Node.js)
13+
- The **WhatSaS Flask server** running (see `server/README.md`)
14+
- A modern browser (Chrome 120+, Firefox 121+, Edge 120+)
15+
16+
---
17+
18+
## Installation
19+
20+
### Step 1 — Install dependencies
21+
22+
Open a terminal, navigate to the `client-web` directory, and run:
23+
24+
```bash
25+
cd client-web
26+
npm install
27+
```
28+
29+
This installs `argon2-browser` (used for Argon2id password hashing) into `node_modules/`. No build or compile step is needed — the client uses ES modules loaded directly by the browser.
30+
31+
### Step 2 — Add background image (optional)
32+
33+
The chat background uses `bows_background.png`. If you have this file, place it at:
34+
35+
```text
36+
client-web/images/bows_background.png
37+
```
38+
39+
The app works without it — the background falls back to a plain pink gradient.
40+
41+
### Step 3 — Start the backend server
42+
43+
The web client has no standalone server of its own. It is served as static files by the Flask backend. Start the server from the project root:
44+
45+
```bash
46+
cd server
47+
python run.py
48+
```
49+
50+
See `server/README.md` for full server setup instructions including environment variables and database setup.
51+
52+
---
53+
54+
## Running the App
55+
56+
Once the Flask server is running, open your browser and navigate to:
57+
58+
```text
59+
https://sas.theburkenator.com
60+
```
61+
62+
For **local development** (Flask with SSL context on port 5000):
63+
64+
```text
65+
https://localhost:5000
66+
```
67+
68+
That's it — no separate build or bundling step required.
69+
70+
---
71+
72+
## Project Structure
73+
74+
```text
75+
client-web/
76+
├── index.html # App shell — all views rendered dynamically by JS
77+
├── package.json # npm dependencies
78+
├── node_modules/ # Installed by npm install
79+
│ └── argon2-browser/
80+
├── css/
81+
│ ├── base.css # Reset, CSS variables, navbar, layout, buttons, forms
82+
│ ├── auth.css # Login, register, unlock views + password rule checklist
83+
│ ├── chat.css # Two-column chat layout, message bubbles, send bar
84+
│ └── verify.css # Blockchain verification view
85+
├── js/
86+
│ ├── app.js # Router and navbar — controls which view is shown
87+
│ ├── api.js # All HTTP calls to the backend (fetch wrapper + session state)
88+
│ └── views/
89+
│ ├── auth.js # Login, register, unlock screens
90+
│ ├── inbox.js # Chat threads, send, forward, revoke, delete
91+
│ └── helpers.js # Shared utilities (escaping, crypto helpers, TOFU, validation)
92+
├── crypto/
93+
│ ├── constants.js # HKDF domain separation info strings
94+
│ ├── hkdf.js # HKDF-Extract and HKDF-Expand (Web Crypto)
95+
│ ├── keypair.js # X25519 keypair generation
96+
│ ├── keyStorage.js # Private key wrap/unwrap (Argon2id KEK + AES-GCM)
97+
│ └── messageEncryption.js # HPKE-Auth encrypt/decrypt
98+
├── blockchain/
99+
│ └── blockchainVerifyView.js # Standalone Merkle root verification page (no login needed)
100+
└── images/
101+
└── bows_background.png # Chat area background (optional)
102+
```
103+
104+
---
105+
106+
## Features
107+
108+
| Feature | Notes |
109+
|---|---|
110+
| Sign up | Password must be 8+ chars with uppercase, lowercase, number, and special character |
111+
| Sign in | JWT stored in sessionStorage — cleared when tab closes |
112+
| Change password | Re-wraps private key under the new password, same strength rules |
113+
| Conversations | WhatsApp-style: contacts list on the left, active thread on the right |
114+
| Send messages | Encrypted client-side with HPKE-Auth before leaving the browser |
115+
| Receive & decrypt | Decrypted in the browser — server never sees plaintext |
116+
| Forward | Re-encrypts for a new recipient; shows their key fingerprint first |
117+
| Revoke | Blocks recipient's access; message stays visible to sender with "Revoked" badge |
118+
| Delete | Hard-deletes from the database; sender only |
119+
| Download | Saves message as a `.txt` file |
120+
| Key fingerprints | Shown in thread header for out-of-band identity verification |
121+
| TOFU pinning | First-seen key pinned in `localStorage`; key changes trigger a warning |
122+
| Blockchain verify | Public page at `#verify` — no login required |
123+
124+
---
125+
126+
## Cryptographic Summary
127+
128+
For the full threat model and primitive justifications see the cryptographic design document (to be submitted alongside the project).
129+
130+
| Layer | Primitive |
131+
|---|---|
132+
| Key exchange | DHKEM(X25519) — two DH operations (sender auth) |
133+
| Key derivation | HKDF-SHA256 (RFC 5869) |
134+
| Encryption | AES-256-GCM with associated data |
135+
| Associated data | `{sender_id, recipient_id, message_id, timestamp}` (canonical JSON, no spaces) |
136+
| Password hashing | Argon2id (m=32768 KiB, t=2, p=4) |
137+
| Key at rest | AES-256-GCM wrapped private key |
138+
139+
---
140+
141+
## Troubleshooting
142+
143+
**Login page not visible / blank screen**
144+
- Open the browser DevTools console (`F12`) and check for JavaScript errors
145+
- Ensure the Flask server is running and accessible
146+
147+
**Messages show as `(encrypted)`**
148+
- Both clients (web and C++) use the same wire format and key encoding — accounts created on either client are interoperable
149+
- The exception is the C++ Argon2id fallback path, which does not interoperate with the web client's key derivation
150+
- Check that `sender_x25519_public_key` is present in the server's `/messages` response
151+
152+
**`argon2-browser` not found**
153+
- Run `npm install` inside the `client-web/` directory
154+
155+
**CORS errors on the blockchain verify page**
156+
- The Sepolia RPC endpoint (`sepolia.gateway.tenderly.co`) must be CORS-enabled; the one configured in `index.html` supports browser requests

client-web/css/auth.css

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* ── Auth views (login, register, unlock) ─────────────────────────────────── */
2+
3+
/* ── Password rules checklist ────────────────────────────────────────────── */
4+
.pw-rules {
5+
display: flex;
6+
flex-wrap: wrap;
7+
justify-content: center;
8+
gap: .3rem .75rem;
9+
margin-top: .5rem;
10+
}
11+
12+
.pw-rules span {
13+
font-size: .65rem;
14+
color: var(--muted);
15+
transition: color .15s;
16+
}
17+
18+
.pw-rules span.pw-rule-ok {
19+
color: var(--success-txt);
20+
}
21+
.auth-wrap {
22+
max-width: 420px;
23+
margin: 4rem auto;
24+
}
25+
26+
.auth-wrap h1 {
27+
font-size: 1.5rem;
28+
font-weight: 700;
29+
text-align: center;
30+
margin-bottom: 1.75rem;
31+
}
32+
33+
.auth-toggle {
34+
text-align: center;
35+
margin-top: 1.25rem;
36+
font-size: .875rem;
37+
color: var(--muted);
38+
}
39+
40+
.auth-toggle button {
41+
background: none;
42+
border: none;
43+
color: var(--primary);
44+
cursor: pointer;
45+
font-size: .875rem;
46+
text-decoration: underline;
47+
padding: 0;
48+
}

0 commit comments

Comments
 (0)