reze 58f585b691 reze: Add Node.js password generator with memorable and random modes
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.
2026-10-21 09:01:42 +00:00

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), where poolSize is 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.

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-test on 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.yml posts to it on every push to trunk so Dokploy rebuilds and redeploys the service.

License

MIT for the code. The bundled word lists are CC BY 3.0, © Electronic Frontier Foundation.

S
Description
No description provided
Readme
107 KiB
Languages
JavaScript 84.1%
CSS 7.5%
HTML 7.3%
Shell 0.6%
Dockerfile 0.5%