Add NickServ LOGOUT command

Clears the account (RPL_LOGGEDOUT) and renames the user to a
configurable guest nick (default Guest) via SVSNICK.
This commit is contained in:
Jean Chevronnet 2026-07-12 05:06:34 +00:00
parent a382ac8ad3
commit 60fc687162
No known key found for this signature in database
7 changed files with 77 additions and 2 deletions

View file

@ -2,6 +2,7 @@
// sequence in Network-Links (protocols/inspircd.py); mode/burst details get
// firmed up against a live insp4 uplink.
use super::{NetAction, NetEvent, Protocol};
use std::time::{SystemTime, UNIX_EPOCH};
pub struct InspIrcd {
sid: String,
@ -163,6 +164,12 @@ impl Protocol for InspIrcd {
NetAction::Metadata { target, key, value } => {
vec![self.from_us(format!("METADATA {} {} :{}", target, key, value))]
}
// SVSNICK <uid> <newnick> <nickts> — the new nick takes the current
// time as its TS so it wins any collision resolution.
NetAction::ForceNick { uid, nick } => {
let now = SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_secs()).unwrap_or(self.ts);
vec![self.from_us(format!("SVSNICK {} {} {}", uid, nick, now))]
}
NetAction::Raw(s) => vec![s.clone()],
// Internal: the link layer handles this before serialization.
NetAction::DeferRegister { .. } => vec![],

View file

@ -34,6 +34,9 @@ pub enum NetAction {
// Publish network state to the uplink: target "*" is server-global (e.g. the
// advertised SASL mechanism list), otherwise a user uid (e.g. their account).
Metadata { target: String, key: String, value: String },
// Force a user's nick (SVSNICK), e.g. renaming to a guest nick on logout.
// The protocol stamps the new nick's timestamp.
ForceNick { uid: String, nick: String },
Raw(String),
// Internal only, never serialized to the wire: a registration whose password
// still needs its (expensive) key derivation. The link layer runs the