admin-dashboard-backend/modules/structs/socket.go

126 lines
2.9 KiB
Go

package structs
import (
"encoding/json"
"errors"
"sync"
"time"
"github.com/gofiber/websocket/v2"
"github.com/rs/zerolog/log"
)
const (
// Note: Status codes in the range 4000-4999 are reserved for private use
SocketCloseCodeUnauthorized = 4001
SocketCloseCodeSessionClosed = 4002 // when user logs out of the session and has multiple tabs with the same session open
)
type SocketClient struct {
SessionId string
UserId string
Conn *websocket.Conn
connMu sync.Mutex
}
type SocketMessage struct {
Conn *websocket.Conn
Msg []byte
}
type SendSocketMessage struct {
Cmd int
Body any
}
type ReceivedMessage struct {
Cmd int
Body map[string]interface{}
}
func (socketClient *SocketClient) SendSessionClosedMessage() error {
return socketClient.writeMessage(websocket.CloseMessage, SendSocketMessage{}, SocketCloseCodeSessionClosed)
}
func (socketClient *SocketClient) SendUnauthorizedCloseMessage() error {
return socketClient.writeMessage(websocket.CloseMessage, SendSocketMessage{}, SocketCloseCodeUnauthorized)
}
func (socketClient *SocketClient) SendMessage(message SendSocketMessage) error {
return socketClient.writeMessage(websocket.TextMessage, message, 0)
}
func (socketClient *SocketClient) writeMessage(messageType int, message SendSocketMessage, closeMessageCode int) error {
var marshaledMessage []byte
var err error
if closeMessageCode > 0 {
marshaledMessage = websocket.FormatCloseMessage(closeMessageCode, "")
} else {
marshaledMessage, err = json.Marshal(message)
if err != nil {
log.Error().Msgf("Failed to marshal ws message, err: %s", err)
return err
}
}
socketClient.connMu.Lock()
defer socketClient.connMu.Unlock()
if socketClient.Conn == nil {
log.Error().Msgf("Failed to ws message because conn is nil")
return errors.New("ws client conn is nil")
}
err = socketClient.Conn.WriteMessage(messageType, marshaledMessage)
if err != nil {
log.Error().Msgf("Failed to write ws message, err: %s", err)
return err
}
return nil
}
type InitUserSocketConnection struct {
User UserData
CategoryGroups []CategoryGroup // config specific group tasks
GroupTasks []GroupTasks // in database saved group tasks
GroupTasksSteps []GroupTaskSteps
AllUsers []AllUsers
Scanners []Scanner
AllRoles []Role
AdminArea InitUserSocketConnectionAdminArea
}
type InitUserSocketConnectionAdminArea struct {
RolesPermissions []RolePermissions `json:"RolesPermissions,omitempty"`
}
type AllUsers struct {
Id string
RoleId string
Avatar string
Username string
ConnectionStatus uint8
LastOnline time.Time
}
type UserData struct {
Id string
RoleId string
Username string
Email string
Sessions []UserSessionSocket
Permissions []string
}
type UserSessionSocket struct {
IdForDeletion string
UserAgent string
ConnectionStatus uint8
LastUsed time.Time
ExpiresAt time.Time
}