dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit 4f694f191e5834e91b8d1e26f932f302f7165702
parent 1b5f3c6ecf56ac266d697eed117beb2a12171349
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Thu, 25 May 2023 23:31:31 -0700

strongly typed Username

Diffstat:
Mpkg/database/database.go | 12++++++------
Mpkg/database/tableChatMessages.go | 8++++----
Mpkg/database/tableIgnoredUsers.go | 2+-
Mpkg/database/tableLinks.go | 6+++---
Mpkg/database/tableUsers.go | 26++++++++++++++------------
Mpkg/database/table_forum_threads.go | 2+-
Mpkg/database/utils/utils.go | 8++++----
Mpkg/managers/managers.go | 10+++++-----
Mpkg/web/handlers/admin.go | 4++--
Mpkg/web/handlers/api/v1/battleship.go | 6+++---
Mpkg/web/handlers/api/v1/chess.go | 6+++---
Mpkg/web/handlers/api/v1/handlers.go | 8++++----
Mpkg/web/handlers/api/v1/messages.qtpl | 20++++++++++----------
Mpkg/web/handlers/api/v1/messages.qtpl.go | 28++++++++++++++--------------
Mpkg/web/handlers/api/v1/slashInterceptor.go | 70+++++++++++++++++++++++++++++++++++-----------------------------------
Mpkg/web/handlers/api/v1/snippetInterceptor.go | 4++--
Mpkg/web/handlers/api/v1/topBarHandler.go | 18+++++++++---------
Mpkg/web/handlers/api/v1/werewolf.go | 32++++++++++++++++----------------
Mpkg/web/handlers/chat.go | 2+-
Mpkg/web/handlers/data.go | 14+++++++-------
Mpkg/web/handlers/handlers.go | 26+++++++++++++-------------
21 files changed, 157 insertions(+), 155 deletions(-)

diff --git a/pkg/database/database.go b/pkg/database/database.go @@ -29,8 +29,8 @@ type IDkfDB interface { AddLinkTag(linkID, tagID int64) (err error) AddUserToRoomGroup(roomID RoomID, groupID GroupID, userID UserID) (out ChatRoomUserGroup, err error) AddWhitelistedUser(userID, whitelistedUserID UserID) - CanRenameTo(oldUsername, newUsername string) error - CanUseUsername(username string, isFirstUser bool) error + CanRenameTo(oldUsername, newUsername Username) error + CanUseUsername(username Username, isFirstUser bool) error ClearRoomGroup(roomID RoomID, groupID GroupID) (err error) CreateChatReaction(userID UserID, messageID, reaction int64) error CreateChatRoomGroup(roomID RoomID, name, color string) (out ChatRoomGroup, err error) @@ -100,7 +100,7 @@ type IDkfDB interface { DoCreateSession(userID UserID, userAgent string) Session GetActiveUserSessions(userID UserID) (out []Session) GetCategories() (out []CategoriesResult, err error) - GetChatMessages(roomID RoomID, username string, userID UserID, displayPms PmDisplayMode, mentionsOnly, displayHellbanned, displayIgnored, displayModerators, displayIgnoredMessages bool, minID1 int64) (out ChatMessages, err error) + GetChatMessages(roomID RoomID, username Username, userID UserID, displayPms PmDisplayMode, mentionsOnly, displayHellbanned, displayIgnored, displayModerators, displayIgnoredMessages bool, minID1 int64) (out ChatMessages, err error) GetChatRoomByID(roomID RoomID) (out ChatRoom, err error) GetChatRoomByName(roomName string) (out ChatRoom, err error) GetChessSubscribers() (out []User, err error) @@ -163,7 +163,7 @@ type IDkfDB interface { GetUserByApiKey(user *User, apiKey string) error GetUserByID(userID UserID) (out User, err error) GetUserBySessionKey(user *User, sessionKey string) error - GetUserByUsername(username string) (out User, err error) + GetUserByUsername(username Username) (out User, err error) GetUserChatInboxMessages(userID UserID) (msgs []ChatInboxMessage, err error) GetUserChatInboxMessagesSent(userID UserID) (msgs []ChatInboxMessage, err error) GetUserInboxMessagesCount(userID UserID) (count int64) @@ -187,7 +187,7 @@ type IDkfDB interface { GetUsersByUsername(usernames []string) (out []User, err error) GetUsersSubscribedToForumThread(threadID ForumThreadID) (out []UserForumThreadSubscription, err error) GetVerifiedUserBySessionID(token string) (out User, err error) - GetVerifiedUserByUsername(username string) (out User, err error) + GetVerifiedUserByUsername(username Username) (out User, err error) GetWhitelistedUsers(roomID RoomID) (out []ChatRoomWhitelistedUser, err error) GetXmrInvoiceByAddress(address string) (out XmrInvoice, err error) IgnoreMessage(userID UserID, messageID int64) @@ -199,7 +199,7 @@ type IDkfDB interface { IsUserSubscribedToForumThread(userID UserID, threadID ForumThreadID) bool IsUserSubscribedToRoom(userID UserID, roomID RoomID) bool IsUserWhitelistedInRoom(userID UserID, roomID RoomID) bool - IsUsernameAlreadyTaken(username string) bool + IsUsernameAlreadyTaken(username Username) bool NewAudit(authUser User, log string) RmBlacklistedUser(userID, blacklistedUserID UserID) RmUserFromRoomGroup(roomID RoomID, groupID GroupID, userID UserID) (err error) diff --git a/pkg/database/tableChatMessages.go b/pkg/database/tableChatMessages.go @@ -89,7 +89,7 @@ type ChatMessage struct { Rev int64 // Revision, is incr every time a message is edited } -func (m *ChatMessage) GetProfile(authUser *User) string { +func (m *ChatMessage) GetProfile(authUser *User) Username { if m.ToUserID != nil && *m.ToUserID != authUser.ID { return m.ToUser.Username } @@ -134,8 +134,8 @@ func (m *ChatMessage) MarshalJSON() ([]byte, error) { UUID string Message string RawMessage string - Username string - ToUsername *string `json:"ToUsername,omitempty"` + Username Username + ToUsername *Username `json:"ToUsername,omitempty"` CreatedAt string IsHellbanned bool } @@ -321,7 +321,7 @@ const ( PmNone ) -func (d *DkfDB) GetChatMessages(roomID RoomID, username string, userID UserID, displayPms PmDisplayMode, mentionsOnly, displayHellbanned, displayIgnored, displayModerators, displayIgnoredMessages bool, minID1 int64) (out ChatMessages, err error) { +func (d *DkfDB) GetChatMessages(roomID RoomID, username Username, userID UserID, displayPms PmDisplayMode, mentionsOnly, displayHellbanned, displayIgnored, displayModerators, displayIgnoredMessages bool, minID1 int64) (out ChatMessages, err error) { cmp := func(t, t2 ChatMessage) bool { return t.ID > t2.ID } diff --git a/pkg/database/tableIgnoredUsers.go b/pkg/database/tableIgnoredUsers.go @@ -19,7 +19,7 @@ func (d *DkfDB) GetIgnoredUsers(userID UserID) (out []IgnoredUser, err error) { return } -func (d *DkfDB) GetIgnoredUsersUsernames(userID UserID) (out []string, err error) { +func (d *DkfDB) GetIgnoredUsersUsernames(userID UserID) (out []Username, err error) { err = d.db.Model(&IgnoredUser{}). Joins("INNER JOIN users ON users.id = ignored_users.ignored_user_id"). Where("ignored_users.user_id = ?", userID). diff --git a/pkg/database/tableLinks.go b/pkg/database/tableLinks.go @@ -26,7 +26,7 @@ type Link struct { OwnerUser *User } -func (l Link) GenOwnershipCert(signerUsername string) string { +func (l Link) GenOwnershipCert(signerUsername Username) string { return fmt.Sprintf(""+ "DarkForest ownership certificate\n"+ "\n"+ @@ -175,8 +175,8 @@ ORDER BY t.name`, linkID).Scan(&out).Error // LinksCategoriesLinks many-to-many table type LinksCategoriesLinks struct { - LinkID int64 - CategoryID int64 + LinkID int64 + CategoryID int64 } func (d *DkfDB) GetTags() (out []LinksTag, err error) { diff --git a/pkg/database/tableUsers.go b/pkg/database/tableUsers.go @@ -15,6 +15,8 @@ import ( type UserID int64 +type Username string + func (u UserID) String() string { return utils.FormatInt64(int64(u)) } @@ -23,7 +25,7 @@ func (u UserID) String() string { type User struct { ID UserID Avatar []byte - Username string + Username Username GPGPublicKey string AgePublicKey string Password string `json:"-"` @@ -312,12 +314,12 @@ func (d *DkfDB) GetUserByID(userID UserID) (out User, err error) { } // GetUserByUsername ... -func (d *DkfDB) GetUserByUsername(username string) (out User, err error) { +func (d *DkfDB) GetUserByUsername(username Username) (out User, err error) { err = d.db.First(&out, "username = ? COLLATE NOCASE", username).Error return } -func (d *DkfDB) GetVerifiedUserByUsername(username string) (out User, err error) { +func (d *DkfDB) GetVerifiedUserByUsername(username Username) (out User, err error) { err = d.db.First(&out, "username = ? COLLATE NOCASE AND verified = 1", username).Error return } @@ -431,7 +433,7 @@ func ValidateUsername(username string, isFirstUser bool) (bool, error) { return true, nil } -func isUsernameReserved(username string) bool { +func isUsernameReserved(username Username) bool { return false } @@ -449,7 +451,7 @@ func (d *DkfDB) GetRecentUsersCount() int64 { } // IsUsernameAlreadyTaken ... -func (d *DkfDB) IsUsernameAlreadyTaken(username string) bool { +func (d *DkfDB) IsUsernameAlreadyTaken(username Username) bool { var count int64 d.db.Table("users").Where("username = ? COLLATE NOCASE", username).Count(&count) return count > 0 || isUsernameReserved(username) @@ -498,8 +500,8 @@ func (p *PasswordValidator) Hash() (string, error) { return string(h), p.error } -func (d *DkfDB) CanUseUsername(username string, isFirstUser bool) error { - if _, err := ValidateUsername(username, isFirstUser); err != nil { +func (d *DkfDB) CanUseUsername(username Username, isFirstUser bool) error { + if _, err := ValidateUsername(string(username), isFirstUser); err != nil { return err } else if d.IsUsernameAlreadyTaken(username) { return errors.New("username already taken") @@ -507,11 +509,11 @@ func (d *DkfDB) CanUseUsername(username string, isFirstUser bool) error { return nil } -func (d *DkfDB) CanRenameTo(oldUsername, newUsername string) error { - if _, err := ValidateUsername(newUsername, false); err != nil { +func (d *DkfDB) CanRenameTo(oldUsername, newUsername Username) error { + if _, err := ValidateUsername(string(newUsername), false); err != nil { return err } - if strings.ToLower(oldUsername) != strings.ToLower(newUsername) { + if strings.ToLower(string(oldUsername)) != strings.ToLower(string(newUsername)) { if d.IsUsernameAlreadyTaken(newUsername) { return errors.New("username already taken") } @@ -539,8 +541,8 @@ func (d *DkfDB) CreateZeroUser() (User, UserErrors) { // skipUsernameValidation: entirely skip username validation (for "0" user) // isFirstUser: less strict username validation; can use "admin"/"n0tr1v" usernames -func (d *DkfDB) createUser(username, password, repassword, gpgPublicKey string, isAdmin, verified, temp, isFirstUser, skipUsernameValidation bool, registrationDuration int64, signupInfoEnc string) (User, UserErrors) { - username = strings.TrimSpace(username) +func (d *DkfDB) createUser(usernameStr, password, repassword, gpgPublicKey string, isAdmin, verified, temp, isFirstUser, skipUsernameValidation bool, registrationDuration int64, signupInfoEnc string) (User, UserErrors) { + username := Username(strings.TrimSpace(usernameStr)) var errs UserErrors if !skipUsernameValidation { if err := d.CanUseUsername(username, isFirstUser); err != nil { diff --git a/pkg/database/table_forum_threads.go b/pkg/database/table_forum_threads.go @@ -120,7 +120,7 @@ func (m *ForumMessage) Escape(db *DkfDB) string { var tagRgx = regexp.MustCompile(`@(\w{3,20})`) if tagRgx.MatchString(res) { res = tagRgx.ReplaceAllStringFunc(res, func(s string) string { - if user, err := db.GetUserByUsername(strings.TrimPrefix(s, "@")); err == nil { + if user, err := db.GetUserByUsername(Username(strings.TrimPrefix(s, "@"))); err == nil { return `<span style="color: ` + user.ChatColor + `;">` + s + `</span>` } return s diff --git a/pkg/database/utils/utils.go b/pkg/database/utils/utils.go @@ -24,8 +24,8 @@ func GetZeroUser(db *database.DkfDB) database.User { func SendNewChessGameMessages(db *database.DkfDB, key, roomKey string, roomID database.RoomID, zeroUser, player1, player2 database.User) { // Send game link to players getPlayerMsg := func(opponent database.User) (raw string, msg string) { - raw = `Chess game against ` + opponent.Username - msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game against ` + opponent.Username + `</a>` + raw = `Chess game against ` + string(opponent.Username) + msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game against ` + string(opponent.Username) + `</a>` return } raw, msg := getPlayerMsg(player2) @@ -34,8 +34,8 @@ func SendNewChessGameMessages(db *database.DkfDB, key, roomKey string, roomID da _, _ = db.CreateMsg(raw, msg, roomKey, roomID, zeroUser.ID, &player2.ID) // Send notifications to chess games subscribers - raw = `Chess game: ` + player1.Username + ` VS ` + player2.Username - msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game: ` + player1.Username + ` VS ` + player2.Username + `</a>` + raw = `Chess game: ` + string(player1.Username) + ` VS ` + string(player2.Username) + msg = `<a href="/chess/` + key + `" rel="noopener noreferrer" target="_blank">Chess game: ` + string(player1.Username) + ` VS ` + string(player2.Username) + `</a>` activeUsers := managers.ActiveUsers.GetActiveUsers() activeUsersIDs := make([]database.UserID, 0) diff --git a/pkg/managers/managers.go b/pkg/managers/managers.go @@ -20,7 +20,7 @@ func init() { type UserInfo struct { UserID database.UserID - Username string + Username database.Username Color string RefreshRate int64 LastUpdate time.Time @@ -57,7 +57,7 @@ func NewUserInfoUpdateActivity(user *database.User) UserInfo { func (m UserInfo) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { - Username string + Username database.Username Color string }{ Username: m.Username, @@ -65,7 +65,7 @@ func (m UserInfo) MarshalJSON() ([]byte, error) { }) } -type UsersMap map[string]UserInfo // Username -> UserInfo +type UsersMap map[database.Username]UserInfo // Username -> UserInfo func (m UsersMap) ToArray() []UserInfo { out := make([]UserInfo, len(m)) @@ -185,7 +185,7 @@ func (m *ActiveUsersManager) GetActiveUsers() []UserInfo { return activeUsers.ToArray() } -func (m *ActiveUsersManager) GetRoomUsers(room database.ChatRoom, ignoredSet *hashset.HashSet[string]) (inRoom, inChat []UserInfo) { +func (m *ActiveUsersManager) GetRoomUsers(room database.ChatRoom, ignoredSet *hashset.HashSet[database.Username]) (inRoom, inChat []UserInfo) { outsideUsers := make(UsersMap) newRoomUsersMap := make(UsersMap) roomIDStr := getRoomKey(room) @@ -210,7 +210,7 @@ func (m *ActiveUsersManager) GetRoomUsers(room database.ChatRoom, ignoredSet *ha } } // Delete ignored users - ignoredSet.Each(func(ignoreUsername string) { + ignoredSet.Each(func(ignoreUsername database.Username) { delete(newRoomUsersMap, ignoreUsername) delete(outsideUsers, ignoreUsername) }) diff --git a/pkg/web/handlers/admin.go b/pkg/web/handlers/admin.go @@ -551,7 +551,7 @@ func AdminEditUserHandler(c echo.Context) error { return c.Redirect(http.StatusFound, c.Request().Referer()) } - data.Username = c.FormValue("username") + data.Username = database.Username(c.FormValue("username")) data.Role = c.Request().PostFormValue("role") data.IsAdmin = utils.DoParseBool(c.FormValue("isAdmin")) data.IsHellbanned = utils.DoParseBool(c.FormValue("isHellbanned")) @@ -665,7 +665,7 @@ func StreamUsersHandler(c echo.Context) error { users, _ := db.GetUsersByID(usersIDs) out := "" for _, user := range users { - out += user.Username + ", " + out += string(user.Username) + ", " } return c.String(http.StatusOK, out) } diff --git a/pkg/web/handlers/api/v1/battleship.go b/pkg/web/handlers/api/v1/battleship.go @@ -39,7 +39,7 @@ type BSCoordinate struct { type BSPlayer struct { id database.UserID - username string + username database.Username userStyle string card *BSCard shots map[int]struct{} @@ -540,7 +540,7 @@ func (b *Battleship) InterceptMsg(cmd *Command) { if len(m) != 3 { return } - enemyUsername := m[1] + enemyUsername := database.Username(m[1]) pos := m[2] if err := b.playMove(cmd.room.Name, cmd.room.ID, cmd.roomKey, *cmd.authUser, enemyUsername, pos); err != nil { cmd.err = err @@ -550,7 +550,7 @@ func (b *Battleship) InterceptMsg(cmd *Command) { return } -func (b *Battleship) playMove(roomName string, roomID database.RoomID, roomKey string, authUser database.User, enemyUsername, pos string) error { +func (b *Battleship) playMove(roomName string, roomID database.RoomID, roomKey string, authUser database.User, enemyUsername database.Username, pos string) error { b.Lock() defer b.Unlock() diff --git a/pkg/web/handlers/api/v1/chess.go b/pkg/web/handlers/api/v1/chess.go @@ -28,7 +28,7 @@ import ( type ChessPlayer struct { ID database.UserID - Username string + Username database.Username UserStyle string NotifyChessMove bool } @@ -490,7 +490,7 @@ func (b *Chess) InterceptMsg(cmd *Command) { if len(m) != 3 { return } - enemyUsername := m[1] + enemyUsername := database.Username(m[1]) pos := m[2] if err := b.playMove(enemyUsername, pos, *cmd.authUser, cmd.c, cmd.room.Name, cmd.roomKey, cmd.room.ID); err != nil { cmd.err = err @@ -499,7 +499,7 @@ func (b *Chess) InterceptMsg(cmd *Command) { cmd.err = ErrStop } -func (b *Chess) playMove(enemyUsername, pos string, authUser database.User, c echo.Context, roomName, roomKey string, roomID database.RoomID) error { +func (b *Chess) playMove(enemyUsername database.Username, pos string, authUser database.User, c echo.Context, roomName, roomKey string, roomID database.RoomID) error { b.Lock() defer b.Unlock() diff --git a/pkg/web/handlers/api/v1/handlers.go b/pkg/web/handlers/api/v1/handlers.go @@ -103,7 +103,7 @@ func GetChatMenuData(c echo.Context, room database.ChatRoom) ChatMenuData { data.OfficialRooms, _ = db.GetOfficialChatRooms1(authUser.ID) data.SubscribedRooms, _ = db.GetUserRoomSubscriptions(authUser.ID) - ignoredSet := hashset.New[string]() + ignoredSet := hashset.New[database.Username]() // Only fill the ignored set if the user does not display the ignored users ("Toggle ignored" chat setting) // and if the user has "Hide ignored users from users lists" enabled (user setting) if !authUser.DisplayIgnored && authUser.HideIgnoredUsersFromList { @@ -325,7 +325,7 @@ func shouldPlaySound(authUser *database.User, lastKnownDate string, msgs []datab if createdAtTrunc.After(lastKnownDateTrunc) { if msg.User.ID != authUser.ID { newMessageSound = true - if strings.Contains(msg.Message, "@"+authUser.Username) { + if strings.Contains(msg.Message, "@"+string(authUser.Username)) { taggedSound = true } if msg.ToUserID != nil && *msg.ToUserID == authUser.ID { @@ -626,7 +626,7 @@ func ChessHandler(c echo.Context) error { authUser := c.Get("authUser").(*database.User) db := c.Get("database").(*database.DkfDB) roomName := c.Request().PostFormValue("room") - enemyUsername := c.Request().PostFormValue("enemyUsername") + enemyUsername := database.Username(c.Request().PostFormValue("enemyUsername")) pos := c.Request().PostFormValue("move") redirectURL := "/api/v1/chat/messages/" + roomName room, roomKey, err := dutils.GetRoomAndKey(db, c, roomName) @@ -660,7 +660,7 @@ func BattleshipHandler(c echo.Context) error { authUser := c.Get("authUser").(*database.User) db := c.Get("database").(*database.DkfDB) roomName := c.Request().PostFormValue("room") - enemyUsername := c.Request().PostFormValue("enemyUsername") + enemyUsername := database.Username(c.Request().PostFormValue("enemyUsername")) pos := c.Request().PostFormValue("move") redirectURL := "/api/v1/chat/messages/" + roomName room, roomKey, err := dutils.GetRoomAndKey(db, c, roomName) diff --git a/pkg/web/handlers/api/v1/messages.qtpl b/pkg/web/handlers/api/v1/messages.qtpl @@ -330,7 +330,7 @@ <button class="mod-btn delete_msg_btn " title="delete" style=" - {%- if e.User.Username != NullUsername -%} + {%- if string(e.User.Username) != NullUsername -%} {%- if (AuthUser.IsModerator() && e.UserID != AuthUser.ID) || AuthUser.IsAdmin || (e.Room.OwnerUserID != nil && *e.Room.OwnerUserID == AuthUser.ID) -%} animation: {%dl e.DeleteSecondsRemaining() %}s 1s forwards orange_btn; {%- else -%} @@ -360,7 +360,7 @@ {%- if AuthUser.IsModerator() -%} {%- if e.UserID != AuthUser.ID -%} {%- if AuthUser.DisplayHellbanButton -%} - {%- if e.User.Username == NullUsername -%} + {%- if string(e.User.Username) == NullUsername -%} <div class="spacer16"></div> {%- else -%} {%- if e.User.IsHellbanned -%} @@ -403,7 +403,7 @@ <a href="{%s baseTopBarURL %}?quote={%s e.UUID %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1" class="date date-link" title="{%s e.CreatedAt.Format("01-02 15:04:05") %}{% if *isFirstMsg %} ({%s humanize.Time(e.CreatedAt) %}){% endif %}">{%s e.CreatedAt.Format(AuthUser.GetDateFormat()) %}</a> {% code *isFirstMsg = false %} {%- endif -%} - <a href="/u/{%s e.GetProfile(AuthUser) %}" target="_blank" class="f-def-clr">-</a> + <a href="/u/{%s string(e.GetProfile(AuthUser)) %}" target="_blank" class="f-def-clr">-</a> {%- if e.System -%} <span class="sysmsg">{%= unesc(e.Message) %}</span> {%- else -%} @@ -412,7 +412,7 @@ {%- if e.ToUserID != nil -%} [{%-= fromUsername(AuthUser, Data, e, baseTopBarURL) -%} → - {%- if e.ToUser.ID == AuthUser.ID -%}<span {%= unesc(e.ToUser.GenerateChatStyle()) %}>{%s e.ToUser.Username %}</span>{%- else -%}<a {%= unesc(e.ToUser.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?pm={%s e.ToUser.Username %}{%s Data.TopBarQueryParams %}" target="iframe1">{%s e.ToUser.Username %}</a>{%- endif -%}] - + {%- if e.ToUser.ID == AuthUser.ID -%}<span {%= unesc(e.ToUser.GenerateChatStyle()) %}>{%s string(e.ToUser.Username) %}</span>{%- else -%}<a {%= unesc(e.ToUser.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?pm={%s string(e.ToUser.Username) %}{%s Data.TopBarQueryParams %}" target="iframe1">{%s string(e.ToUser.Username) %}</a>{%- endif -%}] - {%- else -%} {%-= fromUsername(AuthUser, Data, e, baseTopBarURL) -%} {%- if !e.IsMe() -%} @@ -434,7 +434,7 @@ {%- code baseTopBarURL := "/api/v1/chat/top-bar/" + Data.RoomName -%} {%- if El.Username == AuthUser.Username -%} <div> - <span style="color: {%s El.Color %};">{%s El.Username %}</span> + <span style="color: {%s El.Color %};">{%s string(El.Username) %}</span> {%- if El.AfkIndicatorEnabled -%} <small class="afk-indicator">afk</small> {%- endif -%} @@ -447,15 +447,15 @@ {%- code tagType = "htag" -%} {%- endif -%} {%- stripspace -%} - <a href="{%s baseTopBarURL %}?{%s tagType %}={%s El.Username %}{%= unesc(Data.TopBarQueryParams) %}" + <a href="{%s baseTopBarURL %}?{%s tagType %}={%s string(El.Username) %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1" {% if El.IsHellbanned && AuthUser.DisplayHellbanned %}class="hb-row"{% endif %} style="color: {%s El.Color %};">{%s string(El.Username[0]) %}</a> - <a href="{%s baseTopBarURL %}?pm={%s El.Username %}{%= unesc(Data.TopBarQueryParams) %}" + <a href="{%s baseTopBarURL %}?pm={%s string(El.Username) %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1" {% if El.IsHellbanned && AuthUser.DisplayHellbanned %}class="hb-row"{% endif %} style="color: {%s El.Color %};">{%s string(El.Username[1 : len(El.Username)-1]) %}</a> - <a href="/u/{%s El.Username %}" + <a href="/u/{%s string(El.Username) %}" rel="noopener noreferrer" target="_blank" {% if El.IsHellbanned && AuthUser.DisplayHellbanned %}class="hb-row"{% endif %} style="color: {%s El.Color %};">{%s string(El.Username[len(El.Username)-1]) %}</a> @@ -479,6 +479,6 @@ {%- code tagType = "mtag" -%} {%- endif -%} {%- if El.User.ID == AuthUser.ID -%} - {%- if El.CanBeEdited() -%}<a {%= unesc(El.User.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?e={%s El.CreatedAt.Format("15:04:05") %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1">{%s El.User.Username %}</a>{%- else -%}<span {%= unesc(El.User.GenerateChatStyle()) %}>{%s El.User.Username %}</span>{%- endif -%} - {%- else -%}<a {%= unesc(El.User.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?{%s tagType %}={%s El.User.Username %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1">{%s El.User.Username %}</a>{%- endif -%} + {%- if El.CanBeEdited() -%}<a {%= unesc(El.User.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?e={%s El.CreatedAt.Format("15:04:05") %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1">{%s string(El.User.Username) %}</a>{%- else -%}<span {%= unesc(El.User.GenerateChatStyle()) %}>{%s string(El.User.Username) %}</span>{%- endif -%} + {%- else -%}<a {%= unesc(El.User.GenerateChatStyle()) %} href="{%s baseTopBarURL %}?{%s tagType %}={%s string(El.User.Username) %}{%= unesc(Data.TopBarQueryParams) %}" target="iframe1">{%s string(El.User.Username) %}</a>{%- endif -%} {%- endfunc -%} diff --git a/pkg/web/handlers/api/v1/messages.qtpl.go b/pkg/web/handlers/api/v1/messages.qtpl.go @@ -760,7 +760,7 @@ func StreamRenderMessage(qw422016 *qt422016.Writer, idx int, e database.ChatMess style=" `) //line messages.qtpl:333 - if e.User.Username != NullUsername { + if string(e.User.Username) != NullUsername { //line messages.qtpl:334 if (AuthUser.IsModerator() && e.UserID != AuthUser.ID) || AuthUser.IsAdmin || (e.Room.OwnerUserID != nil && *e.Room.OwnerUserID == AuthUser.ID) { //line messages.qtpl:334 @@ -837,7 +837,7 @@ func StreamRenderMessage(qw422016 *qt422016.Writer, idx int, e database.ChatMess //line messages.qtpl:362 if AuthUser.DisplayHellbanButton { //line messages.qtpl:363 - if e.User.Username == NullUsername { + if string(e.User.Username) == NullUsername { //line messages.qtpl:363 qw422016.N().S(` <div class="spacer16"></div> `) @@ -982,7 +982,7 @@ func StreamRenderMessage(qw422016 *qt422016.Writer, idx int, e database.ChatMess //line messages.qtpl:405 qw422016.N().S(` <a href="/u/`) //line messages.qtpl:406 - qw422016.E().S(e.GetProfile(AuthUser)) + qw422016.E().S(string(e.GetProfile(AuthUser))) //line messages.qtpl:406 qw422016.N().S(`" target="_blank" class="f-def-clr">-</a> `) @@ -1049,7 +1049,7 @@ func StreamRenderMessage(qw422016 *qt422016.Writer, idx int, e database.ChatMess //line messages.qtpl:415 qw422016.N().S(`>`) //line messages.qtpl:415 - qw422016.E().S(e.ToUser.Username) + qw422016.E().S(string(e.ToUser.Username)) //line messages.qtpl:415 qw422016.N().S(`</span>`) //line messages.qtpl:415 @@ -1065,13 +1065,13 @@ func StreamRenderMessage(qw422016 *qt422016.Writer, idx int, e database.ChatMess //line messages.qtpl:415 qw422016.N().S(`?pm=`) //line messages.qtpl:415 - qw422016.E().S(e.ToUser.Username) + qw422016.E().S(string(e.ToUser.Username)) //line messages.qtpl:415 qw422016.E().S(Data.TopBarQueryParams) //line messages.qtpl:415 qw422016.N().S(`" target="iframe1">`) //line messages.qtpl:415 - qw422016.E().S(e.ToUser.Username) + qw422016.E().S(string(e.ToUser.Username)) //line messages.qtpl:415 qw422016.N().S(`</a>`) //line messages.qtpl:415 @@ -1176,7 +1176,7 @@ func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatM //line messages.qtpl:437 qw422016.N().S(`;">`) //line messages.qtpl:437 - qw422016.E().S(El.Username) + qw422016.E().S(string(El.Username)) //line messages.qtpl:437 qw422016.N().S(`</span> `) @@ -1218,7 +1218,7 @@ func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatM //line messages.qtpl:450 qw422016.N().S(`=`) //line messages.qtpl:450 - qw422016.E().S(El.Username) + qw422016.E().S(string(El.Username)) //line messages.qtpl:450 streamunesc(qw422016, Data.TopBarQueryParams) //line messages.qtpl:450 @@ -1244,7 +1244,7 @@ func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatM //line messages.qtpl:454 qw422016.N().S(`?pm=`) //line messages.qtpl:454 - qw422016.E().S(El.Username) + qw422016.E().S(string(El.Username)) //line messages.qtpl:454 streamunesc(qw422016, Data.TopBarQueryParams) //line messages.qtpl:454 @@ -1266,7 +1266,7 @@ func StreamMember(qw422016 *qt422016.Writer, AuthUser *database.User, Data ChatM //line messages.qtpl:457 qw422016.N().S(`</a><a href="/u/`) //line messages.qtpl:458 - qw422016.E().S(El.Username) + qw422016.E().S(string(El.Username)) //line messages.qtpl:458 qw422016.N().S(`"rel="noopener noreferrer" target="_blank"`) //line messages.qtpl:460 @@ -1371,7 +1371,7 @@ func streamfromUsername(qw422016 *qt422016.Writer, AuthUser *database.User, Data //line messages.qtpl:482 qw422016.N().S(`" target="iframe1">`) //line messages.qtpl:482 - qw422016.E().S(El.User.Username) + qw422016.E().S(string(El.User.Username)) //line messages.qtpl:482 qw422016.N().S(`</a>`) //line messages.qtpl:482 @@ -1383,7 +1383,7 @@ func streamfromUsername(qw422016 *qt422016.Writer, AuthUser *database.User, Data //line messages.qtpl:482 qw422016.N().S(`>`) //line messages.qtpl:482 - qw422016.E().S(El.User.Username) + qw422016.E().S(string(El.User.Username)) //line messages.qtpl:482 qw422016.N().S(`</span>`) //line messages.qtpl:482 @@ -1405,13 +1405,13 @@ func streamfromUsername(qw422016 *qt422016.Writer, AuthUser *database.User, Data //line messages.qtpl:483 qw422016.N().S(`=`) //line messages.qtpl:483 - qw422016.E().S(El.User.Username) + qw422016.E().S(string(El.User.Username)) //line messages.qtpl:483 streamunesc(qw422016, Data.TopBarQueryParams) //line messages.qtpl:483 qw422016.N().S(`" target="iframe1">`) //line messages.qtpl:483 - qw422016.E().S(El.User.Username) + qw422016.E().S(string(El.User.Username)) //line messages.qtpl:483 qw422016.N().S(`</a>`) //line messages.qtpl:483 diff --git a/pkg/web/handlers/api/v1/slashInterceptor.go b/pkg/web/handlers/api/v1/slashInterceptor.go @@ -174,7 +174,7 @@ func handleListModeratorsCmd(c *Command) (handled bool) { if len(mods) > 0 { c.message += "\n" for _, mod := range mods { - c.message += "@" + mod.Username + "\n" + c.message += "@" + string(mod.Username) + "\n" } } else { c.message += "no moderators" @@ -187,7 +187,7 @@ func handleListModeratorsCmd(c *Command) (handled bool) { func handleKickCmd(c *Command) (handled bool) { if m := kickRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) if err := kickCmd(c, username, true, false); err != nil { c.err = err return true @@ -201,7 +201,7 @@ func handleKickCmd(c *Command) (handled bool) { // Kick a user but keep the messages func handleKickKeepCmd(c *Command) (handled bool) { if m := kickKeepRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) if err := kickCmd(c, username, false, false); err != nil { c.err = err return true @@ -215,7 +215,7 @@ func handleKickKeepCmd(c *Command) (handled bool) { // Kick a user, no system message in chat func handleKickSilentCmd(c *Command) (handled bool) { if m := kickSilentRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) if err := kickCmd(c, username, true, true); err != nil { c.err = err return true @@ -229,7 +229,7 @@ func handleKickSilentCmd(c *Command) (handled bool) { // Kick a user, keep the messages, no system message in chat func handleKickKeepSilentCmd(c *Command) (handled bool) { if m := kickKeepSilentRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) if err := kickCmd(c, username, false, true); err != nil { c.err = err return true @@ -240,7 +240,7 @@ func handleKickKeepSilentCmd(c *Command) (handled bool) { return } -func kickCmd(c *Command, username string, purge, silent bool) error { +func kickCmd(c *Command, username database.Username, purge, silent bool) error { user, err := c.db.GetUserByUsername(username) if err != nil { return ErrUsernameNotFound @@ -253,7 +253,7 @@ var ErrUnauthorized = errors.New("unauthorized") func handleUnkickCmd(c *Command) (handled bool) { if m := unkickRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrUsernameNotFound @@ -278,7 +278,7 @@ func handleUnkickCmd(c *Command) (handled bool) { func handleForceCaptchaCmd(c *Command) (handled bool) { if m := forceCaptchaRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrUsernameNotFound @@ -297,7 +297,7 @@ func handleForceCaptchaCmd(c *Command) (handled bool) { func handleLogoutCmd(c *Command) (handled bool) { if m := logoutRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrUsernameNotFound @@ -324,7 +324,7 @@ func handleLogoutCmd(c *Command) (handled bool) { func handleResetTutorialCmd(c *Command) (handled bool) { if m := rtutoRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrUsernameNotFound @@ -347,7 +347,7 @@ func handleResetTutorialCmd(c *Command) (handled bool) { func handleHellbanCmd(c *Command) (handled bool) { if m := hellbanRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrUsernameNotFound @@ -369,7 +369,7 @@ func handleHellbanCmd(c *Command) (handled bool) { func handleUnhellbanCmd(c *Command) (handled bool) { if m := unhellbanRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrUsernameNotFound @@ -601,7 +601,7 @@ func handleGroupUsersCmd(c *Command) (handled bool) { if len(users) > 0 { c.message += "\n" for _, user := range users { - c.message += "@" + user.User.Username + "\n" + c.message += "@" + string(user.User.Username) + "\n" } } else { c.message += "no user in th group: " + groupName @@ -637,7 +637,7 @@ func handleListGroupsCmd(c *Command) (handled bool) { func handleGroupAddUserCmd(c *Command) (handled bool) { if m := groupAddUserRgx.FindStringSubmatch(c.message); len(m) == 3 { groupName := m[1] - username := m[2] + username := database.Username(m[2]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = err @@ -664,7 +664,7 @@ func handleGroupAddUserCmd(c *Command) (handled bool) { func handleGroupRmUserCmd(c *Command) (handled bool) { if m := groupRmUserRgx.FindStringSubmatch(c.message); len(m) == 3 { groupName := m[1] - username := m[2] + username := database.Username(m[2]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = err @@ -712,7 +712,7 @@ func handleSetModeStandardCmd(c *Command) (handled bool) { func handleGetRoomWhitelistCmd(c *Command) (handled bool) { if m := whitelistUserRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.message = fmt.Sprintf(`username "%s" not found`, username) @@ -753,7 +753,7 @@ func handleWhitelistCmd(c *Command) (handled bool) { if len(whitelistedUsers) > 0 { usernames := make([]string, 0) for _, whitelistedUser := range whitelistedUsers { - usernames = append(usernames, "@"+whitelistedUser.User.Username) + usernames = append(usernames, "@"+string(whitelistedUser.User.Username)) } sort.Slice(usernames, func(i, j int) bool { return usernames[i] < usernames[j] }) c.message = "whitelisted users: " + strings.Join(usernames, ", ") @@ -902,7 +902,7 @@ func canUserPmOther(db *database.DkfDB, user, other database.User, roomIsPrivate func handlePMCmd(c *Command) (handled bool) { if m := pmRgx.FindStringSubmatch(c.message); len(m) == 3 { - username := m[1] + username := database.Username(m[1]) newMsg := m[2] // Chat helpers @@ -927,7 +927,7 @@ func handlePMCmd(c *Command) (handled bool) { } c.toUser = &user c.message = newMsg - c.redirectQP.Set(redirectPmQP, user.Username) + c.redirectQP.Set(redirectPmQP, string(user.Username)) if newMsg == "/d" || strings.HasPrefix(newMsg, "/d ") { handled = handleDeleteMsgCmd(c) @@ -1108,7 +1108,7 @@ func handleListIgnoredCmd(c *Command) (handled bool) { if len(ignoredUsers) > 0 { c.message += "\n" for _, ignoredUser := range ignoredUsers { - c.message += "@" + ignoredUser.IgnoredUser.Username + "\n" + c.message += "@" + string(ignoredUser.IgnoredUser.Username) + "\n" } } else { c.message += "no ignored users" @@ -1129,7 +1129,7 @@ func handleListPmWhitelistCmd(c *Command) (handled bool) { if len(pmWhitelistUsers) > 0 { c.message += "\n" for _, ignoredUser := range pmWhitelistUsers { - c.message += "@" + ignoredUser.WhitelistedUser.Username + "\n" + c.message += "@" + string(ignoredUser.WhitelistedUser.Username) + "\n" } } else { c.message += "no PM whitelisted users" @@ -1164,7 +1164,7 @@ func handleSetPmModeStandardCmd(c *Command) (handled bool) { func handleTogglePmBlacklistedUser(c *Command) (handled bool) { if m := pmToggleBlacklistUserRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrRedirect @@ -1182,7 +1182,7 @@ func handleTogglePmBlacklistedUser(c *Command) (handled bool) { func handleTogglePmWhitelistedUser(c *Command) (handled bool) { if m := pmToggleWhitelistUserRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrRedirect @@ -1200,7 +1200,7 @@ func handleTogglePmWhitelistedUser(c *Command) (handled bool) { func handleChessCmd(c *Command) (handled bool) { if m := chessRgx.FindStringSubmatch(c.message); len(m) == 3 { - username := m[1] + username := database.Username(m[1]) color := m[2] player1 := *c.authUser player2, err := c.db.GetUserByUsername(username) @@ -1226,7 +1226,7 @@ func handleChessCmd(c *Command) (handled bool) { func handleInboxCmd(c *Command) (handled bool) { if m := inboxRgx.FindStringSubmatch(c.message); len(m) == 4 { - username := m[1] + username := database.Username(m[1]) encryptRaw := m[2] message := m[3] tryEncrypt := false @@ -1261,7 +1261,7 @@ func handleInboxCmd(c *Command) (handled bool) { html, _, _ = ProcessRawMessage(c.db, html, c.roomKey, c.authUser.ID, c.room.ID, nil, c.authUser.CanUseMultiline) c.db.CreateInboxMessage(html, c.room.ID, c.authUser.ID, toUser.ID, true, false, nil) - c.dataMessage = "/inbox " + username + " " + c.dataMessage = "/inbox " + string(username) + " " c.err = NewErrSuccess("inbox sent") return true @@ -1274,7 +1274,7 @@ func handleInboxCmd(c *Command) (handled bool) { func handleProfileCmd(c *Command) (handled bool) { if m := profileRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrUsernameNotFound @@ -1403,7 +1403,7 @@ func handleDeleteMsgCmd(c *Command) (handled bool) { } var msg database.ChatMessage for _, msgTmp := range msgs { - if msgTmp.User.Username == matchUsername { + if string(msgTmp.User.Username) == matchUsername { msg = msgTmp break } @@ -1478,14 +1478,14 @@ func handleUnHideMsgCmd(c *Command) (handled bool) { func handleIgnoreCmd(c *Command) (handled bool) { if m := ignoreRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrRedirect return true } c.db.IgnoreUser(c.authUser.ID, user.ID) - database.MsgPubSub.Pub("refresh_"+c.authUser.Username, database.ChatMessageType{Typ: database.ForceRefresh}) + database.MsgPubSub.Pub("refresh_"+string(c.authUser.Username), database.ChatMessageType{Typ: database.ForceRefresh}) c.err = ErrRedirect return true } else if strings.HasPrefix(c.message, "/ignore ") || strings.HasPrefix(c.message, "/i ") { @@ -1497,14 +1497,14 @@ func handleIgnoreCmd(c *Command) (handled bool) { func handleUnIgnoreCmd(c *Command) (handled bool) { if m := unIgnoreRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = ErrRedirect return true } c.db.UnIgnoreUser(c.authUser.ID, user.ID) - database.MsgPubSub.Pub("refresh_"+c.authUser.Username, database.ChatMessageType{Typ: database.ForceRefresh}) + database.MsgPubSub.Pub("refresh_"+string(c.authUser.Username), database.ChatMessageType{Typ: database.ForceRefresh}) c.err = ErrRedirect return true } else if strings.HasPrefix(c.message, "/unignore ") || strings.HasPrefix(c.message, "/ui ") { @@ -1592,7 +1592,7 @@ func handleSetChatRoomExternalLink(c *Command) (handled bool) { func handlePurge(c *Command) (handled bool) { if m := purgeRgx.FindStringSubmatch(c.message); len(m) == 2 { - username := m[1] + username := database.Username(m[1]) user, err := c.db.GetUserByUsername(username) if err != nil { c.err = err @@ -1609,8 +1609,8 @@ func handlePurge(c *Command) (handled bool) { func handleRename(c *Command) (handled bool) { if m := renameRgx.FindStringSubmatch(c.message); len(m) == 3 { - oldUsername := m[1] - newUsername := m[2] + oldUsername := database.Username(m[1]) + newUsername := database.Username(m[2]) user, err := c.db.GetUserByUsername(oldUsername) if err != nil { c.err = err diff --git a/pkg/web/handlers/api/v1/snippetInterceptor.go b/pkg/web/handlers/api/v1/snippetInterceptor.go @@ -46,9 +46,9 @@ func autocompleteTags(html string) string { s1 = strings.TrimSuffix(s1, "*") s1 = strings.ToLower(s1) for _, au := range activeUsers { - l := strings.ToLower(au.Username) + l := strings.ToLower(string(au.Username)) if strings.HasPrefix(l, s1) { - return "@" + au.Username + return "@" + string(au.Username) } } return s diff --git a/pkg/web/handlers/api/v1/topBarHandler.go b/pkg/web/handlers/api/v1/topBarHandler.go @@ -601,7 +601,7 @@ func colorifyTaggedUsers(html string, getUsersByUsername getUsersByUsernameFn) ( taggedUsersMap := make(map[string]database.User) taggedUsersIDsMap := make(map[database.UserID]database.User) for _, taggedUser := range taggedUsers { - taggedUsersMap["@"+strings.ToLower(taggedUser.Username)] = taggedUser + taggedUsersMap["@"+strings.ToLower(string(taggedUser.Username))] = taggedUser if taggedUser.Username != config.NullUsername { taggedUsersIDsMap[taggedUser.ID] = taggedUser } @@ -631,7 +631,7 @@ func linkRoomTags(db *database.DkfDB, html string) string { } // Given a roomID and hourMinSec (01:23:45) and a username, retrieve the message from database that fits the predicates. -func getQuotedChatMessage(db *database.DkfDB, hourMinSec, username string, roomID database.RoomID) (quoted *database.ChatMessage) { +func getQuotedChatMessage(db *database.DkfDB, hourMinSec string, username database.Username, roomID database.RoomID) (quoted *database.ChatMessage) { if dt, err := utils.ParsePrevDatetimeAt(hourMinSec, clockwork.NewRealClock()); err == nil { if msgs, err := db.GetRoomChatMessagesByDate(roomID, dt.UTC()); err == nil && len(msgs) > 0 { msg := msgs[0] @@ -729,7 +729,7 @@ func convertQuote(db *database.DkfDB, origHtml string, roomKey string, roomID da suffixLen := len(quoteSuffix) if len(origHtml) > prefixLen+9 { hourMinSec := origHtml[prefixLen : prefixLen+8] - username := origHtml[prefixLen+10 : strings.Index(origHtml[prefixLen+10:], " ")+prefixLen+10] + username := database.Username(origHtml[prefixLen+10 : strings.Index(origHtml[prefixLen+10:], " ")+prefixLen+10]) if quoted = getQuotedChatMessage(db, hourMinSec, username, roomID); quoted != nil { html = getQuoteTxt(db, roomKey, *quoted) html += origHtml[idx+suffixLen:] @@ -814,7 +814,7 @@ func splitQuote(in string) (string, string) { return in[:idx], in[idx:] } -func convertLinks(in string, getUserByUsername func(string) (database.User, error)) string { +func convertLinks(in string, getUserByUsername func(database.Username) (database.User, error)) string { quote, rest := splitQuote(in) libredditURLs := []string{ @@ -856,11 +856,11 @@ func convertLinks(in string, getUserByUsername func(string) (database.User, erro newRest := linkOrProfileRgx.ReplaceAllStringFunc(rest, func(link string) string { // Convert all occurrences of "/u/username" to a link to user profile page if the user exists if userProfileLinkRgx.MatchString(link) { - user, err := getUserByUsername(strings.TrimPrefix(link, "/u/")) + user, err := getUserByUsername(database.Username(strings.TrimPrefix(link, "/u/"))) if err != nil { return link } - href := "/u/" + user.Username + href := "/u/" + string(user.Username) return makeHtmlLink(href, href) } @@ -1002,9 +1002,9 @@ func convertLinks(in string, getUserByUsername func(string) (database.User, erro } // Allows to have messages such as: "my profile is /u/username :)" if userProfileLinkRgx.MatchString(trimmed) { - if user, err := getUserByUsername(strings.TrimPrefix(trimmed, "/u/")); err == nil { - label = "/u/" + user.Username - href = "/u/" + user.Username + if user, err := getUserByUsername(database.Username(strings.TrimPrefix(trimmed, "/u/"))); err == nil { + label = "/u/" + string(user.Username) + href = "/u/" + string(user.Username) } } return makeHtmlLink(label, href) diff --git a/pkg/web/handlers/api/v1/werewolf.go b/pkg/web/handlers/api/v1/werewolf.go @@ -46,8 +46,8 @@ type Werewolf struct { werewolfGroupID database.GroupID spectatorGroupID database.GroupID deadGroupID database.GroupID - players map[string]*Player - playersAlive map[string]*Player + players map[database.Username]*Player + playersAlive map[database.Username]*Player state int64 werewolfSet *hashset.HashSet[database.UserID] spectatorSet *hashset.HashSet[database.UserID] @@ -92,13 +92,13 @@ func (b *Werewolf) InterceptPreGameMsg(cmd *Command) { } b.players[cmd.authUser.Username] = player b.playersAlive[cmd.authUser.Username] = player - b.Narrate("@"+cmd.authUser.Username+" joined the Game", nil, nil) + b.Narrate("@"+string(cmd.authUser.Username)+" joined the Game", nil, nil) cmd.err = ErrRedirect return } else if cmd.message == "/spectate" { b.spectatorSet.Insert(cmd.authUser.ID) - b.Narrate("@"+cmd.authUser.Username+" spectate the Game", nil, nil) + b.Narrate("@"+string(cmd.authUser.Username)+" spectate the Game", nil, nil) cmd.err = ErrRedirect return @@ -320,7 +320,7 @@ func (b *Werewolf) waitNameFromHealer() (name string) { func (b *Werewolf) isValidPlayerName(name string) bool { name = strings.TrimSpace(name) for _, player := range b.playersAlive { - if player.Username == name { + if string(player.Username) == name { return true } } @@ -341,7 +341,7 @@ func (b *Werewolf) NarrateRaw(msg string, toUserID *database.UserID, groupID *da func (b *Werewolf) displayRoles() { msg := "Roles were:\n" for _, player := range b.players { - msg += "@" + player.Username + " : " + player.Role + "\n" + msg += "@" + string(player.Username) + " : " + player.Role + "\n" } b.Narrate(msg, nil, nil) } @@ -421,7 +421,7 @@ func (b *Werewolf) StartGame(db *database.DkfDB) { "There you find @"+playerNameToKill+"’s mangled remains by the Great Oak.\n"+ "Curiously, there are deep claw marks in the bark of the surrounding trees.\n"+ "It looks like @"+playerNameToKill+" put up a fight.", nil, nil) - b.kill(db, playerNameToKill) + b.kill(db, database.Username(playerNameToKill)) } b.Narrate("Players still alive: "+b.alivePlayersStr(), nil, nil) @@ -451,7 +451,7 @@ func (b *Werewolf) StartGame(db *database.DkfDB) { b.Narrate("Townspeople do not want to execute anyone", nil, nil) } else { b.Narrate("Townspeople execute @"+killName, nil, nil) - b.kill(db, killName) + b.kill(db, database.Username(killName)) } b.Narrate("Players still alive: "+b.alivePlayersStr(), nil, nil) @@ -472,14 +472,14 @@ func (b *Werewolf) StartGame(db *database.DkfDB) { func (b *Werewolf) alivePlayersStr() (out string) { arr := make([]string, 0) for _, player := range b.playersAlive { - arr = append(arr, "@"+player.Username) + arr = append(arr, "@"+string(player.Username)) } sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] }) return strings.Join(arr, ", ") } // Kill a player -func (b *Werewolf) kill(db *database.DkfDB, playerName string) { +func (b *Werewolf) kill(db *database.DkfDB, playerName database.Username) { player, found := b.playersAlive[playerName] if !found { return @@ -531,8 +531,8 @@ func (b *Werewolf) killVote() string { return maxName } -func (b *Werewolf) getAlivePlayersArr(includeWerewolves bool) []string { - arr := make([]string, 0) +func (b *Werewolf) getAlivePlayersArr(includeWerewolves bool) []database.Username { + arr := make([]database.Username, 0) for _, player := range b.playersAlive { if !includeWerewolves && b.werewolfSet.Contains(player.UserID) { continue @@ -617,7 +617,7 @@ func (b *Werewolf) processSeer() { msg += b.createPickUserForm() b.NarrateRaw(msg, b.seerID, nil) name := b.waitNameFromSeer() - player := b.playersAlive[name] + player := b.playersAlive[database.Username(name)] b.Narrate(name+" is a "+player.Role, b.seerID, nil) } @@ -651,15 +651,15 @@ func (b *Werewolf) UnlockGroup(groupName string) { type Player struct { UserID database.UserID - Username string + Username database.Username Role string } func (b *Werewolf) reset() { b.ctx, b.cancel = context.WithCancel(context.Background()) b.state = PreGameState - b.players = make(map[string]*Player) - b.playersAlive = make(map[string]*Player) + b.players = make(map[database.Username]*Player) + b.playersAlive = make(map[database.Username]*Player) b.werewolfSet = hashset.New[database.UserID]() b.spectatorSet = hashset.New[database.UserID]() b.townspersonSet = hashset.New[database.UserID]() diff --git a/pkg/web/handlers/chat.go b/pkg/web/handlers/chat.go @@ -188,7 +188,7 @@ func handleChatPasswordPost(db *database.DkfDB, c echo.Context, data chatData, a return c.Render(http.StatusOK, chatPasswordTmplName, data) } - if err := db.CanUseUsername(data.GuestUsername, false); err != nil { + if err := db.CanUseUsername(database.Username(data.GuestUsername), false); err != nil { data.ErrGuestUsername = err.Error() return c.Render(http.StatusOK, chatPasswordTmplName, data) } diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go @@ -107,7 +107,7 @@ type forgotPasswordBypassChallengeData struct { type forgotPasswordData struct { Error string - Username string + Username database.Username UsernameError string Frames []string CaptchaSec int64 @@ -600,8 +600,8 @@ type settingsChatPMData struct { ActiveTab string PmMode int64 BlockNewUsersPm bool - AddWhitelist string - AddBlacklist string + AddWhitelist database.Username + AddBlacklist database.Username WhitelistedUsers []database.PmWhitelistedUsers BlacklistedUsers []database.PmBlacklistedUsers Error string @@ -610,7 +610,7 @@ type settingsChatPMData struct { type settingsChatIgnoreData struct { ActiveTab string PmMode int64 - AddIgnored string + AddIgnored database.Username IgnoredUsers []database.IgnoredUser Error string } @@ -750,7 +750,7 @@ type settingsPasswordData struct { type settingsAccountData struct { AccountTooYoungErrorString string ActiveTab string - Username string + Username database.Username Website string Email string LastSeenPublic bool @@ -782,7 +782,7 @@ type adminEditUsereData struct { IsEdit bool ActiveTab string User database.User - Username string + Username database.Username Password string RePassword string ApiKey string @@ -884,5 +884,5 @@ type stego1RoadChallengeData struct { type chessData struct { Games []v1.ChessGame Error string - Username string + Username database.Username } diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -292,7 +292,7 @@ func loginHandler(c echo.Context) error { actualLogin := func(username, password string, captchaSolved bool) error { username = strings.TrimSpace(username) - user, err := db.GetVerifiedUserByUsername(username) + user, err := db.GetVerifiedUserByUsername(database.Username(username)) if err != nil { time.Sleep(utils.RandMs(50, 200)) data.Error = "Invalid username/password" @@ -1018,7 +1018,7 @@ func forgotPasswordHandler(c echo.Context) error { if formName == "step1" { // Receive and validate Username/Captcha data.Step = usernameCaptchaStep - data.Username = c.Request().PostFormValue("username") + data.Username = database.Username(c.Request().PostFormValue("username")) captchaID := c.Request().PostFormValue("captcha_id") captchaInput := c.Request().PostFormValue("captcha") data.GpgMode = utils.DoParseBool(c.Request().PostFormValue("gpg_mode")) @@ -2515,7 +2515,7 @@ func SettingsChatPMHandler(c echo.Context) error { formName := c.Request().PostFormValue("formName") if formName == "addWhitelist" { - data.AddWhitelist = strings.TrimSpace(c.Request().PostFormValue("username")) + data.AddWhitelist = database.Username(strings.TrimSpace(c.Request().PostFormValue("username"))) user, err := db.GetUserByUsername(data.AddWhitelist) if err != nil { data.Error = "username not found" @@ -2530,7 +2530,7 @@ func SettingsChatPMHandler(c echo.Context) error { return c.Redirect(http.StatusFound, c.Request().Referer()) } else if formName == "addBlacklist" { - data.AddBlacklist = strings.TrimSpace(c.Request().PostFormValue("username")) + data.AddBlacklist = database.Username(strings.TrimSpace(c.Request().PostFormValue("username"))) user, err := db.GetUserByUsername(data.AddBlacklist) if err != nil { data.Error = "username not found" @@ -2568,7 +2568,7 @@ func SettingsChatIgnoreHandler(c echo.Context) error { formName := c.Request().PostFormValue("formName") if formName == "addIgnored" { - data.AddIgnored = strings.TrimSpace(c.Request().PostFormValue("username")) + data.AddIgnored = database.Username(strings.TrimSpace(c.Request().PostFormValue("username"))) user, err := db.GetUserByUsername(data.AddIgnored) if err != nil { data.Error = "username not found" @@ -3050,7 +3050,7 @@ func changeUsernameForm(c echo.Context, data settingsAccountData) error { return c.Render(http.StatusOK, "settings.account", data) } - username := c.Request().PostFormValue("username") + username := database.Username(c.Request().PostFormValue("username")) data.Username = username if username == authUser.Username { @@ -3659,7 +3659,7 @@ func TwoFactorAuthenticationVerifyHandler(c echo.Context) error { db.CreateSecurityLog(authUser.ID, database.TotpEnabledSecurityLog) return c.Render(http.StatusOK, "flash", FlashResponse{"Two-factor authentication enabled", "/", "alert-success"}) } - key, _ := totp.Generate(totp.GenerateOpts{Issuer: "DarkForest", AccountName: authUser.Username}) + key, _ := totp.Generate(totp.GenerateOpts{Issuer: "DarkForest", AccountName: string(authUser.Username)}) img, _ := key.Image(150, 150) recovery := utils.ShortDisplayID(10) data.QRCode = getImgStr(img) @@ -3942,7 +3942,7 @@ func CaptchaHandler(c echo.Context) error { } func PublicUserProfileHandler(c echo.Context) error { - username := c.Param("username") + username := database.Username(c.Param("username")) db := c.Get("database").(*database.DkfDB) user, err := db.GetUserByUsername(username) if err != nil { @@ -3956,7 +3956,7 @@ func PublicUserProfileHandler(c echo.Context) error { } func PublicUserProfilePGPHandler(c echo.Context) error { - username := c.Param("username") + username := database.Username(c.Param("username")) db := c.Get("database").(*database.DkfDB) user, err := db.GetUserByUsername(username) if err != nil { @@ -4679,7 +4679,7 @@ func ChessHandler(c echo.Context) error { data.Games = v1.ChessInstance.GetGames() if c.Request().Method == http.MethodPost { - data.Username = c.Request().PostFormValue("username") + data.Username = database.Username(c.Request().PostFormValue("username")) player2, err := db.GetUserByUsername(data.Username) if err != nil { data.Error = "invalid username" @@ -5012,7 +5012,7 @@ func applyUserFilters(db *database.DkfDB, authUser *database.User, msg *database } } - if mentionsOnlyQuery && !strings.Contains(msg.Message, "@"+authUser.Username) { + if mentionsOnlyQuery && !strings.Contains(msg.Message, "@"+string(authUser.Username)) { return false } return true @@ -5085,7 +5085,7 @@ func ChatStreamMessagesHandler(c echo.Context) error { send("<div>" + v1.RenderMessages(authUser, data, csrf, config.NullUsername) + "</div>") c.Response().Flush() - selfRefreshTopic := "refresh_" + authUser.Username + selfRefreshTopic := "refresh_" + string(authUser.Username) authorizedChannels := []string{ "refresh", selfRefreshTopic, @@ -5188,7 +5188,7 @@ Loop: var newMessageSound, taggedSound, pmSound bool if msg.User.ID != authUser.ID { newMessageSound = true - if strings.Contains(renderedMsg, "@"+authUser.Username) { + if strings.Contains(renderedMsg, "@"+string(authUser.Username)) { taggedSound = true } if msg.ToUserID != nil && msg.ToUser.ID == authUser.ID {