reze: Fix unicode splitting, strict booleans, symbol validation and entropy

Six fixes, each with a test:

1. Character pools are built as arrays of code points, so astral characters
   (emoji) are never split into lone surrogates. Entropy counts code points.
2. Boolean options are parsed strictly: true/false, 1/0, "true"/"false",
   "1"/"0", "yes"/"no", "on"/"off" (case-insensitive). Anything else
   is a 400 naming the option instead of a silent truthy fallback.
3. customSymbols is validated: at most 64 code points, duplicates dropped,
   control characters and whitespace rejected with a 400.
4. Random mode entropy with requireEach now counts only the passwords that
   contain a character of every enabled class (inclusion-exclusion). The
   value is an upper bound and is labelled as such in the API
   (entropyApproximate/entropyNote) and in the UI.
5. docker-compose.yml uses expose instead of ports, so it no longer
   collides with Dokploy's own port 3000.
6. SIGTERM/SIGINT shut the server down gracefully: close the listener, let
   in-flight requests finish, force-exit after 5s. Measured at ~60ms.

The server now exports createServer() so the API can be tested over HTTP
without binding a fixed port.
This commit is contained in:
2026-10-21 09:26:32 +00:00
parent dfe3e94aa4
commit 1965c6efaa
9 changed files with 793 additions and 74 deletions
+4
View File
@@ -98,6 +98,10 @@
<h2>Output</h2>
<p class="hint">Entropy is exact for memorable passphrases. In random mode it is an upper
bound when &ldquo;require at least one of each selected set&rdquo; is on, because the
generator samples the valid passwords non-uniformly.</p>
<div class="field">
<label for="count">How many passwords</label>
<input type="number" id="count" min="1" max="10" step="1" value="1">