Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 97 additions & 98 deletions controllers/room_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,9 @@ func CreateRoom(c *gin.Context) {

// Create the room
room := models.Room{
Name: input.Name,
Type: input.Type,
CreatedBy: userID,
Name: input.Name,
Type: input.Type,
CreatedBy: userID,
}

if err := database.DB.Create(&room).Error; err != nil {
Expand Down Expand Up @@ -297,15 +296,16 @@ func GetRoom(c *gin.Context) {
// @Security BearerAuth
// @Router /api/rooms/groups [get]
func GetGroupRooms(c *gin.Context) {
var groups []models.Room
if err := database.DB.Preload("Users").
Where("type = ?", "group").
Find(&groups).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch group rooms"})
return
}
c.JSON(http.StatusOK, gin.H{"rooms": groups})
var groups []models.Room
if err := database.DB.Preload("Users").
Where("type = ?", "group").
Find(&groups).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch group rooms"})
return
}
c.JSON(http.StatusOK, gin.H{"rooms": groups})
}

// UpdateRoom godoc
// @Summary Update a room's details
// @Description Updates a room's name and/or members
Expand Down Expand Up @@ -568,56 +568,56 @@ func SetActivateRoom(c *gin.Context) {
// @Failure 404 {object} map[string]string "Room not found"
// @Router /api/rooms/{id}/join [post]
func JoinRoom(c *gin.Context) {
userID := c.MustGet("userID").(uint)
roomID64, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid room ID"})
return
}
roomID := uint(roomID64)

// Check room exists
var room models.Room
if err := database.DB.First(&room, roomID).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Room not found"})
return
}

// Check user is not already in room
var existing models.RoomUser
if err := database.DB.
Where("room_id = ? AND user_id = ?", roomID, userID).
First(&existing).Error; err == nil {
c.Status(http.StatusNoContent)
return
}

// Create membership
ru := models.RoomUser{
RoomID: roomID,
UserID: userID,
LastReadAt: time.Now(),
}
if err := database.DB.Create(&ru).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to join room"})
return
}
userID := c.MustGet("userID").(uint)
roomID64, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid room ID"})
return
}
roomID := uint(roomID64)

// Check room exists
var room models.Room
if err := database.DB.First(&room, roomID).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Room not found"})
return
}

// Check user is not already in room
var existing models.RoomUser
if err := database.DB.
Where("room_id = ? AND user_id = ?", roomID, userID).
First(&existing).Error; err == nil {
c.Status(http.StatusNoContent)
return
}

// Create membership
ru := models.RoomUser{
RoomID: roomID,
UserID: userID,
LastReadAt: time.Now(),
}
if err := database.DB.Create(&ru).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to join room"})
return
}
var u models.User
if err := database.DB.First(&u, userID).Error; err == nil {
websocket.BroadcastToRoom(
roomID,
"system",
map[string]interface{}{
"room_id": roomID,
"user_id": userID,
"username": u.Username,
"action": "join",
"timestamp": time.Now().UTC(),
},
)
}

c.Status(http.StatusNoContent)
if err := database.DB.First(&u, userID).Error; err == nil {
websocket.BroadcastToRoom(
roomID,
"system",
map[string]interface{}{
"room_id": roomID,
"user_id": userID,
"username": u.Username,
"action": "join",
"timestamp": time.Now().UTC(),
},
)
}

c.Status(http.StatusNoContent)
}

// LeaveRoom godoc
Expand All @@ -635,43 +635,42 @@ func JoinRoom(c *gin.Context) {
// @Failure 404 {object} map[string]string "Room not found or not a member"
// @Router /api/rooms/{id}/leave [post]
func LeaveRoom(c *gin.Context) {
userID := c.MustGet("userID").(uint)
roomID64, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid room ID"})
return
}
roomID := uint(roomID64)

// Ensure membership exists
var ru models.RoomUser
if err := database.DB.
Where("room_id = ? AND user_id = ?", roomID, userID).
First(&ru).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "You are not a member of this room"})
return
}

// Remove membership
if err := database.DB.Delete(&ru).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to leave room"})
return
}
userID := c.MustGet("userID").(uint)
roomID64, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid room ID"})
return
}
roomID := uint(roomID64)

// Ensure membership exists
var ru models.RoomUser
if err := database.DB.
Where("room_id = ? AND user_id = ?", roomID, userID).
First(&ru).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "You are not a member of this room"})
return
}

// Remove membership
if err := database.DB.Delete(&ru).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to leave room"})
return
}
var u models.User
if err := database.DB.First(&u, userID).Error; err == nil {
websocket.BroadcastToRoom(
roomID,
"system",
map[string]interface{}{
"room_id": roomID,
"user_id": userID,
"username": u.Username,
"action": "leave",
"timestamp": time.Now().UTC(),
},
)
}

c.Status(http.StatusNoContent)
}
if err := database.DB.First(&u, userID).Error; err == nil {
websocket.BroadcastToRoom(
roomID,
"system",
map[string]interface{}{
"room_id": roomID,
"user_id": userID,
"username": u.Username,
"action": "leave",
"timestamp": time.Now().UTC(),
},
)
}

c.Status(http.StatusNoContent)
}
2 changes: 1 addition & 1 deletion controllers/user_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func SearchUsers(c *gin.Context) {
// Find users with usernames that start with the provided prefix
var users []models.User
if err := database.DB.Where("username LIKE ?", usernamePrefix+"%").
Select("id, username, email, created_at, updated_at").
Select("id, username, email, status, created_at, updated_at").
Limit(10).
Find(&users).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to search users"})
Expand Down
26 changes: 16 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,29 @@ func main() {
// Set up router
router := gin.Default()

// CORS middleware
// CORS middleware
router.Use(func(c *gin.Context) {
envHost := os.Getenv("HOST")
if envHost == "" {
envHost = "localhost" // fallback
}
allowedOrigin := "http://" + envHost + ":3000"

origin := c.Request.Header.Get("Origin")
if origin == "http://192.168.1.37:3000" {
if origin == allowedOrigin {
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
}
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")

if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}

c.Next()
})
c.Next()
})

// Swagger documentation
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
Expand Down Expand Up @@ -93,8 +99,8 @@ func main() {
api.GET("/rooms/groups", controllers.GetGroupRooms)
api.PUT("/rooms/:id", controllers.UpdateRoom)
api.DELETE("/rooms/:id", controllers.DeleteRoom)
api.POST("/rooms/:id/join",controllers.JoinRoom)
api.POST("/rooms/:id/leave",controllers.LeaveRoom)
api.POST("/rooms/:id/join", controllers.JoinRoom)
api.POST("/rooms/:id/leave", controllers.LeaveRoom)
api.GET("/rooms/:id/unread", controllers.GetUnreadCount)
api.POST("/rooms/set-activate-room", controllers.SetActivateRoom)

Expand Down