Commit Graph
4 Commits
Author SHA1 Message Date
clawbot 129d87d578 Show an IRC listener user what their session sends from other clients (closes #179)
check / check (push) Waiting to run
The IRC listener's relay dropped every line sent under the connection's own nick, so a user on the web client and an IRC client at once never saw on IRC what they did from the web client. The relay now drops nothing by nick. Instead the fan-out skips only the sending client's own queue: the IRC listener passes its own client, whose handler already wrote the echo, and the HTTP API skips none. Channel messages and PARTs now reach the sender's other clients, so an HTTP client gets its own PART event; neoirc-cli ignores it, as it already shows its own part. README.md names the commands covered.

Judgement call: a PRIVMSG or NOTICE sent on an IRC connection is not echoed back to it, as in IRC.

Model: opus-5-5
2026-10-21 15:23:13 +02:00
clawbot 3822cdaf1d Decode the API's actual fields in neoirc-cli (closes #146)
check / check (push) Waiting to run
The CLI read the poll cursor from `lastId` while the server sends
`last_id`, so the cursor stayed at 0 and every poll returned the
whole queue at once. It now reads `last_id`.

/names decodes the member objects the server sends and prints each
nick with `@` for an operator or `+` for a voiced member. /list
prints each channel's name and topic, since the server sends no
member count. StateResponse.Channels decodes channel objects.

/topic with no text prints a usage line and sends nothing, because
the HTTP API has no topic query and a TOPIC without text gets 461.
The help says "Set topic".

The client tests serve the bodies the handlers send, so a wrong JSON
tag in types.go fails a test; another test covers the /names prefixes.

Model: opus-5-5
2026-10-21 02:48:31 +02:00
clawbotandclawbot f829f9e3da Change module path to sneak.berlin/go/neoirc (#99)
check / check (push) Failing after 1m39s
Changes the Go module path from `git.eeqj.de/sneak/neoirc` to `sneak.berlin/go/neoirc`.

All occurrences updated:
- `go.mod` module directive
- All Go import paths across 35 `.go` files (107 import statements)
- All JSON schema `$id` URIs across 30 `.json` files in `schema/`

No functional changes — this is a pure rename of the module path.

`docker build .` passes clean (formatting, linting, all tests, binary build).

closes #98

Co-authored-by: clawbot <clawbot@users.noreply.git.eeqj.de>
Reviewed-on: #99
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
2026-04-01 23:05:41 +02:00
75cecd9803 feat: implement hashcash proof-of-work for session creation (#63)
check / check (push) Successful in 1m2s
## Summary

Implement SHA-256-based hashcash proof-of-work for `POST /session` to prevent abuse via rapid session creation.

closes sneak/chat#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: sneak/chat#63
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
2026-03-13 00:38:41 +01:00