usernames: operator reserved-username blocklist
A plain blocklist for names like @support - separate from the collectible
system, so a reservation has no owner, no price and no "bought on Fragment"
badge.
- reserved_usernames table + migration.
- Enforced in replacePeerUsernameTx (the single editable-username write point:
account.updateUsername, channels.updateUsername, @BotFather /setusername) and
in the collectible mint path; a reserved name returns USERNAME_OCCUPIED.
- admin.Service: ReserveUsername / UnreserveUsername (journalled commands) and
the ReservedUsernames listing.
- adminapi: /v1/reserved-usernames{,/reserve,/unreserve}.
- telesrv-admin panel + a "Reserved Usernames" page in the web UI (dist rebuilt).
- Postgres and in-memory store implementations; the memory registry gains an
optional reserved-name check so tests exercise the same rule.
This commit is contained in:
parent
515038aace
commit
65aaa263b1
23 changed files with 874 additions and 39 deletions
22
internal/store/reserved_username.go
Normal file
22
internal/store/reserved_username.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
// ReservedUsernameStore owns the operator username blocklist. IsReserved is the
|
||||
// hot path consulted on every editable-username write; the rest are the admin
|
||||
// lifecycle.
|
||||
type ReservedUsernameStore interface {
|
||||
// IsReserved reports whether usernameLower (already lowercased) is blocked.
|
||||
IsReserved(ctx context.Context, usernameLower string) (bool, error)
|
||||
// ReserveUsername adds an entry. Returns created=false if it already existed
|
||||
// (the existing reason/actor are kept).
|
||||
ReserveUsername(ctx context.Context, username, reason, actor string) (created bool, err error)
|
||||
// UnreserveUsername removes an entry. Returns removed=false if absent.
|
||||
UnreserveUsername(ctx context.Context, username string) (removed bool, err error)
|
||||
// ReservedUsernames pages the blocklist, newest first.
|
||||
ReservedUsernames(ctx context.Context, filter domain.ReservedUsernameFilter) ([]domain.ReservedUsername, error)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue