diff --git a/group/group.go b/group/group.go index f3b5f57..dcf1e27 100644 --- a/group/group.go +++ b/group/group.go @@ -159,6 +159,10 @@ func (g *Group) API() *webrtc.API { } func Add(name string, desc *description) (*Group, error) { + if name == "" || strings.HasSuffix(name, "/") { + return nil, UserError("illegal group name") + } + groups.mu.Lock() defer groups.mu.Unlock() diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go index ef35795..9b748b3 100644 --- a/rtpconn/webclient.go +++ b/rtpconn/webclient.go @@ -3,11 +3,11 @@ package rtpconn import ( "encoding/json" "errors" + "fmt" "log" "os" "sync" "time" - "fmt" "github.com/gorilla/websocket" "github.com/pion/webrtc/v3" @@ -1031,29 +1031,36 @@ func handleClientMessage(c *webClient, m clientMessage) error { c.password = m.Password g, err := group.AddClient(m.Group, c) if err != nil { + var s string if os.IsNotExist(err) { - return c.error( - group.UserError("group does not exist"), - ) + s = "group does not exist" } else if err == group.ErrNotAuthorised { + s = "not authorised" time.Sleep(200 * time.Millisecond) - s := "not authorised" - return c.write(clientMessage{ - Type: "joined", - Kind: "fail", - Group: m.Group, - Permissions: &group.ClientPermissions{}, - Value: &s, - }) + } else if e, ok := err.(group.UserError); ok { + s = string(e) + } else { + s = "internal server error" + log.Printf("Join group: %v") } - return err + return c.write(clientMessage{ + Type: "joined", + Kind: "fail", + Group: m.Group, + Permissions: &group.ClientPermissions{}, + Value: &s, + }) } if redirect := g.Redirect(); redirect != "" { // We normally redirect at the HTTP level, but the group // description could have been edited in the meantime. - return c.error( - group.UserError("group is now at " + redirect), - ) + return c.write(clientMessage{ + Type: "joined", + Kind: "redirect", + Group: m.Group, + Permissions: &group.ClientPermissions{}, + Value: &redirect, + }) } c.group = g perms := c.permissions @@ -1264,11 +1271,11 @@ func handleClientMessage(c *webClient, m clientMessage) error { sg.Name, sg.Clients, plural) } c.write(clientMessage{ - Type: "chat", - Dest: c.id, + Type: "chat", + Dest: c.id, Username: "Server", - Time: group.ToJSTime(time.Now()), - Value: &s, + Time: group.ToJSTime(time.Now()), + Value: &s, }) default: return group.ProtocolError("unknown group action") diff --git a/static/sfu.js b/static/sfu.js index b874508..d05895c 100644 --- a/static/sfu.js +++ b/static/sfu.js @@ -271,7 +271,7 @@ function setConnected(connected) { userpass ? userpass.password : ''; userbox.classList.add('invisible'); connectionbox.classList.remove('invisible'); - displayError("Disconnected!", "error"); + displayError('Disconnected', 'error'); hideVideo(); closeVideoControls(); } @@ -1425,43 +1425,54 @@ let presentRequested = null; * @param {Object} perms */ async function gotJoined(kind, group, perms, message) { - if(kind === 'fail') { + let present = presentRequested; + presentRequested = null; + + switch(kind) { + case 'fail': displayError('The server said: ' + message); this.close(); return; + case 'redirect': + this.close(); + document.location = message; + return; + case 'leave': + this.close(); + return; + case 'join': + break; + default: + displayError('Unknown join message'); + this.close(); + return; } displayUsername(); setButtonsVisibility(); - if(kind !== 'leave') - this.request(getSettings().request); + this.request(getSettings().request); - try { - if(kind === 'join' && - serverConnection.permissions.present && !findUpMedia('local')) { - if(presentRequested) { - if(presentRequested === 'mike') - updateSettings({video: ''}); - else if(presentRequested === 'both') - delSetting('video'); - reflectSettings(); + if(serverConnection.permissions.present && !findUpMedia('local')) { + if(present) { + if(present === 'mike') + updateSettings({video: ''}); + else if(present === 'both') + delSetting('video'); + reflectSettings(); - let button = getButtonElement('presentbutton'); - button.disabled = true; - try { - await addLocalMedia(); - } finally { - button.disabled = false; - } - } else { - displayMessage( - "Press Present to enable your camera or microphone" - ); + let button = getButtonElement('presentbutton'); + button.disabled = true; + try { + await addLocalMedia(); + } finally { + button.disabled = false; } + } else { + displayMessage( + "Press Ready to enable your camera or microphone" + ); } - } finally { - presentRequested = null; } } diff --git a/webserver/webserver.go b/webserver/webserver.go index 75731c1..f811691 100644 --- a/webserver/webserver.go +++ b/webserver/webserver.go @@ -243,6 +243,12 @@ func groupHandler(w http.ResponseWriter, r *http.Request) { return } + if strings.HasSuffix(r.URL.Path, "/") { + http.Redirect(w, r, r.URL.Path[:len(r.URL.Path)-1], + http.StatusPermanentRedirect) + return + } + g, err := group.Add(name, nil) if err != nil { if os.IsNotExist(err) {