feat: add OPER command and oper-only WHOIS client info

- Add OPER command with NEOIRC_OPER_NAME/NEOIRC_OPER_PASSWORD config
- Add is_oper column to sessions table
- Add RPL_WHOISACTUALLY (338): show client IP/hostname to opers
- Add RPL_WHOISOPERATOR (313): show oper status in WHOIS
- Add GetOperCount for accurate LUSERS oper count
- Fix README schema: add ip/is_oper to sessions, ip/hostname to clients
- Add OPER command documentation and numeric references to README
- Refactor executeWhois to stay under funlen limit
- Add comprehensive tests for OPER auth, oper WHOIS, non-oper WHOIS

Closes #81
This commit is contained in:
clawbot
2026-03-17 10:48:04 -07:00
committed by user
parent 58f958c8d3
commit d85956ca1a
9 changed files with 815 additions and 44 deletions

View File

@@ -46,6 +46,8 @@ type Config struct {
FederationKey string
SessionIdleTimeout string
HashcashBits int
OperName string
OperPassword string
params *Params
log *slog.Logger
}
@@ -78,6 +80,8 @@ func New(
viper.SetDefault("FEDERATION_KEY", "")
viper.SetDefault("SESSION_IDLE_TIMEOUT", "720h")
viper.SetDefault("NEOIRC_HASHCASH_BITS", "20")
viper.SetDefault("NEOIRC_OPER_NAME", "")
viper.SetDefault("NEOIRC_OPER_PASSWORD", "")
err := viper.ReadInConfig()
if err != nil {
@@ -104,6 +108,8 @@ func New(
FederationKey: viper.GetString("FEDERATION_KEY"),
SessionIdleTimeout: viper.GetString("SESSION_IDLE_TIMEOUT"),
HashcashBits: viper.GetInt("NEOIRC_HASHCASH_BITS"),
OperName: viper.GetString("NEOIRC_OPER_NAME"),
OperPassword: viper.GetString("NEOIRC_OPER_PASSWORD"),
log: log,
params: &params,
}