srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/web/README.md
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-12-15 20:44:00 +0200
committersrdusr <[email protected]>2025-12-15 20:44:00 +0200
commit1740327557074df0c8b99635ee949e2540ac94d0 (patch)
treeeb88af6056350798fa3f53ff4349b1e947c71d6e /web/README.md
parent3dbebfbc9345d2603908f32c0dabebc0ff21feb3 (diff)
downloadtyperpunk-1740327557074df0c8b99635ee949e2540ac94d0.tar.gz
typerpunk-1740327557074df0c8b99635ee949e2540ac94d0.zip
Harden for production: dependencies, headers, admin roles, docs
Dependencies - The server build carried 37 known advisories, including RUSTSEC-2024-0363 in sqlx 0.7, which is the database layer. sqlx moved to 0.8 with default-features off, which also drops the MySQL and SQLite drivers and with them rsa and RUSTSEC-2023-0071. reqwest moved to 0.12, which brings hyper 1.x and was the sole source of every remaining advisory: h2 0.3, rustls-webpki 0.101, rustls-pemfile 1.0 and idna 0.3. - The server build now reports no known vulnerabilities against OSV. cargo audit itself would not compile, so the check queries OSV with the crate versions cargo tree reports for the server binary. - Cargo.lock is committed. This workspace produces binaries, so the lockfile is what makes a deployed build reproducible and the audit above meaningful. Headers - The application sent no security headers at all. The static server now sends a Content-Security-Policy, nosniff, frame options, a referrer policy and a permissions policy; the API sends a policy of its own, since it serves JSON and should load and frame nothing. - The one inline script in index.html moved to a file so script-src needs no unsafe-inline. WebAssembly needs wasm-unsafe-eval, without which nothing types at all, so that is present and explained. - Five style attributes moved to the CSSOM rather than adding unsafe-inline for styles. A style attribute in markup is refused by the policy; the same property set through element.style is not. Production configuration - With TYPERPUNK_ENV=production the server refuses to start if COOKIE_SECURE is off, if DATABASE_URL is still the development default, or if FRONTEND_ORIGIN is http on a non-local host. These were warnings, and a warning in a log nobody reads is not a safeguard. Administration - Moderators were appointed with psql. There is now an admin role, bootstrapped from TYPERPUNK_ADMIN_USERNAME at startup, and a UI to appoint and remove moderators. An administrator's own role cannot be changed through the API, so a mistake cannot lock everyone out of moderation. Corpus - scripts/export_approved.js writes approved submissions back into data/packs/community-*.json. Approved passages are served from the database and merged at startup, so without this the repository dataset and the live corpus drift apart, and a fresh checkout or the TUI sees only what shipped. Documentation - README rewritten for the repository: what it does, how to run it, the pack format, the server variables, deployment, and what the security posture actually is. Plain English, no em dashes, no emoji. Checked and found already correct: every private endpoint refuses anonymous callers, session cookies are HttpOnly and SameSite=Lax, CORS names a single origin, internal errors are logged rather than returned, and every query is parameterised.
Diffstat (limited to 'web/README.md')
-rw-r--r--web/README.md86
1 files changed, 39 insertions, 47 deletions
diff --git a/web/README.md b/web/README.md
index ff0a8a4..f883e16 100644
--- a/web/README.md
+++ b/web/README.md
@@ -1,67 +1,59 @@
-# TyperPunk Web
+# TyperPunk web client
-The TyperPunk web client, in plain HTML, CSS, and JavaScript, backed by the shared Rust/WASM game core. No npm packages, no bundler, no build step. This avoids pulling in the npm dependency tree entirely, which removes the main supply-chain attack surface a typical React/Vite frontend carries.
+Plain HTML, CSS and JavaScript, backed by the shared Rust core compiled to
+WebAssembly. There is no bundler, no build step and no npm dependency tree,
+which removes the supply chain a typical framework setup carries.
-Features:
+## Requirements
-- Real-time WPM and accuracy tracking
-- Ghost text typing interface
-- Light/dark mode support
-- Responsive design
-- Modern UI with cyberpunk-inspired theme
+- Rust and `cargo`, for the WebAssembly core.
+- `wasm-pack`. `launch.sh` installs it if it is missing.
+- Node.js, used only to run the dataset script and the static file server. No
+ packages are installed.
-## Prerequisites
-
-- Rust and `cargo` (for the WASM game core)
-- `wasm-pack` (installed automatically by `launch.sh` if missing)
-- Node.js (used only to run the zero-dependency dev server and dataset scripts; no npm packages are installed)
-
-## Getting Started
+## Running it
```bash
-# From repo root: builds WASM, merges the dataset, and starts the dev server
./web/launch.sh
```
-Opens http://localhost:4173
+This builds the WebAssembly module, merges the text packs, and serves the app
+on http://localhost:4173.
+
+Accounts, the leaderboard, friends and multiplayer need `typerpunk-server` as
+well. See the root README.
-## Project Structure
+## Layout
```
-web/
-├── src/
-│ ├── screens/ # Screen renderers (main menu, typing game, end screen)
-│ ├── app.js # Top-level screen controller
-│ ├── game.js # WASM game instance lifecycle
-│ ├── chart.js # Canvas-based WPM/accuracy graph
-│ ├── stats.js # WPM/accuracy calculation
-│ ├── theme.js # Light/dark theme state
-│ ├── main.js # Application entry point
-│ └── styles.css # Global styles
-├── wasm/ # WASM bindings, copied here by launch.sh (gitignored)
-├── index.html # HTML entry point
-└── serve.mjs # Zero-dependency static file server
+src/screens/ one file per screen
+src/app.js screen controller and routing
+src/game.js WebAssembly game lifecycle
+src/chart.js end screen graph
+src/stats.js WPM and accuracy
+src/customText.js importing and chunking your own text
+src/languages.js typing vocabularies
+src/styles.css all styling
+wasm/ WebAssembly bindings, copied here by launch.sh, gitignored
+index.html entry point
+serve.mjs static file server
```
-## Development
+## Working on it
-The project uses:
+There is no build step. Edit a file under `src/` and reload the page.
-- Vanilla JavaScript (ES modules), no framework or bundler
-- The browser's native `<canvas>` API for the results graph
-- Node's built-in `http` module for local serving (`serve.mjs`)
-- Plain CSS for styling
+The one exception is the Rust core: changing `crates/core` or `crates/wasm`
+means running `launch.sh` again to rebuild the WebAssembly module.
-Because there is no build step, editing a file under `src/` and reloading the page is the whole workflow.
+`serve.mjs` sends the Content-Security-Policy. It forbids inline script, so
+new code belongs in a file rather than in a `<script>` block.
-## Contributing
+## Tests
-1. Fork the repository
-2. Create your feature branch (`git checkout -b feature/amazing-feature`)
-3. Commit your changes (`git commit -m 'Add some amazing feature'`)
-4. Push to the branch (`git push origin feature/amazing-feature`)
-5. Open a Pull Request
-
-## License
+```bash
+cd web/tests && python3 run_all.py
+```
-This project is licensed under the MIT License - see the LICENSE file for details.
+These drive the real application with Playwright. Both servers must already
+be running. See `tests/README.md`.