Adding some hardening to user joining
Client sends the server a object to join instead of a message server can send a message to notify the user closes #57
This commit is contained in:
parent
5819bdb85a
commit
ad2579d59a
42
chatroom.go
42
chatroom.go
|
@ -76,7 +76,7 @@ func (cr *ChatRoom) JoinTemp(conn *chatConnection) (string, error) {
|
|||
|
||||
//registering a new client
|
||||
//returns pointer to a Client, or Nil, if the name is already taken
|
||||
func (cr *ChatRoom) Join(name, uid string) (*Client, error) {
|
||||
func (cr *ChatRoom) Join(uid string, data common.JoinData) (*Client, error) {
|
||||
defer cr.clientsMtx.Unlock()
|
||||
cr.clientsMtx.Lock()
|
||||
|
||||
|
@ -85,41 +85,63 @@ func (cr *ChatRoom) Join(name, uid string) (*Client, error) {
|
|||
return nil, errors.New("connection is missing from temp connections")
|
||||
}
|
||||
|
||||
if !common.IsValidName(name) {
|
||||
return nil, UserFormatError{Name: name}
|
||||
sendHiddenMessage := func(cd common.ClientDataType, i interface{}) {
|
||||
// If the message cant be converted, then just don't send
|
||||
if d, err := common.NewChatHiddenMessage(cd, i).ToJSON(); err == nil {
|
||||
conn.WriteJSON(d)
|
||||
}
|
||||
}
|
||||
|
||||
nameLower := strings.ToLower(name)
|
||||
if !common.IsValidName(data.Name) {
|
||||
sendHiddenMessage(common.CdNotify, "Invalid name")
|
||||
return nil, UserFormatError{Name: data.Name}
|
||||
}
|
||||
|
||||
nameLower := strings.ToLower(data.Name)
|
||||
for _, client := range cr.clients {
|
||||
if strings.ToLower(client.name) == nameLower {
|
||||
return nil, UserTakenError{Name: name}
|
||||
sendHiddenMessage(common.CdNotify, "Name already taken")
|
||||
return nil, UserTakenError{Name: data.Name}
|
||||
}
|
||||
}
|
||||
|
||||
client, err := NewClient(conn, cr, name, common.RandomColor())
|
||||
// If color is invalid, then set it to a random color
|
||||
if !common.IsValidColor(data.Color) {
|
||||
data.Color = common.RandomColor()
|
||||
}
|
||||
|
||||
client, err := NewClient(conn, cr, data.Name, data.Color)
|
||||
if err != nil {
|
||||
sendHiddenMessage(common.CdNotify, "Could not join client")
|
||||
return nil, fmt.Errorf("Unable to join client: %v", err)
|
||||
}
|
||||
|
||||
// Overwrite to use client instead
|
||||
sendHiddenMessage = func(cd common.ClientDataType, i interface{}) {
|
||||
client.SendChatData(common.NewChatHiddenMessage(cd, i))
|
||||
}
|
||||
|
||||
host := client.Host()
|
||||
|
||||
if banned, names := settings.IsBanned(host); banned {
|
||||
return nil, newBannedUserError(host, name, names)
|
||||
sendHiddenMessage(common.CdNotify, "You are banned")
|
||||
return nil, newBannedUserError(host, data.Name, names)
|
||||
}
|
||||
|
||||
cr.clients[uid] = client
|
||||
delete(cr.tempConn, uid)
|
||||
|
||||
common.LogChatf("[join] %s %s\n", host, name)
|
||||
common.LogChatf("[join] %s %s\n", host, data.Color)
|
||||
playingCommand, err := common.NewChatCommand(common.CmdPlaying, []string{cr.playing, cr.playingLink}).ToJSON()
|
||||
if err != nil {
|
||||
common.LogErrorf("Unable to encode playing command on join: %s\n", err)
|
||||
} else {
|
||||
client.Send(playingCommand)
|
||||
}
|
||||
cr.AddEventMsg(common.EvJoin, name, client.color)
|
||||
cr.AddEventMsg(common.EvJoin, data.Name, data.Color)
|
||||
|
||||
client.SendChatData(common.NewChatHiddenMessage(common.CdEmote, common.Emotes))
|
||||
sendHiddenMessage(common.CdJoin, nil)
|
||||
sendHiddenMessage(common.CdEmote, common.Emotes)
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
|
|
@ -242,3 +242,8 @@ func DecodeData(rawjson string) (ChatDataJSON, error) {
|
|||
err := json.Unmarshal([]byte(rawjson), &data)
|
||||
return data, err
|
||||
}
|
||||
|
||||
type JoinData struct {
|
||||
Name string
|
||||
Color string
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ const (
|
|||
CdAuth // get the auth levels of the user
|
||||
CdColor // get the users color
|
||||
CdEmote // get a list of emotes
|
||||
CdJoin // a message saying the client wants to join
|
||||
CdNotify // a notify message for the client to show
|
||||
)
|
||||
|
||||
type DataType int
|
||||
|
|
13
handlers.go
13
handlers.go
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
|
@ -119,12 +120,20 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
var data common.ClientData
|
||||
err := chatConn.ReadData(&data)
|
||||
if err != nil {
|
||||
common.LogInfof("[handler] Client closed connection: %s\n", conn.RemoteAddr().String())
|
||||
common.LogInfof("[handler] Client closed connection: %s: %v\n",
|
||||
conn.RemoteAddr().String(), err)
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
client, err = chat.Join(data.Message, uid)
|
||||
var joinData common.JoinData
|
||||
err = json.Unmarshal([]byte(data.Message), &joinData)
|
||||
if err != nil {
|
||||
common.LogInfof("[handler] Could not unmarshal join data %#v: %v\n", data.Message, err)
|
||||
continue
|
||||
}
|
||||
|
||||
client, err = chat.Join(uid, joinData)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case UserFormatError, UserTakenError:
|
||||
|
|
|
@ -16,6 +16,10 @@ function getCookie(cname) {
|
|||
return "";
|
||||
}
|
||||
|
||||
function deleteCookie(cname) {
|
||||
document.cookie = `${cname}=;expires=Thu, 01 Jan 1970 00:00:01 GMT`
|
||||
}
|
||||
|
||||
function setPlaying(title, link) {
|
||||
if (title !== "") {
|
||||
$('#playing').text(title);
|
||||
|
@ -96,28 +100,6 @@ function closeChat() {
|
|||
inChat = false;
|
||||
}
|
||||
|
||||
function join() {
|
||||
let name = $("#name").val();
|
||||
if (!isValidName(name)) {
|
||||
setNotifyBox("Please input a valid name");
|
||||
return;
|
||||
}
|
||||
if (!sendMessage($("#name").val())) {
|
||||
setNotifyBox("could not join");
|
||||
return;
|
||||
}
|
||||
setNotifyBox();
|
||||
openChat();
|
||||
|
||||
let color = getCookie("color");
|
||||
if (color !== "") {
|
||||
// Do a timeout because timings
|
||||
setTimeout(() => {
|
||||
sendMessage("/color " + color);
|
||||
}, 250);
|
||||
}
|
||||
}
|
||||
|
||||
function websocketSend(data) {
|
||||
if (ws.readyState == ws.OPEN) {
|
||||
ws.send(data);
|
||||
|
|
55
wasm/main.go
55
wasm/main.go
|
@ -19,6 +19,41 @@ var (
|
|||
auth common.CommandLevel
|
||||
)
|
||||
|
||||
func getElement(s string) js.Value {
|
||||
return js.Get("document").Call("getElementById", s)
|
||||
}
|
||||
|
||||
func join(v []js.Value) {
|
||||
color := js.Call("getCookie", "color").String()
|
||||
if color == "" {
|
||||
// If a color is not set, do a random color
|
||||
color = common.RandomColor()
|
||||
} else if !common.IsValidColor(color) {
|
||||
// Don't show the user the error, just clear the cookie
|
||||
common.LogInfof("%#v is not a valid color, clearing cookie", color)
|
||||
js.Call("deleteCookie", "color")
|
||||
}
|
||||
|
||||
joinData, err := json.Marshal(common.JoinData{
|
||||
Name: getElement("name").Get("value").String(),
|
||||
Color: color,
|
||||
})
|
||||
if err != nil {
|
||||
notify("Error prepping data for join")
|
||||
common.LogErrorf("Could not prep data: %#v\n", err)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(common.ClientData{
|
||||
Type: common.CdJoin,
|
||||
Message: string(joinData),
|
||||
})
|
||||
if err != nil {
|
||||
common.LogErrorf("Could not marshal data: %v", err)
|
||||
}
|
||||
|
||||
js.Call("websocketSend", string(data))
|
||||
}
|
||||
|
||||
func recieve(v []js.Value) {
|
||||
if len(v) == 0 {
|
||||
fmt.Println("No data received")
|
||||
|
@ -61,6 +96,11 @@ func recieve(v []js.Value) {
|
|||
emotes[k] = v.(string)
|
||||
}
|
||||
sort.Strings(emoteNames)
|
||||
case common.CdJoin:
|
||||
notify("")
|
||||
js.Call("openChat")
|
||||
case common.CdNotify:
|
||||
notify(h.Data.(string))
|
||||
}
|
||||
case common.DTEvent:
|
||||
d := chat.Data.(common.DataEvent)
|
||||
|
@ -152,6 +192,10 @@ func showChatError(err error) {
|
|||
}
|
||||
}
|
||||
|
||||
func notify(msg string) {
|
||||
js.Call("setNotifyBox", msg)
|
||||
}
|
||||
|
||||
func showTimestamp(v []js.Value) {
|
||||
if len(v) != 1 {
|
||||
// Don't bother with returning a value
|
||||
|
@ -167,13 +211,6 @@ func isValidColor(this js.Value, v []js.Value) interface{} {
|
|||
return common.IsValidColor(v[0].String())
|
||||
}
|
||||
|
||||
func isValidName(this js.Value, v []js.Value) interface{} {
|
||||
if len(v) != 1 {
|
||||
return false
|
||||
}
|
||||
return common.IsValidName(v[0].String())
|
||||
}
|
||||
|
||||
func debugValues(v []js.Value) {
|
||||
for k, v := range map[string]interface{}{
|
||||
"timestamp": timestamp,
|
||||
|
@ -190,15 +227,17 @@ func debugValues(v []js.Value) {
|
|||
}
|
||||
|
||||
func main() {
|
||||
common.SetupLogging(common.LLDebug, "")
|
||||
|
||||
js.Set("processMessageKey", js.FuncOf(processMessageKey))
|
||||
js.Set("sendMessage", js.FuncOf(send))
|
||||
js.Set("isValidColor", js.FuncOf(isValidColor))
|
||||
js.Set("isValidName", js.FuncOf(isValidName))
|
||||
|
||||
js.Set("recieveMessage", js.CallbackOf(recieve))
|
||||
js.Set("processMessage", js.CallbackOf(processMessage))
|
||||
js.Set("debugValues", js.CallbackOf(debugValues))
|
||||
js.Set("showTimestamp", js.CallbackOf(showTimestamp))
|
||||
js.Set("join", js.CallbackOf(join))
|
||||
|
||||
go func() {
|
||||
time.Sleep(time.Second * 1)
|
||||
|
|
Loading…
Reference in New Issue