add new event types

This commit is contained in:
2026-04-28 16:38:16 +02:00
parent 00eddfb53e
commit 79219971d0
10 changed files with 137 additions and 67 deletions
BIN
View File
Binary file not shown.
+3 -1
View File
@@ -17,6 +17,7 @@ func withCORS(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "token, Content-Type") w.Header().Set("Access-Control-Allow-Headers", "token, Content-Type")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS")
h(w, r) h(w, r)
} }
} }
@@ -30,7 +31,7 @@ func main() {
http.HandleFunc("OPTIONS /", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("OPTIONS /", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "token, Content-Type") w.Header().Set("Access-Control-Allow-Headers", "token, Content-Type")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS")
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
}) })
@@ -61,6 +62,7 @@ func main() {
http.HandleFunc("POST /connection/message", withCORS(httpRequest.HandleDm)) http.HandleFunc("POST /connection/message", withCORS(httpRequest.HandleDm))
http.HandleFunc("GET /ws", wsServer.ServeWsConnection) http.HandleFunc("GET /ws", wsServer.ServeWsConnection)
http.Handle("GET /client/", http.StripPrefix("/client/", http.FileServer(http.Dir("machine-client"))))
log.Println("beep boop; server server started") log.Println("beep boop; server server started")
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(int(config.Port)), nil)) log.Fatal(http.ListenAndServe(":"+strconv.Itoa(int(config.Port)), nil))
@@ -9,5 +9,8 @@ const (
ConnectionDeleted ConnectionDeleted
ConnectionElevated ConnectionElevated
ConnectionDeElevated ConnectionDeElevated
UserProfileChange
UserAvatarChange
UserProfileBgChange
HubMessage HubMessage
) )
+7 -34
View File
@@ -52,14 +52,7 @@ func HandleDm(response http.ResponseWriter, request *http.Request) {
var target *types.User var target *types.User
if user.Id == conn.RequestorId { target, err = getUserById(ctx, conn.GetSecondUser(user.Id))
target, err = getUserById(ctx, conn.RecipientId)
} else if user.Id == conn.RecipientId {
target, err = getUserById(ctx, conn.RequestorId)
} else {
http.Error(response, "invalid connectionid", http.StatusBadRequest)
return
}
if err != nil { if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
@@ -279,25 +272,11 @@ func HandleUserDeleteConnection(response http.ResponseWriter, request *http.Requ
return return
} }
var user2 *types.User user2, err := getUserById(ctx, conn.GetSecondUser(user.Id))
if conn.RequestorId == user.Id {
recipient, err := getUserById(ctx, conn.RecipientId)
if err != nil { if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
return return
} }
user2 = recipient
} else if conn.RecipientId == user.Id {
requestor, err := getUserById(ctx, conn.RequestorId)
if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError)
return
}
user2 = requestor
} else {
http.Error(response, "invalid connectionid", http.StatusBadRequest)
return
}
err = postgresql.ConnectionDelete(ctx, conn) err = postgresql.ConnectionDelete(ctx, conn)
if err != nil { if err != nil {
@@ -349,12 +328,7 @@ func HandleUserElevateConnection(response http.ResponseWriter, request *http.Req
} }
response.Write([]byte("elevated")) response.Write([]byte("elevated"))
var user2 *types.User user2, err := getUserById(ctx, conn.GetSecondUser(user.Id))
if conn.RequestorId == user.Id {
user2, err = getUserById(ctx, conn.RecipientId)
} else {
user2, err = getUserById(ctx, conn.RequestorId)
}
if err != nil { if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
return return
@@ -400,11 +374,10 @@ func HandleUserDeElevateConnection(response http.ResponseWriter, request *http.R
return return
} }
var user2 *types.User user2, err := getUserById(ctx, conn.GetSecondUser(user.Id))
if conn.RequestorId == user.Id { if err != nil {
user2, err = getUserById(ctx, conn.RecipientId) http.Error(response, "internal server error", http.StatusInternalServerError)
} else { return
user2, err = getUserById(ctx, conn.RequestorId)
} }
wsServer.WsSendMessageCloseIfTimeout(user2, types.WsEventMessage{ wsServer.WsSendMessageCloseIfTimeout(user2, types.WsEventMessage{
+54 -14
View File
@@ -2,10 +2,15 @@ package httpRequest
import ( import (
json2 "encoding/json" json2 "encoding/json"
"maps"
"net/http"
"slices"
"strings"
"go-socket/packages/Enums/WsEventType"
"go-socket/packages/postgresql" "go-socket/packages/postgresql"
"go-socket/packages/types" "go-socket/packages/types"
"net/http" "go-socket/packages/wsServer"
"strings"
"go-socket/packages/config" "go-socket/packages/config"
"go-socket/packages/convertions" "go-socket/packages/convertions"
@@ -100,21 +105,39 @@ func HandleSetUserAvatar(response http.ResponseWriter, request *http.Request) {
return return
} }
if user.AvatarUrl != "" { if user.AvatarType != "" {
if err = minio.Delete(ctx, user.AvatarUrl); err != nil { if err = minio.Delete(ctx, user.AvatarType); err != nil {
minio.Delete(ctx, key) minio.Delete(ctx, key)
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
return return
} }
} }
user.AvatarUrl = key user.AvatarType = key
err = postgresql.UserUpdateProfile(ctx, user, &types.UserProfileUpdateList{Avatar: true}) err = postgresql.UserUpdateProfile(ctx, user, &types.UserProfileUpdateList{Avatar: true})
if err != nil { if err != nil {
http.Error(response, "failed to update user avatar", http.StatusInternalServerError) http.Error(response, "failed to update user avatar", http.StatusInternalServerError)
minio.Delete(ctx, user.AvatarUrl) minio.Delete(ctx, user.AvatarType)
return return
} }
user.Mu.RLock()
connections := slices.Collect(maps.Values(user.Connections))
user.Mu.RUnlock()
for _, conn := range connections {
targetId := conn.GetSecondUser(user.Id)
target, err := getUserById(ctx, targetId)
if err != nil {
continue
}
wsServer.WsSendMessageCloseIfTimeout(target, types.WsEventMessage{
Type: WsEventType.UserAvatarChange,
Event: &map[string]any{
"userId": user.Id,
},
})
}
response.WriteHeader(http.StatusCreated) response.WriteHeader(http.StatusCreated)
} }
@@ -142,12 +165,12 @@ func HandleGetUserAvatar(response http.ResponseWriter, request *http.Request) {
return return
} }
if target.AvatarUrl == "" { if target.AvatarType == "" {
http.Error(response, "user have no avatar", http.StatusNoContent) http.Error(response, "user have no avatar", http.StatusNoContent)
return return
} }
url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, target.AvatarUrl) url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, target.AvatarType)
if err != nil { if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
return return
@@ -203,21 +226,38 @@ func HandleSetUserProfileBg(response http.ResponseWriter, request *http.Request)
return return
} }
if user.ProfileBgUrl != "" { if user.ProfileBgType != "" {
if err = minio.Delete(ctx, user.ProfileBgUrl); err != nil { if err = minio.Delete(ctx, user.ProfileBgType); err != nil {
minio.Delete(ctx, key) minio.Delete(ctx, key)
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
return return
} }
} }
user.ProfileBgUrl = key user.ProfileBgType = key
err = postgresql.UserUpdateProfile(ctx, user, &types.UserProfileUpdateList{ProfileBg: true}) err = postgresql.UserUpdateProfile(ctx, user, &types.UserProfileUpdateList{ProfileBg: true})
if err != nil { if err != nil {
http.Error(response, "failed to update user profile background", http.StatusInternalServerError) http.Error(response, "failed to update user profile background", http.StatusInternalServerError)
minio.Delete(ctx, user.ProfileBgUrl) minio.Delete(ctx, user.ProfileBgType)
return return
} }
user.Mu.RLock()
connections := slices.Collect(maps.Values(user.Connections))
user.Mu.RUnlock()
for _, conn := range connections {
target, err := getUserById(ctx, conn.GetSecondUser(user.Id))
if err != nil {
continue
}
wsServer.WsSendMessageCloseIfTimeout(target, types.WsEventMessage{
Type: WsEventType.UserProfileBgChange,
Event: &map[string]any{
"userId": user.Id,
},
})
}
response.WriteHeader(http.StatusCreated) response.WriteHeader(http.StatusCreated)
} }
@@ -245,12 +285,12 @@ func HandleGetUserProfileBg(response http.ResponseWriter, request *http.Request)
return return
} }
if target.ProfileBgUrl == "" { if target.ProfileBgType == "" {
http.Error(response, "user have no profile background", http.StatusNoContent) http.Error(response, "user have no profile background", http.StatusNoContent)
return return
} }
url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, target.ProfileBgUrl) url, meta, err := minio.GetDownloadUrlAndMetadata(ctx, target.ProfileBgType)
if err != nil { if err != nil {
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
return return
+1
View File
@@ -31,6 +31,7 @@ func validCheckWithResponseOnFail(response *http.ResponseWriter, request *http.R
} }
if request.ContentLength > maxSize { if request.ContentLength > maxSize {
io.Copy(io.Discard, request.Body)
http.Error(*response, "Request too large", http.StatusRequestEntityTooLarge) http.Error(*response, "Request too large", http.StatusRequestEntityTooLarge)
return false return false
} }
+13
View File
@@ -155,3 +155,16 @@ func HandleHubJoin(response http.ResponseWriter, request *http.Request) {
hub.Users[hubUser.OriginalId] = hubUser hub.Users[hubUser.OriginalId] = hubUser
addHubUserToPermissionCache(hub, hubUser) addHubUserToPermissionCache(hub, hubUser)
} }
// func HandleHubMessage(response http.ResponseWriter, request *http.Request) {
// if !validCheckWithResponseOnFail(&response, request, normal) {
// return
// }
// ctx := request.Context()
// user, hubUser, hub, err := getHubUserIfValidWithResponseOnFail(ctx, response, request.Header.Get("token"), request.FormValue("hubid"))
// if err != nil {
// return
// }
//
//
// }
+31
View File
@@ -2,15 +2,19 @@ package httpRequest
import ( import (
json2 "encoding/json" json2 "encoding/json"
"maps"
"net/http" "net/http"
"slices"
"time" "time"
"go-socket/packages/Enums/WsEventType"
"go-socket/packages/cache" "go-socket/packages/cache"
"go-socket/packages/convertions" "go-socket/packages/convertions"
"go-socket/packages/passwords" "go-socket/packages/passwords"
"go-socket/packages/postgresql" "go-socket/packages/postgresql"
"go-socket/packages/tokens" "go-socket/packages/tokens"
"go-socket/packages/types" "go-socket/packages/types"
"go-socket/packages/wsServer"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
@@ -150,6 +154,7 @@ func HandleUserModProfile(response http.ResponseWriter, request *http.Request) {
} }
updateList := &types.UserProfileUpdateList{} updateList := &types.UserProfileUpdateList{}
updatedValues := map[string]any{}
if pronouns := request.FormValue("pronouns"); pronouns != "" { if pronouns := request.FormValue("pronouns"); pronouns != "" {
if len(pronouns) > 32 { if len(pronouns) > 32 {
@@ -158,6 +163,7 @@ func HandleUserModProfile(response http.ResponseWriter, request *http.Request) {
} }
user.Pronouns = pronouns user.Pronouns = pronouns
updateList.Pronouns = true updateList.Pronouns = true
updatedValues["pronouns"] = pronouns
} }
if description := request.FormValue("description"); description != "" { if description := request.FormValue("description"); description != "" {
@@ -167,6 +173,7 @@ func HandleUserModProfile(response http.ResponseWriter, request *http.Request) {
} }
user.Description = description user.Description = description
updateList.Description = true updateList.Description = true
updatedValues["description"] = description
} }
if colorStr := request.FormValue("color"); colorStr != "" { if colorStr := request.FormValue("color"); colorStr != "" {
@@ -177,6 +184,12 @@ func HandleUserModProfile(response http.ResponseWriter, request *http.Request) {
} }
user.Color = color user.Color = color
updateList.Color = true updateList.Color = true
updatedValues["color"] = color
}
if len(updatedValues) == 0 {
http.Error(response, "no values", http.StatusBadRequest)
return
} }
err = postgresql.UserUpdateProfile(ctx, user, updateList) err = postgresql.UserUpdateProfile(ctx, user, updateList)
@@ -184,6 +197,24 @@ func HandleUserModProfile(response http.ResponseWriter, request *http.Request) {
http.Error(response, "internal server error", http.StatusInternalServerError) http.Error(response, "internal server error", http.StatusInternalServerError)
return return
} }
user.Mu.RLock()
connections := slices.Collect(maps.Values(user.Connections))
user.Mu.RUnlock()
for _, conn := range connections {
target, err := getUserById(ctx, conn.GetSecondUser(user.Id))
if err != nil {
continue
}
wsServer.WsSendMessageCloseIfTimeout(target, types.WsEventMessage{
Type: WsEventType.UserProfileChange,
Event: &map[string]any{
"userId": user.Id,
"profileChangeList": updatedValues,
},
})
}
response.WriteHeader(http.StatusAccepted) response.WriteHeader(http.StatusAccepted)
} }
+4 -4
View File
@@ -95,7 +95,7 @@ func UserGetStandardInfoByName(ctx context.Context, user *types.User) error {
var rgba int64 var rgba int64
err := dbConn.QueryRow(ctx, ` err := dbConn.QueryRow(ctx, `
SELECT id, name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE name = $1 SELECT id, name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE name = $1
`, user.Name).Scan(&user.Id, &user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.AvatarUrl, &user.ProfileBgUrl) `, user.Name).Scan(&user.Id, &user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.AvatarType, &user.ProfileBgType)
if err == nil { if err == nil {
user.Color = convertions.Uint32ToRgba(uint32(rgba)) user.Color = convertions.Uint32ToRgba(uint32(rgba))
} }
@@ -106,7 +106,7 @@ func UserGetById(ctx context.Context, user *types.User) error {
var rgba int64 var rgba int64
err := dbConn.QueryRow(ctx, ` err := dbConn.QueryRow(ctx, `
SELECT name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE id = $1 SELECT name, pass_hash, COALESCE(pronouns, ''), rgba, created_at, COALESCE(avatar, ''), COALESCE(profile_bg, '') FROM users WHERE id = $1
`, user.Id).Scan(&user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.AvatarUrl, &user.ProfileBgUrl) `, user.Id).Scan(&user.Name, &user.PasswordHash, &user.Pronouns, &rgba, &user.CreatedAt, &user.AvatarType, &user.ProfileBgType)
if err == nil { if err == nil {
user.Color = convertions.Uint32ToRgba(uint32(rgba)) user.Color = convertions.Uint32ToRgba(uint32(rgba))
} }
@@ -135,12 +135,12 @@ func UserUpdateProfile(ctx context.Context, user *types.User, updateList *types.
} }
if updateList.Avatar { if updateList.Avatar {
setClauses = append(setClauses, fmt.Sprintf("avatar = $%d", argIdx)) setClauses = append(setClauses, fmt.Sprintf("avatar = $%d", argIdx))
args = append(args, user.AvatarUrl) args = append(args, user.AvatarType)
argIdx++ argIdx++
} }
if updateList.ProfileBg { if updateList.ProfileBg {
setClauses = append(setClauses, fmt.Sprintf("profile_bg = $%d", argIdx)) setClauses = append(setClauses, fmt.Sprintf("profile_bg = $%d", argIdx))
args = append(args, user.ProfileBgUrl) args = append(args, user.ProfileBgType)
argIdx++ argIdx++
} }
+9 -2
View File
@@ -30,8 +30,8 @@ type User struct {
Name string `json:"name"` Name string `json:"name"`
Pronouns string `json:"pronouns"` Pronouns string `json:"pronouns"`
Description string `json:"description"` Description string `json:"description"`
AvatarUrl string `json:"avatarUrl"` AvatarType string `json:"avatarType"`
ProfileBgUrl string `json:"profileBackgroundUrl"` ProfileBgType string `json:"profileBackgroundType"`
PasswordHash string `json:"-"` PasswordHash string `json:"-"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
WsConn *websocket.Conn `json:"-"` WsConn *websocket.Conn `json:"-"`
@@ -95,6 +95,13 @@ func (conn *Connection) GetSortedMessagesBuff() ([]*Message, uint32) {
return sorted, size return sorted, size
} }
func (conn *Connection) GetSecondUser(id uuid.UUID) uuid.UUID {
if id == conn.RequestorId {
return conn.RecipientId
}
return conn.RequestorId
}
type ConnectionStatusSetData struct { type ConnectionStatusSetData struct {
Id uuid.UUID `json:"id"` Id uuid.UUID `json:"id"`
NewState ConnectionState.ConnectionState `json:"newState"` NewState ConnectionState.ConnectionState `json:"newState"`