| --- |
| title: Paper |
| emoji: π |
| colorFrom: purple |
| colorTo: pink |
| sdk: docker |
| pinned: false |
| --- |
| |
| # Paper β¨ |
|
|
| A minimal, secure notepad for temporary notes. Zero tracking, zero accounts β just encrypted notes. |
|
|
| ## Features |
|
|
| - π **Client-side encryption** β Your password never leaves your browser |
| - ποΈ **Auto-delete** β Notes removed after 2 days of inactivity |
| - π **Access anywhere** β Same password = same note, from any device |
| - π« **No tracking** β No cookies, no analytics, no accounts |
|
|
| ## How It Works |
|
|
| ``` |
| βββββββββββββββββββ βββββββββββββββββββ |
| β Browser β β Server β |
| βββββββββββββββββββ€ βββββββββββββββββββ€ |
| β β β β |
| β Password βββββββΌββΊ SHA-256 Hash (16 char) β |
| β β β β β β |
| β βΌ β β βΌ β |
| β PBKDF2 Key β β File ID β |
| β (250k rounds) β β (no password) β |
| β β β β β |
| β βΌ β β β |
| β AES-GCM β β β |
| β Encrypt/DecryptββββββββββΊβ Store/Load β |
| β β β Encrypted Blob β |
| βββββββββββββββββββ βββββββββββββββββββ |
| ``` |
|
|
| **Key points:** |
| - Password β PBKDF2 β AES-256-GCM key (client only) |
| - Password β SHA-256 β File identifier (sent to server) |
| - Server stores only: encrypted content + random salt |
| - Server never sees: password or decrypted content |
|
|
| ## Architecture |
|
|
| ``` |
| Paper/ |
| βββ index.html # Single-page app (HTML + CSS + JS) |
| βββ main.py # Flask backend |
| βββ Dockerfile # Container setup |
| βββ requirements.txt |
| ``` |
|
|
| ### Frontend (`index.html`) |
| - Single HTML file with embedded CSS and JavaScript |
| - Crypto API for AES-GCM encryption and PBKDF2 key derivation |
| - Auto-save with debounce (1.5s after typing stops) |
| - Dark theme with colorful accents |
|
|
| ### Backend (`main.py`) |
| - Flask server with CORS support |
| - Two endpoints: `/api/load` and `/api/save` |
| - File-based storage (configurable via `DATA_DIR`) |
| - Auto-cleanup: files older than 2 days or when storage exceeds limit |
|
|
| ## Environment Variables |
|
|
| | Variable | Default | Description | |
| |----------|---------|-------------| |
| | `DATA_DIR` | `/tmp` | Storage directory | |
| | `AGE_LIMIT_DAYS` | `2` | Days before auto-delete | |
| | `MAX_TOTAL_SIZE_MB` | `100` | Max storage size | |
| | `MAX_CONTENT_SIZE_MB` | `10` | Max note size | |
|
|
| ## Run Locally |
|
|
| ```bash |
| # Install dependencies |
| pip -r requirements.txt |
| |
| # Start server |
| python main.py |
| ``` |
|
|
| Open http://localhost:7860 |
|
|
| ## Deploy |
|
|
| ### Docker |
| ```bash |
| docker build -t paper . |
| docker run -p 7860:7860 paper |
| ``` |
|
|
| ## Security Notes |
|
|
| - All encryption happens in your browser |
| - Password is never transmitted or stored |
| - Server cannot decrypt your notes |
| - Use a strong, memorable password |
| - No password recovery possible |
|
|
| ## License |
|
|
| MIT |
|
|