Add nick-protection enforcement: prompt then rename an unidentified user on a registered nick
All checks were successful
CI / check (push) Successful in 3m51s

On connect or nick-change to a registered nick the user isn't identified
to, NickServ prompts them to IDENTIFY and schedules a rename; a short
enforcement sweep renames them to a guest nick after a grace period if
they still haven't. Gated on the uplink's initial burst so a relink does
not enforce every already-online user, and cancelled the moment they
identify (via IDENTIFY or SASL) or leave the nick.
This commit is contained in:
Jean Chevronnet 2026-07-15 17:41:33 +00:00
parent 54ad013e49
commit a26ee722d1
No known key found for this signature in database
3 changed files with 160 additions and 2 deletions

View file

@ -148,6 +148,7 @@ async fn main() -> Result<()> {
engine.lock().await.set_irc_out(irc_tx);
engine.lock().await.set_opers(cfg.opers());
engine.lock().await.set_sid(cfg.server.sid.clone());
engine.lock().await.set_guest_nick(&cfg.server.guest_nick);
engine.lock().await.set_log_channel(cfg.log.as_ref().map(|l| l.channel.clone()));
if let Some(expire) = &cfg.expire {
engine.lock().await.set_expiry(expire.account_ttl(), expire.channel_ttl(), expire.warn_ttl());
@ -188,6 +189,18 @@ async fn main() -> Result<()> {
});
}
// Nick protection: rename anyone who didn't identify to their registered nick
// in time. Short cadence so the grace period is honoured closely.
{
let engine = engine.clone();
tokio::spawn(async move {
loop {
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
engine.lock().await.enforce_sweep();
}
});
}
// ChanFix scores op-time on a shorter cadence so the fix has fresh data.
if enabled("chanfix") {
let engine = engine.clone();