From 9139398d465f5899cc31bc4cdd54daa7392ca550 Mon Sep 17 00:00:00 2001 From: Doan Luu Duc Tai Date: Sat, 31 Oct 2026 12:25:30 -0500 Subject: Migrate browser code and tests to strict TypeScript --- docs/CHAT-APPLICATION.txt | 19 +++--- docs/CHAT-OPENSSL-MIGRATION.txt | 6 +- docs/CHAT-PRODUCTION.txt | 10 ++-- docs/POLICY.txt | 9 ++- docs/TYPESCRIPT.txt | 128 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 docs/TYPESCRIPT.txt (limited to 'docs') diff --git a/docs/CHAT-APPLICATION.txt b/docs/CHAT-APPLICATION.txt index 27ab61f..7ebac77 100644 --- a/docs/CHAT-APPLICATION.txt +++ b/docs/CHAT-APPLICATION.txt @@ -25,8 +25,9 @@ EXPERIMENTAL PRIVATE CHAT WHAT EXISTS A Rust HTTP server and a Rust cryptographic command compiled to WASI. - Small, readable, free JavaScript modules implement the browser interface and - a capability-limited WASI host. Text is displayed through textContent. + Strict TypeScript implements the browser interface and a capability-limited + WASI host, compiled to small, readable, free JavaScript classic scripts. + Build configuration and source licensing are documented in TYPESCRIPT.txt. Text is displayed through textContent. SearXNG and the other existing services are unchanged. Startup shows an ASCII download bar, percentage, and received/total MiB @@ -377,7 +378,8 @@ LICENSES, SOURCE, AND VERIFICATION The yellow GNU LibreJS-compliant badge links to the GNU project and exposes a hover/focus explanation distinguishing software freedom from security. A source archive is built by infra/chat/build-source.sh from an explicit - source allowlist, Cargo-vendored dependencies, and the original verified + source allowlist, TypeScript sources/configurations/npm lock, Cargo-vendored + dependencies, and the original verified OpenSSL archive. It excludes .env, .git, keys, target files, runtime data, downloaded browser tools, and exports. .env.example is public. The original dependency license texts are preserved. GNU-friendly human-readable names @@ -393,12 +395,13 @@ LICENSES, SOURCE, AND VERIFICATION Run the normal strict workspace check, then browser tests: cargo stack check - PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" node crates/chat-crypto/tests/browser.mjs - PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" node crates/chat-server/tests/browser.mjs - PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" node crates/chat-server/tests/progress.mjs + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:crypto + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:chat + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:progress - Browser automation additionally needs Node, Playwright under .tools/browser, - and its browser downloads under .tools/browsers. These are development tools + Browser automation additionally needs Node and the root locked Playwright + development dependency, with browser downloads under .tools/browsers. See + TYPESCRIPT.txt for installation and the strict TypeScript build. These tools are excluded from releases. The fixtures use temporary isolated installation roots with one temporary .env each, and remove their private data on completion. They listen on loopback port 9081 by default (override with CHAT_TEST_PORT), diff --git a/docs/CHAT-OPENSSL-MIGRATION.txt b/docs/CHAT-OPENSSL-MIGRATION.txt index d2901c4..8c9ee28 100644 --- a/docs/CHAT-OPENSSL-MIGRATION.txt +++ b/docs/CHAT-OPENSSL-MIGRATION.txt @@ -224,9 +224,9 @@ REPRODUCE FROM THE STACK ROOT cargo test --locked -p stack-chat-crypto cargo run --locked -p stack-chat-crypto sh infra/chat/build-openssl-wasi.sh - npm install --prefix .tools/browser --save-exact playwright@1.64.1 - PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" .tools/browser/node_modules/.bin/playwright install chromium - PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" node crates/chat-crypto/tests/browser.mjs + npm run build + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" node_modules/.bin/playwright install chromium + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:crypto cargo stack check The build script pins archive versions and hashes, configures static OpenSSL, diff --git a/docs/CHAT-PRODUCTION.txt b/docs/CHAT-PRODUCTION.txt index 8830920..cf8fc17 100644 --- a/docs/CHAT-PRODUCTION.txt +++ b/docs/CHAT-PRODUCTION.txt @@ -42,14 +42,16 @@ BUILD ON THE WORKSTATION Current releases require an x86_64 GNU/Linux build host and matching target. Use the pinned Rust toolchain, Podman, Git, GnuPG, a GCC-compatible C compiler, - Linux UAPI headers, libclang, pkg-config, make, Perl, curl, and tar. Native + Linux UAPI headers, libclang, pkg-config, make, Perl, curl, tar, Node >=22.18.0, + and npm. Native workspace checks need OpenSSL 3.5+ development libraries. Browser testing - additionally needs Node, Playwright, Chromium, and Firefox. These tools remain + additionally needs the pinned Playwright, Chromium, and Firefox. These tools remain on the workstation; production does not need Cargo or a compiler. cargo stack release - This runs formatting, strict Clippy, all workspace tests, rustdoc, cargo-deny, + This first builds/checks TypeScript, then runs formatting, strict Clippy, + all workspace tests, rustdoc, cargo-deny, and cargo-about. It then builds static native binaries, the WASI module, corresponding sources, the chat/cgit images, and the complete image export. THIRD-PARTY-LICENSES.html is regenerated from the full workspace before @@ -201,7 +203,7 @@ VERIFICATION HTTPS_PORT=8443, and LOCAL_HTTP_PORT=8180: ./bin/stack up --production - CHAT_TEST_ROOT=/absolute/disposable/stack CHAT_TEST_ORIGIN=https://chat.fixture.localhost:8443 PLAYWRIGHT_BROWSERS_PATH=.tools/browsers node crates/chat-server/tests/browser.mjs + CHAT_TEST_ROOT=/absolute/disposable/stack CHAT_TEST_ORIGIN=https://chat.fixture.localhost:8443 PLAYWRIGHT_BROWSERS_PATH=.tools/browsers npm run test:chat Run from the source checkout for the harness and Playwright installation. Add CHAT_LIBREJS=1 for Firefox with the actual GNU LibreJS add-on. That test diff --git a/docs/POLICY.txt b/docs/POLICY.txt index 16d97c2..1f54398 100644 --- a/docs/POLICY.txt +++ b/docs/POLICY.txt @@ -23,7 +23,9 @@ PROJECT CONVENTIONS file carries the AGPL copyright and permission header. LICENSE is the unmodified license text. Binary public keys and empty WKD policy files retain their protocol format. Generated Cargo.lock retains Cargo's own - metadata as well as the project notice. + metadata as well as the project notice. JSON npm manifests carry the legal + notice in a top-level // metadata field; compiler JSONC files use the usual + header syntax. Keep generated JavaScript legal markers when compiling. Do not add explanatory source comments. Express intent through structure and names. Legal headers are the required exception. Use .txt for prose @@ -58,6 +60,11 @@ STRICTNESS The dependency allowlist retains the requested permissive licenses and Zlib; an unused allowance may produce an informational audit warning. + Browser logic and automation use strict TypeScript configurations with + separate browser/worker/Node environments and checked untrusted responses. + npm dependencies are exact, development-only, integrity-locked, and installed + with lifecycle scripts disabled. See TYPESCRIPT.txt for the build contract. + Human license names follow https://www.gnu.org/licenses/license-list.html. In particular, display Expat License for SPDX MIT. Do not alter original copyright notices, legal texts, crate metadata, or machine SPDX identifiers. diff --git a/docs/TYPESCRIPT.txt b/docs/TYPESCRIPT.txt new file mode 100644 index 0000000..d50ea95 --- /dev/null +++ b/docs/TYPESCRIPT.txt @@ -0,0 +1,128 @@ +Copyright (C) 2026 Doan Luu Duc Tai + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + +TYPESCRIPT BROWSER TOOLCHAIN + + All first-party browser logic and browser automation are TypeScript. + Rust still implements cryptography, the API, backups, and deployment. + Browsers execute JavaScript generated by TypeScript; TypeScript adds + compile-time checks and does not replace validation of untrusted input. + +SOURCE LAYOUT + + crates/chat-server/web/app.ts + Interface, session state, history, downloads, and API validation. + crates/chat-server/web/worker.ts + One-shot cryptographic worker; its lifetime ends after each request. + crates/chat-crypto/browser/wasi.ts + Restricted browser WASI host for the unchanged Rust/OpenSSL module. + crates/chat-crypto/browser/protocol.d.ts + Shared API and cryptographic request/response contracts. Declarations + emit no JavaScript and are checked for both browser environments. + crates/chat-crypto/tests/browser.ts + Real WebAssembly compatibility, entropy, and capability tests. + crates/chat-server/tests/browser.ts + Complete browser chat and recovery tests, including GNU LibreJS. + crates/chat-server/tests/progress.ts + Download progress and failure tests, including GNU LibreJS. + tests/browser-support.ts + Checked fixture parsing and typed browser-automation helpers. + + tsconfig.json supplies shared strict checks. The browser, worker, and + test configurations use separate DOM, WebWorker, and Node environments. + Production browser builds cannot accidentally rely on Node APIs. + strict, unchecked indexed access, exact optional properties, unused + declarations/parameters, implicit returns, switch fallthrough, implicit + overrides, and indexed-property access are checked. Type errors prevent + emission. No suppression directives or untyped escape hatches are used. + +DEVELOPMENT + + Install Node >=22.18.0 and npm on the development machine. Root package.json + and package-lock.json pin TypeScript 7.0.2, Playwright 1.64.1, Node type + declarations, platform compiler packages, and their integrity hashes. + There are no npm application/runtime dependencies. TypeScript and + Playwright use the Apache License, Version 2.0; Node declarations and + undici-types use the Expat License. Original notices remain in the + installed packages. SPDX identifiers retain their required spelling. + + Build and check all TypeScript, including browser tests: + + npm run build + + infra/chat/build-typescript.sh installs the locked development packages + with lifecycle scripts disabled, checks all three configurations, and + emits JavaScript under var/build/typescript. The npm cache stays under + .tools/npm-cache. node_modules and generated outputs are ignored by Git. + Generated scripts are readable and unminified; no bundler is needed. + + cargo stack check includes this build, then the strict Rust checks and + cargo-about license generation. cargo stack release builds TypeScript + before packaging the complete production release. + + Check without installing packages or emitting output after npm run build: + + npm run check + + Fetch the pinned Playwright browser versions once: + + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" node_modules/.bin/playwright install chromium firefox + + After building the native chat server and WASI module: + + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:crypto + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:chat + PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:progress + CHAT_LIBREJS=1 PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:chat + CHAT_LIBREJS=1 PLAYWRIGHT_BROWSERS_PATH="$PWD/.tools/browsers" npm run test:progress + + LibreJS variants require the signed Mozilla extension at + .tools/librejs.xpi as documented in CHAT-APPLICATION.txt. The complete + chat test proves LibreJS is active and rejects an unlicensed control. + Run chat variants sequentially because they share the default test port. + npm audit checks the development dependency lock separately from + cargo-deny; it does not audit Rust, browser-delivered code, or containers. + +RELEASES, SOURCE, AND LIBREJS + + Generated app.js, worker.js, and wasi.mjs keep their existing public URLs. + They preserve the AGPL headers and recognized @license/@license-end + markers. The JavaScript license table links each generated file to its + complete corresponding TypeScript and Rust source archive. Classic scripts + and importScripts remain in use for LibreJS compatibility; the migration + introduces no runtime module loader or third-party browser scripts. + + Local native-server tests serve generated files from var/build/typescript. + The release packages those files into bin/chat/web and bin/chat/wasi.mjs. + Containers serve the packaged files. HTML and CSS are copied explicitly, + so TypeScript source files are not substituted for executable JavaScript. + /SOURCE.tar.gz includes TypeScript, shared declarations, all compiler + configurations, the npm lock, tests and build scripts, together with the + existing Cargo-vendored dependencies and verified OpenSSL source archive. + Node/npm/TypeScript are general-purpose development tools, documented and + pinned here; their installed copies and downloaded browsers are excluded. + + Source exports, releases, and backups carry the root npm manifests and + TypeScript configurations. Release activation and restored prebuilt images + need no Node, npm, TypeScript, or Rust installation on the destination. + They retain the single private root .env and existing persistent data. + The source archive excludes that .env, credentials, runtime databases, + exports, .git, node_modules, and build/cache directories. The root + .env.example remains public. No additional environment file is introduced. + + Test the actual generated JavaScript after any compiler upgrade. Static + types cannot guarantee privacy, security, or LibreJS recognition. Browser + storage restrictions, protocol validation, and algorithm choices continue + to be enforced by the existing runtime and Rust implementation. -- cgit v1.2.3