Remove hardcoded reserved names - all reserved usernames now DB-only via admin console
This commit is contained in:
parent
2fb413c8d2
commit
d73b73ac89
|
|
@ -22,32 +22,9 @@ type UsernameCheckResult struct {
|
|||
Message string
|
||||
}
|
||||
|
||||
// ValidateUsernameWithDB checks a handle against reserved names (hardcoded + DB),
|
||||
// inappropriate words, and format rules.
|
||||
// ValidateUsernameWithDB checks a handle against the reserved_usernames DB table,
|
||||
// inappropriate words, and format rules. All reserved names are managed via admin console.
|
||||
func ValidateUsernameWithDB(ctx context.Context, pool *pgxpool.Pool, handle string) UsernameCheckResult {
|
||||
result := ValidateUsername(handle)
|
||||
if result.Violation != UsernameOK {
|
||||
return result
|
||||
}
|
||||
|
||||
// Also check DB reserved_usernames table
|
||||
if pool != nil {
|
||||
var count int
|
||||
err := pool.QueryRow(ctx, `SELECT COUNT(*) FROM reserved_usernames WHERE username = $1`, strings.ToLower(strings.TrimSpace(handle))).Scan(&count)
|
||||
if err == nil && count > 0 {
|
||||
return UsernameCheckResult{
|
||||
UsernameReserved,
|
||||
"This username is reserved. If you officially represent this brand, company, or public figure, you can submit a verification request at support@sojorn.net to claim it.",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return UsernameCheckResult{UsernameOK, ""}
|
||||
}
|
||||
|
||||
// ValidateUsername checks a handle against reserved names, inappropriate words,
|
||||
// and format rules. Returns a result with a user-facing message.
|
||||
func ValidateUsername(handle string) UsernameCheckResult {
|
||||
h := strings.ToLower(strings.TrimSpace(handle))
|
||||
|
||||
// Format check
|
||||
|
|
@ -58,11 +35,15 @@ func ValidateUsername(handle string) UsernameCheckResult {
|
|||
return UsernameCheckResult{UsernameInvalidFormat, "Username can only contain letters, numbers, underscores, and periods."}
|
||||
}
|
||||
|
||||
// Reserved check
|
||||
if isReserved(h) {
|
||||
return UsernameCheckResult{
|
||||
UsernameReserved,
|
||||
"This username is reserved. If you officially represent this brand, company, or public figure, you can submit a verification request at support@sojorn.net to claim it.",
|
||||
// Reserved check — DB only
|
||||
if pool != nil {
|
||||
var count int
|
||||
err := pool.QueryRow(ctx, `SELECT COUNT(*) FROM reserved_usernames WHERE username = $1`, h).Scan(&count)
|
||||
if err == nil && count > 0 {
|
||||
return UsernameCheckResult{
|
||||
UsernameReserved,
|
||||
"This username is reserved. If you officially represent this brand, company, or public figure, you can submit a verification request at support@sojorn.net to claim it.",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,136 +69,6 @@ func ValidateDisplayName(name string) UsernameCheckResult {
|
|||
|
||||
var validHandleRegex = regexp.MustCompile(`^[a-z0-9_.]+$`)
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Reserved usernames
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
func isReserved(h string) bool {
|
||||
// Exact match
|
||||
if reservedSet[h] {
|
||||
return true
|
||||
}
|
||||
// Prefix match (e.g. "sojorn_anything", "admin_anything")
|
||||
for _, prefix := range reservedPrefixes {
|
||||
if strings.HasPrefix(h, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// Contains match for brand names that shouldn't appear even as substrings
|
||||
for _, substr := range reservedSubstrings {
|
||||
if strings.Contains(h, substr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Platform terms, system accounts, and roles
|
||||
var platformReserved = []string{
|
||||
"sojorn", "admin", "administrator", "moderator", "mod",
|
||||
"support", "help", "helpdesk", "system", "official",
|
||||
"root", "superuser", "staff", "team", "security",
|
||||
"abuse", "postmaster", "webmaster", "info", "contact",
|
||||
"noreply", "no_reply", "mailer", "daemon", "bot",
|
||||
"api", "dev", "developer", "ceo", "cto", "cfo", "coo",
|
||||
"founder", "cofounder", "intern", "hr",
|
||||
"legal", "compliance", "privacy", "terms",
|
||||
"news", "press", "media", "blog", "status",
|
||||
"feedback", "report", "bug", "feature",
|
||||
"billing", "payment", "sales", "marketing",
|
||||
"everyone", "all", "here", "channel",
|
||||
"null", "undefined", "anonymous", "unknown",
|
||||
"test", "testing", "demo", "example",
|
||||
"signup", "signin", "login", "logout", "register",
|
||||
"settings", "account", "profile", "dashboard",
|
||||
"home", "feed", "explore", "discover", "search",
|
||||
"notification", "notifications", "message", "messages",
|
||||
"chat", "dm", "dms", "inbox", "outbox",
|
||||
"verified", "verification", "verify",
|
||||
"beacon", "beacons", "quip", "quips",
|
||||
}
|
||||
|
||||
// Major tech companies and social platforms
|
||||
var techCompanyReserved = []string{
|
||||
"google", "apple", "microsoft", "amazon", "meta",
|
||||
"facebook", "instagram", "twitter", "tiktok", "snapchat",
|
||||
"linkedin", "reddit", "pinterest", "youtube", "twitch",
|
||||
"discord", "telegram", "whatsapp", "signal",
|
||||
"netflix", "spotify", "hulu", "disney", "disneyplus",
|
||||
"openai", "chatgpt", "anthropic", "claude",
|
||||
"nvidia", "amd", "intel", "samsung", "sony",
|
||||
"tesla", "spacex", "nasa", "boeing", "airbus",
|
||||
"uber", "lyft", "airbnb", "doordash", "grubhub",
|
||||
"paypal", "stripe", "venmo", "cashapp", "zelle",
|
||||
"coinbase", "binance", "robinhood", "fidelity",
|
||||
"github", "gitlab", "stackoverflow", "atlassian",
|
||||
"slack", "zoom", "teams", "webex",
|
||||
"shopify", "squarespace", "wordpress", "wix",
|
||||
"dropbox", "icloud", "onedrive",
|
||||
"oracle", "ibm", "salesforce", "adobe", "canva",
|
||||
}
|
||||
|
||||
// Major brands and corporations
|
||||
var brandReserved = []string{
|
||||
"nike", "adidas", "puma", "reebok", "underarmour",
|
||||
"cocacola", "coca_cola", "pepsi", "starbucks", "mcdonalds",
|
||||
"walmart", "target", "costco", "kroger", "wholefoods",
|
||||
"bmw", "mercedes", "audi", "porsche", "ferrari",
|
||||
"lamborghini", "ford", "chevrolet", "toyota", "honda",
|
||||
"gucci", "louisvuitton", "chanel", "prada", "hermes",
|
||||
"rolex", "cartier", "tiffany", "burberry",
|
||||
"nfl", "nba", "mlb", "nhl", "mls", "fifa", "ufc",
|
||||
"espn", "cnn", "bbc", "foxnews", "msnbc", "nytimes",
|
||||
"washingtonpost", "wsj", "reuters", "apnews",
|
||||
"marvel", "dccomics", "nintendo", "playstation", "xbox",
|
||||
"paramount", "warner", "universal",
|
||||
}
|
||||
|
||||
// Public figures, politicians, and notable people
|
||||
var publicFigureReserved = []string{
|
||||
"elonmusk", "elon_musk", "jeffbezos", "jeff_bezos",
|
||||
"markzuckerberg", "mark_zuckerberg", "zuckerberg",
|
||||
"timcook", "tim_cook", "billgates", "bill_gates",
|
||||
"satyanadella", "sundarpichai", "samaltman",
|
||||
"joebiden", "joe_biden", "donaldtrump", "donald_trump",
|
||||
"barackobama", "barack_obama", "kamalaharris",
|
||||
"taylorswift", "taylor_swift", "beyonce", "rihanna",
|
||||
"drake", "kanyewest", "kanye_west", "ye",
|
||||
"kimkardashian", "kim_kardashian", "kyliejenner",
|
||||
"cristiano", "ronaldo", "messi", "lebronjames", "lebron_james",
|
||||
"therock", "the_rock", "dwaynejohnson",
|
||||
"mrbeaast", "mrbeast", "pewdiepie", "ninja",
|
||||
"joerogan", "joe_rogan", "oprah",
|
||||
"pope", "popefrancis", "dalailama",
|
||||
}
|
||||
|
||||
var reservedPrefixes = []string{
|
||||
"sojorn_", "sojorn.", "official_", "official.",
|
||||
"admin_", "admin.", "mod_", "mod.",
|
||||
"support_", "support.", "team_", "team.",
|
||||
"staff_", "staff.", "system_", "system.",
|
||||
}
|
||||
|
||||
var reservedSubstrings = []string{
|
||||
"sojorn",
|
||||
}
|
||||
|
||||
var reservedSet map[string]bool
|
||||
|
||||
func init() {
|
||||
reservedSet = make(map[string]bool)
|
||||
for _, lists := range [][]string{
|
||||
platformReserved,
|
||||
techCompanyReserved,
|
||||
brandReserved,
|
||||
publicFigureReserved,
|
||||
} {
|
||||
for _, name := range lists {
|
||||
reservedSet[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Inappropriate content filter
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue