131 lines
2.9 KiB
Go
131 lines
2.9 KiB
Go
package rest
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// sanitizeRoomName trims a room name and collapses any character that is not
|
|
// allowed in a room name into a single dash, stripping leading/trailing dashes.
|
|
// Case is preserved because Jitsi room names are case-sensitive.
|
|
func sanitizeRoomName(value string) string {
|
|
var builder strings.Builder
|
|
builder.Grow(len(value))
|
|
previousDash := false
|
|
for _, r := range strings.TrimSpace(value) {
|
|
allowed := (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '-' || r == '_'
|
|
if allowed {
|
|
builder.WriteRune(r)
|
|
previousDash = false
|
|
continue
|
|
}
|
|
if !previousDash {
|
|
builder.WriteByte('-')
|
|
previousDash = true
|
|
}
|
|
}
|
|
return strings.Trim(builder.String(), "-")
|
|
}
|
|
|
|
type joinRoomRequest struct {
|
|
Room string `json:"room"`
|
|
}
|
|
|
|
type joinRoomResponse struct {
|
|
Room string `json:"room"`
|
|
Token string `json:"token"`
|
|
Url string `json:"url"`
|
|
AppId string `json:"appId"`
|
|
AppName string `json:"appName"`
|
|
Domain string `json:"domain"`
|
|
}
|
|
|
|
type roomHistoryResponse struct {
|
|
RoomName string `json:"roomName"`
|
|
LastJoinedAt time.Time `json:"lastJoinedAt"`
|
|
}
|
|
|
|
func (h *Handler) listRecentRooms(w http.ResponseWriter, r *http.Request) {
|
|
u := userFromRequest(r)
|
|
|
|
limit, offset := pagination(r)
|
|
rooms, err := h.jitsi.RoomHistory(r.Context(), u, limit, offset)
|
|
if err != nil {
|
|
h.fail(w, err)
|
|
return
|
|
}
|
|
|
|
result := make([]roomHistoryResponse, 0, len(rooms))
|
|
for _, room := range rooms {
|
|
result = append(result, roomHistoryResponse{
|
|
RoomName: room.RoomName,
|
|
LastJoinedAt: room.LastJoinedAt,
|
|
})
|
|
}
|
|
|
|
writeJson(w, http.StatusOK, result)
|
|
}
|
|
|
|
func (h *Handler) joinRoom(w http.ResponseWriter, r *http.Request) {
|
|
u := userFromRequest(r)
|
|
|
|
var req joinRoomRequest
|
|
if err := decodeJson(r, &req); err != nil {
|
|
writeError(w, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
room := sanitizeRoomName(req.Room)
|
|
if room == "" {
|
|
writeError(w, http.StatusBadRequest, "room is required")
|
|
return
|
|
}
|
|
|
|
// Moderator rights are inherited from the user's admin flag.
|
|
moderator := u.IsAdmin
|
|
|
|
token, err := h.jitsi.GenerateToken(
|
|
formatUserId(u.Id),
|
|
u.DisplayedName(),
|
|
room,
|
|
moderator,
|
|
h.avatarURL(r, u.Id),
|
|
)
|
|
if err != nil {
|
|
h.fail(w, err)
|
|
return
|
|
}
|
|
|
|
if err := h.jitsi.RecordRoomJoin(r.Context(), u, room); err != nil {
|
|
h.fail(w, err)
|
|
return
|
|
}
|
|
|
|
writeJson(w, http.StatusOK, joinRoomResponse{
|
|
Room: room,
|
|
Token: token,
|
|
Url: h.jitsi.MeetUrl(room, token),
|
|
AppId: h.jitsi.AppID,
|
|
AppName: h.jitsi.AppName,
|
|
Domain: h.jitsi.Domain,
|
|
})
|
|
}
|
|
|
|
func (h *Handler) deleteRecentRoom(w http.ResponseWriter, r *http.Request) {
|
|
u := userFromRequest(r)
|
|
|
|
room := sanitizeRoomName(r.PathValue("room"))
|
|
if room == "" {
|
|
writeError(w, http.StatusBadRequest, "room is required")
|
|
return
|
|
}
|
|
|
|
if err := h.jitsi.DeleteRoom(r.Context(), u, room); err != nil {
|
|
h.fail(w, err)
|
|
return
|
|
}
|
|
|
|
writeNoContent(w)
|
|
}
|