Public password generator with no auth and no npm dependencies. - Server-side generation using crypto.randomInt; two levels: diceware-style memorable passphrases (42abacus-91abdomen) and fully random characters. - Configurable word list (EFF Large / EFF Short), digits per word, separators, capitalization, length, character class toggles, custom symbols and ambiguous-character exclusion. - Light/dark theme matching druid520/site, entropy estimate and strength bar, clipboard copy, options persisted in localStorage. - Dockerfile for Dokploy plus a Woodpecker deploy hook on trunk.
5.7 KiB
reze-test
A small, dependency-free password generator. It has two modes:
- Memorable — diceware-style passphrases shaped like
[num][word]-[num][word]-…, e.g.42abacus-91abdomen. - Random — fully random characters from a configurable character set.
Everything is generated server-side with Node's CSPRNG (crypto.randomInt). There is no
account, no login, no database, and nothing you generate is stored or logged.
Features
- Two randomization levels: memorable passphrases and fully random passwords.
- EFF word lists (7776-word and 1296-word) selectable per request.
- Configurable digits per word, digit separator, group separator and capitalization.
- Configurable length, character classes, custom symbol set, ambiguous-character exclusion and "at least one of each selected set".
- Generate up to 10 passwords at once, each with an entropy estimate and a strength bar.
- One-click copy with a clipboard fallback.
- Light/dark theme with a system-theme fallback, persisted in
localStorage. - Options persisted in
localStorage; generated passwords are never persisted. - No npm dependencies at all — Node.js built-ins only.
Requirements
- Node.js 22 or newer (ESM,
"type": "module").
Run locally
node server.js
The server listens on 0.0.0.0:3000 by default. Override the port with PORT:
PORT=8080 node server.js
Open http://localhost:3000.
Or via the POSIX sh helper, which defaults PORT to 3000:
sh scripts/run.sh
PORT=8080 sh scripts/run.sh
Tests
node --test
API
All API responses are JSON. Every response carries the security headers
X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer,
X-Frame-Options: DENY and a strict Content-Security-Policy.
GET /healthz
Liveness probe used by the Docker HEALTHCHECK.
curl -s localhost:3000/healthz
{"status":"ok"}
GET /api/meta
Describes the available word lists.
curl -s localhost:3000/api/meta
{"lists":[{"id":"eff-large","name":"EFF Large Word List","size":7776},{"id":"eff-short","name":"EFF Short Word List (2.0)","size":1296}]}
POST /api/generate
Body is a JSON object. mode selects the algorithm; count (1–10, default 1) is the
number of passwords to return. Unknown modes, malformed JSON and out-of-range options
are rejected with 400 and a JSON {"error": "…"} body. Request bodies are limited to
64 KB.
Memorable options: words (2–10), digits (0–4), digitSeparator ('' or '-'),
separator ('-', '_', '.', ' ' or ''), capitalization
('none', 'title', 'upper'), list ('eff-large', 'eff-short').
curl -s -X POST localhost:3000/api/generate \
-H 'Content-Type: application/json' \
-d '{"mode":"memorable","words":2,"digits":2,"separator":"-","digitSeparator":"","capitalization":"title","list":"eff-large","count":2}'
{"mode":"memorable","count":2,"passwords":[{"value":"07Sample-29Breach","mode":"memorable","entropy":39.1},{"value":"69Reassign-85Probation","mode":"memorable","entropy":39.1}],"entropy":39.1}
Random options: length (8–64), useLower, useUpper, useDigits, useSymbols,
customSymbols (replaces the default symbol set when non-empty), excludeAmbiguous
(removes 0 O 1 l I |) and requireEach.
curl -s -X POST localhost:3000/api/generate \
-H 'Content-Type: application/json' \
-d '{"mode":"random","length":24,"useLower":true,"useUpper":true,"useDigits":true,"useSymbols":true,"requireEach":true,"count":1}'
{"mode":"random","count":1,"passwords":[{"value":"3V#P@bQ2C4c3;=igw}E(EpnG","mode":"random","entropy":154.6}],"entropy":154.6}
Entropy
- Random mode:
length * log2(poolSize), wherepoolSizeis the size of the union of all enabled character classes. - Memorable mode:
words * log2(listSize) + words * digits * log2(10). Separators and the capitalization scheme add no entropy.
Other paths
Unknown /api/* paths return a JSON 404. Unknown page paths return
public/404.html with HTTP 404. Only GET and HEAD are accepted for static files.
Word lists
| id | list | size |
|---|---|---|
eff-large |
EFF Large Word List | 7776 |
eff-short |
EFF Short Word List (2.0) | 1296 |
Both files live in public/words/ and are loaded once at startup.
- Source: Electronic Frontier Foundation — the EFF Diceware wordlists.
- Licence: Creative Commons Attribution 3.0 Unported (CC BY 3.0), https://www.eff.org/copyright.
The lists contain a few hyphenated entries (drop-down, felt-tip, t-shirt, yo-yo),
which are used verbatim.
Environment variables
| variable | default | description |
|---|---|---|
PORT |
3000 |
TCP port the HTTP server binds to on 0.0.0.0. |
NODE_ENV |
— | Set to production in the image. |
Docker
docker build -t reze-test .
docker run --rm -p 3000:3000 reze-test
Or with compose:
docker compose up --build -d
The image is a single stage based on node:22-alpine, runs as the non-root node user
and ships a HEALTHCHECK that polls http://127.0.0.1:3000/healthz with wget.
Deployment (Dokploy)
- Repository:
druid520/reze-teston Gitea (git.kg.boson.party). - Branch:
trunk. - Build type: Dockerfile (or "Nixpacks" — the app needs nothing but Node).
- Environment variable:
PORT=3000. - Exposed port:
3000. - CI hook: add the repository secret
DEPLOY_URL(the Dokploy deploy webhook URL)..woodpecker.ymlposts to it on every push totrunkso Dokploy rebuilds and redeploys the service.
License
MIT for the code. The bundled word lists are CC BY 3.0, © Electronic Frontier Foundation.