package web import ( "fmt" "net/http" "strconv" "uPortal/internal/auth" ) // HandleJitsi renders the Jitsi room form on GET and redirects to Jitsi Meet on POST. func (s *WebService) HandleJitsi(w http.ResponseWriter, r *http.Request) { data, ok := s.basicViewData(w, r, "Jitsi") if !ok { http.Redirect(w, r, "/signin", http.StatusSeeOther) return } switch r.Method { case http.MethodGet: s.render(w, r, "jitsi/token.html", data) case http.MethodPost: if err := auth.ValidateCsrf(r, CsrfCookieName, CsrfFieldName); err != nil { data.Error = "Invalid form, please try again" s.render(w, r, "jitsi/token.html", data) return } if s.jitsiCfg == nil || s.jitsiCfg.Secret == "" { data.Error = "Jitsi is not configured" s.render(w, r, "jitsi/token.html", data) return } room := r.FormValue("room") if room == "" { data.Error = "Room name is required" s.render(w, r, "jitsi/token.html", data) return } avatar := avatarURL(r, s, data.User.Id) token, err := s.jitsiCfg.GenerateToken( strconv.FormatInt(data.User.Id, 10), data.User.EffectiveDisplayName(), room, data.User.SuperUser, avatar, ) if err != nil { data.Error = "Could not generate token" s.render(w, r, "jitsi/token.html", data) return } http.Redirect(w, r, s.jitsiCfg.MeetURL(room, token), http.StatusSeeOther) } } // HandleJitsiGo is a GET endpoint that reads a "room" query parameter, // generates a JWT token, and redirects to the Jitsi Meet URL. func (s *WebService) HandleJitsiGo(w http.ResponseWriter, r *http.Request) { if s.jitsiCfg == nil || s.jitsiCfg.Secret == "" { http.Error(w, "Jitsi is not configured", http.StatusInternalServerError) return } user, err := s.currentUser(r) if err != nil { http.Redirect(w, r, "/signin", http.StatusSeeOther) return } room := r.URL.Query().Get("room") if room == "" { http.Redirect(w, r, "/jitsi", http.StatusSeeOther) return } avatar := avatarURL(r, s, user.Id) token, err := s.jitsiCfg.GenerateToken( strconv.FormatInt(user.Id, 10), user.EffectiveDisplayName(), room, user.SuperUser, avatar, ) if err != nil { http.Error(w, "Could not generate token", http.StatusInternalServerError) return } http.Redirect(w, r, s.jitsiCfg.MeetURL(room, token), http.StatusSeeOther) } // avatarURL returns the app's avatar URL for the given user id, or an empty // string if the user has no stored avatar. If the Jitsi site domain is // configured, an absolute https:// URL is returned so Jitsi (running on a // different domain) can load the avatar; otherwise a relative URL is used. func avatarURL(r *http.Request, s *WebService, id int64) string { data, err := s.users.GetAvatar(r.Context(), id) if err != nil || len(data) == 0 { return "" } path := fmt.Sprintf("/avatar/%d", id) if s.jitsiCfg != nil && s.jitsiCfg.SiteDomain != "" { return fmt.Sprintf("https://%s%s", s.jitsiCfg.SiteDomain, path) } return path }