package socketclients import ( "janex/admin-dashboard-backend/modules/cache" "janex/admin-dashboard-backend/modules/database" "janex/admin-dashboard-backend/modules/structs" "janex/admin-dashboard-backend/modules/utils" "time" ) func BroadcastMessage(sendSocketMessage structs.SendSocketMessage) { for _, client := range cache.GetSocketClients() { client.SendMessage(sendSocketMessage) } } func BroadcastMessageExceptUserSessionId(ignoreUserSessionId string, sendSocketMessage structs.SendSocketMessage) { for _, client := range cache.GetSocketClients() { if client.SessionId != ignoreUserSessionId { client.SendMessage(sendSocketMessage) } } } func UpdateConnectedUsers(userId string) { var user structs.User database.DB.First(&user, "id = ?", userId) BroadcastMessage(structs.SendSocketMessage{ Cmd: utils.SentCmdUpdateConnectedUsers, Body: struct { WebSocketUsersCount int UserId string ConnectionStatus uint8 LastOnline time.Time }{ WebSocketUsersCount: len(cache.GetSocketClients()), UserId: userId, ConnectionStatus: isUserGenerallyConnected(userId), LastOnline: user.LastOnline, }, }) } func SendMessageToUser(userId string, ignoreUserSessionId string, sendSocketMessage structs.SendSocketMessage) { for _, client := range cache.GetSocketClients() { if client.UserId == userId && client.SessionId != ignoreUserSessionId { client.SendMessage(sendSocketMessage) } } } // This close all connections that are connected with one session id. // For example when a user has two browser tabs opened func CloseAllUserSessionConnections(sessionId string) { for _, client := range cache.GetSocketClients() { if client.SessionId == sessionId { client.SendSessionClosedMessage() } } } func GetUserSessions(userId string) []structs.UserSessionSocket { var userSessions []structs.UserSession database.DB.Where("user_id = ?", userId).Find(&userSessions) var userSessionsSocket []structs.UserSessionSocket socketClients := cache.GetSocketClients() for _, userSession := range userSessions { userSessionsSocket = append(userSessionsSocket, structs.UserSessionSocket{ IdForDeletion: userSession.IdForDeletion, UserAgent: userSession.UserAgent, ConnectionStatus: isUserSessionConnected(userSession.Id, socketClients), LastUsed: userSession.LastUsed, ExpiresAt: userSession.ExpiresAt, }) } return userSessionsSocket } func UpdateUserSessionsForUser(userId string, ignoreUserSessionId string) { GetUserSessions(userId) SendMessageToUser(userId, ignoreUserSessionId, structs.SendSocketMessage{ Cmd: utils.SentCmdUpdateUserSessions, Body: GetUserSessions(userId), }) } func isUserSessionConnected(userSessionId string, socketClients []*structs.SocketClient) uint8 { for _, socketClient := range socketClients { if socketClient.SessionId == userSessionId { return 1 } } return 0 } // Used to determine if a user is connected regardless of the session used func isUserGenerallyConnected(userId string) uint8 { for _, socketClient := range cache.GetSocketClients() { if socketClient.UserId == userId { return 1 } } return 0 } // Get all users from database. // This is used in the UI to display all users. func GetAllUsers() []structs.AllUsers { var users []structs.User var allUsers []structs.AllUsers database.DB.Find(&users) for _, user := range users { allUsers = append(allUsers, structs.AllUsers{ Id: user.Id, Avatar: user.Avatar, Username: user.Username, ConnectionStatus: isUserGenerallyConnected(user.Id), LastOnline: user.LastOnline, }) } return allUsers } func GetAllScanners() []structs.Scanner { var scanners []structs.Scanner var allScanners []structs.Scanner database.DB.Find(&scanners) for _, scanner := range scanners { // clear session to prevent leaking and sending to ui scanner.Session = "" allScanners = append(allScanners, scanner) } return allScanners }