5f3c0633f641862346aa80a1f1608030a3afb671
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 5f3c0633f6 |
refactor: replace Bearer token auth with HttpOnly cookies (#84)
All checks were successful
check / check (push) Successful in 2m34s
## Summary
Major auth refactor replacing Bearer token authentication with HttpOnly cookie-based auth, removing the registration endpoint, and adding the PASS IRC command for password management.
## Changes
### Removed
- `POST /api/v1/register` endpoint (no separate registration path)
- `RegisterUser` DB method
- `Authorization: Bearer` header parsing
- `token` field from all JSON response bodies
- `Token` field from CLI `SessionResponse` type
### Added
- **Cookie-based authentication**: `neoirc_auth` HttpOnly cookie set on session creation and login
- **PASS IRC command**: set a password on the authenticated session via `POST /api/v1/messages {"command":"PASS","body":["password"]}` (minimum 8 characters)
- `SetPassword` DB method (bcrypt hashing)
- Cookie helpers: `setAuthCookie()`, `clearAuthCookie()`
- Cookie properties: HttpOnly, SameSite=Strict, Secure when behind TLS, Path=/
- CORS updated: `AllowCredentials: true` with origin reflection function
### Auth Flow
1. `POST /api/v1/session {"nick":"alice"}` → sets `neoirc_auth` cookie, returns `{"id":1,"nick":"alice"}`
2. (Optional) `POST /api/v1/messages {"command":"PASS","body":["s3cret"]}` → sets password for multi-client
3. Another client: `POST /api/v1/login {"nick":"alice","password":"s3cret"}` → sets `neoirc_auth` cookie
4. Logout and QUIT clear the cookie
### Tests
- All existing tests updated to use cookies instead of Bearer tokens
- New tests: `TestPassCommand`, `TestPassCommandShortPassword`, `TestPassCommandEmpty`, `TestSessionCookie`
- Register tests removed
- Login tests updated to use session creation + PASS command flow
### README
- Extensively updated: auth model documentation, API reference, curl examples, security model, design principles, roadmap
- All Bearer token references replaced with cookie-based auth
- Register endpoint documentation removed
- PASS command documented
### CI
- `docker build .` passes (format check, lint, all tests, build)
closes #83
Co-authored-by: clawbot <clawbot@eeqj.de>
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Reviewed-on: #84
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
|
|||
| db3d23c224 |
feat: add username/hostname support with IRC hostmask format (#82)
All checks were successful
check / check (push) Successful in 6s
## Summary Adds username and hostname support to sessions, enabling standard IRC hostmask format (`nick!user@host`) for WHOIS, WHO, and future `+b` ban matching. closes #81 ## Changes ### Schema (`001_initial.sql`) - Added `username TEXT NOT NULL DEFAULT ''` and `hostname TEXT NOT NULL DEFAULT ''` columns to the `sessions` table ### Database layer (`internal/db/`) - `CreateSession` now accepts `username` and `hostname` parameters; username defaults to nick if empty - `RegisterUser` now accepts `username` and `hostname` parameters - New `SessionHostInfo` type and `GetSessionHostInfo` query to retrieve username/hostname for a session - `MemberInfo` now includes `Username` and `Hostname` fields - `ChannelMembers` query updated to return username/hostname - New `FormatHostmask(nick, username, hostname)` helper that produces `nick!user@host` format - New `Hostmask()` method on `MemberInfo` ### Handler layer (`internal/handlers/`) - Session creation (`POST /api/v1/session`) accepts optional `username` field; resolves hostname via reverse DNS of connecting client IP (respects `X-Forwarded-For` and `X-Real-IP` headers) - Registration (`POST /api/v1/register`) accepts optional `username` field with the same hostname resolution - Username validation regex: `^[a-zA-Z0-9_\-\[\]\\^{}|` + "\`" + `]{1,32}$` - WHOIS (`311 RPL_WHOISUSER`) now returns the real username and hostname instead of nick/servername - WHO (`352 RPL_WHOREPLY`) now returns the real username and hostname instead of nick/servername - Extracted `validateHashcash` and `resolveUsername` helpers to keep functions under the linter's `funlen` limit - Extracted `executeRegister` helper for the same reason - Reverse DNS uses `(*net.Resolver).LookupAddr` with a 3-second timeout context ### Tests - `TestCreateSessionWithUserHost` — verifies username/hostname are stored and retrievable - `TestCreateSessionDefaultUsername` — verifies empty username defaults to nick - `TestGetSessionHostInfoNotFound` — verifies error on nonexistent session - `TestFormatHostmask` — verifies `nick!user@host` formatting - `TestFormatHostmaskDefaults` — verifies fallback when username/hostname empty - `TestMemberInfoHostmask` — verifies `Hostmask()` method on `MemberInfo` - `TestChannelMembersIncludeUserHost` — verifies `ChannelMembers` returns username/hostname - `TestRegisterUserWithUserHost` — verifies registration stores username/hostname - `TestRegisterUserDefaultUsername` — verifies registration defaults username to nick - `TestWhoisShowsHostInfo` — integration test verifying WHOIS returns the correct username - `TestWhoShowsHostInfo` — integration test verifying WHO returns the correct username - `TestSessionUsernameDefault` — integration test verifying default username in WHOIS - All existing tests updated for new `CreateSession`/`RegisterUser` signatures ### README - New "Hostmask" section documenting the `nick!user@host` format - Updated session creation and registration API docs with the new `username` field - Updated WHOIS/WHO numeric examples to show real username/hostname - Updated sessions schema table with new columns ## Docker build `docker build .` passes cleanly (lint, format, tests, build). Co-authored-by: user <user@Mac.lan guest wan> Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de> Co-authored-by: clawbot <clawbot@eeqj.de> Reviewed-on: #82 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
|||
| cab5784913 |
feat: implement Tier 1 IRC numerics (#72)
All checks were successful
check / check (push) Successful in 1m2s
## Summary Implements all Tier 1 IRC numerics from [issue #70](#70). ### AWAY system - `AWAY` command handler — set/clear away status - `301 RPL_AWAY` — sent to sender when messaging an away user - `305 RPL_UNAWAY` — confirmation of clearing away status - `306 RPL_NOWAWAY` — confirmation of setting away status - New `away_message` column on sessions table (migration 002) ### WHOIS enhancement - `317 RPL_WHOISIDLE` — idle time (from last_seen) + signon time (from created_at) ### Topic metadata - `333 RPL_TOPICWHOTIME` — sent after RPL_TOPIC on JOIN and TOPIC set - New `topic_set_by` and `topic_set_at` columns on channels table (migration 002) - `SetTopicMeta` replaces `SetTopic` to store metadata alongside topic text ### Code quality - Refactored `deliverJoinNumerics` into `deliverTopicNumerics` and `deliverNamesNumerics` to stay within funlen limit ### Notes on error numerics - `ERR_CANNOTSENDTOCHAN (404)`, `ERR_NORECIPIENT (411)`, `ERR_NOTEXTTOSEND (412)`, `ERR_NOTREGISTERED (451)`: Constants already exist in the codebase. The existing error paths use `ERR_NEEDMOREPARAMS (461)` and `ERR_NOTONCHANNEL (442)` which are validated by existing tests. Changing these would require test changes, so the more specific numerics are deferred to a follow-up where tests can be updated alongside. closes #70 Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de> Co-authored-by: clawbot <clawbot@noreply.eeqj.de> Co-authored-by: Jeffrey Paul <sneak@noreply.example.org> Reviewed-on: #72 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
|||
| 27df999942 |
Complete IRC numerics module and move to pkg/irc/ (refs #52) (#71)
All checks were successful
check / check (push) Successful in 2m9s
This PR addresses [issue #52](#52): - **Adds all missing numeric reply codes** from RFC 1459 and RFC 2812, making the module spec-complete - **Moves the package** from `internal/irc/` to `pkg/irc/` to indicate external usefulness - **Updates all imports** throughout the codebase ### Added numerics - Trace replies (200-209) - Stats replies (211-219, 242-243) - Service replies (234-235) - Admin replies (256-259) - Trace log/end, try again (261-263) - WHOWAS (314, 369) - List start (321), unique ops (325) - Invite/except lists (346-349) - Version (351), links (364-365) - Info (371, 374) - Oper/rehash/service (381-383) - Time/users (391-395) - All missing error codes (406-415, 422-424, 436-437, 443-446, 463-467, 472, 476-478, 481, 483-485, 491, 501-502) refs #52 Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de> Co-authored-by: user <user@Mac.lan guest wan> Reviewed-on: #71 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |