diff --git a/Enums/WsEventType/WsMessageFrom.go b/Enums/WsEventType/WsMessageFrom.go
new file mode 100644
index 0000000..ac7c5ed
--- /dev/null
+++ b/Enums/WsEventType/WsMessageFrom.go
@@ -0,0 +1,11 @@
+package WsEventType
+
+type WsEventType uint8
+
+const (
+ Authentication WsEventType = iota
+ DirectMessage
+ ConnectionCreated
+ ConnectionDeleted
+ ConnectionElevated
+)
diff --git a/Enums/WsMessageFrom/WsMessageFrom.go b/Enums/WsMessageFrom/WsMessageFrom.go
deleted file mode 100644
index 8db0175..0000000
--- a/Enums/WsMessageFrom/WsMessageFrom.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package WsMessageFrom
-
-type WsMessageToUserFrom uint8
-
-const (
- Server WsMessageToUserFrom = iota
- DirectMessage
- Group
-)
diff --git a/go-socket b/go-socket
index a5479d0..11959d7 100755
Binary files a/go-socket and b/go-socket differ
diff --git a/httpConnectionAndDm.go b/httpConnectionAndDm.go
index c2ce932..a368a96 100644
--- a/httpConnectionAndDm.go
+++ b/httpConnectionAndDm.go
@@ -8,6 +8,7 @@ import (
"time"
"go-socket/Enums/ConnectionState"
+ "go-socket/Enums/WsEventType"
"github.com/google/uuid"
)
@@ -64,7 +65,10 @@ func HttpHandleDm(response http.ResponseWriter, request *http.Request) {
Receiver: conn.Id,
}
- WsMessageSendToUser(target, message)
+ WsSendMessageCloseIfTimeout(target, WsEventMessage{
+ Type: WsEventType.DirectMessage,
+ Event: message,
+ })
err = DbMessageSave(ctx, message)
if err != nil {
@@ -201,6 +205,11 @@ func HttpHandleUserNewConnection(response http.ResponseWriter, request *http.Req
}
CacheAddConnection(requestor, recipient, connection)
+ WsSendMessageCloseIfTimeout(recipient, WsEventMessage{
+ Type: WsEventType.ConnectionCreated,
+ Event: connection,
+ })
+
response.WriteHeader(http.StatusCreated)
return
}
@@ -256,6 +265,10 @@ func HttpHandleUserDeleteConnection(response http.ResponseWriter, request *http.
}
CacheDeleteConnection(user, user2, connectionId)
+ WsSendMessageCloseIfTimeout(user2, WsEventMessage{
+ Type: WsEventType.ConnectionDeleted,
+ Event: connectionId,
+ })
response.WriteHeader(http.StatusAccepted)
}
@@ -281,29 +294,53 @@ func HttpHandleUserElevateConnection(response http.ResponseWriter, request *http
return
}
- if conn.RecipientId != user.Id {
- http.Error(response, "invalid connectionid", http.StatusBadRequest)
- return
- }
-
- switch conn.State {
- case ConnectionState.Stranger:
- conn.State = ConnectionState.Friend
- break
- case ConnectionState.GroupFellow:
- conn.State = ConnectionState.Stranger
- break
- default:
- http.Error(response, "cannot elevate further", http.StatusBadRequest)
- return
- }
-
- err = DbConnectionUpdateState(ctx, conn)
- if err != nil {
- http.Error(response, "internal server error", http.StatusInternalServerError)
- return
- }
response.WriteHeader(http.StatusAccepted)
+
+ // TODO change to != "" after user id via uuid
+ if conn.UserWantingToElevate != 0 && conn.UserWantingToElevate != user.Id {
+ switch conn.State {
+ case ConnectionState.Stranger:
+ conn.State = ConnectionState.Friend
+ break
+ case ConnectionState.GroupFellow:
+ conn.State = ConnectionState.Stranger
+ break
+ default:
+ http.Error(response, "cannot elevate further", http.StatusBadRequest)
+ return
+ }
+
+ err = DbConnectionUpdateState(ctx, conn)
+ if err != nil {
+ http.Error(response, "internal server error", http.StatusInternalServerError)
+ return
+ }
+ response.Write([]byte("elevated"))
+
+ var user2 *User
+ if conn.RequestorId == user.Id {
+ user2, err = GetUserById(ctx, conn.RecipientId)
+ } else {
+ user2, err = GetUserById(ctx, conn.RequestorId)
+ }
+ if err != nil {
+ http.Error(response, "internal server error", http.StatusInternalServerError)
+ return
+ }
+
+ WsSendMessageCloseIfTimeout(user2, WsEventMessage{
+ Type: WsEventType.ConnectionElevated,
+ Event: ConnectionElevationData{
+ Id: connectionId,
+ NewState: conn.State,
+ },
+ })
+
+ return
+ }
+
+ conn.UserWantingToElevate = user.Id
+ response.Write([]byte("waiting for second user to elevate"))
}
func HttpHandleUserGetConnections(response http.ResponseWriter, request *http.Request) {
diff --git a/httpGroup.go b/httpGroup.go
index 46ea877..816263b 100644
--- a/httpGroup.go
+++ b/httpGroup.go
@@ -338,7 +338,7 @@ func HttpHandleGroupMessage(response http.ResponseWriter, request *http.Request)
return
}
- err = WsSendToGroup(group, user, content)
+ err = WsSendToGroupAsUser(group, user, content)
if err != nil {
http.Error(response, err.Error(), http.StatusBadRequest)
return
diff --git a/httpUser.go b/httpUser.go
index 3a6296c..2f059e5 100644
--- a/httpUser.go
+++ b/httpUser.go
@@ -53,13 +53,13 @@ func HttpHandleUserNewToken(response http.ResponseWriter, request *http.Request)
token, err := TokenCreate(user.Id)
if err != nil {
- http.Error(response, "internal server error2", http.StatusInternalServerError)
+ http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
json, err := json2.Marshal(LoginReturn{Token: token, UserId: user.Id})
if err != nil {
- http.Error(response, "internal server error3", http.StatusInternalServerError)
+ http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
diff --git a/machine-client/index.html b/machine-client/index.html
index 0b62d7e..d62ffba 100644
--- a/machine-client/index.html
+++ b/machine-client/index.html
@@ -73,7 +73,6 @@
-
@@ -81,6 +80,7 @@
+
@@ -164,14 +164,6 @@
],
submit: () => httpPost('/mod/connection/accept', { token:'ca-token', connectionid:'ca-connectionid' })
},
- 'delete-connection': {
- title: 'POST /mod/connection/delete — delete connection',
- fields: [
- { id: 'cd-token', label: 'token', ph: '' },
- { id: 'cd-connectionid', label: 'connectionid', ph: 'UUID' },
- ],
- submit: () => httpPost('/mod/connection/delete', { token:'cd-token', connectionid:'cd-connectionid' })
- },
'add-users': {
title: 'POST /mod/group/addusers — add users (owner only)',
fields: [
@@ -230,6 +222,13 @@
],
submit: () => httpPost('/get/group/members', { token:'gm-token', group:'gm-group' })
},
+ 'del-user': {
+ title: 'POST /del/user — delete own account',
+ fields: [
+ { id: 'du-token', label: 'token', ph: '' },
+ ],
+ submit: () => httpPost('/del/user', { token:'du-token' })
+ },
'del-group': {
title: 'POST /del/group — delete group (owner only)',
fields: [
diff --git a/structs.go b/structs.go
index 184eb56..f6aad1c 100644
--- a/structs.go
+++ b/structs.go
@@ -5,6 +5,7 @@ import (
"time"
"go-socket/Enums/ConnectionState"
+ "go-socket/Enums/WsEventType"
"github.com/coder/websocket"
"github.com/google/uuid"
@@ -24,15 +25,16 @@ type User struct {
}
type Connection struct {
- Mu sync.RWMutex `json:"-"`
- Id uuid.UUID `json:"id"`
- CreatedAt time.Time `json:"createdAt"`
- MessagesBuff [MaxDirectMsgCache]*Message `json:"-"`
- NextBuffIdx uint32 `json:"-"`
- HaveOverflowed bool `json:"-"`
- RequestorId uint32 `json:"requestorId"`
- RecipientId uint32 `json:"recipientId"`
- State ConnectionState.ConnectionState `json:"state"`
+ Mu sync.RWMutex `json:"-"`
+ Id uuid.UUID `json:"id"`
+ CreatedAt time.Time `json:"createdAt"`
+ MessagesBuff [MaxDirectMsgCache]*Message `json:"-"`
+ NextBuffIdx uint32 `json:"-"`
+ RequestorId uint32 `json:"requestorId"`
+ RecipientId uint32 `json:"recipientId"`
+ UserWantingToElevate uint32 `json:"userWantingToElevate"` // TODO add to database
+ HaveOverflowed bool `json:"-"`
+ State ConnectionState.ConnectionState `json:"state"`
}
func (conn *Connection) AddMessageToBuff(message *Message) {
@@ -62,12 +64,17 @@ func (conn *Connection) GetSortedMessagesBuff() (*[MaxDirectMsgCache]*Message, u
return sorted, MaxDirectMsgCache
}
+type ConnectionElevationData struct {
+ Id uuid.UUID `json:"id"`
+ NewState ConnectionState.ConnectionState `json:"newState"`
+}
+
type Message struct {
- Id uuid.UUID `json:"id"`
- Content string `json:"content"`
- CreatedAt time.Time `json:"createdAt"`
- Sender uint32 `json:"sender"`
- Receiver uuid.UUID `json:"receiver"`
+ Id uuid.UUID `json:"id"`
+ Content string `json:"content"`
+ CreatedAt time.Time `json:"createdAt"`
+ Sender uint32 `json:"sender"`
+ Receiver uuid.UUID `json:"receiver"`
}
type Group struct {
@@ -85,3 +92,13 @@ type LoginReturn struct {
Token string `json:"token"`
UserId uint32 `json:"userId"`
}
+
+type WsEventMessage struct {
+ Type WsEventType.WsEventType `json:"type"`
+ Event any `json:"event"`
+}
+
+type WsAuthMessage struct {
+ Success bool `json:"success"`
+ Error string `json:"error"`
+}
diff --git a/wsServer.go b/wsServer.go
index 62460ba..494aa69 100644
--- a/wsServer.go
+++ b/wsServer.go
@@ -7,7 +7,7 @@ import (
"net/http"
"time"
- "go-socket/Enums/WsMessageFrom"
+ "go-socket/Enums/WsEventType"
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
@@ -54,21 +54,7 @@ func ServeWsConnection(responseWriter http.ResponseWriter, request *http.Request
}
}
-func sendMessageStructCloseIfTimeout(user *User, message *Message) {
- if user.WsConn == nil {
- return
- }
-
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
-
- err := wsjson.Write(ctx, user.WsConn, message)
- if err != nil {
- log.Printf("json write error: %v", err)
- }
-}
-
-func sendMessageCloseIfTimeout(user *User, message *map[string]any) {
+func WsSendMessageCloseIfTimeout(user *User, message any) {
if user.WsConn == nil {
return
}
@@ -94,65 +80,64 @@ func sendToAllMessageCloseIfTimeout(message *map[string]any) {
mu.RUnlock()
for _, user := range users {
- sendMessageCloseIfTimeout(user, message)
+ WsSendMessageCloseIfTimeout(user, message)
}
}
-func WsMessageSendToUser(to *User, message *Message) {
- sendMessageStructCloseIfTimeout(to, message)
-}
-
-func WsSendToGroup(group *Group, sender *User, message string) error {
+func WsSendToGroupAsUser(group *Group, sender *User, message string) error {
for groupUserId := range group.Users {
groupUser, err := CacheGetUserById(groupUserId)
if err != nil || groupUser.Id == sender.Id {
continue
}
+ // TODO update on groups rework
var msg = map[string]any{
- "type": WsMessageFrom.Group,
+ // "type": WsEventType.Group,
"from": group.Id,
"sender": sender.Id,
"content": message,
}
- sendMessageCloseIfTimeout(groupUser, &msg)
+ WsSendMessageCloseIfTimeout(groupUser, &msg)
}
return nil
}
func handleAuthenticatedMessage(user *User, userMessage *map[string]any) bool {
- sendMessageCloseIfTimeout(user, userMessage)
+ WsSendMessageCloseIfTimeout(user, userMessage)
return true
}
func handleUnauthenticatedMessage(ctx context.Context, user *User, userMessage *map[string]any) bool {
token, ok := (*userMessage)["token"].(string)
+ response := WsEventMessage{Type: WsEventType.Authentication}
+
if !ok {
- var msg = map[string]any{
- "type": WsMessageFrom.Server,
- "error": "no token in message",
+ response.Event = WsAuthMessage{
+ Success: false,
+ Error: "no token in message",
}
- sendMessageCloseIfTimeout(user, &msg)
+ WsSendMessageCloseIfTimeout(user, response)
return false
}
userId, err := TokenValidateGetId(token)
if err != nil {
- var msg = map[string]any{
- "type": WsMessageFrom.Server,
- "error": "invalid token",
+ response.Event = WsAuthMessage{
+ Success: false,
+ Error: "invalid token",
}
- sendMessageCloseIfTimeout(user, &msg)
+ WsSendMessageCloseIfTimeout(user, response)
return false
}
userFromCache, err := CacheGetUserById(userId)
if err != nil {
- var msg = map[string]any{
- "type": WsMessageFrom.Server,
- "error": "user not found",
+ response.Event = WsAuthMessage{
+ Success: false,
+ Error: "user not found",
}
- sendMessageCloseIfTimeout(user, &msg)
+ WsSendMessageCloseIfTimeout(user, response)
return false
}
@@ -166,25 +151,31 @@ func handleUnauthenticatedMessage(ctx context.Context, user *User, userMessage *
err = DbGroupGetById(ctx, dbGroup)
if err != nil {
- var msg = map[string]any{
- "type": "server",
- "error": "invalid user data",
+ response.Event = WsAuthMessage{
+ Success: false,
+ Error: "invalid user data",
}
- sendMessageCloseIfTimeout(user, &msg)
+ WsSendMessageCloseIfTimeout(user, response)
return false
}
err = DbGroupGetMembers(ctx, dbGroup)
if err != nil {
- var msg = map[string]any{
- "type": "server",
- "error": "invalid user data",
+ response.Event = WsAuthMessage{
+ Success: false,
+ Error: "invalid user data",
}
- sendMessageCloseIfTimeout(user, &msg)
+ WsSendMessageCloseIfTimeout(user, response)
return false
}
CacheSaveGroup(dbGroup)
}
}
+
+ response.Event = WsAuthMessage{
+ Success: true,
+ Error: "",
+ }
+ WsSendMessageCloseIfTimeout(user, response)
return true
}