mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
WIP: legacy WS.
This commit is contained in:
parent
5527642878
commit
e4c0c68d79
@ -34,7 +34,7 @@ export class WebsocketReconnector extends ReconnectorAbstract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let url = this._state.url
|
let url = this._state.url
|
||||||
url = url.replace(/^http/, 'ws').replace(/\/+$/, '') + '/api/ws'
|
url = url.replace(/^http/, 'ws').replace(/\/+$/, '') + '/ws'
|
||||||
|
|
||||||
const token = this._state.token
|
const token = this._state.token
|
||||||
if (token) {
|
if (token) {
|
||||||
|
@ -16,6 +16,11 @@ export default defineConfig({
|
|||||||
server: {
|
server: {
|
||||||
port: 3001,
|
port: 3001,
|
||||||
proxy: process.env.NEKO_HOST ? {
|
proxy: process.env.NEKO_HOST ? {
|
||||||
|
'/ws': {
|
||||||
|
target: 'http://' + process.env.NEKO_HOST + ':' + process.env.NEKO_PORT + '/',
|
||||||
|
changeOrigin: true,
|
||||||
|
ws: true
|
||||||
|
},
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://' + process.env.NEKO_HOST + ':' + process.env.NEKO_PORT + '/',
|
target: 'http://' + process.env.NEKO_HOST + ':' + process.env.NEKO_PORT + '/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
64
server/internal/http/legacy/event/events.go
Normal file
64
server/internal/http/legacy/event/events.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package event
|
||||||
|
|
||||||
|
const (
|
||||||
|
SYSTEM_INIT = "system/init"
|
||||||
|
SYSTEM_DISCONNECT = "system/disconnect"
|
||||||
|
SYSTEM_ERROR = "system/error"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SIGNAL_OFFER = "signal/offer"
|
||||||
|
SIGNAL_ANSWER = "signal/answer"
|
||||||
|
SIGNAL_PROVIDE = "signal/provide"
|
||||||
|
SIGNAL_CANDIDATE = "signal/candidate"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MEMBER_LIST = "member/list"
|
||||||
|
MEMBER_CONNECTED = "member/connected"
|
||||||
|
MEMBER_DISCONNECTED = "member/disconnected"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CONTROL_LOCKED = "control/locked"
|
||||||
|
CONTROL_RELEASE = "control/release"
|
||||||
|
CONTROL_REQUEST = "control/request"
|
||||||
|
CONTROL_REQUESTING = "control/requesting"
|
||||||
|
CONTROL_GIVE = "control/give"
|
||||||
|
CONTROL_CLIPBOARD = "control/clipboard"
|
||||||
|
CONTROL_KEYBOARD = "control/keyboard"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CHAT_MESSAGE = "chat/message"
|
||||||
|
CHAT_EMOTE = "chat/emote"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FILETRANSFER_LIST = "filetransfer/list"
|
||||||
|
FILETRANSFER_REFRESH = "filetransfer/refresh"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SCREEN_CONFIGURATIONS = "screen/configurations"
|
||||||
|
SCREEN_RESOLUTION = "screen/resolution"
|
||||||
|
SCREEN_SET = "screen/set"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BROADCAST_STATUS = "broadcast/status"
|
||||||
|
BROADCAST_CREATE = "broadcast/create"
|
||||||
|
BROADCAST_DESTROY = "broadcast/destroy"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ADMIN_BAN = "admin/ban"
|
||||||
|
ADMIN_KICK = "admin/kick"
|
||||||
|
ADMIN_LOCK = "admin/lock"
|
||||||
|
ADMIN_MUTE = "admin/mute"
|
||||||
|
ADMIN_UNLOCK = "admin/unlock"
|
||||||
|
ADMIN_UNMUTE = "admin/unmute"
|
||||||
|
ADMIN_CONTROL = "admin/control"
|
||||||
|
ADMIN_RELEASE = "admin/release"
|
||||||
|
ADMIN_GIVE = "admin/give"
|
||||||
|
)
|
175
server/internal/http/legacy/handler.go
Normal file
175
server/internal/http/legacy/handler.go
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
package legacy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/demodesk/neko/pkg/types"
|
||||||
|
"github.com/demodesk/neko/pkg/utils"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// DefaultUpgrader specifies the parameters for upgrading an HTTP
|
||||||
|
// connection to a WebSocket connection.
|
||||||
|
DefaultUpgrader = &websocket.Upgrader{
|
||||||
|
ReadBufferSize: 1024,
|
||||||
|
WriteBufferSize: 1024,
|
||||||
|
CheckOrigin: func(r *http.Request) bool {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultDialer is a dialer with all fields set to the default zero values.
|
||||||
|
DefaultDialer = websocket.DefaultDialer
|
||||||
|
)
|
||||||
|
|
||||||
|
type LegacyHandler struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *LegacyHandler {
|
||||||
|
// Init
|
||||||
|
|
||||||
|
return &LegacyHandler{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *LegacyHandler) Route(r types.Router) {
|
||||||
|
log.Println("legacy handler route")
|
||||||
|
|
||||||
|
r.Get("/ws", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
connBackend, _, err := DefaultDialer.Dial("ws://127.0.0.1:8080/api/ws?token="+r.URL.Query().Get("token"), nil)
|
||||||
|
if err != nil {
|
||||||
|
return utils.HttpError(http.StatusServiceUnavailable).
|
||||||
|
WithInternalErr(err).
|
||||||
|
Msg("couldn't dial to remote backend url")
|
||||||
|
}
|
||||||
|
defer connBackend.Close()
|
||||||
|
|
||||||
|
connClient, err := DefaultUpgrader.Upgrade(w, r, nil)
|
||||||
|
if err != nil {
|
||||||
|
return utils.HttpError(http.StatusInternalServerError).
|
||||||
|
WithInternalErr(err).
|
||||||
|
Msg("couldn't upgrade connection to websocket")
|
||||||
|
}
|
||||||
|
defer connClient.Close()
|
||||||
|
|
||||||
|
errClient := make(chan error, 1)
|
||||||
|
errBackend := make(chan error, 1)
|
||||||
|
replicateWebsocketConn := func(dst, src *websocket.Conn, errc chan error, rewriteTextMessage func([]byte) ([]byte, error)) {
|
||||||
|
for {
|
||||||
|
msgType, msg, err := src.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
m := websocket.FormatCloseMessage(websocket.CloseNormalClosure, fmt.Sprintf("%v", err))
|
||||||
|
if e, ok := err.(*websocket.CloseError); ok {
|
||||||
|
if e.Code != websocket.CloseNoStatusReceived {
|
||||||
|
m = websocket.FormatCloseMessage(e.Code, e.Text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errc <- err
|
||||||
|
dst.WriteMessage(websocket.CloseMessage, m)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if msgType == websocket.TextMessage {
|
||||||
|
msg, err = rewriteTextMessage(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("websocketproxy: Error when rewriting message: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = dst.WriteMessage(msgType, msg)
|
||||||
|
if err != nil {
|
||||||
|
errc <- err
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// client -> backend
|
||||||
|
go replicateWebsocketConn(connClient, connBackend, errClient, h.wsToBackend)
|
||||||
|
|
||||||
|
// backend -> client
|
||||||
|
go replicateWebsocketConn(connBackend, connClient, errBackend, h.wsToClient)
|
||||||
|
|
||||||
|
var message string
|
||||||
|
select {
|
||||||
|
case err = <-errClient:
|
||||||
|
message = "websocketproxy: Error when copying from backend to client: %v"
|
||||||
|
case err = <-errBackend:
|
||||||
|
message = "websocketproxy: Error when copying from client to backend: %v"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, ok := err.(*websocket.CloseError); !ok || e.Code == websocket.CloseAbnormalClosure {
|
||||||
|
log.Printf(message, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
r.Get("/stats", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
password := r.URL.Query().Get("pwd")
|
||||||
|
isAdmin, err := webSocketHandler.IsAdmin(password)
|
||||||
|
if err != nil {
|
||||||
|
return utils.HttpForbidden(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isAdmin {
|
||||||
|
return utils.HttpUnauthorized().Msg("bad authorization")
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
stats := webSocketHandler.Stats()
|
||||||
|
return json.NewEncoder(w).Encode(stats)
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Get("/screenshot.jpg", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
password := r.URL.Query().Get("pwd")
|
||||||
|
isAdmin, err := webSocketHandler.IsAdmin(password)
|
||||||
|
if err != nil {
|
||||||
|
return utils.HttpForbidden(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isAdmin {
|
||||||
|
return utils.HttpUnauthorized().Msg("bad authorization")
|
||||||
|
}
|
||||||
|
|
||||||
|
if webSocketHandler.IsLocked("login") {
|
||||||
|
return utils.HttpError(http.StatusLocked).Msg("room is locked")
|
||||||
|
}
|
||||||
|
|
||||||
|
quality, err := strconv.Atoi(r.URL.Query().Get("quality"))
|
||||||
|
if err != nil {
|
||||||
|
quality = 90
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
|
w.Header().Set("Content-Type", "image/jpeg")
|
||||||
|
|
||||||
|
img := desktop.GetScreenshotImage()
|
||||||
|
if err := jpeg.Encode(w, img, &jpeg.Options{Quality: quality}); err != nil {
|
||||||
|
return utils.HttpInternalServerError().WithInternalErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// allow downloading and uploading files
|
||||||
|
if webSocketHandler.FileTransferEnabled() {
|
||||||
|
r.Get("/file", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
r.Post("/file", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
r.Get("/health", func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
_, err := w.Write([]byte("true"))
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
155
server/internal/http/legacy/message/messages.go
Normal file
155
server/internal/http/legacy/message/messages.go
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package message
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/demodesk/neko/internal/http/legacy/types"
|
||||||
|
|
||||||
|
"github.com/pion/webrtc/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemInit struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ImplicitHosting bool `json:"implicit_hosting"`
|
||||||
|
Locks map[string]string `json:"locks"`
|
||||||
|
FileTransfer bool `json:"file_transfer"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemMessage struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignalProvide struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
SDP string `json:"sdp"`
|
||||||
|
Lite bool `json:"lite"`
|
||||||
|
ICE []webrtc.ICEServer `json:"ice"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignalOffer struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
SDP string `json:"sdp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignalAnswer struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
DisplayName string `json:"displayname"`
|
||||||
|
SDP string `json:"sdp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignalCandidate struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Data string `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MembersList struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Members []*types.Member `json:"members"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Member struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
*types.Member
|
||||||
|
}
|
||||||
|
type MemberDisconnected struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Clipboard struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Keyboard struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Layout *string `json:"layout,omitempty"`
|
||||||
|
CapsLock *bool `json:"capsLock,omitempty"`
|
||||||
|
NumLock *bool `json:"numLock,omitempty"`
|
||||||
|
ScrollLock *bool `json:"scrollLock,omitempty"` // TODO: ScrollLock is deprecated.
|
||||||
|
}
|
||||||
|
|
||||||
|
type Control struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ControlTarget struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatReceive struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatSend struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmoteReceive struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Emote string `json:"emote"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmoteSend struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Emote string `json:"emote"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileTransferList struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Cwd string `json:"cwd"`
|
||||||
|
Files []types.FileListItem `json:"files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Admin struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdminTarget struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdminLock struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Resource string `json:"resource"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ScreenResolution struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Width int `json:"width"`
|
||||||
|
Height int `json:"height"`
|
||||||
|
Rate int16 `json:"rate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ScreenConfigurations struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
Configurations map[int]types.ScreenConfiguration `json:"configurations"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BroadcastStatus struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
IsActive bool `json:"isActive"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BroadcastCreate struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
20
server/internal/http/legacy/types/types.go
Normal file
20
server/internal/http/legacy/types/types.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
type Member struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"displayname"`
|
||||||
|
Admin bool `json:"admin"`
|
||||||
|
Muted bool `json:"muted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileListItem struct {
|
||||||
|
Filename string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ScreenConfiguration struct {
|
||||||
|
Width int `json:"width"`
|
||||||
|
Height int `json:"height"`
|
||||||
|
Rates map[int]int16 `json:"rates"`
|
||||||
|
}
|
161
server/internal/http/legacy/wstobackend.go
Normal file
161
server/internal/http/legacy/wstobackend.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package legacy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/demodesk/neko/internal/http/legacy/event"
|
||||||
|
"github.com/demodesk/neko/internal/http/legacy/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *LegacyHandler) wsToBackend(msg []byte) ([]byte, error) {
|
||||||
|
header := message.Message{}
|
||||||
|
err := json.Unmarshal(msg, &header)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var response any
|
||||||
|
switch header.Event {
|
||||||
|
// Signal Events
|
||||||
|
case event.SIGNAL_OFFER:
|
||||||
|
request := &message.SignalOffer{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.SIGNAL_ANSWER:
|
||||||
|
request := &message.SignalAnswer{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.SIGNAL_CANDIDATE:
|
||||||
|
request := &message.SignalCandidate{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control Events
|
||||||
|
case event.CONTROL_RELEASE:
|
||||||
|
case event.CONTROL_REQUEST:
|
||||||
|
case event.CONTROL_GIVE:
|
||||||
|
request := &message.Control{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.CONTROL_CLIPBOARD:
|
||||||
|
request := &message.Clipboard{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.CONTROL_KEYBOARD:
|
||||||
|
request := &message.Keyboard{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chat Events
|
||||||
|
case event.CHAT_MESSAGE:
|
||||||
|
request := &message.ChatReceive{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.CHAT_EMOTE:
|
||||||
|
request := &message.EmoteReceive{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// File Transfer Events
|
||||||
|
case event.FILETRANSFER_REFRESH:
|
||||||
|
|
||||||
|
// Screen Events
|
||||||
|
case event.SCREEN_RESOLUTION:
|
||||||
|
case event.SCREEN_CONFIGURATIONS:
|
||||||
|
case event.SCREEN_SET:
|
||||||
|
request := &message.ScreenResolution{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast Events
|
||||||
|
case event.BROADCAST_CREATE:
|
||||||
|
request := &message.BroadcastCreate{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.BROADCAST_DESTROY:
|
||||||
|
|
||||||
|
// Admin Events
|
||||||
|
case event.ADMIN_LOCK:
|
||||||
|
request := &message.AdminLock{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.ADMIN_UNLOCK:
|
||||||
|
request := &message.AdminLock{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.ADMIN_CONTROL:
|
||||||
|
case event.ADMIN_RELEASE:
|
||||||
|
case event.ADMIN_GIVE:
|
||||||
|
request := &message.Admin{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.ADMIN_BAN:
|
||||||
|
request := &message.Admin{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.ADMIN_KICK:
|
||||||
|
request := &message.Admin{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.ADMIN_MUTE:
|
||||||
|
request := &message.Admin{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
case event.ADMIN_UNMUTE:
|
||||||
|
request := &message.Admin{}
|
||||||
|
err := json.Unmarshal(msg, request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown event type: %s", header.Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(request)
|
||||||
|
}
|
162
server/internal/http/legacy/wstoclient.go
Normal file
162
server/internal/http/legacy/wstoclient.go
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
package legacy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/demodesk/neko/internal/http/legacy/event"
|
||||||
|
"github.com/demodesk/neko/internal/http/legacy/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *LegacyHandler) wsToClient(msg []byte) ([]byte, error) {
|
||||||
|
header := message.Message{}
|
||||||
|
err := json.Unmarshal(msg, &header)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload any
|
||||||
|
switch header.Event {
|
||||||
|
// System Events
|
||||||
|
case:
|
||||||
|
payload = &message.SystemMessage{
|
||||||
|
Event: event.SYSTEM_DISCONNECT,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.SystemMessage{
|
||||||
|
Event: event.SYSTEM_ERROR,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.SystemInit{
|
||||||
|
Event: event.SYSTEM_INIT,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Member Events
|
||||||
|
case:
|
||||||
|
payload = &message.MembersList{
|
||||||
|
Event: event.MEMBER_LIST,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.Member{
|
||||||
|
Event: event.MEMBER_CONNECTED,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.MemberDisconnected{
|
||||||
|
Event: event.MEMBER_DISCONNECTED,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal Events
|
||||||
|
case:
|
||||||
|
payload = &message.SignalOffer{
|
||||||
|
Event: event.SIGNAL_OFFER,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.SignalAnswer{
|
||||||
|
Event: event.SIGNAL_ANSWER,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.SignalCandidate{
|
||||||
|
Event: event.SIGNAL_CANDIDATE,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.SignalProvide{
|
||||||
|
Event: event.SIGNAL_PROVIDE,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control Events
|
||||||
|
case:
|
||||||
|
payload = &message.Clipboard{
|
||||||
|
Event: event.CONTROL_CLIPBOARD,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.Control{
|
||||||
|
Event: event.CONTROL_REQUEST,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.Control{
|
||||||
|
Event: event.CONTROL_REQUESTING,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.ControlTarget{
|
||||||
|
Event: event.CONTROL_GIVE,
|
||||||
|
} // message.AdminTarget
|
||||||
|
case:
|
||||||
|
payload = &message.Control{
|
||||||
|
Event: event.CONTROL_RELEASE,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.Control{
|
||||||
|
Event: event.CONTROL_LOCKED,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chat Events
|
||||||
|
case:
|
||||||
|
payload = &message.ChatSend{
|
||||||
|
Event: event.CHAT_MESSAGE,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.EmoteSend{
|
||||||
|
Event: event.CHAT_EMOTE,
|
||||||
|
}
|
||||||
|
|
||||||
|
// File Transfer Events
|
||||||
|
case:
|
||||||
|
payload = &message.FileTransferList{
|
||||||
|
Event: event.FILETRANSFER_LIST,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screen Events
|
||||||
|
case:
|
||||||
|
payload = &message.ScreenResolution{
|
||||||
|
Event: event.SCREEN_RESOLUTION,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.ScreenConfigurations{
|
||||||
|
Event: event.SCREEN_CONFIGURATIONS,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast Events
|
||||||
|
case:
|
||||||
|
payload = &message.BroadcastStatus{
|
||||||
|
Event: event.BROADCAST_STATUS,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Admin Events
|
||||||
|
case:
|
||||||
|
payload = &message.AdminLock{
|
||||||
|
Event: event.ADMIN_UNLOCK,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.AdminLock{
|
||||||
|
Event: event.ADMIN_LOCK,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.AdminTarget{
|
||||||
|
Event: event.ADMIN_CONTROL,
|
||||||
|
} // message.Admin
|
||||||
|
case:
|
||||||
|
payload = &message.AdminTarget{
|
||||||
|
Event: event.ADMIN_RELEASE,
|
||||||
|
} // message.Admin
|
||||||
|
case:
|
||||||
|
payload = &message.AdminTarget{
|
||||||
|
Event: event.ADMIN_MUTE,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.AdminTarget{
|
||||||
|
Event: event.ADMIN_UNMUTE,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.AdminTarget{
|
||||||
|
Event: event.ADMIN_KICK,
|
||||||
|
}
|
||||||
|
case:
|
||||||
|
payload = &message.AdminTarget{
|
||||||
|
Event: event.ADMIN_BAN,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown event type: %s", header.Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal(payload)
|
||||||
|
}
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"github.com/demodesk/neko/internal/config"
|
"github.com/demodesk/neko/internal/config"
|
||||||
|
"github.com/demodesk/neko/internal/http/legacy"
|
||||||
"github.com/demodesk/neko/pkg/types"
|
"github.com/demodesk/neko/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,6 +55,9 @@ func New(WebSocketManager types.WebSocketManager, ApiManager types.ApiManager, c
|
|||||||
return config.AllowOrigin(r.Header.Get("Origin"))
|
return config.AllowOrigin(r.Header.Get("Origin"))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// Legacy handler
|
||||||
|
legacy.New().Route(router)
|
||||||
|
|
||||||
batch := batchHandler{
|
batch := batchHandler{
|
||||||
Router: router,
|
Router: router,
|
||||||
PathPrefix: "/api",
|
PathPrefix: "/api",
|
||||||
|
Loading…
Reference in New Issue
Block a user