Files
ntfy/visitor/key.go
T
binwiederhier ac9c6b2bac Keep the UnifiedPush rate visitors in the topic service, derive the limiter key at push time
The server uses the topic package instead of the limit service for the rate
visitors: a subscribe sets the rate visitor (user ID and masked IP), a poll,
a stream close and the manager's keepalive record subscriber activity, a
refused push notes an unknown topic (insert-only). The limiter key is derived
on every push from the rate visitor's current tier (refreshed in the
background every minute, never on the publish path), so a downgrade or a
deleted account charges the IP. Before a 404 for an abandoned topic the row
is read from the database. The Matrix gateway rejects the pushkey under the
same 7-day rule; its 12 h per-node rule is gone.
2026-10-31 14:05:37 +00:00

29 lines
936 B
Go

package visitor
import (
"net/netip"
"heckel.io/ntfy/v2/user"
)
// Key returns the identifier a visitor's limits are keyed by: "user:<id>" for a user with a tier,
// or "ip:<prefix>" otherwise, with the IP masked to the configured prefix bits (see Mask). A user
// without a tier shares the IP key with everyone behind the same prefix.
func Key(ip netip.Addr, u *user.User, conf *Config) string {
if u != nil && u.Tier != nil {
return "user:" + u.ID
}
return "ip:" + Mask(ip, conf).String()
}
// Mask returns the IP masked to the configured prefix bits: what the visitors behind one prefix
// share, and what is kept of a subscriber's IP (see package topic). Masking twice is harmless.
func Mask(ip netip.Addr, conf *Config) netip.Addr {
if ip.Is4() {
return netip.PrefixFrom(ip, conf.PrefixBitsIPv4).Masked().Addr()
} else if ip.Is6() {
return netip.PrefixFrom(ip, conf.PrefixBitsIPv6).Masked().Addr()
}
return ip
}