feat: implement hashcash proof-of-work for session creation #63

Merged
sneak merged 11 commits from feat/hashcash-pow into main 2026-03-13 00:38:41 +01:00

11 Commits

Author SHA1 Message Date
3cf6f8b47f Merge branch 'main' into feat/hashcash-pow
All checks were successful
check / check (push) Successful in 2m13s
2026-03-13 00:34:16 +01:00
clawbot
cdb808bc4f fix: update internal/irc import to pkg/irc after rebase
All checks were successful
check / check (push) Successful in 4s
2026-03-10 11:41:12 -07:00
user
6fece9a78c fix: rename hashcash→pow_token JSON field reference in README 2026-03-10 11:40:33 -07:00
clawbot
b47a05a4d7 fix: complete pow_token rename in README documentation
Update 4 remaining references where the JSON field name was still
'hashcash' instead of 'pow_token' in README.md.
2026-03-10 11:40:33 -07:00
user
5b4ac75b23 rename JSON field 'hashcash' to 'pow_token' in API request body 2026-03-10 11:40:33 -07:00
clawbot
ba304e322e test: add hashcash validator tests with bits=2
Comprehensive test suite covering:
- Mint and validate with bits=2
- Replay detection
- Resource mismatch
- Invalid format, bad version, bad date
- Insufficient difficulty
- Expired stamps
- Zero bits bypass
- Long date format (YYMMDDHHMMSS)
- Multiple unique stamps
- Higher difficulty stamps accepted at lower threshold
2026-03-10 11:40:33 -07:00
clawbot
f5d1594150 refactor: remove dead doWithHeaders/extraHeaders code from CLI API client 2026-03-10 11:40:33 -07:00
clawbot
09a1dddbd0 refactor: move hashcash stamp from X-Hashcash header to JSON request body
Move the hashcash proof-of-work stamp from the X-Hashcash HTTP header
into the JSON request body as a 'hashcash' field on POST /api/v1/session.

Updated server handler, CLI client, SPA client, and documentation.
2026-03-10 11:40:33 -07:00
clawbot
db4cd9f055 refactor: move CLI code from cmd/ to internal/cli
Move all non-bootstrapping CLI code to internal/cli package.
cmd/neoirc-cli/main.go now contains only minimal bootstrapping
that calls cli.Run(). The App struct, UI, command handlers, poll
loop, and api client are now in internal/cli/ and internal/cli/api/.
2026-03-10 11:40:32 -07:00
clawbot
2f905bda9f fix: move hashcash PoW from build artifact to JSX source
The hashcash proof-of-work implementation was incorrectly added to the
build artifact web/dist/app.js instead of the source file web/src/app.jsx.
Running web/build.sh would overwrite all hashcash changes.

Changes:
- Add checkLeadingZeros() and mintHashcash() functions to app.jsx
- Integrate hashcash into LoginScreen: fetch hashcash_bits from /server,
  compute stamp via Web Crypto API before session creation, show
  'Computing proof-of-work...' feedback
- Remove web/dist/ from git tracking (build artifacts)
- Add web/dist/ to .gitignore
2026-03-10 11:40:18 -07:00
clawbot
f53b8f13eb feat: implement hashcash proof-of-work for session creation
Add SHA-256-based hashcash proof-of-work requirement to POST /session
to prevent abuse via rapid session creation. The server advertises the
required difficulty via GET /server (hashcash_bits field), and clients
must include a valid stamp in the X-Hashcash request header.

Server-side:
- New internal/hashcash package with stamp validation (format, bits,
  date, resource, replay prevention via in-memory spent set)
- Config: NEOIRC_HASHCASH_BITS env var (default 20, set 0 to disable)
- GET /server includes hashcash_bits when > 0
- POST /session validates X-Hashcash header when enabled
- Returns HTTP 402 for missing/invalid stamps

Client-side:
- SPA: fetches hashcash_bits from /server, computes stamp using Web
  Crypto API with batched SHA-256, shows 'Computing proof-of-work...'
  feedback during computation
- CLI: api package gains MintHashcash() function, CreateSession()
  auto-fetches server info and computes stamp when required

Stamp format: 1:bits:YYMMDD:resource::counter (standard hashcash)

closes #11
2026-03-10 11:40:18 -07:00