Commit graph

12 commits

Author SHA1 Message Date
930198b826
Expand OperServ: SQLINE nick bans, GLOBAL, and KILL
Generalise the network-ban store to carry the ircd X-line kind (defaulted
to the user@host G-line for existing records) so one event-sourced,
lazily-expiring, burst-reasserted list backs every ban type, and drive
ADD/DEL/LIST from one implementation per kind:

- AKILL stays the user@host G-line; SQLINE is a nick Q-line, its mask
  validated as a nick glob (an @ is refused so an AKILL-shaped mask can't
  become an over-broad nick ban). Both are keyed by (kind, mask).
- GLOBAL <message> announces to every user via a $* server-glob notice.
- KILL <nick> [reason] disconnects a user, attributed to the operator.

All four are admin-gated, and OperServ itself stays invisible to non-opers.
Bans and kills go out as typed actions (AddLine/DelLine/KillUser) the ircd
link serialises to ADDLINE/DELLINE/KILL.
2026-07-14 00:45:52 +00:00
d2c1d076fb
Add OperServ with AKILL network bans
The first operator module. AKILL manages network bans as a typed,
event-sourced list with lazy expiry, mirroring the patterns the other
modules use:

- AKILL ADD [+expiry] <user@host> <reason> stores the ban and drives an
  ircd G-line (applied to matching users already online and to future
  connections); AKILL DEL <mask|number> lifts it; AKILL LIST [pattern]
  shows the live list, numbered. Admin-only.
- Bans are Global events, so every node holds the list and re-asserts each
  one at burst with its remaining duration. Expired bans are hidden lazily
  and dropped at compaction.
- Masks are normalised to user@host (a nick! prefix is stripped, both
  sides lowercased) and an all-wildcard mask is refused.

Email (send_email) is already reachable from the api via ServiceCtx, and
adds AddLine/DelLine to the action vocabulary for any future X-line kinds.
2026-07-14 00:12:29 +00:00
5d67133295
Strip CR/LF/NUL from every outbound s2s line
Free-form trailing text (message bodies, kick reasons, topics, metadata)
now passes through a single sanitizing choke-point in the serializer, so
no such text can carry an embedded line break that would smuggle a second
command onto the link. Line-based input closes the obvious path today,
but sanitizing at the point of serialization removes the whole class
regardless of where the text originated (federation, config, future
non-line sources).
2026-07-13 23:34:51 +00:00
2fd5676ff2
Clippy sweep: clean across the workspace
- Box the oversized enum variants (Event::AccountRegistered, gossip
  Msg::Entry) so small events aren't sized to a full Account; serde is
  transparent so the wire/log format is unchanged.
- Use the configured server description in the SERVER line (it was
  hardcoded and the config field went unread).
- Derive the ChanServ SET label from the ChanSetting (drops toggle's 8th
  arg); rename inspircd from_us -> sourced.
- allow the two framework-idiom lints with rationale (tonic's Status in
  authorize; the guest-rename handler's inherent arg count).
- Auto-fixed map_or/contains/split_once style lints.
2026-07-13 23:30:51 +00:00
898461d1c2
HostServ: ident@host vhosts (CHGIDENT)
A vhost may be ident@host, not just host: apply_vhost splits it and sends
CHGIDENT for the ident plus CHGHOST for the host. valid_vhost validates
the optional ident part; ON/SET/ACTIVATE/identify all route through
apply_vhost, so a bare host still works unchanged. New SetIdent action.
2026-07-13 22:04:16 +00:00
1227e26b95
Add HostServ: virtual hosts
New HostServ pseudo-service assigns and applies vhosts. A vhost is a typed
Option<Vhost>{host,setter,ts} on the account (VhostSet/VhostDeleted events),
applied to the displayed host on identify and re-applied by ON; OFF restores
the normal host for the session. Operators SET/DEL (applied at once to
online sessions) and LIST; hosts are validated as dot-separated labels.

New SetHost NetAction -> InspIRCd ENCAP <target-sid> CHGHOST <uid> <host>.
2026-07-13 21:26:38 +00:00
5d1bfb3144
BotServ: DONTKICKVOICES, plus neutral code comments
KICK <#channel> DONTKICKVOICES <on|off> exempts voiced users from the
kickers. The network view now tracks +v the same way it tracks +o: a new
ChannelVoice event is parsed from FMODE +v/-v and from +v join prefixes,
and set_voice/is_voiced mirror set_op/is_op (voice is cleared on part and
quit). scan_ops generalised to scan_status for any status letter.

Also scrubbed third-party project name-drops from code comments.
2026-07-13 18:19:37 +00:00
b25870e14b
botserv: ASSIGN / UNASSIGN a bot to a channel
A channel gains a typed assigned_bot (event-logged, snapshotted). ASSIGN
<#channel> <bot> / UNASSIGN <#channel> is founder-gated (or admin oper). The
engine reconcile now also diffs channel assignments against tracked bot
memberships: a live bot IJOINs its assigned channels and PARTs unassigned ones
(new ServiceJoin/ServicePart actions), at burst and after commands; a deleted
bot's memberships are dropped. Engine test for join-on-assign / part-on-unassign.
2026-07-13 13:42:14 +00:00
577c05ad2e
memoserv: complete + improve the memo service
Finish MemoServ on the typed, event-logged memo model: Db memo_send/list/read/
del/unread_memos + Store facade, and a new fedserv-memoserv crate (a default
service). Beyond the basics: SEND caps a mailbox (30) so nobody's flooded, READ
takes <num>|NEW|ALL, DEL takes <num>|ALL, LIST previews and flags unread, and
NickServ notifies you of waiting memos on login. Memos persist and federate
(Global scope) like other account data. Also lands NetAction::QuitUser (BotServ
plumbing). Data + delivery/login-notify tests.
2026-07-13 04:50:27 +00:00
4600ee062c
chanserv: SET TOPICLOCK and KEEPTOPIC (topic subsystem)
Adds topic tracking: a TopicChange event (parsed from InspIRCd FTOPIC, our own
changes filtered by SID like FMODE) and a stored topic on the channel, folded
through the event log. TOPICLOCK reverts a topic change by a user without
op-level access back to the stored topic; KEEPTOPIC remembers the topic and
restores it when a registered channel is recreated. Both via the typed
ChanSettings path; shown in INFO. Parse + engine tests cover both.
2026-07-13 03:30:04 +00:00
75ba9b35b4
nickserv: AJOIN auto-join list
Adds the account auto-join list (AJOIN ADD/DEL/LIST): NickServ SVSJOINs you
into your listed channels each time you identify. The list is a typed
Vec<AjoinEntry> on the account, folded through the event log like the cert and
akick lists (persists and replays; no separate store), reached by modules
through the Store trait. New ForceJoin action serialises to InspIRCd SVSJOIN.
Shown in INFO. Operates on the caller's own account; the oper form for other
users waits on a privilege system.
2026-07-13 02:09:03 +00:00
596630df53
modules: split services and the ircd link into external crates
nickserv, chanserv and the InspIRCd protocol move out of the binary into their
own workspace crates (fedserv-nickserv, fedserv-chanserv, fedserv-inspircd),
each depending only on fedserv-api. human_time and the branded account emails
move into the SDK crate so a module needs nothing from core; the engine keeps
its own inherent methods and builds emails via fedserv-api too. The bin now
constructs each module from its crate instead of an in-tree #[path] include.
Proves the SDK is self-sufficient: a third-party module is the same shape.
2026-07-13 01:33:56 +00:00