- Remove POST /api/v1/register endpoint entirely
- Session creation (POST /api/v1/session) now sets neoirc_auth HttpOnly
cookie instead of returning token in JSON body
- Login (POST /api/v1/login) now sets neoirc_auth HttpOnly cookie
instead of returning token in JSON body
- Add PASS IRC command for setting session password (enables multi-client
login via POST /api/v1/login)
- All per-request auth reads from neoirc_auth cookie instead of
Authorization: Bearer header
- Cookie properties: HttpOnly, SameSite=Strict, Secure when behind TLS
- Logout and QUIT clear the auth cookie
- Update CORS to AllowCredentials:true with origin reflection
- Remove Authorization from CORS AllowedHeaders
- Update CLI client to use cookie jar (net/http/cookiejar)
- Remove Token field from SessionResponse
- Add SetPassword to DB layer, remove RegisterUser
- Comprehensive test updates for cookie-based auth
- Add tests: TestPassCommand, TestPassCommandShortPassword,
TestPassCommandEmpty, TestSessionCookie
- Update README extensively: auth model, API reference, curl examples,
security model, design principles, roadmap
closes#83
## Summary
Implement SHA-256-based hashcash proof-of-work for `POST /session` to prevent abuse via rapid session creation.
closes #11
## What Changed
### Server
- **New `internal/hashcash` package**: Validates hashcash stamps (format, difficulty bits, date/expiry, resource, replay prevention via in-memory spent set with TTL pruning)
- **Config**: `NEOIRC_HASHCASH_BITS` env var (default 20, set to 0 to disable)
- **`GET /api/v1/server`**: Now includes `hashcash_bits` field when > 0
- **`POST /api/v1/session`**: Validates `X-Hashcash` header when hashcash is enabled; returns HTTP 402 for missing/invalid stamps
### Clients
- **Web SPA**: Fetches `hashcash_bits` from `/server`, computes stamp using Web Crypto API (`crypto.subtle.digest`) with batched parallelism (1024 hashes/batch), shows "Computing proof-of-work..." feedback
- **CLI (`neoirc-cli`)**: `CreateSession()` auto-fetches server info and computes a valid hashcash stamp when required; new `MintHashcash()` function in the API package
### Documentation
- README updated with full hashcash documentation: stamp format, computing stamps, configuration, difficulty table
- Server info and session creation API docs updated with hashcash fields/headers
- Roadmap updated (hashcash marked as implemented)
## Stamp Format
Standard hashcash: `1:bits:YYMMDD:resource::counter`
The SHA-256 hash of the entire stamp string must have at least `bits` leading zero bits.
## Validation Rules
- Version must be `1`
- Claimed bits ≥ required bits
- Resource must match server name
- Date within 48 hours (not expired, not too far in future)
- SHA-256 hash has required leading zero bits
- Stamp not previously used (replay prevention)
## Testing
- All existing tests pass (hashcash disabled in test config with `HashcashBits: 0`)
- `docker build .` passes (lint + test + build)
<!-- session: agent:sdlc-manager:subagent:f98d712e-8a40-4013-b3d7-588cbff670f4 -->
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Co-authored-by: clawbot <clawbot@noreply.eeqj.de>
Co-authored-by: user <user@Mac.lan guest wan>
Co-authored-by: Jeffrey Paul <sneak@noreply.example.org>
Reviewed-on: #63
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>