diff --git a/pkg/handlers.go b/pkg/handlers.go index 766f1b0..7133045 100644 --- a/pkg/handlers.go +++ b/pkg/handlers.go @@ -51,7 +51,25 @@ func (s *Server) OnLogin(sub *Subscriber, msg Message) { } // Ensure the username is unique, or rename it. - msg.Username = s.UniqueUsername(msg.Username) + username, err := s.UniqueUsername(msg.Username) + if err != nil { + // If JWT authentication was used: disconnect the original (conflicting) username. + if claims.Subject == msg.Username { + if other, err := s.GetSubscriber(msg.Username); err == nil { + other.ChatServer("You have been signed out of chat because you logged in from another location.") + other.SendJSON(Message{ + Action: ActionKick, + }) + s.DeleteSubscriber(other) + } + + // They will take over their original username. + username = msg.Username + } + + // If JWT auth was not used: UniqueUsername already gave them a uniquely spelled name. + } + msg.Username = username // Use their username. sub.Username = msg.Username diff --git a/pkg/websocket.go b/pkg/websocket.go index dcaba2b..3b4507d 100644 --- a/pkg/websocket.go +++ b/pkg/websocket.go @@ -275,8 +275,8 @@ func (s *Server) IterSubscribers(isLocked ...bool) []*Subscriber { return result } -// UniqueUsername ensures a username will be unique or renames it. -func (s *Server) UniqueUsername(username string) string { +// UniqueUsername ensures a username will be unique or renames it. If the name is already unique, the error result is nil. +func (s *Server) UniqueUsername(username string) (string, error) { var ( subs = s.IterSubscribers() usernames = map[string]interface{}{} @@ -297,7 +297,11 @@ func (s *Server) UniqueUsername(username string) string { } } - return username + if username != origUsername { + return username, errors.New("username was not unique and a unique name has been returned") + } + + return username, nil } // Broadcast a message to the chat room. diff --git a/web/static/js/BareRTC.js b/web/static/js/BareRTC.js index 7a72264..491699b 100644 --- a/web/static/js/BareRTC.js +++ b/web/static/js/BareRTC.js @@ -975,6 +975,23 @@ const app = Vue.createApp({ } return this.channels[channel].unread; }, + hasAnyUnread() { + // Returns total unread count (for mobile responsive view to show in the left drawer button) + let count = 0; + for (let channel of Object.keys(this.channels)) { + count += this.channels[channel].unread; + } + return count; + }, + anyUnreadDMs() { + // Returns true if any unread messages are DM threads + for (let channel of Object.keys(this.channels)) { + if (channel.indexOf("@") === 0 && this.channels[channel].unread > 0) { + return true; + } + } + return false; + }, openDMs(user) { let channel = "@" + user.username; this.initHistory(channel); diff --git a/web/templates/chat.html b/web/templates/chat.html index 7a5d3da..0a592be 100644 --- a/web/templates/chat.html +++ b/web/templates/chat.html @@ -503,7 +503,7 @@