发布 0.2.1 并完善工具边界与安全性
This commit is contained in:
@@ -15,8 +15,10 @@ This file is mandatory for AI and coding agents working in this repository. Read
|
||||
- Web Tools is an anonymous-access, self-hosted Vue 3 + TypeScript browser-local tools application with a zero-dependency Node.js static/configuration server.
|
||||
- The default production port is `9000`. Port `8081` is only the local Vite development proxy target.
|
||||
- The application is anonymous. Do not add login, accounts, favorites, sponsorship, analytics, telemetry, advertising, CDN assets, or a database.
|
||||
- A deployment may place Cloudflare in front of the origin. The server's per-response CSP nonce exists only to support Cloudflare JavaScript Detections without `unsafe-inline`; it is not permission to add application analytics, telemetry, or remote tool processing.
|
||||
- Tool inputs, keys, files, images, and results must remain inside the current browser tab. Do not send them to the Node server, a third-party API, or any remote service.
|
||||
- `/setting` is a fixed, unlisted route for navigation management. It has no authentication and is not a security boundary. Anyone who can access the application can open it and change the globally shared navigation order.
|
||||
- `/tools/setting` is the fixed, unlisted route for navigation management. It has no authentication and is not a security boundary. Anyone who can access the application can open it and change the globally shared navigation order.
|
||||
- The first-run default category order is `encoding`, `checksum`, `crypto`, `formatting`, `image`; an existing saved navigation file keeps its custom order and is never reset by a release.
|
||||
- The server persists only navigation configuration. Preserve `data/navigation.json` and the configured external data directory; writes must remain temporary-file plus atomic-replace operations.
|
||||
- Multiple users and tabs may use every tool concurrently. Their calculation state must remain independent; only navigation order is globally shared.
|
||||
|
||||
@@ -34,14 +36,14 @@ This file is mandatory for AI and coding agents working in this repository. Read
|
||||
|
||||
## Stable tool behavior
|
||||
|
||||
- ASCII/Hex uses UTF-8. Hex input accepts continuous text or chunks separated by whitespace, English commas, or Chinese commas, with an optional `0x` prefix on each chunk. Invalid UTF-8 must fail rather than silently replace bytes.
|
||||
- UTF-8 / Hex has the permanent tool ID `utf8-hex` and route `/tools/utf8-hex`. It uses strict UTF-8 conversion. Hex input accepts continuous text or chunks separated by whitespace, English commas, or Chinese commas, with an optional `0x` prefix on each chunk. Invalid UTF-8 must fail rather than silently replace bytes.
|
||||
- Base64 supports standard and URL-safe input. Decoded output supports strict UTF-8, continuous Hex, and `0xNN, ...` byte arrays. Reject invalid characters, padding placement, lengths, and non-canonical trailing bits.
|
||||
- AES-128-CMAC follows RFC 4493. The key is exactly 16 bytes of Hex and accepts continuous input or whitespace/comma/Chinese-comma-separated chunks with optional `0x` prefixes. Hex messages use the same parser.
|
||||
- CRC supports BIN and multi-block Intel HEX, CRC-8/16/32/64 presets, and custom `Width`, `Poly`, `Init`, `XorOut`, `RefIn`, and `RefOut`. Combined data is ordered by address without filling gaps, and per-block results remain available.
|
||||
- AES-CMAC accepts exactly 16, 24, or 32 key bytes for AES-128, AES-192, or AES-256, defaulting to 16 bytes. Never pad or truncate the key. Key and Hex-message input accepts continuous Hex or whitespace/comma/Chinese-comma-separated chunks with optional `0x` prefixes. The CMAC tag remains exactly 16 bytes for every key size. Preserve RFC 4493 AES-128 and NIST SP 800-38B AES-192/256 vectors.
|
||||
- CRC supports BIN and multi-block Intel HEX, CRC-8/16/32/64 presets, and custom `Width`, `Poly`, `Init`, `XorOut`, `RefIn`, and `RefOut`. The Chinese UI labels `RefIn`/`RefOut` as input/output bit reversal; these flags do not reverse byte order or the complete input. Combined data is ordered by address without filling gaps, and per-block results remain available.
|
||||
- Firmware Hash accepts Intel HEX and computes SHA-256 and SHA-512. Effective-data mode concatenates sorted blocks without gap filling. Block-header mode prepends exactly two binary uint32 values, `startAddress` and data-only `dataLength`, to every block. Both fields are four bytes; Big Endian is the default; total input is `Header1 || Data1 || Header2 || Data2 ...`. Never hash a textual Hex representation of the header.
|
||||
- RSA allows 2048, 3072, and 4096-bit keys with public exponent 65537. Prefer Web Crypto; the node-forge fallback must be seeded from `crypto.getRandomValues`. Export public SPKI PEM, private PKCS#8 PEM, and separately copyable N/E continuous Hex or byte arrays.
|
||||
- Secure random output comes only from `crypto.getRandomValues`, is limited to 1-65,536 bytes, and supports continuous Hex, spaced Hex, and byte arrays. Changing display format must not regenerate bytes.
|
||||
- JSON/XML formatting, minification, validation, and syntax highlighting stay local. When highlighting limits are exceeded, render the complete result as plain text rather than truncating it.
|
||||
- RSA allows 2048, 3072, and 4096-bit keys with public exponent 65537. Prefer Web Crypto; dynamically load the node-forge fallback only when needed, and seed it from `crypto.getRandomValues`. Export public SPKI PEM, private PKCS#8 PEM, and separately copyable N/E continuous Hex or byte arrays.
|
||||
- Secure random output comes only from `crypto.getRandomValues`, defaults to 16 bytes, is limited to 1-65,536 bytes, and supports continuous Hex, spaced Hex, and byte arrays. Changing display format must not regenerate bytes. Missing or failed cryptographic sources must fail closed without a pseudorandom fallback.
|
||||
- JSON/XML formatting, minification, validation, and syntax highlighting stay local. XML parser failures are identified by the browser parser-error namespace; a valid user element named `parsererror` must not be rejected. When highlighting limits are exceeded, render the complete result as plain text rather than truncating it.
|
||||
- PNG/ICO processing stays local and must enforce both compressed-file and decoded-pixel limits before costly rendering or allocation.
|
||||
|
||||
## Intel HEX and asynchronous safety
|
||||
@@ -49,6 +51,8 @@ This file is mandatory for AI and coding agents working in this repository. Read
|
||||
- Treat every address, length, end-address, offset, and allocation calculation as checked uint32 arithmetic. JavaScript bitwise operators are signed 32-bit and must not be used as unchecked address arithmetic.
|
||||
- Validate record syntax, byte counts, checksums, control-record lengths/addresses, EOF placement, extended addresses, and the `0xFFFFFFFF` boundary.
|
||||
- Sort records by absolute address, merge contiguous records, deduplicate identical overlaps, and reject conflicting overlaps. Enforce record, block, and effective-byte limits before allocating combined buffers.
|
||||
- The default Intel HEX effective-data allocation limit is 64 MiB (`DEFAULT_MAX_INTEL_HEX_BYTES`); keep it aligned with `MAX_FIRMWARE_FILE_SIZE` and the limits table in `README.zh-CN.md`.
|
||||
- Navigation GET normalization and PUT writes are serialized within each Node process. Do not remove that lock without replacing it with an equally strong concurrency design.
|
||||
- CRC and Firmware Hash may share the reviewed Intel HEX parser but must keep separate calculation logic, Worker protocols, and Vue state.
|
||||
- File replacement, clear, mode change, option change, repeated generation, and component unmount can invalidate asynchronous work. Terminate obsolete Workers where possible and use monotonically increasing request/version IDs. A stale Worker, file read, image decode, or key-generation result must never replace current state.
|
||||
- Clear the native file input value after handling a selection so choosing the same file again still emits a change event.
|
||||
@@ -61,15 +65,16 @@ This file is mandatory for AI and coding agents working in this repository. Read
|
||||
- Keep desktop controls compact. Use stable grid/flex constraints and allow controls to become full-width where appropriate on narrow screens.
|
||||
- Prevent horizontal page overflow, clipped controls, nested scrolling accidents, text overlap, layout shifts, and unbounded result columns. Long Hex, hashes, filenames, and table cells require explicit wrapping or contained scrolling.
|
||||
- Version information remains at the bottom of the sidebar and is read from `package.json`. Every page footer displays exactly `Copyright © mid All Rights Reserved.`
|
||||
- Do not add a visible link to `/setting`, explanatory marketing copy, login UI, favorites, or sponsorship UI.
|
||||
- Do not add a visible link to `/tools/setting`, explanatory marketing copy, login UI, favorites, or sponsorship UI.
|
||||
- Every native `input`, `select`, and `textarea` must have a unique `id` and stable `name`. `TextEditor` requires an explicit `id` and uses it as the default `name`; preserve the existing implicit or explicit label association.
|
||||
- Preserve the application icon contract under `public/`: `favicon.svg`, a 16/32/48-frame `favicon.ico`, `apple-touch-icon.png` at 180x180, `icon-192.png`, `icon-512.png`, `icon-maskable-512.png`, and `site.webmanifest`. Keep the icon visually aligned with the sidebar brand and keep the maskable artwork inside its safe zone.
|
||||
- The manifest is metadata/install-ready only. Do not add a Service Worker, offline cache, install prompt, splash-screen bundle, Safari mask icon, legacy `browserconfig.xml`, redundant Apple sizes, or separate 16/32 PNG favicons unless requirements explicitly change.
|
||||
- Preserve the share metadata contract: the single user-facing description is exactly `一个匿名访问、自托管的浏览器本地工具箱`, represented by the standard HTML description and the identical `og:description` compatibility field. Do not add a custom share image, other Open Graph or platform-specific metadata, platform crawlers, route-specific previews, tool lists, or user data. Sharing clients may fall back to the document title and existing favicon assets, but their final preview and cache behavior remain platform-controlled.
|
||||
- For UI work, verify a wide desktop, an intermediate width around 801-1040 px, and mobile portrait around 390 x 844 in a real browser. Check direct routes, refresh, navigation, search, `/setting`, both themes, console errors, and network requests.
|
||||
- For UI work, verify a wide desktop, an intermediate width around 801-1040 px, and mobile portrait around 390 x 844 in a real browser. Check direct routes, refresh, navigation, search, `/tools/setting`, both themes, console errors, and network requests.
|
||||
|
||||
## Adding a tool
|
||||
|
||||
1. Choose a permanent, unique kebab-case ID. Published IDs must not change because routes and saved navigation depend on them.
|
||||
1. Choose a permanent, unique kebab-case ID. IDs must remain stable after publication because routes and saved navigation depend on them. The recorded pre-0.2.0 correction from `ascii-hex` to `utf8-hex` is the sole existing ID migration. `setting` is reserved by `/tools/setting` and cannot be used as a tool ID.
|
||||
2. Add pure logic and normal, invalid, boundary, resource-limit, and known-vector tests.
|
||||
3. Add one Vue component under `src/tools/` using shared components and responsive styles.
|
||||
4. Add matching metadata to `shared/tool-catalog.json` and its default position to `shared/default-navigation.json`. Only change navigation `version: 1` for a schema migration, not for a new tool.
|
||||
@@ -77,6 +82,7 @@ This file is mandatory for AI and coding agents working in this repository. Read
|
||||
6. Verify that an old saved `navigation.json` retains its order and receives the missing tool after the Node process restarts and navigation is next loaded.
|
||||
|
||||
IDs must remain synchronized across the catalog, default navigation, icon map, and component registry. Existing catalog tests enforce this contract.
|
||||
The `ascii-hex` ID is a legacy input accepted only while normalizing existing `navigation.json` files; it migrates in place to `utf8-hex`. Do not restore it as a catalog ID, component key, form-field prefix, or route.
|
||||
|
||||
## Deployment and release
|
||||
|
||||
@@ -85,6 +91,9 @@ IDs must remain synchronized across the catalog, default navigation, icon map, a
|
||||
- The Windows update flow requires a clean `main` checkout and uses `git pull --ff-only`. Preserve external `C:\ProgramData\WebTools\data` state.
|
||||
- Running `web-tools.ps1` without an action is an interactive user entry point and must keep the start/update/update-without-start/exit menu. Scheduled tasks and automation must pass an explicit `start` or `update` action so they never wait for input.
|
||||
- New catalog data is loaded by the Node process at startup. Rebuilding `dist` alone is insufficient after catalog changes; restart the server and refresh already-open browser pages.
|
||||
- Preserve the per-response 128-bit CSP nonce generated with `node:crypto`. Cloudflare parses the nonce from the response header for JavaScript Detections. Never replace it with a fixed nonce or `unsafe-inline`; keep HTML uncached/no-cache so a document and its nonce cannot become mismatched.
|
||||
- Keep one-year immutable caching limited to fingerprinted files under `dist/assets/`. Stable filenames such as HTML, favicon assets, and `site.webmanifest` must use `no-cache` so a deployment can replace them safely.
|
||||
- Browser navigation PUT requests carrying Fetch Metadata must be same-origin. Requests without `Sec-Fetch-Site` remain supported for non-browser administration, so document this as defense in depth and never as authentication.
|
||||
- If a single EXE is later authorized, use Node.js SEA with embedded read-only web/catalog assets and an external writable data directory. Add per-architecture builds, asset-read abstraction, Windows smoke tests, replacement/update instructions, and optional Authenticode signing. Derive EXE version metadata from `package.json`; do not create another manually maintained version source. Do not commit generated executables.
|
||||
|
||||
For a release, synchronize these five tracked files:
|
||||
|
||||
Reference in New Issue
Block a user