- POST /api/v1/chats (ensure chat between users, normalized pair) - GET /api/v1/chats (list with last message + unread) - GET /api/v1/chats/:id/messages - POST /api/v1/chats/:id/messages (send text/photo, push via WS) - PUT /api/v1/chats/:id/read (mark all read) - PUT /api/v1/messages/:msgId (edit, owner only) - DELETE /api/v1/messages/:msgId (soft delete) - POST /api/v1/blocks, DELETE /api/v1/blocks/:id - POST /api/v1/reports - WS /ws?token= (real-time message push, ping/pong) - migrations 0003: chats, messages, blocks, reports
56 lines
1.3 KiB
Go
56 lines
1.3 KiB
Go
package ws
|
||
|
||
import (
|
||
"strings"
|
||
|
||
"github.com/gofiber/contrib/websocket"
|
||
"github.com/gofiber/fiber/v2"
|
||
"github.com/google/uuid"
|
||
|
||
"github.com/buhapp/backend/internal/auth"
|
||
)
|
||
|
||
// AuthMiddleware — авторизация по ?token=... (для WS)
|
||
func AuthMiddleware(svc *auth.Service) fiber.Handler {
|
||
return func(c *fiber.Ctx) error {
|
||
tok := c.Query("token")
|
||
if tok == "" {
|
||
h := c.Get("Authorization")
|
||
if strings.HasPrefix(h, "Bearer ") {
|
||
tok = strings.TrimPrefix(h, "Bearer ")
|
||
}
|
||
}
|
||
if tok == "" {
|
||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "token required"})
|
||
}
|
||
claims, err := svc.Parse(c.UserContext(), tok)
|
||
if err != nil {
|
||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid token"})
|
||
}
|
||
c.Locals("user_id", claims.UserID)
|
||
return c.Next()
|
||
}
|
||
}
|
||
|
||
// Upgrade — проверка что соединение upgradeable
|
||
func Upgrade(c *fiber.Ctx) error {
|
||
if websocket.IsWebSocketUpgrade(c) {
|
||
c.Locals("allowed", true)
|
||
return c.Next()
|
||
}
|
||
return fiber.ErrUpgradeRequired
|
||
}
|
||
|
||
// Handler — отдаёт hub'у новое WS-соединение
|
||
func Handler(hub *Hub) fiber.Handler {
|
||
return websocket.New(func(c *websocket.Conn) {
|
||
v := c.Locals("user_id")
|
||
uid, ok := v.(uuid.UUID)
|
||
if !ok {
|
||
_ = c.Close()
|
||
return
|
||
}
|
||
hub.Handle(uid, c)
|
||
})
|
||
}
|